​​​​​

0、常见的几种模式对比

模式

版本

优点

缺点

主从模式 redis2.8之前

1、解决数据备份问题

2、做到读写分离,提高服务器性能

1、master故障,无法自动故障转移,需人工介入

2、master无法实现动态扩容

哨兵模式 redis2.8级之后的模式

1、Master 状态监测

2、master节点故障,自动切换主从,故障自愈

3、所有slave从节点,随之更改新的master节点

1、slave节点下线,sentinel不会对一进行故障转移,连接从节点的客户端因为无法获取到新的可用从节点

2、master无法实行动态扩容

redis cluster模式 redis3.0版本之后

1、有效的解决了redis在分布式方面的需求

2、遇到单机内存,并发和流量瓶颈等问题时,可采用Cluster方案达到负载均衡的目的

3、可实现动态扩容

4、P2P模式,无中心化

5、通过Gossip协议同步节点信息

6、自动故障转移、Slot迁移中数据可用

7、自动分割数据到不同的节点上

8、整个集群的部分节点失败或者不可达的情况下能够继续处理命令

1、架构比较新,最佳实践较少

2、为了性能提升,客户端需要缓存路由表信息

3、节点发现、reshard操作不够自动化

4、不支持处理多个keys的命令,因为这需要在不同的节点间移动数据

5、Redis 集群不像单机 Redis 那样支持多数据库功能, 集群只使用默认的 0 号数据库, 并且不能使用 SELECT index 命令

一、redis cluster 是什么

Redis集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。Redis集群不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。redis集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单。redis集群的运用主要是针对海量数据+高并发+高可用的场景。

二、集群架构图

在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作

三、集群原理图

介绍:

对象保存到redis之前先经过CRC16哈希到一个指定的Node上(这个过程即redis cluster的分片),集群内部将所有的key映射到16384个Slot中,集群中的每个Redis Instance负责其中的一部分的Slot的读写。集群客户端连接集群中任一Redis Instance即可发送命令,当Redis Instance收到自己不负责的Slot的请求时,会将负责请求Key所在Slot的Redis Instance地址返回给客户端,客户端收到后自动将原请求重新发往这个地址,对外部透明。一个Key到底属于哪个Slot由 (HASH_SLOT = CRC16(key) mod 16384) 决定。只有master节点会被分配槽位,slave节点不会分配槽位。

四、集群通信

1)集群发现:MEET

最开始时,每个redis实例自己是一个集群,我们通过cluster meet让各个节点互相“握手”,需要续建一个真正可工作的集群,我们必须将各个节点连接起来,构成一个包含多个节点的集群。连接各个节点的工作使用CLUSTER MEET命令来完成。

CLUSTER MEET命令实现:

1)节点A会为节点B创建一个clusterNode结构,并将该结构添加到自己的clusterState.nodes字典里面。

2)节点A根据CLUSTER MEET命令给定的IP地址和端口号,向节点B发送一条MEET消息。

3)节点B接收到节点A发送的MEET消息,节点B会为节点A创建一个clusterNode结构,并将该结构添加到自己的clusterState.nodes字典里面。

4)节点B向节点A返回一条PONG消息。

5)节点A将受到节点B返回的PONG消息,通过这条PONG消息节点A可以知道节点B已经成功的接收了自己发送的MEET消息。

6)之后,节点A将向节点B返回一条PING消息。

7)节点B将接收到的节点A返回的PING消息,通过这条PING消息节点B可以知道节点A已经成功的接收到了自己返回的PONG消息,握手完成。

8)之后,节点A会将节点B的信息通过Gossip协议传播给集群中的其他节点,让其他节点也与节点B进行握手,最终,经过一段时间后,节点B会被集群中的所有节点认识。

2)gossip协议

gossip协议包含多种消息,包含ping、pong、meet、fail等

1)meet:某个节点在内部发送了一个gossip meet 消息给新加入的节点,通知那个节点去加入我们的集群。然后新节点就会加入到集群的通信中

2)ping:每个节点都会频繁给其它节点发送 ping,其中包含自己的状态还有自己维护的集群元数据,互相通过 ping 交换元数据

3)pong:ping 和 meet消息的返回响应,包含自己的状态和其它信息,也用于信息广播和更新

4)fail:某个节点判断另一个节点 fail 之后,就发送 fail 给其它节点,通知其它节点说这个节点已宕机

五、集群概念

1)多slave选举

选新主的过程基于Raft协议选举方式来实现的

1)当从节点发现自己的主节点进行已下线状态时,从节点会广播一条CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有收到这条消息,并且具有投票权的主节点向这个从节点投票

2)如果一个主节点具有投票权,并且这个主节点尚未投票给其他从节点,那么主节点将向要求投票的从节点返回一条,CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示这个主节点支持从节点成为新的主节点

3)每个参与选举的从节点都会接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并根据自己收到了多少条这种消息来统计自己获得了多少主节点的支持

4)如果集群里有N个具有投票权的主节点,那么当一个从节点收集到大于等于集群N/2+1张支持票时,这个从节点就成为新的主节点

5)如果在一个选举周期没有从能够收集到足够的支持票数,那么集群进入一个新的选举周期,并再次进行选主,直到选出新的主节点为止

2)slot(槽)

Redis Cluster中有一个16384长度的槽的概念,他们的编号为0、1、2、3……16382、16383。这个槽是一个虚拟的槽,并不是真正存在的。正常工作的时候,Redis Cluster中的每个Master节点都会负责一部分的槽,当有某个key被映射到某个Master负责的槽,那么这个Master负责为这个key提供服务,至于哪个Master节点负责哪个槽,这是可以由用户指定的,也可以在初始化的时候自动生成(redis-trib.rb脚本)。这里值得一提的是,在Redis Cluster中,只有Master才拥有槽的所有权,如果是某个Master的slave,这个slave只负责槽的使用,但是没有所有权。

3)数据分片

在Redis Cluster中,拥有16384个slot,这个数是固定的,存储在Redis Cluster中的所有的键都会被映射到这些slot中。数据库中的每个键都属于这16384个哈希槽的其中一个,集群使用公式CRC16(key) % 16384来计算键key属于哪个槽,其中CRC16(key)语句用于计算键key的CRC16校验和。集群中的每个节点负责处理一部分哈希槽。

4)请求重定向

由于每个节点只负责部分slot,以及slot可能从一个节点迁移到另一节点,造成客户端有可能会向错误的节点发起请求。因此需要有一种机制来对其进行发现和修正,这就是请求重定向。有两种不同的重定向场景:

a)MOVED错误

1.请求的key对应的槽不在该节点上,节点将查看自身内部所保存的哈希槽到节点ID的映射记录, 节点回复一个MOVED错误。

2.需要客户端进行再次重试。

b)ASK错误(一般发生在数据迁移的过程中)

1.请求的key对应的槽目前的状态属于MIGRATING状态,并且当前节点找不到这个key了,节点回 复ASK错误。ASK会把对应槽的IMPORTING节点返回给你,告诉你去IMPORTING的节点尝试找找。

2.客户端进行重试首先发送ASKING命令,节点将为客户端设置一个一次性的标志(flag),使得 客户端可以执行一次针对IMPORTING状态的槽的命令请求,然后再发送真正的命令请求。

3.不必更新客户端所记录的槽至节点的映射。

5)数据迁移

当槽x从Node A向Node B迁移时,Node A和Node B都会有这个槽x,Node A上槽x的状态设置为MIGRATING,Node B上槽x的状态被设置为IMPORTING。

MIGRATING状态

1)如果key存在则成功处理

2)如果key不存在,则返回客户端ASK,客户端根据ASK首先发送ASKING命令到目标节点,然后发送请求的命令到目标节点

3)当key包含多个命令,

a)如果都存在则成功处理

b)如果都不存在,则返回客户端ASK

c)如果一部分存在,则返回客户端TRYAGAIN,通知客户端稍后重试,这样当所有的 key都迁移完毕的时候客户端重试请求的时候回得到ASK,然后经过一次重定向就 可以获取这批键

4)此时不刷新客户端中node的映射关系

IMPORTING状态

1)如果key不在该节点上,会被MOVED重定向,刷新客户端中node的映射关系

2)如果是ASKING命令则命令会被执行,key不在迁移的节点已经被迁移到目标的节点

3)Key不存在则新建

6)故障转移

当从节点发现自己的主节点变为已下线(FAIL)状态时,便尝试进Failover,以期成为新的主。

以下是故障转移的执行步骤:

1)从下线主节点的所有从节点中选中一个从节点

2)被选中的从节点执行SLAVEOF NO NOE命令,成为新的主节点

3)新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己

4)新的主节点对集群进行广播PONG消息,告知其他节点已经成为新的主节点

5)新的主节点开始接收和处理槽相关的请求

7)集群slots是否必须完整才能对外提供服务

当redis.conf的配置cluster-require-full-coverage为no时,表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用,如果为yes则集群不可用。

六、集群健康检查机制

1、集群的每个节点都会相互发送一个活跃的ping包,当ping包确认返回的时间超过node_timeout的时间,我们认为节点失效
2、当然,当节点在等待时间超过一半node_timeout的时间还没有收到目标节点对于ping包的回复的时候,就会立马尝试重连该节点,这个机制可以确保链接都保证有效,所以节点之间的失效链接都不会导致错误的失效报告
3、节点从正常状态到fail状态,需要收集每个节点对不正常节点(B)的确认:1)当节点(A)发送的ping包没有返回,此时将B节点的状态信息标记为(PFAIL)状态,然后将信息发送到集群的其它节点,同理当A收集本地有关B状态的信息,当大多数主节点认为B节点是PFAIL状态时,节点A将标记B的状态为FAIL状态,然后向所有的可达节点发送这个消息
4、当大多数主节点都将B节点标示为FAIL状态时,B节点才最终被集群标记为FAIL状态,此时B1(B的从节点)提升为主节点提供服务
5、本质上来说,FAIL 标识只是用来触发从节点提升(slave promotion)算法的安全部分。理论上一个从节点会在它的主节点不可达的时候独立起作用并且启动从节点提升程序,然后等待主节点来拒绝认可该提升(如果主节点对大部分节点恢复连接)。PFAIL -> FAIL 的状态变化、弱协议、强制在集群的可达部分用最短的时间传播状态变更的 FAIL 消息,这些东西增加的复杂性有实际的好处。由于这种机制,如果集群处于错误状态的时候,所有节点都会在同一时间停止接收写入操作,这从使用 Redis 集群的应用的角度来看是个很好的特性。还有非必要的选举,是从节点在无法访问主节点的时候发起的,若该主节点能被其他大多数主节点访问的话,这个选举会被拒绝掉

7、注意事项

1)redis master 宕机,恢复后不会自动切为主
2)扩容redis cluster如果我们大量使用redis cluster的话,有一个痛点就是扩容的机器加入集群的时候,分配主从。现在只能使用命令去操作,非常的凌乱。而且如果redis cluster是线上集群或者是有数据的话,极其容易造成丢数据,或者扩容是hang住等..隐患
3)redis cluster 从节点支持可读的前提下得在执行readonly执行,程序读取从节点时也需要执行。一次连接需要执行一次,客户端关闭即失效。
4)redis cluster 启动必须以绝对路径的方式启动,如果不用绝对路径启动,会产生新的nodes.conf 文件,集群的主从对应关系就会变乱,从而导致集群奔溃,如下是正确的启动方式
cd /opt/yidian/redis-cluster/6379/ &&  nohup /usr/local/bin/redis-server /opt/yidian/redis-cluster/6379/redis-6379.conf &

八、业务使用Redis Cluster注意事项

操作 业务侧需改造内容 示例 说明
批量操作 需要保证批量操作的key在同一个slot中 mset {test4}:test4 6 {test4}:test8 10 1.示例中的key是{type}:keyword格式,当key中包含{type}的时候,会使用type进行hash运算去判断slot,keyword不影响运算结果。
2.示例中的test4和test8不在同一个slot,但是这两个slot分配给了同一个server。
事务操作 需要保证事务中的key在同一个slot中 MULTI
set {test4}:test4 14
get {test4}:test4
EXEC
Lua脚本 需要保证Lua脚本中的key在同一个slot中 EVAL "return {KEYS[1],KEYS[2]}" 2 {test4}:key1 {test4}:key2
PipeLine 需要保证PipeLine中的key在同一台Server上 Jedis jedis = new Jedis("10.138.20.141", 6379);
Pipeline pipelined = jedis.pipelined();
pipelined.set("test4","pipelineTest4");
pipelined.set("test8","pipelineTest8");
List<Object> objects = pipelined.syncAndReturnAll();
代码控制 连接方式和命令执行的依赖需要改变 JedisCluster jedisCluster = new JedisCluster(new HostAndPort("10.138.20.141", 6379));
jedisCluster.set("test4","abcd");
1.cluster需要连接到这个key所在的节点上,才能进行操作。
2.一般都会有封装好的依赖包,例如Jedis(Java)
多DB 不支持多DB   select命令禁用

redis Cluster集群介绍相关推荐

  1. Ubuntu 16.04下Redis Cluster集群搭建(官方原始方案)

    前提:先安装好Redis,参考:http://www.cnblogs.com/EasonJim/p/7599941.html 说明:Redis Cluster集群模式可以做到动态增加节点和下线节点,使 ...

  2. redis集群扩容和缩容_深入理解Redis Cluster集群

    一.背景 前面的文章<深入理解Redis哨兵机制>一文中介绍了Redis哨兵集群的工作原理,哨兵集群虽然满足了高可用的特性,但是依然存在这样的问题:即数据只能往一个主节点上进行写入. 只能 ...

  3. Redis Cluster 集群扩容与收缩

    2019独角兽企业重金招聘Python工程师标准>>> Redis Cluster 集群伸缩 1. 伸缩原理 Redis提供了灵活的节点扩容和收缩方案.在不影响集群对外服务的情况下, ...

  4. Redis Cluster集群知识学习总结

    Redis集群解决方案有两个: 1)  Twemproxy: 这是Twitter推出的解决方案,简单的说就是上层加个代理负责分发,属于client端集群方案,目前很多应用者都在采用的解决方案.Twem ...

  5. redis cluster 集群 HA 原理和实操(史上最全、面试必备)

    文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 经典图书:<Java高并发核心编程(卷1)> 面试必备 ...

  6. python连接redis集群如何释放内存_python 连接 redis cluster 集群

    一. redis集群模式有多种, cluster模式只是其中的一种实现方式, 其原理请自行谷歌或者百度, 这里只举例如何使用Python操作 redis cluster 集群 二. python 连接 ...

  7. redis cluster集群选主

    redis 选主过程分析  当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的master.由于挂掉的master可能会有多个slave.Failover的 ...

  8. centos7 docker-compose安装_Docker Compose 搭建 Redis Cluster 集群环境

    在前文<Docker 搭建 Redis Cluster 集群环境>中我已经教过大家如何搭建了,本文使用 Docker Compose 再带大家搭建一遍,其目的主要是为了让大家感受 Dock ...

  9. redis cluster 集群重新启动关闭

    找遍了redis cluster官方文档,没发现有关集群重新启动和关闭的方法.为啥会没有呢,推測redis cluster至少要三个节点才干执行,三台同一时候挂掉的可能性比較小,仅仅要不同一时候挂掉. ...

最新文章

  1. 脆弱的Scrum,敏捷在哪里?
  2. 贪心算法之用优先队列解决最短路径问题(Dijkstra算法)
  3. vertx rest 跨域_在基于简单Vertx Rest的应用程序上为REST资源设置基本响应HTTP标头...
  4. Calculation控制台
  5. 微课|玩转Python轻松过二级(3.2节):元组与生成器推导式
  6. Linux学习笔记012---Centos7修改环境变量
  7. 多图像合成为延时视频的方法
  8. 项目周例会会议纪要模板
  9. 全同高校名称MySQL数据表
  10. 5254. 卖木头块 动态规划
  11. GOP和帧率、码率的关系
  12. 小白系统盘制作详细教程
  13. KafkaStream之时间窗口WindowBy
  14. 音乐网站制作之音乐播放
  15. PL/SQL破解方法(不需要注册码)
  16. QT报错:Gtk-Message:Failed to load module :gail“
  17. 奥比中光astra 摄像头采集深度图和RGB图像(小白版)
  18. 华为中央软件院编译器与编程语言实验室人才招募
  19. hadoop:常用web界面和命令
  20. 【22年2月12日更新】新版傻妞+对接onebot协议+对接青龙教程+常用命令

热门文章

  1. JavaScript中的方法是什么
  2. tree view android,AndroidTreeView
  3. LTE中小区选择流程及其S准则详解
  4. 儿童七彩浏览器 隐私声明
  5. python爬取天天基金_Python爬虫日记二:爬取天天基金网
  6. 互斥(mutual exclusion)
  7. FPGA开发中全局复位置位(GSR)简介
  8. 极客日报第5期:华为剥离荣耀 交易价格1000亿元;2020年十大热词出炉:开头看着想笑,后面感动到哭
  9. 什么是CN2线路服务器
  10. win10自带的截图工具命令