一个典型的高可用Redis集群示例配置
1个主服务器
2-3个从服务器
3-5个哨兵
哨兵和集群就是为了高可用
哨兵
哨兵的功能:监听和故障转移
(1)客户端可以从哨兵获得集群的状态。
(2)当主服务器断开,哨兵可以进行选举主服务器。
哨兵的工作流程
- 在配置中,设置master的ip和端口
- 创建master之间的命令连接和订阅连接
命令连接:发送命令
订阅连接:即发布与订阅功能的订阅功能,订阅了_sentinel_:hello频道,用来发布配置变更等
当一个哨兵通过命令连接向服务器发送一条命令后,服务器会再哨兵频道发布这条命令,此时订阅的所有哨兵都能感知到
- sentinel默认10秒一次通过命令连接向主服务器获取当前集群消息。(从服务器的ip,port,状态,offset等)
- 建立从服务器的命令连接和订阅哨兵频道
- 和其他哨兵建立命令连接
- 主服务器主观下线和客观下线
因为哨兵的超时下线时间配置不同,当一个哨兵检测到下线那么就是主观下线,当多个哨兵(个数需要配置)同时同意主服务器下线,那么就是客观下线
- 选举领头哨兵(随机)
- 领头哨兵进行故障转移(raft)
将一个从服务器转为主服务器,掉线主服务器重连后作为从服务器。
即向新主服务器发送slaveof no one,其他服务器发送slaveof 新主服务器的ip port
集群
redis的主从框架是为了备份和高可用,集群是为了分布式集群扩容。
集群就是将数据发布到不同的redis程序中。
使用集群功能时只能使用0号数据库。
数据分片
所有的信息都分布到槽中:
Redis 集群使用 CRC16 哈希函数来计算每个键的哈希值,然后对 16384 取模,以确定该键属于哪个槽。具体公式为:
计算一个key的hash值:slot=CRC16(key)%16384
要想集群工作,需要将1万6的槽都分配
如果 Redis 集群中的所有 16384 个槽没有被分配完,那么集群将无法正常工作。每个槽都需要被分配给一个节点,否则集群会认为它尚未完全初始化,导致集群状态为不健康。
重定向
当客户端请求的键不在当前节点负责的槽范围内时,需要进行重定向,以确保请求被正确处理。
客户端只需发送一次 GET 命令,Redis 集群会处理重定向并将结果返回给客户端。
节点间通信
Redis 集群中的所有节点(主节点和从节点)需要互相通信以交换状态信息、检测故障以及协调数据分片和故障转移。主要的通信方式包括:
Gossip 协议:节点之间使用 Gossip 协议交换集群状态信息。每个节点会定期向其他节点发送 PING 消息,并接收 PONG 响应,以检测节点的健康状况和状态变化。
Pub/Sub 机制:节点之间使用发布/订阅机制来传播集群配置更改和槽分配信息。
故障检测和转移
Redis 集群通过节点间的心跳消息和故障检测机制来实现高可用性。当主节点发生故障时,集群会自动进行故障转移(failover),具体步骤如下:
故障检测:集群中的每个节点都会定期向其他节点发送 PING 消息,以检测节点的健康状态。如果一个节点在一定时间内未能响应 PING 消息,该节点将被标记为下线。
故障确认:其他节点也会检查该节点的状态,如果大多数主节点都认为该节点下线,则该节点会被标记为故障节点。
选举新的主节点:从节点中选举一个新的主节点。选举过程由集群中的节点协同完成,通常选择拥有最新数据的从节点作为新的主节点。
角色转换:被选中的从节点会转换为主节点,并接管故障主节点的槽。其他从节点会重新配置,开始复制新的主节点的数据。
新的主节点接管了故障主节点的槽,客户端请求会被重定向到新的主节点。
开放通信端口
Redis 节点需要开放两个端口,一个是标准的 Redis 端口(默认 6379),另一个是集群总线端口(通常是 Redis 端口加 10000,例如 16379)。集群总线端口用于节点间的 Gossip 通信和故障检测。
集群配置
配置 Redis 集群时,需要确保各个节点可以正确识别和通信。常见的配置步骤包括:
配置文件:在每个 Redis 实例的配置文件中启用集群模式,并指定节点间的通信端口。例如:
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
启动集群:使用 redis-cli 工具创建和初始化集群时,确保所有节点的 IP 地址和端口正确,并且节点间可互相访问。例如:
redis-cli --cluster create 192.168.1.1:6379 192.168.1.2:6379 192.168.1.3:6379 --cluster-replicas 1
从节点加入集群
(1)正确配置 slaveof 命令:
从节点需要通过 slaveof 命令将自己配置为某个主节点的从节点。例如:
slaveof
(2)从节点需要开启集群模式:
在 Redis 集群中,所有的节点(主节点和从节点)都需要在配置文件中启用集群模式。这可以通过设置 cluster-enabled yes 来实现。
(3)集群握手和加入:
当从节点正确配置了 slaveof 命令并启用了集群模式后,它会尝试连接主节点,并进行握手和加入集群的过程。主节点会识别连接的从节点,并将其加入到集群中。从节点会从主节点同步数据,并参与集群中的数据复制和故障转移。
(4)自动发现其他节点:
一旦从节点成功加入集群,它会通过集群的 gossip 协议与其他节点通信,获取集群的配置信息和状态。
集群客户端:lettuce
在 Java 中连接 Redis 集群,通常使用的是 lettuce 或 Jedis Cluster 这两个主要的客户端库。它们都支持 Redis 集群模式,并提供了自动的节点发现、数据分片管理和自动重定向功能。