Redis 5 之后版本的高可用集群搭建

Redis 5.0之后版本的高可用集群搭建

Redis系统介绍:

Redis的基础介绍与安装使用步骤:https://www.jianshu.com/p/2a23257af57b
Redis的基础数据结构与使用:https://www.jianshu.com/p/c95c8450c5b6
Redis核心原理:https://www.jianshu.com/p/4e6b7809e10a
Redis 5 之后版本的高可用集群搭建:https://www.jianshu.com/p/8045b92fafb2
Redis 5 版本的高可用集群的水平扩展:https://www.jianshu.com/p/6355d0827aea
Redis 5 集群选举原理分析:https://www.jianshu.com/p/e6894713a6d5
Redis 5 通信协议解析以及手写一个Jedis客户端:https://www.jianshu.com/p/575544f68615


集群方案比较:

redis3.0版本的集群模式

哨兵模式:

在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般,特别是在主从切换的瞬间存在访问瞬断的情况,而且哨兵模式只有一个主节点对外提供服务,没法支持很高的并发,且单个主节点内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率。

Redis 5 之后版本的高可用集群搭建_第1张图片

 

高可用集群模式:

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

Redis 5 之后版本的高可用集群搭建_第2张图片

 

集群的基本原理

下面将进一步深入,介绍集群的原理。集群最核心的功能是数据分区,因此首先介绍数据的分区规则;然后介绍集群实现的细节:通信机制和数据结构;最后以cluster meet(节点握手)、cluster addslots(槽分配)为例,说明节点是如何利用上述数据结构和通信机制实现集群命令的。

1. 数据分区方案

数据分区有顺序分区、哈希分区等,其中哈希分区由于其天然的随机性,使用广泛;集群的分区方案便是哈希分区的一种。

哈希分区的基本思路是:对数据的特征值(如key)进行哈希,然后根据哈希值决定数据落在哪个节点。常见的哈希分区包括:哈希取余分区、一致性哈希分区、带虚拟节点的一致性哈希分区等。

衡量数据分区方法好坏的标准有很多,其中比较重要的两个因素是(1)数据分布是否均匀(2)增加或删减节点对数据分布的影响。由于哈希的随机性,哈希分区基本可以保证数据分布均匀;因此在比较哈希分区方案时,重点要看增减节点对数据分布的影响

(1)哈希取余分区

哈希取余分区思路非常简单:计算key的hash值,然后对节点数量进行取余,从而决定数据映射到哪个节点上。该方案最大的问题是,当新增或删减节点时,节点数量发生变化,系统中所有的数据都需要重新计算映射关系,引发大规模数据迁移。

(2)一致性哈希分区

一致性哈希算法将整个哈希值空间组织成一个虚拟的圆环,如下图所示,范围为0-2^32-1;对于每个数据,根据key计算hash值,确定数据在环上的位置,然后从此位置沿环顺时针行走,找到的第一台服务器就是其应该映射到的服务器。

Redis 5 之后版本的高可用集群搭建_第3张图片

与哈希取余分区相比,一致性哈希分区将增减节点的影响限制在相邻节点。以上图为例,如果在node1和node2之间增加node5,则只有node2中的一部分数据会迁移到node5;如果去掉node2,则原node2中的数据只会迁移到node4中,只有node4会受影响。

一致性哈希分区的主要问题在于,当节点数量较少时,增加或删减节点,对单个节点的影响可能很大,造成数据的严重不平衡。还是以上图为例,如果去掉node2,node4中的数据由总数据的1/4左右变为1/2左右,与其他节点相比负载过高。

(3)带虚拟节点的一致性哈希分区

该方案在一致性哈希分区的基础上,引入了虚拟节点的概念。Redis集群使用的便是该方案,其中的虚拟节点称为槽(slot)。槽是介于数据和实际节点之间的虚拟概念;每个实际节点包含一定数量的槽,每个槽包含哈希值在一定范围内的数据。引入槽以后,数据的映射关系由数据hash->实际节点,变成了数据hash->槽->实际节点。

在使用了槽的一致性哈希分区中,槽是数据管理和迁移的基本单位。槽解耦了数据和实际节点之间的关系,增加或删除节点对系统的影响很小。仍以上图为例,系统中有4个实际节点,假设为其分配16个槽(0-15); 槽0-3位于node1,4-7位于node2,以此类推。如果此时删除node2,只需要将槽4-7重新分配即可,例如槽4-5分配给node1,槽6分配给node3,槽7分配给node4;可以看出删除node2后,数据在其他节点的分布仍然较为均衡。

槽的数量一般远小于2^32,远大于实际节点的数量;在Redis集群中,槽的数量为16384。

下面这张图很好的总结了Redis集群将数据映射到实际节点的过程:

Redis 5 之后版本的高可用集群搭建_第4张图片

图片修改自:https://blog.csdn.net/yejingtao703/article/details/78484151

(1)Redis对数据的特征值(一般是key)计算哈希值,使用的算法是CRC16。

(2)根据哈希值,计算数据属于哪个槽。

(3)根据槽与节点的映射关系,计算数据属于哪个节点。

2. 节点通信机制

集群要作为一个整体工作,离不开节点之间的通信。

两个端口

在哨兵系统中,节点分为数据节点和哨兵节点:前者存储数据,后者实现额外的控制功能。在集群中,没有数据节点与非数据节点之分:所有的节点都存储数据,也都参与集群状态的维护。为此,集群中的每个节点,都提供了两个TCP端口:

  • 普通端口:即我们在前面指定的端口(7000等)。普通端口主要用于为客户端提供服务(与单机节点类似);但在节点间数据迁移时也会使用。
  • 集群端口:端口号是普通端口+10000(10000是固定值,无法改变),如7000节点的集群端口为17000。集群端口只用于节点之间的通信,如搭建集群、增减节点、故障转移等操作时节点间的通信;不要使用客户端连接集群接口。为了保证集群可以正常工作,在配置防火墙时,要同时开启普通端口和集群端口。

Gossip协议

节点间通信,按照通信协议可以分为几种类型:单对单、广播、Gossip协议等。重点是广播和Gossip的对比。

广播是指向集群内所有节点发送消息;优点是集群的收敛速度快(集群收敛是指集群内所有节点获得的集群信息是一致的),缺点是每条消息都要发送给所有节点,CPU、带宽等消耗较大。

Gossip协议的特点是:在节点数量有限的网络中,每个节点都“随机”的与部分节点通信(并不是真正的随机,而是根据特定的规则选择通信的节点),经过一番杂乱无章的通信,每个节点的状态很快会达到一致。Gossip协议的优点有负载(比广播)低、去中心化、容错性高(因为通信有冗余)等;缺点主要是集群的收敛速度慢。

消息类型

集群中的节点采用固定频率(每秒10次)的定时任务进行通信相关的工作:判断是否需要发送消息及消息类型、确定接收节点、发送消息等。如果集群状态发生了变化,如增减节点、槽状态变更,通过节点间的通信,所有节点会很快得知整个集群的状态,使集群收敛。

节点间发送的消息主要分为5种:meet消息、ping消息、pong消息、fail消息、publish消息。不同的消息类型,通信协议、发送的频率和时机、接收节点的选择等是不同的。

  • MEET消息:在节点握手阶段,当节点收到客户端的CLUSTER MEET命令时,会向新加入的节点发送MEET消息,请求新节点加入到当前集群;新节点收到MEET消息后会回复一个PONG消息。
  • PING消息:集群里每个节点每秒钟会选择部分节点发送PING消息,接收者收到消息后会回复一个PONG消息。PING消息的内容是自身节点和部分其他节点的状态信息;作用是彼此交换信息,以及检测节点是否在线。PING消息使用Gossip协议发送,接收节点的选择兼顾了收敛速度和带宽成本,具体规则如下:(1)随机找5个节点,在其中选择最久没有通信的1个节点(2)扫描节点列表,选择最近一次收到PONG消息时间大于cluster_node_timeout/2的所有节点,防止这些节点长时间未更新。
  • PONG消息:PONG消息封装了自身状态数据。可以分为两种:第一种是在接到MEET/PING消息后回复的PONG消息;第二种是指节点向集群广播PONG消息,这样其他节点可以获知该节点的最新信息,例如故障恢复后新的主节点会广播PONG消息。
  • FAIL消息:当一个主节点判断另一个主节点进入FAIL状态时,会向集群广播这一FAIL消息;接收节点会将这一FAIL消息保存起来,便于后续的判断。
  • PUBLISH消息:节点收到PUBLISH命令后,会先执行该命令,然后向集群广播这一消息,接收节点也会执行该PUBLISH命令。

开始搭建

一、安装redis

参考之前博客:Redis的基础介绍与安装使用步骤:https://www.jianshu.com/p/2a23257af57b

下载地址:http://redis.io/download

1、安装gcc

yum install gcc

2、把下载好的redis-5.0.2.tar.gz放在/usr/local文件夹下,并解压

wget http://download.redis.io/releases/redis-5.0.2.tar.gz

tar xzf redis-5.0.2.tar.gz

cd redis-5.0.2

3、进入到解压好的redis-5.0.2目录下,进行编译与安装

make & make install

4、启动并指定配置文件

src/redis-server redis.conf

(注意要使用后台启动,所以修改redis.conf里的daemonize改为yes)

5、验证启动是否成功

ps -ef | grep redis 

6、进入redis客户端

cd /usr/local/redis/redis-5.0.2/src
./redis-cli 

7、退出客户端

exit

8、退出redis服务:

pkill redis-server

kill 进程号

src/redis-cli shutdown

二、开始集群搭建

    redis集群需要至少要三个master节点,我们这里搭建三个master节点,并且给每个master再搭建一个slave节点,总共6个redis节点,这里用一台机器(可以多台机器部署,修改一下ip地址就可以了)部署6个redis实例,三主三从,搭建集群的步骤如下:

第一步:在第一台机器的/usr/local下创建文件夹redis-cluster,然后在其下面创建6个文件夾如下:

mkdir -p /usr/local/redis-cluster

mkdir 8001 8002 8003 8004 8005 8006

第二步:把之前的redis.conf配置文件copy到8001下,修改如下内容:

daemonize yes

port 8001(分别对每个机器的端口号进行设置)

dir /usr/local/redis-cluster/8001/(指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)

cluster-enabled yes(启动集群模式)

cluster-config-file nodes-8001.conf(集群节点信息文件,这里800x最好和port对应上)

cluster-node-timeout 5000

bind 127.0.0.1(去掉bind绑定访问ip信息)

protected-mode no (关闭保护模式)

appendonly yes

如果要设置密码需要增加如下配置:

requirepass xxx (设置redis访问密码)

masterauth xxx (设置集群节点间访问密码,跟上面一致)

 

第三步:把修改后的配置文件,copy到8002-8006,修改第2、3、5项里的端口号,可以用批量替换:

%s/源字符串/目的字符串/g 

第四步:分别启动6个redis实例,然后检查是否启动成功

/usr/local/redis/redis-5.0.2/src/redis-server /usr/local/redis-cluster/800*/redis.conf

查看是否启动成功

ps -ef | grep redis 

第五步:用redis-cli创建整个redis集群(redis5以前的版本集群是依靠ruby脚本redis-trib.rb实现)

/usr/local/redis/redis-5.0.2/src/redis-cli -a xxx --cluster create --cluster-replicas 1 192.168.5.100:8001 192.168.5.100:8002 192.168.5.100:8003 192.168.5.100:8004 192.168.5.100:8005 192.168.5.100:8006
 

Redis 5 之后版本的高可用集群搭建_第5张图片

 

Redis 5 之后版本的高可用集群搭建_第6张图片

代表为每个创建的主服务器节点创建一个从服务器节点

第七步:验证集群:

1)连接任意一个客户端即可:

./redis-cli -c -a xxx -h 192.168.5.100 -p 8001

提示:-a访问服务端密码,-c表示集群模式,指定ip地址和端口号

例如:

/usr/local/redis-5.0.2/src/redis-cli -a xxx -c -h 192.168.5.100 -p 8001

Redis 5 之后版本的高可用集群搭建_第7张图片

注意这里进入到8002了,redirected。

2)进行验证: cluster info(查看集群信息)、cluster nodes(查看节点列表)

Redis 5 之后版本的高可用集群搭建_第8张图片

 

 

3)进行数据操作验证

4)关闭集群则需要逐个进行关闭,使用命令:

/usr/local/redis/src/redis-cli -a xxx -c -h 192.168.0.60 -p 8001 shutdown

Redis 5 之后版本的高可用集群搭建_第9张图片

 

Redis 5 之后版本的高可用集群搭建_第10张图片

 

其它命令:


创建集群
./redis-cli --cluster create 10.105.179.236:9001 10.105.179.236:9002 10.106.157.104:9001 10.106.157.104:9002 10.106.146.95:9001 10.106.146.95:9002 --cluster-replicas 1

追加节点
src/redis-cli --cluster add-node 10.99.32.32:6379 10.99.32.3:6379

查看节点
src/redis-cli -h 10.99.32.9 -c cluster nodes

删除节点, 需要先获取节点node-id
src/redis-cli --cluster del-node 10.99.32.9:6379 08859612fdf824fd07c538c65073a86ca7d522cb

登录本机9001节点
./redis-cli -p 9001
cluster nodes

查看master
./redis-cli -p 9001 cluster nodes | grep master
./redis-cli -p 9001 cluster nodes | grep slave

查看所有keys
./redis-cli -p 9001 keys "*"


./redis-cli -p 9001 keys "*" |xargs ./redis-cli del

./redis-cli -p 9001 keys "*lz*"|xargs ./redis-cli del

检查集群状态
./redis-cli --cluster check 127.0.0.1:9001
./redis-cli -c -p 9001 cluster nodes

连接到10.106.157.104:9001节点
./redis-cli -c -h 10.106.157.104 -p 9001 

连接到10.106.157.104:9001节点  执行cluster nodes
./redis-cli -c -h 10.106.157.104 -p 9001 cluster nodes

发现节点
cluster meet 10.105.179.236 9002


链接:

https://www.cnblogs.com/kismetv/p/9853040.html

https://blog.csdn.net/Aquester/article/details/83419512

https://blog.csdn.net/h2604396739/article/details/89261094

https://www.jianshu.com/p/8045b92fafb2

https://www.infvie.com/ops-notes/redis5-cluster

https://blog.csdn.net/weixin_37882382/article/details/83538367

https://blog.51cto.com/andyxu/2319767

你可能感兴趣的:(Redis/Codis)