分布式redis

Posted 阿拉天啦噜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式redis相关的知识,希望对你有一定的参考价值。

一. 水平拆分 sharding

1. 解决数据量和访问量增加后对单节点造成的性能压力;水平拆分后的每个节点存储和处理的数据原则上没有交集;

2. 数据分布:

hash映射:将不可控的业务值域key均匀映射到可控的有限值域(hash值)上,再将均匀分布的hash值枚举的映射到redis实例上;

范围映射:选择key本身而不是key的某个运算值作为数据分布的条件,且每个数据节点存放的key的值域是连续的;

hash和范围映射:典型的方式是一致性hash,首先对key进行hash运算,得到值域有限的hash值,再对hash值做范围映射;

3. 请求路由

只读的跨实例请求需要将请求中的多个key分别分发到对应实例上执行,再合并结果;

跨实例的原子读写请求中,实例B的写入操作依赖于实例A的读取,没有单线程特性保证并发安全,因此原子请求是不支持的;

二. 主备复制 replication

1. 当某个节点宕机时,其上的数据在其他节点上有副本;同一份数据在多个节点上存储,可以分离读取和写入操作;

2. 主备复制流程

redis包含master和slave两种节点,master提供读写服务,slave作为master的数据备份拥有master的全量数据,不提供写服务;

slave启动后触发SYNC命令,master被动的讲新进slave节点加入主备复制集群;

master收到命令后开启BGSAVE,完成后将快照信息发送给slave,slave将现有数据清空,将快照写入自身内存;

发送期间master接收到的新的写命令将存入一份backlog队列;

快照发送完成后继续发送backlog,slave执行;

backlog发送完成后后续的写操作同时发给slave,保持实时异步复制;

如果有多个slave并发发送SYNC给master,只要第二个slave的SYNC命令发生在master完成BGSAVE前,第二个slave将收到和第一个相同的快照和后续backlog,否则第二个slave的SYNC将触发master第二次BGSAVE;

3. 断点续传

redis的PSYNC可以替代SYNC,做到基于断点续传的主备同步协议;

master-slave两端通过维护一个offset记录当前已经同步过的命令,slave断开期间,master的客户端命令会保持在缓存中,在slave重连之后告知master断开时的最新offset,master则将缓存中大于offset的数据发送给slave,减少数据传输开销;

三. 故障转移 failover

1. 当两台以上redis实例形成了主备关系,他们组成的集群具备了一定的高可用性,当master故障时slave可以成为新的master,这种机制成为failover;

2. sentinel集群:由多个daemon组成,daemon也被成为sentinel节点,节点间相互通信,选举,协商,在master节点的故障发现,failover决策上表现出一致性;

3. sentinel间的相互感知:所有需要相互感知的sentinel都向他们共同的master订阅相同的channel,新加入的sentinel节点向这个channel发布消息,包含自己的信息,该channel的订阅者就可以发现这个sentinel,集群中的所有sentinel两两建立长连接;

4. master的故障发现:sentinel节点定期向master发送心跳包判断其存活状态,一旦发现master没有正确响应即标记为主观不可用,当确认的sentinel节点数>=配置数量时,则转变为客观不可用,进入failover流程;

5. failover决策:

只能有一个sentinel作为failover的发起者,选举算法类似Raft协议;

leader sentinel确定之后从master所有的slave中依据一定的规则选取一个作为新的master,告知其他slave连接这个新的master;

四. redis cluster

1. 拓扑结构:一个redis cluster由多个redis节点组构成,每个节点组的数据无交集,每个节点组内有一个master节点和0到多个slave节点;

2. 配置的一致性

redis master中的每一个节点内部都保存了集群的配置信息,存储在clusterState中,包括集群配置状态,版本号,集群中每个节点的信息(版本号,数据分片,slave节点列表或master节点),全局唯一的NodeId;

通过epoch作为版本号实现集群结构信息的一致性,同时也控制着数据迁移和故障转移的过程;

redis cluster是一个去中心化的分布式实现方案,不存在同一的配置中心,信息交互通过redis cluster bus在独立的端口完成;

配置信息的一致性达成主要依靠PING和PONG两种类型的msg,节点两两之间频繁的周期性的发送和接受消息,消息中包含了该节点所知的集群其他节点信息,其他节点根据这些信息更新自己对于集群结构的认识;

故障转移,分片迁移等情况发生会导致集群结构变更,优先得知变更信息的节点利用epoch变量将自己的最新信息扩散到整个集群,其他节点始终朝着epoch值更大的信息单向更新,达到最终一致性;

3. sharding

每一条数据根据key通过数据分布算法映射到16384个slot中的一个,不支持跨节点的单命令,如果涉及的两个key对应的slot分布在不同的node上,则操作失败;

redis引入hashTag的概念,使得数据分布算法可以根据key的某一部分进行计算,让相关的两条记录落到同一个数据分片;

redis cluster的客户端具备路由语义的识别能力和路由缓存能力,当一个client访问的key不再对应redis节点的slot中,redis返回给client一个moved命令,告知正确的路由信息;

当cluster处在数据重分布过程中时,可以通过ask命令控制客户端的路由,ask命令只是本条操作重定向到新节点,后续的相同slot操作仍路由到旧节点,moved命令会更新client内部的路由缓存信息;

4. failover

当PONG的响应超过一定时间(NODE_TIMEOUT)未收到,则发送者认为接受节点故障,将其置为PFAIL状态,当接收到的来自其他master节点的PFAIL达到一定数量后会升级为FAIL状态,发起选举流程;

slave优先级最重要的决定因素是最后一次同步master信息的时间,数据越新优先级越高;

当slave收到超过半数的master的同意回复时,该slave成为新的master,并以最新的epoch广播出去,其他节点收到消息并更新;

故障master节点恢复后,通过消息将自己降为slave;

5. 可用性和性能

读写分离:客户端向slave发送READONLY命令,slave对于读操作不再MOVED回master而是直接处理,分担master的压力,获得更高的读吞吐量,但可能存在数据不一致的情况;

master单点保护:当一个master唯一的slave宕机后,另一个拥有多个slave的master的其中一个slave会进行副本迁移;集群只需要保持2*master+1个节点,就可以在任一节点宕机后自动维持高可用状态;

以上是关于分布式redis的主要内容,如果未能解决你的问题,请参考以下文章

如何使用redis实现分布式锁功能?

Redis实现分布式锁与Zookeeper实现分布式锁区别

Redis怎么实现分布式锁

分布式锁用zookeeper还是redis好

分布式限流 redis-cell

Redis(十三):Redis分布式锁的正确实现方式