Redis Cluster
本文所使用 Redis 版本为 Redis 5。
业界方案
-
- 本质是个
proxy,通过内存保存着槽位和实例节点之间的映射关系 - 槽位间的信息同步交给
ZooKeeper管理 - 支持一些
MGET等命令,实际是自身实现了Merge功能 Pipeline操作- 不支持事务、
MSETNX等命令
- 本质是个
Redis Cluster
Redis Cluster 是 Redis 官方的集群方案,具体文档可阅读:
大致总结下一些要点如下:
-
基本特性:全网状结构(
full mest),没有中央节点、调度器、Proxy、Merge的概念,也即是所谓的P2P架构。每个节点之间都可以通信,如Heartbeat、Failover等。采用了一种类似Raft算法中term(任期)的概念epoch(纪元),进行选举等。 -
Redis Cluster Bus:每个node需要开启两个监听端口,举例如使用6379用于监听redis-client请求,另一个端口16379(默认 6379 offset 10000) 用于node之间的通信,如选举、侦测、节点变更等等。 -
gossip protocol:gossip 协议是一个去中心化、容错、保证最终一致性的协议。 -
node:每个node本质是全双工的通信(基于TCP)。采用了分布式架构里常见的选举算法,也即需要大于 1/2 个节点同意,所以最少也会存在3个主节点,而通常主节点都会挂载1~n个slave,所以一般情况下,redis-cluster至少有6个nodes。官方文档也是以6个作为示例。 -
shard:每个shard也即master-slave架构,采用异步 replication方式进行数据同步。但不同于传统的主从架构,master和slave本质也是个节点,可通过协议实现角色互换等。 -
slot 机制: 使用pow(2, 14) = 1684个slot,分配至各个master,针对每个key进行一致性 hash,将其存储至某个master。其中一致性 hash 算法为:
|
|
-
MOVED 指令:在集群下任何node针对key的操作,都会根据上述算法move到slot对应的节点。redis-client必须处理该指令,就像操作单机 redis一样。这里可以理解为301 Moved Permanently -
ASK 指令:当node之间发生MIGRATING或IMPORTING的时候,也即表示正在进行slot的迁移,所以需要ASKING。也即是个中间态,因为最终肯定是要迁移完成的(变成MOVED)。这里可以理解为307 Temporary Redirect -
readonly:如果需要在slave上读数据,那么需要显示的执行readonly -
集群操作:
redis-cli提供了很多关于cluster的操作,可完全代替之前的redis-trib.rb脚本。redis-cli --cluster help -
client slot map table:客户端可以自己实现cache the map between keys and nodes -
hash tags: 因为key是分布在不同slot,所以在执行如multi等操作的时候,redis-cluster是不支持CROSSSLOT Keys操作的。所以它提供一种hash tags的方案用于将某些key放到同一slot的方案。
注意:这里使用了
{}用于标记真正被hash的key,第一个{与紧接着其的}将被认为是key。
|
|
-
failover:redis cluster提供的容错机制,采取了ping-pong机制进行侦测(是否超时)。:- 故障 failover:自动恢复集群的可用性
- 人为 failover:支持集群的可运维操作
-
write safety:分区可用性分析(也即网络分区了,互相不可达),需要根据当前client处于何种分区环境进行分析。-
the minority side:位于小分区一端,一直在master写数据,在此期间,因为Failover机制,其他分区的某个slave提升为了master。那么当分区可用后,原master的数据丢失(因为该master的role成了slave)。 -
the majority side:位于大分区一端,因为主从是异步同步的,写操作在master成功后但slave未同步完成,master挂了(master不可达的时间超过阈值node timeout的配置),集群通过选举,某slave为新的master,那么之前写的数据丢失。 -
这里需要注意的是,因为
master之间存在心跳检测,所以当某master发现其与其他master的通信断了超过NODE_TIMEOUT后,则会拒绝write,为readonly。这时slave已经知道自己的master挂了,开始failover,其他master在开始参与选举操作。所以如果网络分区时间大于node timeout,则数据会丢失。
-