Redis集群搭建及选举原理

redis集群简述
哨兵模式中如果主从中 master宕机了 , 是通过哨兵来选举出新的master , 在这个选举切换主从的过程 , 整个redis服务是不可用的 。而且哨兵模式中只有一个主节点对外提供服务 , 因此没法支持更高的并发 。而且当个主节点的内存设置也不宜过大 。否则会导致持久化文件过大 , 影响数据恢复或主从同步的效率 。
redis集群是由 一系列的 主从节点群组成的分布式服务器群 , 它具有复制、高可用和分片特性 。Redis集群不需要 sentinel哨兵也能完成节点移除和故障转移的功能 。需要将每个节点设置成集群模式 , 这种集群模式没有中心节点  , 客户端通过 CRC16算法对key进行hash
得到一个值 , 来判断该 key存储在哪个主从服务上面 , 因此就算是某一个主从整个宕机 , redis集群也是部分可用的 。方便 水平扩展 ,  可以根据业务规模可以随时加减配置 。据官方文档称可以线性扩展到上万个节点 ( 但是 官方推荐不超过 1000个节点) 。redis集群的性能和高可用性均优于哨兵模式。

Redis集群搭建及选举原理

文章插图
 
Redis 集群搭建
1. 修改 redis.conf 配置文件
  1. daemonize yes 后台启动
  2. cluster-enabled yes 开启集群模式
  3. cluster-config-file nodes-6379.conf 集群配置信息存放文件名
  4. cluster-node-timeout 5000 节点离线时间限制 , 到达此值时发起某个主从重新选举 master
  5. protected-mode no 关闭保护模式
  6. requirepass xxx 设置本机密码
  7. masterauth xxx 设置访问别的机器的密码
2. 注意关闭服务器的防火墙 , 否则可能造成节点之间无法通信 , 无法搭建集群
使用修改好的配置文件启动 redis 服务 , 我这里使用三个一主一从来搭建 。因此先将 6 个 redis 服务使用指定的配置文件 redis-master.conf 启动起来: src/redis-server redis-master.conf
3.搭建集群服务
为了保险起见最好先检查下每台机器的 redis 服务是否正常启动了 ps -ef|grep redis
可以看见 redis 服务进程后面有个 cluster 的标志 , 普通启动的 redis 服务是没有这个标志的
Redis集群搭建及选举原理

文章插图
 
5.0 版本可以直接使用 C 语言客户端提供的指令去构建集群:
src/redis-cli -a xxx --cluster create --cluster-replicas 1 192.168.0.67:6379 192.168.0.68:6379 192.168.0.69:6379 192.168.0.70:6379 192.168.0.71:6379 192.168.0.72:6379
-a 配置的密码
--cluster create 表示集群创建
--cluster-replicas 表示每个 master 几个 slave  , 上面一共 6 个 redis 节点 , 因此会构建三个一主一从 。
执行命令之前 , 如果你的 redis 环境以前搭建过主从或者哨兵之类的 , 数据不干净可能会报错 , 最好将持久化文件删掉 , 然后 flushdb  , 将以前脏数据清理掉 , 否则可能出现如下错误:
Redis集群搭建及选举原理

文章插图
 
正常执行会返回一个集群分配计划 , 我们按照它的计划即可:
Redis集群搭建及选举原理

文章插图
 
然后节点之间就开始通信构建集群 , 最后会看见 16384 个 slots 分配完毕 , 可以看见构建计划中有三个 master  , 每个 master 都是有指定槽位的 。意思就是存入的 key 经过 crc16 hash 算法之后得到的值 , 在哪个范围内 , 就存储到那个 redis 主从上面去 , 这就是 redis 的分片集群模式 。
Redis集群搭建及选举原理

文章插图
 
至此集群搭建完毕
4.集群操作
以集群方式连接 redis 客户端通过 cluster info 查看集群信息 , 通过 cluster nodes 查看节点信息
src/redis-cli -a 密码 -c 集群方式连接
Redis集群搭建及选举原理

文章插图
 
我们设置 set abc 123 一个值 会看见客户点会计算 abc 的 slot 是 7638  ,  然后重定向到对应的主从的 master 上面去写数据
Redis集群搭建及选举原理

文章插图
 
现在我看下 JAVA 客户端的 jedis 里面的 key 值计算 redis.clients.util.JedisClusterCRC16#getSlot(java.lang.String) :


推荐阅读