关于redis的几件小事(十)redis cluster模式

redis cluster是redis提供的集群模式。java

1.redis cluster的架构

①能够有多个master node,每一个master node 均可以挂载多个slave node。node

②读写分离的架构,对应每一个master node来讲,写就写到master node,读就从master node对应的slave node去读。redis

③高可用。每一个master node都有多个 slave node,若是master node挂了,redis cluster机制就会自动将某个slave node切换成 master node。算法

因此redis cluster是 多master + 读写分离 + 高可用 的。只要基于edis cluster去搭建集群,就能够达到搭建 replication复制+主从架构+读写分离+哨兵集群+高可用的 集群架构。
api

redis cluster的架构  示意图

2.redis cluster和replication+sentinal

①输入数据量不多,主要是承载高并发的场景,单机就能够了。缓存

②replication只有一个master node节点,多个slave node节点,全部节点上面的数据是同样的,全部它能够提升读请求的吞吐量,而后能够搭建一个Sentinal集群去保证高可用,可是他没法去扩容数据的存储量。网络

③redis cluster,能够有多个master node去存储不一样的数据,全部他适合数据量特别大的场景,并且它能够不用Sentinal集群就能够保证高可用。架构

3.数据分布算法

(1)redis cluster机制

①自动将数据分片,每一个master node上面存放一部分数据。并发

②提供内置的高可用支持,部分master node不可用时,仍是能够工做的。负载均衡

③在redis cluster架构中,每一个redis要开发两个端口,好比一个是6379,那么另外一个就是加10000以后的端口号,好比16379。16379端口是用来进行节点间通讯的,也就是cluster bus集群总线,cluster bus的通讯用来进行故障检测、配置更新、故障转移受权等操做。

④cluster bus用来一种二进制的协议,主要用于节点间进行高效的数据交换,占用更少的网络带宽和处理时间。

####(2)最古老的hash算法
原理 :来了一个key以后,计算hash值,而后对master node节点数量取模,将数据哈希到不一样的节点。
存在问题 :会致使大量缓存重建的问题。这种状况下,一旦一个master宕机了,全部的请求过来以后,就会对新的节点数量(原节点数量-1)去取模,而后去相应的node取数据,这样会致使请求走不到本来路由到的实例上面去,致使大量的key瞬间所有失效。

最古老的hash算法  示意图

(3)一致性hash算法(自动缓存迁移)

原理 :将全部master node落在一个圆环上面,而后,有一个key过来以后。一样就是hash值,而后会用hash值在圆环对应的各个点上(每一个点都有一个hash值)去对比,看hash值落在那个位置,落在圆环上面之后,就会顺时针旋转去寻找距离本身最近的一个节点,数据的存储于读取都在该节点进行。
优点 :保证了任何一个master宕机,只会影响以前在那个master上面的数据,由于照着顺时针走,所有在以前的master上面找不到了,master也宕机了,就会继续顺着顺时针走到下一个master节点去。这样就只会有一部分数据丢失。
存在问题 :假若有3个master,那么就会丢失1/3的数据,这也是不少的。还会存在 缓存热点的问题。 缓存热点问题 :可能在某个hash区间内存在大值特别多,那么就会致使大量的数据进入同一个master,形成该master出现瓶颈。

一致性hash算法示意图

(4)一致性哈希(自动缓存迁移)+虚拟节点(自动负载均衡)

为了解决上面的问题,在一致性哈希的基础上增长了虚拟节点方案来处理。
原理 :给每一个master都作了一部分的虚拟节点,这部分虚拟节点也分布在这个圆环上面,那么在每一个区间内,大量的数据就会均匀的分布在不一样节点上。

一致性哈希+虚拟节点示意图.png

(5)hash slot算法

原理 :①redis cluster有固定的16384个hash slot,每一个key计算CRC16值,而后多 16384取模,能够获取key对应的hash slot。
②redis cluster中每一个master节点都会持有一部分hash slot。
③增长一个master,就讲其余master的hash slot移动一部分给新加入的master。
④减小一个master,就将他的hash slot移动到其余master上面去。
⑤移动hash slot的成本是很是低的。
⑥客户端的api是能够指定hash tag来让数据走同一个hash slot的。

hash slot算法 示意图.png

4.redis cluster的核心原理

(1)节点间的内部通讯机制

1.基础通讯原理
①redis cluster节点间采起gossip协议进行通讯。
跟集中式不一样,不是将集群元数据(节点信息、故障等等)集中存储在某个节点上,而是相互之间不断通讯,保持整个集群全部节点的数据是完整的。

②维护集群的元数据的两种方式对比
A.集中式
优势 :元数据的更新和读取,时效性很是好,一旦元数据出现了变动,当即就更新到集中式的存储中。
缺点 :全部的元数据的更新压力所有集中在一个地方,可能致使元数据的存储有压力。

集中式 示意图.png

B.gossip
优势 :元数据的更新比较分散,不是集中在同一个地方,更新请求会陆陆续续到达全部节点上去更新,有必定的延时,下降了压力。
缺点 :元数据更新有延时,可能会致使集群的一些操做会有一些滞后。

gossip示意图.png

③10000端口
每一个节点都有一个专门用于节点间通讯的端口号,就是本身提供服务的端口号+10000。每一个节点每隔一段时间都会往另外几个节点发送ping消息,同时其余节点接收到ping以后会返回pong消息。

④节点间交换的信息
包含故障信息,节点的增长和移除,hash slot信息等等。

2.gossip协议
gossip协议,即流言协议。gossip协议包含多种消息,包括ping,pong,meet,fail等等。
①ping: 每一个节点都会频繁的给其余节点发送ping,其中包括本身的状态还有本身维护的集群元数据,互相经过ping交换元数据。

②meet:某个节点发送meet给新加入的节点,让其加入进群中,而后新节点就会开始与其余节点进行通讯。

③pong:做为ping和meet的响应,包含本身的状态和其余信息,也能够用于信息广播和更新。

④fail:某个节点判断另外一个节点fail以后,就会发送fail消息给其余节点,通知其余节点,指定的节点宕机了。

3.深刻ping消息
①ping很频繁,并且要携带一些元数据,因此会加剧网络负担。

②每一个节点每秒会执行10次ping,每次会选择5个最久没有通讯的其余节点去通讯。

③如何发现某个节点通讯时延达到了 cluster_node_timeout/2,那么当即发送ping,避免数据交换延时太长,落户的时间太多。

④能够调节 cluster_node_timeout的值,若是调节比较大。就会下降ping发送的几率。

⑤每次ping都会带上本身的信息。还要带上1/10其余节点的信息,发送出去进行交换。

⑥至少包含3个其余节点的信息,最多包含总节点-2个其余节点的信息。

(2)面向集群的jedis内部实现原理

1.基于重定向的客户端
redis-cli c,自动重定向

①请求重定向
客户端可能会挑选任意一个redis实例去发送命令,每一个redis实例接收到命令以后,都会接受key对应的hash slot,若是在本地就在本地处理,不然返回moved给客户端,让客户端进行重定向。
cluster keyslot mykey ,能够查看一个key对应的hash slot是什么。
用redis-cli的时候,能够加入-c参数,支持自动的请求重定向,redis-cli接收到moved以后,会自动重定向到对应的节点执行命令。

②计算hash slot
计算hash slot的算法,就是根据key计算CRC16值,而后对16384取模,拿到对应的hash slot。
用hash tag能够手动指定key对应的slot,同一个hash tag下的key,都会在一个hash slot中,好比set mykey1:{100}和set mykey2:{100}。

③hash slot查找
节点间经过gossip协议进行数据交换,就知道每一个hash slot在那个节点上面了

2.smart jedis
①什么是smart jedis:
基于重定向的客户端,很消耗网络IO,由于大部分状况下,可能都会出现一次请求重定向,才能找到正确的节点。

因此大部分的客户端,好比java redis客户端,就是jedis,都是smart的。

本地维护一份hashslot -> node的映射表,缓存,大部分状况下,直接走本地缓存就能够找到hashslot -> node,不须要经过节点进行moved重定向。

②JedisCluster的工做原理
A:在JedisCluster初始化的时候,就会随机选择一个node,初始化hash slot到node的映射表,同时为每一个节点建立一个JedisPool链接池。
B:每次基于JedisCluster执行操做,首先会在本地计算key的hash slot,而后在本地映射表中找到节点。
C:若是那个node真好仍是持有那个hash slot,那么就OK。
D:若是JedisCluster API返回的是moved,那么利用该节点的数据,更新本地的hash slot 和node的映射表。
E:重复上面的步骤,知道找到对应的节点,若是重试超过5次,就会报错,抛出JedisClusterMaxRedirectionException异常。

jedis老版本,可能会出如今集群某个节点故障还没完成自动切换恢复时,频繁更新hash slot,频繁ping节点检查活跃,致使大量网络IO开销。

jedis最新版本,对于这些过分的hash slot更新和ping,都进行了优化,避免了相似问题。

③hash slot迁移和ask重定向
A:若是hash slot正在进行迁移,那么会返回ask重定向给jedis,
B:jedis接收到ask重定向以后,会从新定位到目标节点去执行。
C:可是由于ask发生在hash slot迁移过程当中,因此收到ask是不会更新hash slot本地缓存。
D:已经能够肯定说hash slot已经迁移完了,moved是会更新本地hash slot到node的映射缓存的。

(3)高可用与主备切换原理

redis cluster的高可用原理,几乎和哨兵时相似的。
1.判断节点宕机
①若是一个节点认为另外一个节点道济,那么就是pfail,主观宕机。

②若是多个节点都认为另一个 节点宕机了,那就是fail,客观宕机。

③在cluster-node-timeout内,某个几点一直没有返回pong,那么就认为pfail。

④若是一个节点认为某个节点pfail了,那么会在gossip ping消息中,发送给其余节点,若是超过半数的节点都认为pfail了,那就好变成fail。

2.从节点过滤
①对宕机的master node,从其全部的slave node中,选择一个切换成master node。

②检查每一个slave node与master node断开链接的时机,若是超过了cluster-node-timeout * cluster-slave-validity-factor,那么这个节点就没有资格切换成 master node,直接被过滤。

3.从节点选举
①每一个从几点,都根据本身对master复制数据的offset,来设置一个选举时间,offset越大的从节点,选举时间越靠前,优先进行选举。

②全部的master node开始slave选举投票,给要进行选举的slave进行投票,若是大部分master node(N/2 + 1)都投票给了某个从节点,那么选举经过,那个从节点能够切换成master node。

③从节点执行主备切换,从节点切换为主节点。

4.与哨兵进行比较 整个流程跟哨兵相比,很是相似,因此说,redis cluster功能强大,直接集成了replication和sentinal的功能

相关文章
相关标签/搜索