文章讲到的说 redis 集群指的是 redis-cluster 集群方式
问题 :
-
redis-cluster 数据是分片的,那么是如何分片的,增加和减少节点如何处理的 redis 使用了一种叫 hash slot 的方式而非一致性hash 算法,增加和减少节点将会迁移某个节点的数据。
-
redis-cluster 中如何保证一致性的 使用共识性算法-Raft
文章来自于官方文档,见参考资料 ,翻译难免有误,还望指正。
概述
redis集群的cluster主要是使用分片策略将数据切分分布在不同的机器。本文主要讲的是主要实现的功能点和特性,具体的实现细节在下一篇。
主要属性和设计基本原理
主要目标是 :
- 高达1000个节点的高性能和线性可扩展性。 没有代理,使用异步复制,并且不对值执行合并操作。
- 可接受的写安全程度:系统尝试(以尽力而为的方式)保留所有来自与大多数主节点连接的客户端的写操作。 通常,有一些小窗口,在这些小窗口中,可能会丢失已确认的写入。 当客户端位于少数分区中时,丢失已确认写入的Windows更大。(脑裂问题,部分写丢失)
- 可用性:Redis Cluster能够在大多数主节点可访问且每个不再可用的主节点上至少有一个可访问的从节点的分区中生存。 此外,使用副本迁移,不再由任何从属复制的主控将从一个由多个从属覆盖的主控接收一个。
实现小述
Redis Cluster implements a concept called hash tags that can be used in order to force certain keys to be stored in the same hash slot. However during manual resharding, multi-key operations may become unavailable for some time while single key operations are always available.
Redis Cluster does not support multiple databases like the stand alone version of Redis. There is just database 0 and the SELECT command is not allowed.
redis 实现了一个叫 “hash tags ”可以用来限定特定的keys储存在相同的 hash slot 的概念。 但是这样子的实现下,手动切片和multi-key 操作变得不可用,而单个的key 操作是可用的。
redis cluster 不支持多个数据库而不像单实例版的可以实现多数据库,它只有一个数据库 0 并且 select 指令是不被允许的。
clients 和 servers 在 redis cluster 中的规则
每个 redis cluster 节点负责自己的数据,获取集群中的状态,包括映射key到正确的节点信息,同时各节点还能自动发现其他节点,发现停止工作的节点,当错误发生时,为了继续工作,节点会变成某个master的 slave .
To perform their tasks all the cluster nodes are connected using a TCP bus and a binary protocol, called the Redis Cluster Bus. Every node is connected to every other node in the cluster using the cluster bus. Nodes use a gossip protocol to propagate information about the cluster in order to discover new nodes, to send ping packets to make sure all the other nodes are working properly, and to send cluster messages needed to signal specific conditions. The cluster bus is also used in order to propagate Pub/Sub messages across the cluster and to orchestrate manual failovers when requested by users (manual failovers are failovers which are not initiated by the Redis Cluster failure detector, but by the system administrator directly).
为执行他们的任务,redis 使用了一个 TCP bus 还有一个二进制协议,称之为 Redis Cluster Bus . 每个节点都使用cluster bus 连接着其他的节点,节点使用 gossip protocol 在集群中传播彼此的信息来发现新的节点,同时 ping 是否其他节点是否工作正常。cluster bus 还被用到传播 pub/sub 信息 。 因为集群中的节点并没有代理请求的功能,所以客户端将会被重新定向到正确的节点,其中常见的就是命令中的'MOVED'和'ASK'.
写安全(Write safety)
write safety 讲的是某些情况会导致写丢失,比如集群中发生脑裂的时候,以下两种情况发生写丢失 :
- 写到 master 之后,master down掉了。
- 集群脑裂,请求写写在了小部分一端,以下情况都会丢失 :
- A master is unreachable because of a partition.
- It gets failed over by one of its slaves.
- After some time it may be reachable again.
- A client with an out-of-date routing table may write to the old master before it is converted into a slave (of the new master) by the cluster. 当出现 slave节点心跳不到 master 的窗口期间会丢失写请求,redis 可以设置 NODE_TIMEOUT 时间,来减少这个窗口时间写请求丢失带来的影响。
可用性
Redis群集在分区的少数部分( minority side of the partition)不可用。在分区的大多数方面,假设每个不可达的主服务器至少有多数主服务器和一个从服务器,则集群将在NODE_TIMEOUT一段时间后再次可用,再加上从服务器被选举并对其主服务器进行故障转移所需的几秒钟时间(故障转移)通常在1或2秒内执行)。
这意味着Redis Cluster旨在承受群集中几个节点的故障,但是对于那些需要大量网络拆分而需要可用性的应用程序来说,它并不是一个合适的解决方案。(这里就是说需要保持高可用的场景redis 的cluster并不是一个合适的解决方法)
在由N个主节点组成的集群的示例中,每个节点都有一个从属节点,只要将单个节点分割开,集群的大部分将保持可用状态,并且有可能1-(1/(N2-1))在两个节点处于同一状态时保持可用状态。分割开(在第一个节点发生故障后,我们N2-1总共剩下节点,而没有副本的唯一主节点发生故障的概率为1/(N*2-1))。
例如,在具有5个节点且每个节点有一个从属节点的群集中,很1/(5*2-1) = 11.11%可能在将两个节点从多数分区中分离出来之后,该群集将不再可用。
由于Redis群集具有称为副本迁移的功能,因此在许多实际情况下,由于副本迁移到了孤立的主服务器(不再具有副本的主服务器),群集的可用性得以提高。因此,在每个成功的故障事件中,群集都可以重新配置从属布局,以便更好地抵抗下一次故障。
性能
在Redis群集中,节点不会将命令代理到给定key正确节点,而是将客户端请求重定向到存放该key的正确节点。
最终,客户端获得群集的最新表示,以及哪个节点提供key的哪个子集,因此在正常操作期间,客户端直接联系正确的节点以发送给定命令。
由于使用了异步复制,因此节点不必等待其他节点的写入确认(如果未使用WAIT命令明确请求)。
同样,由于多键命令仅限于近键,因此除非重新分片,否则数据永远不会在节点之间移动。
正常操作的处理方式与单个Redis实例完全相同。这意味着在具有N个主节点的Redis集群中,随着设计线性扩展,您可以期望获得与单个Redis实例乘以N相同的性能。同时,查询通常是在单次往返中执行的,因为客户端通常会保留与节点的持久连接,因此延迟时间也与单个独立Redis节点的情况相同。
Redis Cluster的主要目标是在保持微弱但合理的数据安全性和可用性形式的同时,具有很高的性能和可伸缩性。
总结
文章主要讲 redis-cluster 的一些重要特性例如 : 主要的属性,性能,可用性等
参考资料
- https://redis.io/topics/cluster-spec