Redis cluster:redis集群架构说明

参考文档如下:

http://redis.io/topics/cluster-spec

 

 

1、扩展性、增删节点影响

         1000节点内线性扩展,最多16384节点,因为slot格式固定为16384个。HASH_SLOT =CRC16(key) mod 16384

         每个节点和其他所有节点建立tcp长连接,用于节点间消息通信

        

         集群中的keyspace(每个slotmasterslave是哪些节点)会同步到客户端,

         jedis客户端据此可以判断每个key属于哪个slot、哪台master

        

        

        

         如果客户端发送命令给某节点(jedis根据本地的slot-node映射判断发给哪个节点),

                   如果服务器判断该key不是自己的处理范围,则会返回重定向(-MOVED)错误,

                   该错误信息中包括key所属的slot、新节点的ip端口,

                   客户端会处理此错误,据此更新本地缓存的slot-node映射关系,并连接返回的新节点地址;

                   连接新的节点后,可能再次返回重定向错误,

                   因为该节点可能还没有完全同步集群配置或集群已经新增或删除了节点造成配置已经发生了变化;

                   因此JedisCluster的构造器中有一个maxRedirections参数,就是用于限制最多处理多少次重定向。

                  

                  

         如果集群正在迁移某slot(可能是新增或删除节点时触发),从AB节点:

                   key逐个迁移,收到B响应后从A中删除该key

                   迁移过程中,客户端属于该slot的请求仍然全部发送到A

                            如果key仍在A,则A直接响应;

                            如果key已经迁移到B,则A返回一个询问(-ASK)错误,

                            客户端据此得知该key已经迁移到B

                            连接B,并发送asking命令及该key的请求(不论是读还是写请求)本身到BB返回正确的响应。

                            客户端收到“-ASK”错误不会和“-MOVED”一样导致刷新本地slot-node映射,也不会记录哪个key在迁移过程中。

        

 

2、节点

         每个节点第一次启动的时候,不论是master还是slave,都会自动生成一个20字节的id,作为自己的标识,除非在该节点手动执行clusterreset命令,或者磁盘损坏,否则nodeid不会发生变化。

         因此,运行过程中可以修改节点的ip地址,会自动重新配置并通知客户端。

        

        

        

3multi key等操作限制、本地配置缓存更新

         key操作都实现了,但多key操作(unionintersection)只在单节点实现(例如mget操作时,jedis客户端会校验多个key是否能落到同一个slot中)。

         手动resharding过程中,多key操作可能会不可用,即使这些key原本是落到一个节点。

         手动指定不同key到同一个slothash标签功能):

                   如果key中包含“{xxx}”,则取大括号中的部分找对应的slot

                   如果有多个匹配的大括号,取第一对大括号中间的部分;

                   如果第一对大括号中没有值,则假设整个key都没有大括号需要特殊处理。

                   例如“foo{{bar}}zap”取“{bar”部分,“foo{bar}{zap}”取“bar”,

                   如果key以“{}”开头,表示无需特殊处理,这可以用于key是二进制数据的情况。

 

         不允许select命令、只能使用db0

         RedisCluster的客户端只能使用有key的命令,所有没有key的命令都会抛出异常。这是因为每个命令都必须发送到特定节点执行。

        

        

         RedisCluster的客户端根据key,及本地缓存的slot-node对应关系,发生命令给服务器节点

                   如果该slot已经被别的节点接管,则会返回重定向(-MOVED)错误

                   客户端收到此类错误后,会从服务器更新最新的配置(slot-node对应关系)到本地缓存。

 

 

4、数据同步

         异步同步,如果master挂(长时间不响应),新master中的数据就是最新的,其他从都要和新master同步。

        

         客户端可以使用wait命令,等待slave同步完成(至发送wait命令时点前一个命令)。

         wait命令返回值为已同步的slave个数(实现机制:slave会带着自己已同步的offset参数ping master,且redis会记录每个客户端最后发送的命令的offset)。

         wait命令可以指定最少要等待几个slave同步完成,也可以指定超时时间。http://redis.io/commands/wait

         此命令必须在某个master执行,但如果使用RedisCluster的客户端,不能使用此命令。

        

 

5master异常

         每个master有一个类似于版本号的标识,原master挂,则新master会将此标识加1,被集群中多数master认可后,即使原master恢复,也不会造成冲突。

 

         服务器可以自动提升slavemaster,自动发现新节点;可以手动failover

        

         如果某个master挂了,新选举的master最有可能是原来的slaveoffset最大的一个,因为选举的时候该slave会有比较高的优先级。

 

         发生网络分区时,例如分为俩部分,如果超过NODE_TIMEOUT没有恢复正常网络,多数master所在的分区丢失数据的概率较低,少数master所在的分区的数据可能会全部丢失。

        

 

6slave异常

         如果某个masterslave全挂了,可能会自动从多slavemaster迁移一个slaveNODE_ID最小的)过来,确保每个master都有slave。因此,masterslave的关系可能不是固定的。

        

 

 

7、集群failover、选举步骤

         pingpong消息可以带着配置信息(自己的标识、自己认为的某些其他节点的状态、自己认为的集群的状态)作为配置更新通知,可以作为心跳包。

         如果某节点超过NODE_TIMEOUT的一半时间没有收到其他节点中某一节点pingpong,则会主动ping该节点;如果失败则会尝试TCP重新连接。因此,如果NODE_TIMEOUT参数过小,则节点间交换的消息数就会很大。

         假设有100个节点,NODE_TIMEOUT60秒,则每30秒,每个节点都会发送99ping,则每秒发送3.3个,100个节点每秒总共发送330个消息。这是假设发出的ping对方都没有收到的情况,正常情况下可能只有330/ 2ping需要发送。

         每个节点在每秒内都必须发送一定的ping、可能收到一定量的pong,二者加总应该是一个常量。

         每个节点(不论主从)如果超过NODE_TIMEOUT的时间后仍无法联系某一其他节点,则会在自己本地标识该节点为PFAIL(可能失败)状态,自己本地的这些信息在ping其他节点的时候可能会带上;

         某一节点A如果发现节点B处于PFAIL状态,则向其他master节点发送信息,收集节点B的状态,如果多数master都认为B处于PFAIL/FAIL状态(NODE_TIMEOUT* FAIL_REPORT_VALIDITY_MULT时间内返回),则标识BFAIL状态,并向所有可达节点广播此信息。

         标识为FAIL的节点,满足条件时可以再次被标识为正常:

                   再次变成可达且为slave

                   再次变成可达且为不服务任何slotmaster

                   再次可达且为master且长时间(NODE_TIMEOUT的倍数)没有从被提升以替换该master

        

        

         slave选举新master应满足的条件:

                   master处于FAIL状态;

                   master服务某些slot

                   slavemaster断开时间没超过阈值(slave不能落后master太久)。

                   选举新master需要现有其他master中的多数同意。

         选举前,slave间根据各自从master复制的offset最新值排序,offset最新的会先提出选举自己作为master,后续的每隔约一秒有一个slave提出选举。如果选举成功,广播通知所有可达节点。

        

         slave提出选举自己为新master时,会增加自己的一个顺序号,该顺序号是从原master同步来的。因此如果远master又重新可用,也不会出现两个master的情况。

         如果slave被提升为master后,又发生了reSharding,则原master恢复后,原master的最后一个slot现在由哪个master负责,原master就会成为该新masterslave

 

 

 

8、读写分离

         jedis客户端中,会记录各个slot对应的masterjedisPool,但不会记录各个slot和“slavejedisPool”的对应关系。

         因此,如果要实现读写分离,则需要修改一下原生jedis

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值