Closed neverchanje closed 5 years ago
redis cluster 支持 auto sharding,支持 failover,整个功能十分完备。
redis 集群每个节点会开启两个端口 6379, 16379,前者对 client 服务,后者对 cluster 内其他节点服务。26379 是 sentinel 的端口。
redis cluster 使用 static hashing 而非 dynamic hashing。每个集群有 16384 个分片(由宏 CLUSTER_SLOTS 指定,想改需要重新编译)。因为 redis cluster 的目标是支持 1000 节点,这个分片数应该足够高。
CLUSTER_SLOTS
redis master-slave 使用 async replication,不支持 strong consistency。
在 cluster-mode 下,redis 的 multi-key operation 只能作用在同一个分片,不支持跨分片 (hash-slot) transaction。
redis 并非使用二级 key 的方式做 hash,而是用 hash-tag 的方式。 this{foo}key 和 another{foo}key 属于同一个 hash-slot。如果没有指定 hash-tag 的话,就用整个 key 做 hash(相当与 pegasus sortkey 为空的场景)。
this{foo}key
another{foo}key
开启 cluster mode: cluster-enabled yes
cluster-enabled yes
cluster mode 不支持多表,一个集群只有一个表。
client 可以 缓存路由表,也可以不缓存路由表。当它随意写到某个节点的时候,如果 key 不对应这个节点,那它会被告知(redirect)key 在 ×× 节点上,redis 的通知方式是返回一个 "MOVED" 错误。
client 可以读 slave。首先需要发 readonly 命令给 slave,建立一个只读连接,然后就可以利用 slave 提升读吞吐(前提是节点有余力)。
membership 会被持久化到 nodes.conf 文件中
redis cluster 通过 gossip protocol 将 membership 传递给其他节点。
ping/pong (heartbeat): gossip 所传递的报文就是 ping/pong,本质就是交换 configuration,假设集群有 n 节点,每秒每个节点平均会选择其他 3.3 个节点做 gossip,最终每秒的 ping/pong 报文数是 3.3*(n-1),网络带宽的开销极小。
slaves 也会参与 gossip,ping/pong 里会包含它的身份(master or slave or others),还有它服务哪些 slots,slots 压缩为 bitmap 以减小空间。
为了避免某个节点拿老旧的配置来 gossip,每个 ping 会带 currentEpoch,类似 ballot。如果收到了更大的 epoch,就更新配置并更新 currentEpoch。新的节点 epoch=0。
failover: 每个节点会配置 node-timeout(cluster-node-timeout),如果一个 ping 在 node-timeout 之内没有收到回复,则认为这个节点可能挂了。为了避免偶然的丢包带来的影响,在 half node-timeout 之后如果没收到回复,ping 还会再发一次,如果第二次依然没有收到 pong,则说明节点确实挂了。
cluster-node-timeout
如果 ping 失败,发送方(名曰 A)会把这个节点(名曰 B)标记 PFAIL (P=Possible)。在 gossip 的过程中,A 如果听闻过半数节点都认同 B 挂了,那么 A 会标记 B 为 FAIL。
如果过半节点认为一个节点挂了,那么他们会通知所有节点这个事件,包括这个节点的 slave(如果它是 master 的话)。在得知 master 挂了后,它的 slave 会发起投票选举,如果其他 masters 认为它没问题,它就会成功当选。这个投票 rpc 是 FAILOVER_AUTH_REQUEST。
FAILOVER_AUTH_REQUEST
Removing Node:使用 CLUSTER FORGET 命令,让所有人忘记你。当然在此之前需要把该节点上的数据都 resharding 走。
# 之前维护集群用的是 redis-trib 的 ruby 脚本,5.0 后用 C 编写的 redis-cli 即可 redis-cli --cluster create $HOSTS --cluster-replicas 1
真正的迁移命令是 CLUSTER SET_SLOTS。主要步骤是告诉 Master A,让它把某个 slot 迁出去(MIGRATING),然后告诉 Master B,让它把这个 slot 引进来(IMPORTING)。迁移过程会一个 key 一个 key 地进行,如果请求发给 A 而 key 已经迁移走了,则会返回 ACK 错误,让 client 去问 B。与 MOVED 错误不同的是,client 此时仍会认为这个 slot 是由 A 服务的。
CLUSTER SET_SLOTS
设置好了 IMPORTING 和 MIGRATING 之后,整个迁移操作上是由 redis-trib 先一批一批获取 slot 内的 key,然后发 MIGRATE 请求将这些 key 迁移走。所有迁移流程完全由 administrator 组织,该操作在 5.0 已被简化为 redis-cli --cluster reshard 命令。
redis-cli --cluster reshard
目标是让每个 master 都有至少一个 slave,
redis cluster 支持 auto sharding,支持 failover,整个功能十分完备。
redis 集群每个节点会开启两个端口 6379, 16379,前者对 client 服务,后者对 cluster 内其他节点服务。26379 是 sentinel 的端口。
redis cluster 使用 static hashing 而非 dynamic hashing。每个集群有 16384 个分片(由宏
CLUSTER_SLOTS
指定,想改需要重新编译)。因为 redis cluster 的目标是支持 1000 节点,这个分片数应该足够高。redis master-slave 使用 async replication,不支持 strong consistency。
在 cluster-mode 下,redis 的 multi-key operation 只能作用在同一个分片,不支持跨分片 (hash-slot) transaction。
redis 并非使用二级 key 的方式做 hash,而是用 hash-tag 的方式。
this{foo}key
和another{foo}key
属于同一个 hash-slot。如果没有指定 hash-tag 的话,就用整个 key 做 hash(相当与 pegasus sortkey 为空的场景)。开启 cluster mode:
cluster-enabled yes
cluster mode 不支持多表,一个集群只有一个表。
client 可以 缓存路由表,也可以不缓存路由表。当它随意写到某个节点的时候,如果 key 不对应这个节点,那它会被告知(redirect)key 在 ×× 节点上,redis 的通知方式是返回一个 "MOVED" 错误。
client 可以读 slave。首先需要发 readonly 命令给 slave,建立一个只读连接,然后就可以利用 slave 提升读吞吐(前提是节点有余力)。
membership
membership 会被持久化到 nodes.conf 文件中
redis cluster 通过 gossip protocol 将 membership 传递给其他节点。
ping/pong (heartbeat): gossip 所传递的报文就是 ping/pong,本质就是交换 configuration,假设集群有 n 节点,每秒每个节点平均会选择其他 3.3 个节点做 gossip,最终每秒的 ping/pong 报文数是 3.3*(n-1),网络带宽的开销极小。
slaves 也会参与 gossip,ping/pong 里会包含它的身份(master or slave or others),还有它服务哪些 slots,slots 压缩为 bitmap 以减小空间。
为了避免某个节点拿老旧的配置来 gossip,每个 ping 会带 currentEpoch,类似 ballot。如果收到了更大的 epoch,就更新配置并更新 currentEpoch。新的节点 epoch=0。
failover: 每个节点会配置 node-timeout(
cluster-node-timeout
),如果一个 ping 在 node-timeout 之内没有收到回复,则认为这个节点可能挂了。为了避免偶然的丢包带来的影响,在 half node-timeout 之后如果没收到回复,ping 还会再发一次,如果第二次依然没有收到 pong,则说明节点确实挂了。如果 ping 失败,发送方(名曰 A)会把这个节点(名曰 B)标记 PFAIL (P=Possible)。在 gossip 的过程中,A 如果听闻过半数节点都认同 B 挂了,那么 A 会标记 B 为 FAIL。
如果过半节点认为一个节点挂了,那么他们会通知所有节点这个事件,包括这个节点的 slave(如果它是 master 的话)。在得知 master 挂了后,它的 slave 会发起投票选举,如果其他 masters 认为它没问题,它就会成功当选。这个投票 rpc 是
FAILOVER_AUTH_REQUEST
。Removing Node:使用 CLUSTER FORGET 命令,让所有人忘记你。当然在此之前需要把该节点上的数据都 resharding 走。
Replica Migration
真正的迁移命令是
CLUSTER SET_SLOTS
。主要步骤是告诉 Master A,让它把某个 slot 迁出去(MIGRATING),然后告诉 Master B,让它把这个 slot 引进来(IMPORTING)。迁移过程会一个 key 一个 key 地进行,如果请求发给 A 而 key 已经迁移走了,则会返回 ACK 错误,让 client 去问 B。与 MOVED 错误不同的是,client 此时仍会认为这个 slot 是由 A 服务的。设置好了 IMPORTING 和 MIGRATING 之后,整个迁移操作上是由 redis-trib 先一批一批获取 slot 内的 key,然后发 MIGRATE 请求将这些 key 迁移走。所有迁移流程完全由 administrator 组织,该操作在 5.0 已被简化为
redis-cli --cluster reshard
命令。目标是让每个 master 都有至少一个 slave,