理解Redis集群

Redis集群理解

Redis 集群可以在多个 Redis 节点之间进行数据共享。Redis 集群不支持那些需要同时处理多个键的 Redis 命令,因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。比如:有 name1 和 name2 两个节点,命令 del name1 name2 要同时删除这个 key,就不能写在一起,得分开写。Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。

使用Redis集群的好处

1. 将数据自动切分(split)到多个节点的能力。

2. 当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。

3.支持动态扩容

Redis集群间的数据共享

Redis 集群使用数据分片(sharding)而非一致性哈希来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot),集群的每个节点负责一部分hash槽。数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16校验。

举个例子,一个Redis集群中有三个哈希槽,三个节点负责如下:

1. 节点 A 负责处理 0 号至 5500 号哈希槽。
2. 节点 B 负责处理 5501 号至 11000 号哈希槽。
3. 节点 C 负责处理 11001 号至 16384 号哈希槽。

以上这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点,可以做到:

1.如果用户将新节点 D 添加到集群中, 那么集群只需要将节点A 、B 、 C 中的某些槽移动到节点 D 就可以了。

2.与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(此时不包含任何哈希槽)的节点 A 就可以了。

这种哈希槽的集群间操作很友好,这是因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 不会影响Redis正常运行,也不会造成集群下线。

Redis集群的主从复制

为了保证redis集群在某一部分节点下线的情况下或者无法与大多数节点进行通讯的情况下,仍然可以正常运作,Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品,其中一个复制品为主节点, 而其余的 N-1 个复制品为从节点。

在上面列举的 A 、B 、C 节点的例子中, 如果节点 B 下线了, 那么集群将无法正常运行, 因为集群找不到节点来处理5501 号至 11000 号的哈希槽。

另一方面, 假如在创建集群的时候(或者至少在节点 B 下线之前), 我们为主节点 B 添加了从节点 B1 , 那么当主节点B 下线的时候, 集群就会将 B1 设置为新的主节点, 并让它代替下线的主节点 B , 继续处理 5501 号至 11000 号的哈希槽, 这样集群就不会因为主节点 B 的下线而无法正常运作了。不过如果节点 B 和 B1 都下线的话, Redis 集群还是会停止运作。

 集群的一致性保证

Redis 集群不保证数据的强一致性(strong consistency),在特定条件下, Redis 集群可能会丢失已经被执行过的写命令。

使用异步复制是 Redis 集群可能会丢失写命令的其中一个原因。 考虑以下这个写命令的例子:
1. 客户端向主节点 B 发送一条写命令
2. 主节点 B 执行写命令,并向客户端返回命令回复
3. 主节点 B 将刚刚执行的写命令复制给它的从节点 B1 、 B2 和B3 

如你所见, 主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 ,所以我们必须在性能一致性之间做出权衡。

Redis 集群另外一种可能会丢失命令的情况是, 集群出现网络分裂(network partition), 并且一个客户端与至少包括一个主节点在内的少数(minority)实例被孤立。

举个例子, 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1六个节点, 其中 A 、B 、C 为主节点, 而 A1 、B1 、C1 分别为三个主节点的从节点, 另外还有一个客户端 Z1 。
假设集群中发生网络分裂, 那么集群可能会分裂为两方,大多数(majority)的一方包含节点 A 、C 、A1 、B1 和C1 , 而少数的一方则包含节点 B 和客户端Z1 。

在网络分裂期间, 主节点 B 仍然会接受 Z1 发送的写命令:
1. 如果网络分裂出现的时间很短, 那么集群会继续正常运行
2. 但是, 如果网络分裂出现的时间足够长, 使得大多数一方将从节点 B1 设置为新的主节点, 并使用 B1 来代替原来的主节点 B ,那么 Z1 发送给主节点 B 的写命令将丢失。

注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是Redis集群的一个重要的配置选项:

1. 对于大多数一方来说, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么集群会将这个主节点视为下线, 并使用从节点来代替这个主节点继续工作

2. 对于少数一方, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么它将停止处理写命令, 并向客户端报告错误。

这一节讲到这里,下一节,讲 Redis 集群的搭建

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一名程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值