lib使用:https://www.cnblogs.com/xiaoblog/p/5776892.html
实操:https://blog.csdn.net/YP_yaopeng/article/details/107547816
Sentinel 主备切换:https://www.cnblogs.com/ericnie/p/7203950.html

主从复制模式

集群 - 图1

持久化 + 主从同步(replication) + 读写分离
缺点:Master 挂掉之后,需要手动选择一个 Master
同步机制:

  • 主从
  • 从从

配置:redis.conf -> slaveof [masterIP]

Sentinel(哨兵)模式

集群 - 图2

使用哨兵,自动选举 Master

  • Sentinel 之间是平等
  • 当发现 Master 客观下线后,Sentinel 会使用 Raft 算法,选举出领头 Sentinel(Leader)
  • 然后由 Leader 按照一定的规则选出新的 Master,并进行故障转移
  • 完成故障转移后,Sentinel 就会恢复成平等模式

配置:sentinel.conf -> sentinel monitor [instanceName] [masterIP] [port] 2

  • 一个 sentinel 可以监控多个 Redis 实例,这里不是用于分片,而是业务上的选择不同的 Redis 实例
  • 最后 2 的意思是,客观下线数量:
    • 如果多个 Sentinel 监控同一个 Redis 实例,当 2 个以上的 Sentinel 发现它挂了,才算挂

主备切换:Sentinel 只会指向 Master,并从 Master 上获取 Slave 的信息,当 Master 挂了,会自动切换

下线:

  • 主观:当前 Sentinel 与某个 Master 失去联系。有可能是个别网络故障,也有可能 Master down 了
  • 客观:指定数量的 Sentinel 与某个 Master 失去联系

客户端高可用:

  • 获取 sentinel 列表并遍历得到可用节点,然后通过 masterName 获取指定 master
  • 客户端只有在初始化和切换主节点时需要和 Sentinel 进行通信,来获取 master 信息

分片:

  • 客户端分片
  • 代理服务器分片
  • 服务器分片:上面的 Cluster 模式

分片算法:
1. 范围分片
2. 哈希分片

一致性哈希特性:

  • key 的哈希结果,要尽可能分配到不同的 Redis 实例
  • 当实例增加或移除后,需要保护已映射的内容不会被重新分配到新的实例上
  • 对 key 的哈希应该尽量避免重复

Cluster 模式:P2P

集群 - 图3

Sentinel 主从+ Cluster 分片:

  • 先对 key 进行分片,然后分别存储在不同的 Master 节点上,之后 Master 再和 Slave 进行同步

集群 - 图4

Sharding 分片技术
Redis 集群没有使用一致性 hash,而是引入了哈希槽【hash slot】的概念。
哈希槽:

  • Redis 集群有16384** **个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽。
  • 集群的每个节点负责一部分 hash 槽
  • 添加或删除节点时,只需要移动 hash 槽即可
  • 每个节点都会保存其他节点的槽信息,所以可以对任何一个节点进行操作,会转发到对应槽的节点

16384 = 2^14 = 16k bit

哈希计算:
HASH_SLOT=CRC16(key) mod 16384

优点:

  • 无需 Sentinel,如果 Master 挂了,Cluster 内部自动将 Slave 切换 Master
  • 可以进行水平扩容
  • 自动化迁移,将 Slave 迁移至其他 Master 下

缺点:

  • 批量操作麻烦
  • 资源隔离性差

Q:为什么 16384?

  • CRC16 结果为 16 bit,2^16 = 65536 = 64k,为什么要选择 mod 2^14 = 16384 = 16k?

A:如果选择 65536,那么心跳包的头会达到 8k,太大了

  • redis 集群 Master 节点数量基本不可能超过 1000 个,否则会导致网络拥堵

unsigned char myslots[CLUSTER_SLOTS/8] = 16384/8/1024 = 2kb(byte)
unsigned char 为 8 bit
65536/8/1024=8kb