Redis集群配置

本文是在本地环境学习配置Redis集群的流程文。使用Redis版本为5.0.8,基于VMware中的centOS7系统。

安装

选择自己喜欢需要的版本,根据Redis官方文档引导执行安装编译。

1
2
3
4
5
6
7
cd ~
mkdir redis-cluster
cd redis-cluster # 该文件我用来存放redis源码
wget http://download.redis.io/releases/redis-5.0.8.tar.gz
tar xzf redis-5.0.8.tar.gz
cd redis-5.0.8
make

执行完成。为了方便操作,我将在src目录下生成的可执行文件拷贝到/usr/local/redis目录下。执行命令如下

1
2
3
4
5
6
7
8
9
cd /usr/local
sudo mkdir redis
sudo chown -R xugz:xugz redis
cd redis
mkdir bin conf
cd bin
cp ~/redis-cluster/redis-5.0.8/src/redis-* .
cd ../conf # 进入conf文件夹,将源码中的redis配置文件拷贝过来,重命名为6380.conf(我虚拟机上6379端口已被占用)
cp ~/redis-cluster/redis-5.0.8/redis.conf 6380.conf

配置最简单的主从

为了方便我在同一台机器上启动两个实例实现。

启动master

修改配置文件必要选项,如将port修改为未被占用的端口如6380。将 daemonize改为 yes,后台程序方式运行。修改pidfile,让其生成到有权限的目录下pidfile /usr/local/redis/redis_6380.pid
指定6380.conf为其配置文件,启动实例 /usr/local/redis/bin/redis-server /usr/local/redis/conf/6380.conf

启动slave

复制一份redis配置文件命名为6381.conf,修改对应的端口和pidfile配置。加入 slaveof 127.0.0.1 6380,意思是将自己作为127.0.0.1主机6380端口的备服。
启动实例 /usr/local/redis/bin/redis-server /usr/local/redis/conf/6381.conf

使用ps -ef | grep redis检查两个进程是否正常存在。
使用./redis-cli -h 127.0.0.1 -p 6380命令指定端口和服务器进入客户端,使用info命令查看Replication选项确定是否配置成功,使用role也可。

1
2
3
4
# Replication
role:master # 角色,master代表是主机
connected_slaves:1 # 连接的从机的数量 我们这里只配置了6381一个
slave0:ip=127.0.0.1,port=6381,state=online,offset=280,lag=0

下图为验证主备功能的。图片显示6380主服务器可读可写,6381备服只有读取权限。

使用哨兵模式实现主从切换

参考Redis中文文档中对哨兵的描述

Redis的Sentinel系统用于管理多个Redis服务器(instance),该系统执行以下三个任务:

  1. 监控(Monitoring):Sentinel会不断地检查你的主服务器和从服务器是否运作正常。
  2. 提醒(Notification):当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。
  3. 自动故障迁移(Automatic failover):当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器, 让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器。

配置

Redis 源码中包含了一个名为 sentinel.conf 的文件, 这个文件是一个带有详细注释的 Sentinel 配置文件示例。
运行一个 Sentinel 所需的配置如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 端口
port 6380
// 工作目录
dir /usr/local/redis/tmp
// 指定的要检测的实例。参数分别是 别名 ip 端口 server异常时需要确认异常的哨兵个数。1表示至少1个setinel实例同时检测到redis server异常时才将redis server的状态判决为"宕机"
sentinel monitor mymaster 127.0.0.1 6380 1
// 指定某个sentinel实例监控到某个redis实例持续异常多长时间后,会判决其状态为down。单位毫秒
sentinel down-after-milliseconds mymaster 60000
// 若sentinel在该配置值内未能完成failover操作(即故障时master/slave自动切换),则认为本次failover失败
sentinel failover-timeout mymaster 180000
// 指定failover过程中,同时被sentinel reconfigure的最大slave实例数。由于reconfigure过程中,对应的slave会中断响应客户端请求,故为避免所有的slave同时不可用,该值需适当配小。
sentinel parallel-syncs mymaster 1
// know-salve 代表已知的从机
sentinel known-slave mymaster 127.0.0.1 6381
// 同时一时间最多3个slave可同时更新配置
sentinel leader-epoch mymaster 3

将Redis源码中的 sentinel.conf 的文件拷贝到/usr/local/redis/conf目录下,修改自身需要的配置选项。

启动

对于 redis-sentinel 程序,可以用./redis-sentinel /path/to/sentinel.conf命令来启动 Sentinel 系统。或者使用nohup /usr/local/redis/bin/redis-sentinel /usr/local/redis/conf/sentinel.conf &不挂断地运行命令。
对于 redis-server 程序,可以用./redis-server /path/to/sentinel.conf --sentinel命令来启动一个运行在 Sentinel 模式下的 Redis 服务器。
启动完成后我进行了数据验证,下图是验证用到的相关命令(注意redis服务的切换)

通过上图的验证我们发现:本来主机是6380可以读写,从服务器是6381只可读。手动杀掉主服务器的运行进程,等待最大持续异常时间(down-after-milliseconds)后,哨兵会将主服务器自动切换成6381,将6380作为6381的备服。即使我们后续将6380再次启动,6380仍是6381的备服,数据只读。这在哨兵的服务进程中也有体现,见下图

主从从配置

如果让所有的slave节点数据的复制和同步都由master节点来处理,会造成master节点I/O压力过大。所以我们打算将6380作为主服务器,用于写入操作,6381和6382作为备服负责读操作。为了减轻master压力,让6382数据备份来源改成6381,实现主从从模式。

配置修改

redis.conf

确认以下参数:port、pidfile、daemonize、dbfilename和dir。
将slaveof选项添加到备服。将6382数据备份来源改成6381,6381的数据备份来源还是6380。6382的部分配置如下

1
2
3
4
5
6
7
bind 127.0.0.1
port 6382
daemonize yes
pidfile "/usr/local/redis/redis_6382.pid"
slaveof 127.0.0.1 6381
dbfilename "dump6382.rdb"
dir "/usr/local/redis/datadir/"

Sentinel.conf

哨兵启动后其实自动修改配置文件,一般建议不要手工修改。
如果之前配的是一主多从,配置中会存在sentinel known-slave选项。如果我们要配置主从从,要把多余的从在配置文件手工删掉。

便捷操作

为了操作方便,将多台服务启动命令整合到可执行脚本。

server_start

该脚本是为了方便启动redis server。在~/redis-cluster目录下新增文件server_start,同时启动三台redis实例和哨兵后台运行。脚本内容如下

1
2
3
4
/usr/local/redis/bin/redis-server /usr/local/redis/conf/6380.conf
/usr/local/redis/bin/redis-server /usr/local/redis/conf/6381.conf
/usr/local/redis/bin/redis-server /usr/local/redis/conf/6382.conf
nohup /usr/local/redis/bin/redis-sentinel /usr/local/redis/conf/sentinel.conf &

cli_start

该脚本是为了方便启动redis server。在~/redis-cluster目录下新增文件cli_start,可支持传入端口参数。脚本内容如下

1
2
3
4
5
6
7
#!/bin/bash
if [ -n "$1" ] #-n 传入参数不为空 $1代表第二参数,$0是可执行文件名自己本身
then
/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p $1
else
echo "error,no port"
fi

将redis server启动后,使用./cli-start port命令进入客户端,各自键入info命令尝试插入获取数据验证发现:6380为master,可读可写。其有一个从服为6381,6381角色为slave,他也有一个从服为6382。6381和6382都只可读。

cluster集群

参考Redis中文文档中对集群的描述

配置

搭建集群的第一件事情我们需要一些运行在 集群模式的Redis实例. 这意味这集群并不是由一些普通的Redis实例组成的,集群模式需要通过配置启用,开启集群模式后的Redis实例便可以使用集群特有的命令和特性了.

下面是一个最少选项的集群的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
port 7000
pidfile "/usr/local/redis/redis_7000.pid"
# 表示打开集群
cluster-enabled yes
cluster-node-timeout 5000
# 开启AOF存储模式
appendonly yes
#集群模式下,每个redis节点生成一个配置文件,由redis自己维护。文件名区分开即可 下面两个文件名如果不像我一样放在同目录的话,可以不修改
cluster-config-file nodes_7000.conf
appendfilename "appendonly_7000.aof"
# 注释掉dbfilename 关闭RDB改用AOF
# dbfilename

# 关掉RDB存储
save ""
#save 900 1
#save 300 10
#save 60 1000

要让集群正常运作至少需要三个主节点,不过在刚开始试用集群功能时, 官方强烈建议使用六个节点: 其中三个为主节点, 而其余三个则是各个主节点的从节点。所以我们创建进入一个新目录cluster_conf,并创建六个以端口号为名字的Redis.conf文件,文件的内容可以使用上面的示例配置文件,稍后我们将运行六个Redis实例。

安装Ruby

低版本的redis需要安装ruby环境,现在高版本的redis-cli已经支持集群了,不再需要安装ruby了。

切换到root账号,执行默认安装。

1
2
3
su - root 
yum -y install ruby ruby-devel rubygems rpm-build
gem install redis

或者编译安装。官方下载地址
wget https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.7.1.tar.gz --no-check-certificate

搭建集群

首先启动六个实例,我们可以使用/usr/local/redis/bin/redis-server /usr/local/redis/cluster_conf/7000.conf命令一条条启动,也可以封装到可执行脚本中。
启动完成 ps -ef | grep redis 查看如下

现在我们已经有了六个正在运行中的 Redis 实例, 接下来我们需要使用这些实例来创建集群, 并为每个节点编写配置文件。
通过使用 Redis 集群命令行工具 redis-trib ,编写节点配置文件的工作可以非常容易地完成:redis-trib 位于 Redis 源码的 src 文件夹中,它是一个 Ruby 程序,这个程序通过向实例发送特殊命令来完成创建新集群,检查集群,或者对集群进行重新分片(reshared)等工作。

创建一个新的集群, 选项–replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。下面命令默认创建7000 7001 7002 为主节点,7003 7004 7005为备节点。
低版本使用:./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
Redis5.0后不再支持上条命令,需要使用redis-cli来实现。如下
./redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
之后跟着的其他参数则是这个集群实例的地址列表,3个master3个slave redis-trib 会打印出一份预想中的配置给你看,如果你觉得没问题的话,就可以输入yes,redis-trib 就会将这份配置应用到集群当中,让各个节点开始互相通讯,最后可以得到如下信息:

[OK] All nodes agree about slots configuration.
[OK] All 16384 slots covered.

这表示集群中的 16384 个槽都有至少一个主节点在处理, 集群运作正常。此时,我们可以使用redis-cli -c -p 7000命令连接到7000端口的客户端,也可以通过脚本进入。相关验证如下图

官方提供了一个自动化脚本,在 redis源码目录的utils文件夹,下面有个create-cluster文件夹,下面有个create-cluster脚本。也可以根据里面的代码进行脚本执行搭建。

常见错误

ERR Slot xxxxx is already busy (Redis::CommandError)

如果上一次运行出错,则必须去datadir对应目录去手工删除自动生成的cluster配置文件。

本文标题:Redis集群配置

文章作者:xugz

发布时间:2020年05月16日 - 14:17

最后更新:2021年09月11日 - 16:21

原始链接:https://xlline.github.io/2020/05/16/Redis-config/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。