Redis集群理论知识

来源:互联网 发布:ckplayer电影网站源码 编辑:程序博客网 时间:2024/05/29 19:39

1、 Redis集群功能
(1) 自动将数据分散存储到不同Redis实例中
(2) 提供新节点识别能力、故障判断及故障转移能力
这里写图片描述
2、 Redis 集群 TCP Ports
(1) 每个节点需要两个TCP端口,一个用于客户端连接(例如6379),一个用于节点间的通信(加上10000=16379作为当前节点与其它节点通信的端口)
(2) Cluster bus:使用二进制协议实现的节点间通信渠道,用于节点失效检测、配置更新检测等,优势是节省带宽,处理速度快

3、 Redis集群正常工作前提
(1) 客户端通信TCP端口(例如6379)必须对该集群的所有客户端开放,并且对集群中的所有其它节点开放(以便在当前节点失效后可以被检测到)
(2) 集群中的所有主节点都正常工作,如果有任何一个失效都将导致集群不可用。因此Redis Cluster对每个工作节点采用一主多从,当主节点失效后,通过选举算法选择一个从节点升级为主节点,保证集群高可用

4、客户端访问集群
(1)客户端可以连接集群中任何一个主节点进行操作,当命令中的Key经过Hash运算后不是当前连接的节点,集群会自动【重定向】到Key的目标节点执行命令

5、 Redis集群数据分片
(1) Redis集群没有使用一致性哈希(consistent hashing),而是将key映射到哈希槽(hash slot)中
(2) Redis集群中总共有16384个哈希槽,映射规则是对key进行CRC16运算,然后对16384取模运算
(3) Redis集群中的主节点(Master Node)对所有哈希槽进行分割,例如有三个主节点A、B、C,则分割如下:
节点A包含哈希槽编号0—5500
节点B包含哈希槽编号5501—11000
节点C包含哈希槽编号11001—16383

哈希槽设计如何保证节点增删灵活性:在三个主节点A、B、C基础上
Redis保证哈希槽在节点间的移动不需要关闭集群和应用
如果新增D节点,则把节点A、B、C中部分哈希槽分给D一点
如果删除A节点,则把属于A节点的哈希槽转移到节点B、C上,当且仅当节点A没有哈希槽时,就可以从Redis集群中删除
(4) 针对多个Key的命令
Redis集群支持【属于同一个哈希槽】的多个Key操作
客户端借助Hash Tags,可以强制多个key被分配到同一个哈希槽中

6、 Redis主从复制模型
Redis集群保持正常工作的前提是主节点(A、B、C)正常运行,如果有一个主节点(比如B)挂掉,那么5501-11000的哈希槽就没法表示了。为了防止这种情况发生,Redis引入了主从复制功能。即一主一从或一主多从,比如给B节点配置一个从节点B1,当B挂掉之后,Redis自动把B1升级为主节点,则Redis集群仍然可以保持正常工作。

7、 Redis集群一致性保证
(1) Redis集群无法保证强一致性
(2) Redis集群可能出现【写丢失】,比如
—客户端向Master B发送写请求
—Master B给客户端发送写的成功响应
—Master B将数据【异步】同步给Slave B1,Slave B2,Slave B3

Master B并没有等到数据【成功】同步给Slave B1,Slave B2,Slave B3就【私自】给客户端成功的响应,那么如果发生Master B刚刚写完就挂掉,数据还没来得及同步到(部分或全部)Slave上面,后面某个Slave(没有收到同步)被选为Master时也就不包含刚刚写入的数据, 因此就发生了【写丢失】

那么为什么不能同步之后再响应客户端呢?因为这样性能就降低了,在分布式CAP理论实践中,往往都是【牺牲强一致性】来换取【高可用性】

如何【主动】防止【写丢失】?
Redis支持主从之间的同步写,可以通过WAIT命令实现。这样可以使得【写丢失】的概率大大降低,但还是不能完全避免。
(3) 另外一种可能导致【写丢失】的场景:网络分区
发生网络分区时,Redis节点和客户端可能被打散,例如针对Redis集群A,B,C,A1,B1,C1和一个客户端Z1,如果分区刚好导致A,C,A1,B1,C1分成一组,而B和Z1分成一组。那么前一组中,可能探测到主节点挂掉,则尝试把B1提升为主节点,而在后一组中,Z1仍然会向B写入数据,那么如果网络分区时间长到足够B1【成功】被提升为主节点,就发生了写丢失。

如果网络分区时间非常短(B1还没来得及提升为主节点),则影响不大。

Node timeout:为了防止这种极端情况数据丢失过多,Redis设置了一个参数Node Timeout,如果多节点的分区在这个时间段内还没选出替代主节点,那么节点少的分区这边,Z1也会主动停止向B写入数据或者当一个主节点在这个时间段内都没有成功探测到其它主节点,则这个主节点也被当做挂掉,开始拒绝写入。