Redis高可用策略与集群方案(主从复制、哨兵、Cluster集群)-实践篇

引言:本篇文章以笔者亲身实践过程来总结和记录Redis的主从复制、哨兵故障转移、集群等内容,避免单纯的理论性知识分享,以具体操作实践来引导来学习的朋友们,希望为大家提供有力的支持与帮助。

文章目录:

Redis环境搭建

Redis主从复制

Redis哨兵模式

Redis集群模式

 

Redis环境搭建

Redis作为NoSQL体系中的最具有代表性的数据库之一,是一款高性能的key-value数据库,概况的讲具有以下特点:

  • 支持数据持久化,可将内存数据保存到硬盘,重启后将从硬盘中再次加载到内容
  • 支持数据类型String、List、Set、Zset、Hash、HyperLogLog 。
  • 支持数据备份、(Master-Slave)主从复制、(Cluster)集群模式
  • 读取速度高达8万-10万次每秒。
  • 支持publish/subscribe,key过期等特性、支持事务。

1.1 下载Redis

官网地址:https://redis.io/

中文官网地址:http://www.redis.cn

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

1.2  安装Redis

下载版本redis-4.0.11.tar.gz,此版本是需要先编译、再安装。

解压:tar -zxvf redis-4.0.11.tar.gz

切换目录:cd redis-4.0.11

编译安装:make install PREFIX=/usr/local/redis (记住可不能写成小写prefix)

完整的步骤命令:

[root@hadoop01 modules]# tar -zxvf redis-4.0.11.tar.gz
[root@hadoop01 modules]# cd redis-4.0.11
[root@hadoop01 modules]# make install PREFIX=/usr/local/redis

安装成功后在/usr/local/目录下有redis:

进入redis目录中,会看到redis的一些操作命令工具:

Redis操作命令工具

redis-server

启动redis服务

redis-cli

进入redis命令客户端

redis-benchmark

性能测试的工具

redis-check-aof

aof文件进行检查的工具

redis-check-dump

rdb文件进行检查的工具

redis-sentinel

启动哨兵监控服务

 

1.3 启动Redis

启动命令:./redis-server redis.conf

[root@hadoop01 bin]# ./redis-server redis.conf

启动成功后控制台信息:

 

2   Redis主从复制

Redis的持久化保证了Redis重启也不会丢失数据,因为Redis在存储时会将内存中的数据存储到硬盘上,当重启后会再次将硬盘上的数据加载到内存中;但是如果硬盘有损坏的话,可能会照成数据丢失,那么通过Redis的主从复制可以避免这种单点故障。如图:

 

Redis主从模式

说明:Master中的数据有两个副本Slave1Slave2,其中任何一台Redis宕机,其他两台任然能继续提供服务。MasterSlave的数据实时保持同步,当Master写入数据后会复制到Slave1Slave2

2.1   配置主从

这里我们采用一主两从的模式,配备3台机器,分别安装好Redis,具体分配入下表:

服务类型

服务器角色

IP

端口

Redis

Master

192.168.100.129

6379

Redis

Slave1

192.168.100.130

6379

Redis

Slave2

192.168.100.131

6379

Master配置文件redis.conf:

redis服务器可以跨网络访问,将默认的127.0.0.1修改为0.0.0.0

bind 0.0.0.0

设定Redis密码

# requirepass foobared
  requirepass redis123

Slave配置文件redis.conf:(两台Slave设置相同)

redis服务器可以跨网络访问,将默认的127.0.0.1修改为0.0.0.0

bind 0.0.0.0

设定Redis密码

# requirepass foobared
  requirepass redis123

设置Slave登录 Master的密码,此处为Master的密码

# masterauth <master-password>
  masterauth redis123

设置所属的主机的IP和端口

# slaveof <masterip> <masterport>
  slaveof 192.168.100.129 6379

2.2    启动主从模式

 启动Master:

启动slave1:

从控制台信息中可以看到,Slave1成功连接Maser-192.168.100.129,并接收到Master的同步数据。

启动slave2:

同样,Slave2也成功连接Maser-192.168.100.129,并接收到Master的同步数据。

查看Master:

再回头看一下Master,当两台Slave都启动之后,控制台信息告诉我们Slave1-192.168.100.130、Slave2-192.168.100.131均同步成功。

2.3    验证主从复制同步

Master中写入k1

[root@hadoop01 ~]# cd /usr/local/redis/bin/
[root@hadoop01 bin]# ./redis-cli 
127.0.0.1:6379> AUTH redis123
OK
127.0.0.1:6379> set k1 vv1
OK
127.0.0.1:6379> get k1
"vv1"
127.0.0.1:6379>

Slave1中读取k1

[root@hadoop02 ~]# cd /usr/local/redis/bin/
[root@hadoop02 bin]# ./redis-cli 
127.0.0.1:6379> AUTH redis123
OK
127.0.0.1:6379> set k1 vv1
OK
127.0.0.1:6379> get k1
"vv1"
127.0.0.1:6379>

Slave2中读取k1

[root@hadoop03 ~]# cd /usr/local/redis/bin/
[root@hadoop03 bin]# ./redis-cli 
127.0.0.1:6379> AUTH redis123
OK
127.0.0.1:6379> set k1 vv1
OK
127.0.0.1:6379> get k1
"vv1"
127.0.0.1:6379>

2.4    优缺点

优点:主从结构模式实现了读写分离,较单机又读又写来说,提高读写操作的性能。

缺点:当其中的任何一台Master或Slave宕机,无法实现自动处理故障。利用Redis-Sentinel哨兵模式可以完美的进行自动故障转移。

 3   Redis哨兵模式

3.1   Redis Sentinel介绍

Redis Sentinel是Redis HA 的实现方案,Sentinel是一个可以对Redis进行监控、通知、故障转移的工具。

3.2   哨兵模式配置

本例中架构模式设置了三台虚拟机,分别为一台作为Redis主节点,另外两台作为Redis从节点;其中开启三个Redis Sentinel来监控各节点的状态,在其中的主节点宕机后,会自动的故障转移,从另外两台从节点中选出一个作为主节点,替代旧的主节点的工作。具体机器的分配如下表:

服务类型

服务器角色

IP

端口

Redis

Master

192.168.100.129

6379

Redis

Slave1

192.168.100.130

6379

Redis

Slave2

192.168.100.131

6379

Sentinel

-

192.168.100.129

26379

Sentinel

-

192.168.100.130

26379

Sentinel

-

192.168.100.131

26379

Master主节点配置文件redis.conf:

bind 0.0.0.0 //可以跨网络访问
protected-mode no  //默认为yes,只允许127.0.0.1访问
requirepass redis123 //Redis的密码
masterauth redis123  //主节点的密码,此处可以不设置;设置的好处是当Master宕机后,Sentinel会自动完成故障转移,再次启动旧的Msater后,它会以Slave的身份自动连接新的Master。

Slave从节点配置文件redis.conf:

bind 0.0.0.0 
protected-mode no   
requirepass redis123
masterauth redis123
slaveof 192.168.100.129 6379 //设置所属的Master的IP和端口

哨兵配置文件sentinel.conf,三个哨兵节点相同:

protected-mode no   //保护模式
sentinel monitor mymaster 192.168.100.129 6379 2
sentinel auth-pass mymaster redis123 //master的密码
sentinel down-after-milliseconds mymaster 10000 //节点认为主观下线的有效时间
sentinel failover-timeout mymaster 60000 //故障转移超时时间*毫秒
sentinel parallel-syncs mymaster 1 //设定同步新主机的节点数

特别注意:一定要将配置文件中redis.conf和sentinel.conf的protected-mode设置为no,否则哨兵无法正常的完成故障转移切换新的主节点

哨兵模式下的一些配置说明:

配置项

参数

作用

Port

整数

哨兵进程端口

Dir

文件目录

哨兵进程服务文件夹,默认为/tmp,要保证有写权限

sentinel down-after-milliseconds <master-name> <milliseconds>

<服务名称><毫秒数(整数)>

指定哨兵在监测Redis服务时,当Redis服务在一个亳秒数内都无法回答时,单个哨兵认为的主观下线时间,默认为 30000(30秒)

sentinel parallel-syncs <master-name> <numslaves>

<服务名称><服务器数(整数)>

指定可以有多少 Redis 服务同步新的主机,一般而言,这个数字越 小同步时间就越长,而越大,则对网络资源要求则越高

sentinel failover-timeout <master-name> <milliseconds>

<服务名称><亳秒数(整数)>

指定在故障切换允许的亳秒数,当超过这个亳秒数的时候,就认为 切换故障失败,默认为 3 分钟

sentinel notification-script <master-name> <script-path>

<服务名称><脚本路径>

指定 sentinel 检测到该监控的 redis 实例指向的实例异常时,调用的 报警脚本。该配置项可选,比较常用

3.3   启动哨兵监控

按先Master后Slave顺序启动各节点:

./redis-server redis.conf

启动3个哨兵监控:

./redis-sentinel sentinel.conf

解释一下这些信息的意思:

Sentinel ID is 4318def4c053269e7750e9452147e04b80dc7f77
//哨兵的ID标识

+monitor master mymaster 192.168.100.129 6379 quorum 2
//增加了对Master -192.168.100.129的监控, 主观下线的判定数量为2或大于2。

+slave slave 192.168.100.130:6379 192.168.100.130 6379 @ mymaster 192.168.100.129 6379
//增加了对slave的监控,后面为该slave-192.168.100.130的信息

+slave slave 192.168.100.131:6379 192.168.100.131 6379 @ mymaster 192.168.100.129 6379
//增加了对slave的监控,后面为该slave-192.168.100.131的信息

+sentinel sentinel 45ccdd2b184adcc047762cf455ebeb3e711b0825 192.168.100.130 26379 @ mymaster 192.168.100.129 6379
//增加了哨兵节点192.168.100.130,标识ID,信息显示其对主节点192.168.100.129的监控。

+sentinel sentinel 217fd238092167299274673707c6bcec2283ca17 192.168.100.131 26379 @ mymaster 192.168.100.129 6379
//增加了哨兵节点192.168.100.131,标识ID,信息显示其对主节点192.168.100.129的监控。

3.4   验证哨兵的故障转移能力

为了验证哨兵模式下自动故障转移的能力,先将Master节点断掉,模拟宕机。然后查看一下Slave1-192.168.100.130节点的情况:出现连接Master失败,随后以Master的身份与Slave2-192.168.100.131同步成功。

以上说明哨兵自动完成故障转移,将Slave1-192.168.100.130的节点选举为新的Master节点,这是刚刚当选主节点Master-192.168.100.130的信息,经过这样一个故障迁移的过程:

旧Master主观下线—>投票->旧Master客观下线—>新Master产生—>通知所有节点

查看下Slave1-192.168.100.130的信息,发现当前节点的角色已经变成Master。

 

接下来重启一下刚刚宕机的那台旧的Master节点,发现它成功同步连接到新的Master-192.168.100.130,此时它是作为一个Slave的节点存在。

可以查看一下节点192.168.100.129的信息,发现它已经变成一个Slave的角色了。

 

3.5    优缺点

优点:读写分离,解决单点故障,自动完成故障转移。

缺点: 在读写高并发状况下,主节点单点写入,无法实现单点扩容,虽然只解决高可用的问题,不能完美的体现高可用的性能。解决这一问题,就要引入Redis Cluster集群来解决。

4  Redis-Cluster集群

Redis的集群需要通过集群管理脚本redis-trib.rb来运行,而Redis5之前的版本需要依赖Ruby环境,我们当前版本是Redis4,所以需要安装Ruby。

4.1   安装Ruby

yum install ruby  //安装ruby,为了可以运行redis-trib.rb
yum install rubygems  //安装gem工具包
gem install redis  //安装ruby与redis的接口程序

gem是管理Ruby库和程序的标准包,通过rubygems(https://rubygems.org/)源来查找、安装、升级、卸载软件包,非常方便。

4.2   安装Redis Cluster集群

Redis Cluster最少需要3个节点,1个Master,2个Slave。例用两台虚拟机模式6个节点:一台机器3个节点,创建出3个Master、3个Slave。所有节点在开始并不指定具体的Master-Slave关系,而是在创建完成集群后会指定哪些节点是Master,哪些节点是Slave。

服务类型

IP

端口

Redis-Node

192.168.100.129

7000

Redis-Node

192.168.100.129

7001

Redis-Node

192.168.100.129

7002

Redis-Node

192.168.100.130

7001

Redis-Node

192.168.100.130

7002

Redis-Node

192.168.100.130

7003

4.3   创建Redis节点

1、在IP为192.168.100.129的机器上/opt/modules/redis-4.0.11目录下创建redis-cluster目录:

 [root@hadoop01 redis-4.0.11]# mkdir redis-cluster

在redis-cluster目录下创建名为7000、7001、7002的目录

[root@hadoop01 redis-4.0.11]# cd redis-cluster/
[root@hadoop01 redis-cluster]# mkdir 7000 7001 7002

2、将redis.conf拷贝到三个目录中。

[root@hadoop01 redis-cluster]# cp ../redis.conf ./7000/
[root@hadoop01 redis-cluster]# cp ../redis.conf ./7001/
[root@hadoop01 redis-cluster]# cp ../redis.conf ./7002/

指定数据文件存放目录:

[root@hadoop01 opt]# mkdir redis-data/

3、修改节点配置文件redis.conf:

目录文件:/opt/modules/redis-4.0.11/redis-cluster/7000/redis.conf

port 7000   //端口 700070017002
bind 0.0.0.0  //默认127.0.0.1,设置可以跨网络访问
daemonize yes  //后台运行
pidfile /var/run/redis_7000.pid  
cluster-enabled yes  //开启集群模式
cluster-config-file  /opt/modules/redis-4.0.11/redis-cluster/7000/nodes-7000.conf  //集群配置,配置文件首次启动自动生成
cluster-node-timeout 15000 //请求超时时间*毫秒,默认15秒
appendonly yes  //aof日志
dir /opt/redis-data/  数据文件的目录

同样配置:

vim /opt/modules/redis-4.0.11/redis-cluster/7001/redis.conf
vim /opt/modules/redis-4.0.11/redis-cluster/7002/redis.conf

在另一台机器192.168.100.130上重复以上的3个步骤,以完成节点7000、7001、7002的配置。

4.4  启动集群节点

在机器192.168.100.129上执行:

[root@hadoop01 src]# redis-server ../redis-cluster/7000/redis.conf
[root@hadoop01 src]# redis-server ../redis-cluster/7001/redis.conf
[root@hadoop01 src]# redis-server ../redis-cluster/7002/redis.conf

在另一台机器192.168.100.130上执行:

[root@hadoop02 src]# ./redis-server ../redis-cluster/7000/redis.conf
[root@hadoop02 src]# ./redis-server ../redis-cluster/7001/redis.conf
[root@hadoop02 src]# ./redis-server ../redis-cluster/7002/redis.conf

4.5   检查节点运行状态

检查机器192.168.100.129 Redis节点运行:

[root@hadoop01 src]# ps -ef |grep redis
root       5054      1  0 00:51 ?        00:00:00 redis-server 0.0.0.0:7000 [cluster]          
root       5059      1  0 00:51 ?        00:00:00 redis-server 0.0.0.0:7001 [cluster]          
root       5081      1  0 00:57 ?        00:00:00 redis-server 0.0.0.0:7002 [cluster]          
root       5088   5031  0 00:57 pts/1    00:00:00 grep redis

查看端口监听状态:

[root@hadoop01 src]# netstat -tlnp |grep redis
tcp        0      0 0.0.0.0:17000               0.0.0.0:*                   LISTEN      5054/redis-server 0 
tcp        0      0 0.0.0.0:17001               0.0.0.0:*                   LISTEN      5059/redis-server 0 
tcp        0      0 0.0.0.0:17002               0.0.0.0:*                   LISTEN      5081/redis-server 0 
tcp        0      0 0.0.0.0:7000                0.0.0.0:*                   LISTEN      5054/redis-server 0 
tcp        0      0 0.0.0.0:7001                0.0.0.0:*                   LISTEN      5059/redis-server 0 
tcp        0      0 0.0.0.0:7002                0.0.0.0:*                   LISTEN      5081/redis-server 0 

检查另一台机器192.168.100.130 Redis各节点运行状态:

4.6   创建集群

 执行命令:

./redis-trib.rb  create --replicas 1 192.168.100.129:7000 192.168.100.129:7001 192.168.100.129:7002 192.168.100.130:7000 192.168.100.130:7001 192.168.100.130:7002

[root@hadoop01 src]# ./redis-trib.rb  create --replicas 1 192.168.100.129:7000 192.168.100.129:7001 192.168.100.129:7002 192.168.100.130:7000 192.168.100.130:7001 192.168.100.130:7002
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.100.129:7000
192.168.100.130:7000
192.168.100.129:7001
Adding replica 192.168.100.130:7002 to 192.168.100.129:7000
Adding replica 192.168.100.129:7002 to 192.168.100.130:7000
Adding replica 192.168.100.130:7001 to 192.168.100.129:7001
M: c16510616904828d6fe93c36b37c54b6b7457423 192.168.100.129:7000
   slots:0-5460 (5461 slots) master
M: 6d9ee8662293b622f696952fb4e75ea8d06650f1 192.168.100.129:7001
   slots:10923-16383 (5461 slots) master
S: 1bab0e61aff928a0265201c64fd4c9193761c081 192.168.100.129:7002
   replicates adcb60cc28d035928636473ed9c2c873c5ec8dad
M: adcb60cc28d035928636473ed9c2c873c5ec8dad 192.168.100.130:7000
   slots:5461-10922 (5462 slots) master
S: db757a83be0fe89e5082a3cfcb145c41c8f5e429 192.168.100.130:7001
   replicates 6d9ee8662293b622f696952fb4e75ea8d06650f1
S: ce1c2b9521c8d3a3dd18cd6ae585dbfec5d6448b 192.168.100.130:7002
   replicates c16510616904828d6fe93c36b37c54b6b7457423
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 192.168.100.129:7000)
M: c16510616904828d6fe93c36b37c54b6b7457423 192.168.100.129:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 1bab0e61aff928a0265201c64fd4c9193761c081 192.168.100.129:7002
   slots: (0 slots) slave
   replicates adcb60cc28d035928636473ed9c2c873c5ec8dad
M: 6d9ee8662293b622f696952fb4e75ea8d06650f1 192.168.100.129:7001
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
M: adcb60cc28d035928636473ed9c2c873c5ec8dad 192.168.100.130:7000
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: ce1c2b9521c8d3a3dd18cd6ae585dbfec5d6448b 192.168.100.130:7002
   slots: (0 slots) slave
   replicates c16510616904828d6fe93c36b37c54b6b7457423
S: db757a83be0fe89e5082a3cfcb145c41c8f5e429 192.168.100.130:7001
   slots: (0 slots) slave
   replicates 6d9ee8662293b622f696952fb4e75ea8d06650f1
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

出现下面的说明集群创建成功。

参考https://blog.csdn.net/qq_39244264/article/details/80277484

4.7   验证集群

使用客户端连接到redis集群,命令: ./redis-cli -h host -p port –c

这里我们连接192.168.100.129:7000这个节点,-c表示连接redis集群。

./redis-cli -h 192.168.100.129 -p 7000 –c

然后创建k1=v1数据写入位于192.168.100.129:7000节的槽12706位置。

创建k2=v2, 数据写入位于192.168.100.129:7000节的槽449位置。

创建k3=v3, 数据写入到本节点。

[root@hadoop03 src]# ./redis-cli -h 192.168.100.129 -p 7000 -c
192.168.100.129:7000> set k1 v1
-> Redirected to slot [12706] located at 192.168.100.129:7001
OK
192.168.100.129:7001> set k2 v2
-> Redirected to slot [449] located at 192.168.100.129:7000
OK
192.168.100.129:7000> get k1
-> Redirected to slot [12706] located at 192.168.100.129:7001
"v1"
192.168.100.129:7001> get k2
-> Redirected to slot [449] located at 192.168.100.129:7000
"v2"
192.168.100.129:7000> set k3 v3
OK
192.168.100.129:7000> get k3
"v3"

4.8   Redis集群常用命令

//集群(cluster)

CLUSTER INFO 打印集群的信息

CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。

//节点(node)

CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的节点。

CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。

CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。

CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。

//槽(slot)

CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。

CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。

CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。

CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。

CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。

CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。

CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。

//键 (key)

CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。

CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。

CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。

4.9   Redis集群原理

Redis Cluster在设计中的每个节点都是平等的,每个节点都保存各自的数据和整个集群的状态。每个节点和其他节点都保持连接,这就保证了我们只需要连接集群中的任何一个节点,就可以获取到其他任何节点上存放的数据了。

Redis Cluster没有使用传统的哈希来存储数据,而是采用一种叫做哈希槽(hash slot)的存储方式来分配的,共分配了16348个哈希槽。当 set一个key时,会用CRC16算法取模得到所属的slot,然后将这个key分配到哈希槽区间的节点上,算法为:CRC16(key)% 16348。所以刚刚在例子中set 和get  k1、k2的时候,跳转到了192.168.100.129:7001节点上。

Redis Cluster会把数据存在一个Master节点,然后这个Master节点和其他的Slave节点进行数据同步。当Master宕机后,会选举一个Slave替代Master。

参考:

https://blog.csdn.net/qq_39244264/article/details/80277484

https://www.cnblogs.com/wuxl360/p/5920330.html

 

感谢技术圈的朋友们常来常往,希望我的每一个分享能帮助到大家,如果帮助到了您,请给我留下点点的评论或关注,我也想和您成为朋友,感谢大家一起交流一起进步
原文地址:https://www.cnblogs.com/fengguozhong/p/12192690.html