`

Redis系列之Redis集群高可用

 
阅读更多

Redis集群的概念:

  RedisClusterredis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的需求,当一个服务挂了可以快速的切换到另外一个服务,当遇到单机内存、并发等瓶颈时,可使用此方案来解决这些问题

一、分布式数据库概念

1. 分布式数据库把整个数据按分区规则映射到多个节点,即把数据划分到多个节点上,每个节点负责整体数据的一个子集。比如我们库有900条用户数据,有3redis节点,将900条分成3份,分别存入到3redis节点

2. 分区规则:

   常见的分区规则哈希分区和顺序分区,redis集群使用了哈希分区,顺序分区暂用不到,不做具体说明;

   rediscluster采用了哈希分区的“虚拟槽分区”方式(哈希分区分节点取余、一致性哈希分区和虚拟槽分区),其它两种也不做介绍,有兴趣可以百度了解一下

3. 虚拟槽分区(槽:slot)

   RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]&16383)映射到016383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据

   哈希函数: Hash()=CRC16[key]&16383 按位与

   槽与节点的关系如下

redis用虚拟槽分区原因:解耦数据与节点关系,节点自身维护槽映射关系,分布式存储

4. redisCluster的缺陷:

a,键的批量操作支持有限,比如mset, mget,如果多个键映射在不同的槽,就不支持了

b,键事务支持有限,当多个key分布在不同节点时无法使用事务,同一节点是支持事务

c,键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点

d不支持多数据库,只有0select 0

e,复制结构只支持单层结构,不支持树型结构。  

二、集群环境搭建-手动篇

部署结构图:6389为6379的从节点,6390为6380的从节点,6391为6381的从节点

 

 

1.在/usr/local/bin/目录下新建一个文件夹clusterconf,用来存放集群的配置文件

2. 分别修改6379、 6380、 7381、 6389、 6390、 6391配置文件

以6379的配置为例:

   port 6379                      //节点端口

   cluster-enabled yes              //开启集群模式

   cluster-node-timeout 15000       //节点超时时间(接收pong消息回复的时间)

   cluster-config-file  /usr/localbin/cluster/data/nodes-6379.conf 集群内部配置文件

  其它节点的配置和这个一致,改端口即可

3. 配置完后,启动6redis服务

./redis-server clusterconf/redis6379.conf &

./redis-server clusterconf/redis6380.conf &

./redis-server clusterconf/redis6381.conf &

./redis-server clusterconf/redis6389.conf &

./redis-server clusterconf/redis6390.conf &

./redis-server clusterconf/redis6391.conf &

4. 各节点启动后,使用cluster meet ip port与各节点握手,是集群通信的第一步(关键步骤1:集群搭建-与各节点握手

 

5. 握手成功后,使用cluster nodes可以看到各节点都可以互相查询到

 

6. 节点握手成功后,此时集群处理下线状态,所有读写都被禁止

7. 使用cluster info命令获取集群当前状态

 

8. redis集群有16384个哈希槽,要把所有数据映射到16384槽,需要批量设置槽(关键步骤2:集群搭建-分配槽

redis-cli -h 192.168.152.128 -p 6379 cluster addslots {0...5461}

redis-cli -h 192.168.152.128 -p 6380 cluster addslots {5641...10922}

redis-cli -h 192.168.152.128 -p 6381 cluster addslots {10923...16383}

9. 分配完槽后,可查看集群状态cluster info

11. 然后再查看cluster nodes,查看每个节点的ID

12. 638963906391与 6379,6380,6381做主从映射(关键步骤3:集群搭建-集群映射),到此redis集群手动搭建完成

 192.168.152.128:6389> cluster replicate 9b7b0c22f95eb01fb9935ad4b04d396c7f99e881

192.168.152.128:6390> cluster replicate 5351c088472467ae485ed519cea271efda646bfa

 92.168.152.128:6391> cluster replicate e718f126278072e1e180c3e518d73e0bc877b3dc

三、集群环境搭建-自动

使用ruby来自动分配槽与主从分配,见redis安装文档,建议用此方式完成

1.首先下载ruby-2.3.1.tar.gz   和  redis-3.3.0.gem,然后把这两个工具通过winscp传入linux虚拟机

2. /usr/local新建目录:ruby

开始安装第一步中下载的两个软件

tar -zxvf ruby-2.3.1.tar.gz 

a) cd /software/rubysoft/ruby-2.3.1

b) ./configure -prefix=/usr/local/ruby

c)  make && make install   //过程会有点慢,大概510分钟

d) 然后gem install -l redis-3.3.0.gem  //没有gem需要安装yum install gem或者yum install rubygems

e) 准备好6个节点,(注意不要设置requirepass,/usr/local/bin/clusterconf/data之前手动配置config-file文件删除;依次启动6个节点:

./redis-server clusterconf/redis6379.conf

....

如果之前redis有数据存在,flushall清空;(:不需要cluster meet ..)

f) 进入cd /usr/local/bin,  执行以下:1代表从节点的个数(最关键的一步:通过这个命令可以自动完成之前手动配置集群的握手、分配槽位、主从映射

./redis-trib.rb create --replicas 1 192.168.152.128:6379 192.168.152.128:6380 192.168.152.128:6381 192.168.152.128:6389 192.168.152.128:6390 192.168.152.128:6391

主从分配,63796389的主节点,6380是6390的主节点,6381是6391的主节点,

貌似只有主节点可读写,从节点只能读

主节点死后,从节点变成主节点

3.集群搭建好以后开始测试

a) 连入redis集群并设置值./redis-cli -h 192.168.152.128 -p 6379 -c

可以看到设置name以后,重定向到了6380的这个redis,这时因为键name经过CRC16[k]&16284虚拟槽分区算法以后落到了6380这个节点,所以数据就存到了6380这个redis节点

切回6379获取name的值也会通过同样的算法重定向到6380

4.集群健康检查

./redis-trib.rb check 192.168.152.128:6379 (注:redis先去注释掉requirepass,不然连不上)

正常的

 

不正常的(来源于网络资源)

如此出现了这个问题,63795798槽位号被打开了

解决如下:

637963806381的有部分槽位被打开了,分别进入这几个节点,执行

6380:>cluster setslot 1180 stable

cluster setslot 2998 stable

cluster setslot 11212 stable

其它也一样,分别执行修复完后:

 

当停掉6379后,过会6389变成主节点

集群正常启动后,在每个redis.conf里加上

   masterauth “12345678”

   requiredpass “12345678”

  当主节点下线时,从节点会变成主节点,用户和密码是很有必要的,设置成一致

5.集群的多主多从

配置如下:

./redis-trib.rb create --replicas 2

192.168.1.111:6379 192.168.1.111:6380 192.168.1.111:6381

192.168.1.111:6479 192.168.1.111:6480 192.168.1.111:6481

192.168.1.111:6579 192.168.1.111:6580 192.168.1.111:6581 

6.集群节点之间的通信

 1. 节点之间采用Gossip协议进行通信,Gossip协议就是指节点彼此之间不断通信交换信息

 

 

当主从角色变化或新增节点,彼此通过ping/pong进行通信知道全部节点的最新状态并达到集群同步

 2. Gossip协议

Gossip协议的主要职责就是信息交换,信息交换的载体就是节点之间彼此发送的Gossip消息,常用的Gossip消息有ping消息、pong消息、meet消息、fail消息

 

meet消息:用于通知新节点加入,消息发送者通知接收者加入到当前集群,meet消息通信完后,接收节点会加入到集群中,并进行周期性ping pong交换

ping消息:集群内交换最频繁的消息,集群内每个节点每秒向其它节点发ping消息,用于检测节点是在在线和状态信息,ping消息发送封装自身节点和其他节点的状态数据;

pong消息,当接收到ping meet消息时,作为响应消息返回给发送方,用来确认正常通信,pong消息也封闭了自身状态数据;

fail消息:当节点判定集群内的另一节点下线时,会向集群内广播一个fail消息,

3. 消息解析流程

所有消息格式为:消息头、消息体,消息头包含发送节点自身状态数据(比如节点ID、槽映射、节点角色、是否下线等),接收节点根据消息头可以获取到发送节点的相关数据。

消息解析流程:

 

 

 

4. 选择节点并发送ping消息:

  Gossip协议信息的交换机制具有天然的分布式特性,但ping pong发送的频率很高,可以实时得到其它节点的状态数据,但频率高会加重带宽和计算能力,因此每次都会有目的性地选择一些节点; 但是节点选择过少又会影响故障判断的速度,redis集群的Gossip协议兼顾了这两者的优缺点,看下图:

 

不难看出:节点选择的流程可以看出消息交换成本主要体现在发送消息的节点数量和每个消息携带的数据量

流程说明:

A,选择发送消息的节点数量:集群内每个节点维护定时任务默认为每秒执行10次,每秒会随机选取5个节点,找出最久没有通信的节点发送ping消息,用来保证信息交换的随机性,每100毫秒都会扫描本地节点列表,如果发现节点最近一次接受pong消息的时间大于cluster-node-timeout/2 则立刻发送ping消息,这样做目的是防止该节点信息太长时间没更新,当我们宽带资源紧张时,在可redis.confcluster-node-timeout 15000  改成30秒,但不能过度加大

B,消息数据:节点自身信息和其他节点信息

四、redis集群扩容

这也是分布式存储最常见的需求,当我们存储不够用时,要考虑扩容

扩容步骤如下:

A. 准备好新节点

B. 加入集群,迁移槽和数据

1) 同目录下新增redis6382.confredis6392.conf两个redis节点

启动两个新redis节点

./redis-server clusterconf/redis6382.conf &  (新主节点)

./redis-server clusterconf/redis6392.conf &   (新从节点)

2) 新增主节点

 ./redis-trib.rb add-node 192.168.152.128:6382 192.168.152.128:6379  

6379是原存在的主节点,6382是新的主节点

 

3),添加从节点

redis-trib.rb add-node --slave --master-id 03ccad2ba5dd1e062464bc7590400441fafb63f2 192.168.152.128:6392 192.168.152.128:6379  

    --slave,表示添加的是从节点

    --master-id 03ccad2ba5dd1e062464bc7590400441fafb63f2表示主节点6382master_id

    192.168.152.128:6392,新从节点

    192.168.152.128:6379集群原存在的旧节点

 

4) redis-trib.rb reshard 192.168.152.128:6382   //为新主节点重新分配solt

How many slots do you want to move (from 1 to 16384)? 1000 //设置slot1000

What is the receiving node ID? 464bc7590400441fafb63f2 //新节点node id

Source node #1:all //表示全部节点重新洗牌

新增完毕!

五、集群减缩节点

集群同时也支持节点下线掉,下线的流程如下:

流程说明:

A,确定下线节点是否存在槽slot,如果有,需要先把槽迁移到其他节点,保证整个集群槽节点映射的完整性;

B,当下线的节点没有槽或本身是从节点时,就可以通知集群内其它节点(或者叫忘记节点),当下线节点被忘记后正常关闭。

删除节点也分两种:

一种是主节点6382,一种是从节点6392

在从节点6392中,没有分配哈希槽,执行

./redis-trib.rb del-node 192.168.1.111:6392 7668541151b4c37d2d9 有两个参数ipport  和节点的id。 从节点6392从集群中删除了。

主节点6382删除步骤:

1./redis-trib.rb reshard 192.168.1.111:6382

  问我们有多少个哈希槽要移走,因为我们这个节点上刚分配了1000 个所以我们这里输入1000

2,最后

./redis-trib.rb del-node 192.168.1.111:6382 3e50c6398c75e0088a41f908071c2c2eda1dc900

此时节点下线完成……

 六、故障转移

redis集群实现了高可用,当集群内少量节点出现故障时,通过故障转移可以保证集群正常对外提供服务。

当集群里某个节点出现了问题,redis集群内的节点通过ping pong消息发现节点是否健康,是否有故障,其实主要环节也包括了 主观下线和客观下线;

主观下线:指某个节点认为另一个节点不可用,即下线状态,当然这个状态不是最终的故障判定,只能代表这个节点自身的意见,也有可能存在误判;

 

 

下线流程:

A,节点a发送ping消息给节点b ,如果通信正常将接收到pong消息,节点a更新最近一次与节点b的通信时间;

B,如果节点a与节点b通信出现问题则断开连接,下次会进行重连,如果一直通信失败,则它们的最后通信时间将无法更新;

节点a内的定时任务检测到与节点b最后通信时间超过cluster_note-timeout时,更新本地对节点b的状态为主观下线(pfail

客观下线:指真正的下线,集群内多个节点都认为该节点不可用,达成共识,将它下线,如果下线的节点为主节点,还要对它进行故障转移

假如节点a标记节点b为主观下线,一段时间后节点a通过消息把节点b的状态发到其它节点,当节点c接受到消息并解析出消息体时,会发现节点bpfail状态时,会触发客观下线流程;

当下线为主节点时,此时redis集群为统计持有槽的主节点投票数是否达到一半,当下线报告统计数大于一半时,被标记为客观下线状态。

故障恢复:

故障主节点下线后,如果下线节点的是主节点,则需要在它的从节点中选一个替换它,保证集群的高可用;转移过程如下:

 

1,资格检查:检查该从节点是否有资格替换故障主节点,如果此从节点与主节点断开过通信,那么当前从节点不具体故障转移;

2,准备选举时间:当从节点符合故障转移资格后,更新触发故障选举时间,只有到达该时间后才能执行后续流程;

3,发起选举:当到达故障选举时间时,进行选举;

4,选举投票:只有持有槽的主节点才有票,会处理故障选举消息,投票过程其实是一个领导者选举(选举从节点为领导者)的过程,每个主节点只能投一张票给从节点,当从节点收集到足够的选票(大于N/2+1)后,触发替换主节点操作,撤销原故障主节点的槽,委派给自己,并广播自己的委派消息,通知集群内所有节点。

 

分享到:
评论

相关推荐

    docker-compose redis主从哨兵 redis多节点高可用 redis集群高可用

    3. **Redis集群高可用**:Redis集群通过分片(Sharding)和槽区(Slot)分配,将数据分散到多个节点上,这样即使部分节点故障,其他节点仍能提供服务。Docker Compose配置中,我们需要定义多个集群节点,每个节点都...

    03-VIP-Redis缓存高可用集群(预习)1

    2. **Redis高可用集群**:Redis集群模式自3.0版本起引入,不再依赖哨兵系统。它由多个主从节点组成,具备复制、高可用性和分片功能。集群无需中心节点,可水平扩展,理论上能扩展至上万个节点(官方建议不超过1000个...

    redis最新版5.0.2高可用集群搭建

    #### 一、Redis集群方案比较 Redis 是一种高性能的键值存储系统,在多种场景中被广泛应用于缓存、消息队列以及实时分析等领域。随着应用规模的增长,单一的 Redis 实例往往难以满足高并发和大数据量的需求,因此...

    搭建redis缓存高可用集群.md

    Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低Redis集群的性能, 并导致不可预测的行为。 Redis 集群通过...

    Redis+nginx集群部署

    5. **配置Redis**:需要在Tomcat的`context.xml`文件中配置一个连接到Redis的SessionManager,例如使用`JedisCluster`库来连接Redis集群。 6. **Nginx与Tomcat的通信**:Nginx配置文件(如`nginx.conf`)需要设置...

    高可用之Redis集群的扩展测试.docx

    高可用之Redis集群的扩展测试 高可用之Redis集群的扩展测试是指在既有的Redis集群基础上,通过添加新的Redis节点来提高集群的可用性和扩展性。本文将介绍如何在现有的Redis集群中添加新的Redis节点,以提高集群的...

    第三节Redis高可用集群之水平扩展1

    Redis 高可用集群是通过分布式方式提供数据存储和读写服务,确保在系统故障时能够自动切换,保持服务连续性。在 Redis 3.0 及以上版本中,引入了集群(Cluster)功能,它允许数据分片到多个节点,同时提供了故障转移...

    高可用之Redis集群的高可用测试(含Jedis客户端的使用).docx

    高可用之Redis集群的高可用测试(含Jedis客户端的使用) 本文主要介绍了高可用之Redis集群的高可用测试,包括使用Jedis客户端的配置和使用。下面是本文的知识点概述: 一、Redis集群的搭建 Redis集群是指通过多个...

    springboot整合redis集群零配置

    总结,Spring Boot与Redis集群的整合使得高可用的缓存管理变得简单。而通过自定义AOP注解,我们可以实现更加定制化的缓存策略,以满足复杂的应用需求。这不仅提高了代码的可读性和可维护性,还使缓存管理变得更加...

    Redis集群测试

    2. **主从复制**:在Redis集群中,每个节点都有一个或多个副本节点,主节点负责处理写操作,而从节点负责备份数据并处理读请求,确保高可用性。当主节点故障时,从节点可以接管其职责。 3. **槽迁移**:在添加或...

    springcloud部署redis集群

    在SpringCloud框架中,部署Redis集群是实现高可用、数据持久化和分布式缓存的关键步骤。Redis是一款高性能的键值数据库,广泛应用于缓存、消息队列等多种场景。SpringCloud通过集成Spring Data Redis模块,使得在...

    SpringBoot集成Redis集群

    同时,Redis集群也可以提供高可用性的服务,避免单点故障的出现。 集成Redis集群的步骤 ### 第一步:架包 在SpringBoot 2.X中,需要添加相关的依赖项,以便集成Redis集群。这些依赖项包括spring-boot-starter-...

    keepalived+redis 高可用方案 集群环境搭建

    keepalived+redis 高可用方案 集群环境搭建. 部分来自网上,部分自己的总结. 详细的记录了如何搭建keepalived+redis的环境

    Redis高可用集群Redis Cluster搭建

    Redis高可用集群Redis Cluster搭建 Redis高可用集群Redis Cluster搭建是 Redis 官方推荐的高可用性解决方案,于 3.0 版本推出。Redis Cluster 的主要用途是实现数据分片(Data Sharding),同时也可以实现高可用...

    Redis 3.x 分布式集群搭建.pdf

    redis从3.0开始支持集群功能。redis集群采用无中心节点方式实现,无需proxy代理,客户端...一旦有主节点发生故障的时候,Redis Cluster可以选举出对应的从结点成为新的主节点,继续对外服务,从而保证服务的高可用性.

    高可用之Redis集群的安装(Redis3+CentOS).docx

    Redis 高可用集群安装指南 本文档将指导您如何安装高可用的 Redis 集群,使用 Redis 3.0.3 和 CentOS 6.6_x64。我们将从基本概念开始,逐步讲解集群的安装和配置过程。 一、Redis 集群简介 Redis 集群是一种高...

    spring集成redis单节点、集群、哨兵配置

    接下来是**Redis集群配置**。在集群模式下,Redis数据分散在多个节点上,每个节点只负责一部分数据,提高扩展性和可用性。Spring Data Redis提供了ClusterConnectionFactory来处理集群连接。配置需要指定所有节点的...

    redis3主3从集群搭建完整版

    Redis 是一款高性能的键值数据库,常用于缓存和数据持久化。...不过,值得注意的是,Redis 集群并不支持所有数据类型的操作,例如 SET 的成员操作在集群模式下是不可用的,需要根据具体应用需求来选择合适的部署方式。

    分享课程:Redis高并发高可用集群百万级秒杀实战

    Redis 的高并发高可用集群:主从复制允许数据集在主节点和多个从节点之间同步。当主节点发生故障时,从节点可以接管服务,从而实现自动故障转移。哨兵机制哨兵系统用于监控 Redis 主节点和从节点的健康状态,并在主...

Global site tag (gtag.js) - Google Analytics