自建redis笔记

最近在linux安装了一下redis,特做一些笔记!

本文先单节点启动redis,然后再进行持久化配置,在次基础上,再分享搭建主从模式的配置以及Sentinel 哨兵模式及集群的搭建

单节点redis

请先确保linux操作系统安装了gcc

安装gcc、gcc-c++

yum -y install gcc+ gcc-c++

检查gcc环境是否安装好

rpm -qa|grep gcc

若安装好,执行rpm -qa|grep gcc后:

libgcc-4.8.5-39.el7.x86_64
gcc-4.8.5-39.el7.x86_64

下载安装redis

请在官网https://redis.io下载对应的redis,本例使用的是redis-5.0.5

在对应的下载目录解压redis,并进入文件夹

tar -zxvf redis-5.0.5.tar.gz

cd redis-5.0.5

编译安装

make && make install(make命令或者make install命令)

自此,redis已经安装成功

启动redis

./src/redis-server redis.conf

启动成功后可看到类似日志

10371:C 09 Oct 2019 16:39:17.783 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
10371:C 09 Oct 2019 16:39:17.783 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=10371, just started
10371:C 09 Oct 2019 16:39:17.783 # Configuration loaded ```

守护线程确定redis

修改redis.conf,将daemonize no 修改为 daemonize yes,重新启动即可!

查看redis服务

ps -ef |grep redis

启动客户端连接

./src/redis-cli

输入info,查看当前redis信息

自此,redis成功安装!

./src/redis-cli 也可进行命令号操作了!

持久化redis

Redis提供了将数据定期自动持久化至硬盘的能力,包括RDB和AOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性。

必须使用数据持久化吗?

Redis的数据持久化机制是可以关闭的。如果你只把Redis作为缓存服务使用,Redis中存储的所有数据都不是该数据的主体而仅仅是同步过来的备份,那么可以关闭Redis的数据持久化机制。

但通常来说,仍然建议至少开启RDB方式的数据持久化,因为:

  • RDB方式的持久化几乎不损耗Redis本身的性能,在进行RDB持久化时,Redis主进程唯一需要做的事情就是fork出一个子进程,所有持久化工作都由子进程完成

  • Redis无论因为什么原因crash掉之后,重启时能够自动恢复到上一次RDB快照中记录的数据。这省去了手工从其他数据源(如DB)同步数据的过程,而且要比其他任何的数据恢复方式都要快

  • 现在硬盘那么大,真的不缺那一点地方

RDB

redis.conf默认配置是开启了RBD的,默认配置

save 900 1
save 300 10
save 60 10000

# In the example below the behaviour will be to save:

# after 900 sec (15 min) if at least 1 key changed

# after 300 sec (5 min) if at least 10 keys changed

# after 60 sec if at least 10000 keys changed

AOF

采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。

AOF默认是关闭的,如要开启,进行如下配置:

AOF提供了三种fsync配置,always/everysec/no,通过配置项[appendfsync]指定:

  • appendfsync no:不进行fsync,将flush文件的时机交给OS决定,速度最快

  • appendfsync always:每写入一条日志就进行一次fsync操作,数据安全性最高,但速度最慢

  • appendfsync everysec:折中的做法,交由后台线程每秒fsync一次:开启后默认

随着AOF不断地记录写操作日志,必定会出现一些无用的日志,例如某个时间点执行了命令SET key1 “abc”,在之后某个时间点又执行了SET key1 “bcd”,那么第一条命令很显然是没有用的。大量的无用日志会让AOF文件过大,也会让数据恢复的时间过长。

所以Redis提供了AOF rewrite功能,可以重写AOF文件,只保留能够把数据恢复到最新状态的最小写操作集。

AOF rewrite可以通过BGREWRITEAOF命令触发,也可以配置Redis定期自动进行:

上面两行配置的含义是,Redis在每次AOF rewrite时,会记录完成rewrite后的AOF日志大小,当AOF日志大小在该基础上增长了100%后,自动进行AOF rewrite。同时如果增长的大小没有达到64mb,则不会进行rewrite。

修改以上配置后,重启redis,则redis持久化完成

当你set一个值到redis中,然后kill该进程,在重启改redis,此值并不会消息

主从模式

以一主多重模式搭建主从模式,计划使用6381、6382、6383三个端口启动redis

新建目录

cd redis-5.0.5
mkdir config
cd config
mkdir 6381
mkdir 6382
mkdir 6383

复制redis.conf到主从目录

cp  redis.conf ./config/6831
cp  redis.conf ./config/6832
cp  redis.conf ./config/6833

修改以下配置文件

1) 主节点master

vim ./config/6381/redis.conf

bind 0.0.0.0   #任意ip都可以连接
protected-mode no   #关闭保护,允许非本地连接
port 6381 #端口号
daemonize yes  #后台运行
pidfile /var/run/redis_6381.pid  #进程守护文件,就是存放该进程号相关信息的地方
dir /root/worksoft/redis-5.0.5/config/6381/ #db等相关目录位置
appendonly yes  #开启日志形式,AOF持久化

2) 从节点slave

vim ./config/6382/redis.conf

protected-mode no   #关闭保护,允许非本地连接
port 6382 #端口号
daemonize yes  #后台运行
pidfile /var/run/redis_6382.pid  #进程守护文件,就是存放该进程号相关信息的地方
dir /root/worksoft/redis-5.0.5/config/6382/ #db等相关目录位置
appendonly yes  #开启日志形式,AOF持久化
slaveof 10.0.20.122 6381   #主信息

vim ./config/6383/redis.conf

protected-mode no   #关闭保护,允许非本地连接
port 6383 #端口号
daemonize yes  #后台运行
pidfile /var/run/redis_6383.pid  #进程守护文件,就是存放该进程号相关信息的地方
dir /root/worksoft/redis-5.0.5/config/6383/ #db等相关目录位置
appendonly yes  #开启日志形式,AOF持久化
slaveof 10.0.20.122 6381   #主信息

启动三台redis

./src/redis-server ./config/6381/redis.conf
./src/redis-server ./config/6382/redis.conf
./src/redis-server ./config/6383/redis.conf

至此,redis主从已经搭建完毕

验证

查看进程:ps -ef|grep redis

root     10360     1  0 Oct09 ?        00:00:36 ./src/redis-server 0.0.0.0:6381
root     10365     1  0 Oct09 ?        00:00:38 ./src/redis-server 0.0.0.0:6382
root     10372     1  0 Oct09 ?        00:00:38 ./src/redis-server 0.0.0.0:6383

查看信息:./src/redis-cli -p 6381

role:master
connected_slaves:2
slave0:ip=10.0.20.122,port=6382,state=online,offset=99216,lag=1
slave1:ip=10.0.20.122,port=6383,state=online,offset=99230,lag=0

然后你还可以在主节点写入数据,看是否同步,或者重启redis,看持久化效果!

编写启动/停止脚本:

mkdir bin

cd bin

vim master-slave-start.sh(启动脚本)

#!/bin/sh
/root/worksoft/redis-5.0.5/src/redis-server /root/worksoft/redis-5.0.5/config/6381/redis.conf
/root/worksoft/redis-5.0.5/src/redis-server /root/worksoft/redis-5.0.5/config/6382/redis.conf
/root/worksoft/redis-5.0.5/src/redis-server /root/worksoft/redis-5.0.5/config/6383/redis.conf```

vim master-slave-stop.sh(停止脚本)

#!/bin/sh
/root/worksoft/redis-5.0.5/src/redis-cli -p 6381 shutdown
/root/worksoft/redis-5.0.5/src/redis-cli -p 6382 shutdown
/root/worksoft/redis-5.0.5/src/redis-cli -p 6383 shutdown

redis sentinel哨兵模式

哨兵是redis集群架构中非常重要的一个组件,主要功能如下:

(1)集群监控,负责监控redis master 和slave进程是否正常工作。 (2)消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员。 (3)故障转移,如果master node挂掉了,会自动转移到slave node上。 (4)配置中心,如果故障转移发生了,通知client客户端新的master地址。

哨兵本身也是分布式的,作为一个哨兵集群去运行的,相互协同工作

(1)故障转移时,判断一个master node宕机了,需要大部分哨兵都同意才行,涉及到分布式选举问题。 (2)及时部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身就是单点,那么就不靠谱。

哨兵的核心知识

  • 哨兵至少需要3个实例,来保证自己的健壮性。

  • 哨兵+redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性

  • 对于哨兵+redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充分的测试和演练。

由于redis版本已经是5.X,自带集群功能以及很完善,此处略过哨兵机制,直接进去redis cluster搭建!

Redis cluster搭建

2018年十月 Redis 发布了稳定版本的 5.0 版本,推出了各种新特性,其中一点是放弃 Ruby的集群方式,改为 使用 C语言编写的 redis-cli的方式,是集群的构建方式复杂度大大降低。关于集群的更新可以在 Redis5 的版本说明中看到,如下:

可以查看Redis官网查看集群搭建方式,连接如下

https://redis.io/topics/cluster-tutorial

以下步骤是在一台 Linux 服务器上搭建有6个节点的 Redis集群。

创建集群步骤

1、创建目录

新建目录:/home/redis_cluster/

2、下载源码并解压编译

将之前下载的redis-5.0.5.tar.gz复制到/home/redis_cluster/下,并改名为redis_all

3、创建集群目录

在redis_all下创建集群目录,我们以官网示例为例,创建留个目录,3主3从(redis集群最少要有3个master)

mkdir  cluster_7000
mkdir  cluster_7001
mkdir  cluster_7002
mkdir  cluster_7003
mkdir  cluster_7004
mkdir  cluster_7005

4、创建6个Redis配置文件

将配置文件redis.conf复制到集群目录下(当前目录在redis_all下)

cp redis.conf ./cluster_7000/
cp redis.conf ./cluster_7001/
cp redis.conf ./cluster_7002/
cp redis.conf ./cluster_7003/
cp redis.conf ./cluster_7004/
cp redis.conf ./cluster_7005/

修改redis以下配置:

port 7000  #端口
cluster-enabled yes #启用集群模式
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000 #超时时间
appendonly yes
daemonize yes #后台运行
pidfile  /var/run/redis_7000.pid

其中 port 、 pidfile 、 cluster-config-file 需要随着不同的节点调整端口号

5、启动6台redis服务

我的启动脚本如下:

#!/bin/sh
/home/redis_cluster/redis_all/src/redis-server /home/redis_cluster/redis_all/cluster_7000/redis.conf
/home/redis_cluster/redis_all/src/redis-server /home/redis_cluster/redis_all/cluster_7001/redis.conf
/home/redis_cluster/redis_all/src/redis-server /home/redis_cluster/redis_all/cluster_7002/redis.conf
/home/redis_cluster/redis_all/src/redis-server /home/redis_cluster/redis_all/cluster_7003/redis.conf
/home/redis_cluster/redis_all/src/redis-server /home/redis_cluster/redis_all/cluster_7004/redis.conf
/home/redis_cluster/redis_all/src/redis-server /home/redis_cluster/redis_all/cluster_7005/redis.conf

6、查看6个节点的启动进程情况

ps -ef|grep redis

root      5352     1  0 Oct12 ?        00:03:30 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7000 [cluster]
root      5357     1  0 Oct12 ?        00:03:29 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7001 [cluster]
root      5362     1  0 Oct12 ?        00:03:07 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7002 [cluster]
root      5367     1  0 Oct12 ?        00:03:39 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7003 [cluster]
root      5372     1  0 Oct12 ?        00:03:32 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7004 [cluster]
root      5377     1  0 Oct12 ?        00:03:10 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7005 [cluster]

7、将6个节点构建成集群

我使用的是redis5,在src目录下使用redis-cli即可将6个节点串联成集群

/src/redis-cli --cluster create 10.0.14.81:7000 10.0.14.81:7001 10.0.14.81:7002 10.0.14.81:7003 10.0.14.81:7004 10.0.14.81:7005 --cluster-replicas 1

若你使用过的是redis3或者redis4,则使用redis-trib.rb,语法非常相似

/src/redis-trib.rb create --replicas 1 10.0.14.81:7000 10.0.14.81:7001 10.0.14.81:7002 10.0.14.81:7003 10.0.14.81:7004 10.0.14.81:7005

以上是一主一从的配置,Redis-cli将询问你的配置,一路输入yes接受建议的配置。最后,祝您一切顺利,您会看待这样的信息:

[OK] All 16384 slots covered

8、查看集群详情

./src/redis-cli --cluster check 10.0.14.81:7000

结果如下:

10.0.14.81:7003 (b2c9485d...) -> 40 keys | 5462 slots | 1 slaves.
10.0.14.81:7005 (a0d86a09...) -> 34 keys | 5461 slots | 1 slaves.
10.0.14.81:7002 (01af0266...) -> 38 keys | 5461 slots | 1 slaves.
[OK] 112 keys in 3 masters.
0.01 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.14.81:7000)
S: 3d8af4254be23d4548daf361053d40f06a17e785 10.0.14.81:7000
   slots: (0 slots) slave
   replicates a0d86a09aafc2c4ae83fbecb1130919e5461d81e
M: b2c9485d8e2b3ae42444f2f56715086c8682afdb 10.0.14.81:7003
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: b181b7b9aa37bf0a11f6b0d1866124db3f84fc11 10.0.14.81:7001
   slots: (0 slots) slave
   replicates b2c9485d8e2b3ae42444f2f56715086c8682afdb
M: a0d86a09aafc2c4ae83fbecb1130919e5461d81e 10.0.14.81:7005
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 01af026615e4d5ca206b51faa65fca158ac52b3d 10.0.14.81:7002
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 582e7dcebca9a9701a07bbd7799dec6df9e59b22 10.0.14.81:7004
   slots: (0 slots) slave
   replicates 01af026615e4d5ca206b51faa65fca158ac52b3d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Redis cluster扩容与缩容

随着业务的增长,可能之前规划的redis集群已经不能满足业务增长的需求,需要对Redis进行扩容!

Redis cluster提供动态扩容的功能

扩容

集群中新加入节点

首先新建文件夹cluster_7006

mkdir cluster_7006

复制cluster_7000下的redis.conf文件到cluster_7006下

cp ./cluster_7000/redis.conf ./cluster_7000/

修改以下配置文件:

port 7006  #端口
cluster-enabled yes #启用集群模式
cluster-config-file nodes-7006.conf
cluster-node-timeout 5000 #超时时间
appendonly yes
daemonize yes #后台运行
pidfile  /var/run/redis_7006.pid

启动该节点

/home/redis_cluster/redis_all/src/redis-server /home/redis_cluster/redis_all/cluster_7006/redis.conf

ok,7006 端口已经启动好了,并且进程也存在了,下面就是加入到集群中

同理redis5

./src/redis-cli --cluster add-node 10.0.14.81:7006 10.0.14.81:7000

redis3或者redis4

./src/redis-trib.rb add-node 10.0.14.81:7006 10.0.14.81:7000

日志如下

>>> Adding node 10.0.14.81:7006 to cluster 10.0.14.81:7000
>>> Performing Cluster Check (using node 10.0.14.81:7000)
S: 3d8af4254be23d4548daf361053d40f06a17e785 10.0.14.81:7000
   slots: (0 slots) slave
   replicates a0d86a09aafc2c4ae83fbecb1130919e5461d81e
M: b2c9485d8e2b3ae42444f2f56715086c8682afdb 10.0.14.81:7003
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: b181b7b9aa37bf0a11f6b0d1866124db3f84fc11 10.0.14.81:7001
   slots: (0 slots) slave
   replicates b2c9485d8e2b3ae42444f2f56715086c8682afdb
M: a0d86a09aafc2c4ae83fbecb1130919e5461d81e 10.0.14.81:7005
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 01af026615e4d5ca206b51faa65fca158ac52b3d 10.0.14.81:7002
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 582e7dcebca9a9701a07bbd7799dec6df9e59b22 10.0.14.81:7004
   slots: (0 slots) slave
   replicates 01af026615e4d5ca206b51faa65fca158ac52b3d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 10.0.14.81:7006 to make it join the cluster.
[OK] New node added correctly.

以上,表示新的节点连接成功了,而且也已经加入到集群了,我们再来检查一下:

我们再来检查一下节点:

./src/redis-cli --cluster check 10.0.14.81:7000

10.0.14.81:7003 (b2c9485d...) -> 40 keys | 5462 slots | 1 slaves.
10.0.14.81:7005 (a0d86a09...) -> 34 keys | 5461 slots | 1 slaves.
10.0.14.81:7002 (01af0266...) -> 38 keys | 5461 slots | 1 slaves.
10.0.14.81:7006 (7e2bad49...) -> 0 keys | 0 slots | 0 slaves.
[OK] 112 keys in 4 masters.
0.01 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.14.81:7000)
S: 3d8af4254be23d4548daf361053d40f06a17e785 10.0.14.81:7000
   slots: (0 slots) slave
   replicates a0d86a09aafc2c4ae83fbecb1130919e5461d81e
M: b2c9485d8e2b3ae42444f2f56715086c8682afdb 10.0.14.81:7003
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: b181b7b9aa37bf0a11f6b0d1866124db3f84fc11 10.0.14.81:7001
   slots: (0 slots) slave
   replicates b2c9485d8e2b3ae42444f2f56715086c8682afdb
M: a0d86a09aafc2c4ae83fbecb1130919e5461d81e 10.0.14.81:7005
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 01af026615e4d5ca206b51faa65fca158ac52b3d 10.0.14.81:7002
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 7e2bad498c38709068babf5b2b6fcdd26199e070 10.0.14.81:7006
   slots: (0 slots) master
S: 582e7dcebca9a9701a07bbd7799dec6df9e59b22 10.0.14.81:7004
   slots: (0 slots) slave
   replicates 01af026615e4d5ca206b51faa65fca158ac52b3d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

可以看到 有7个节点。7006 也作为了master节点,但是,但是,你看看后面的:

10.0.14.81:7006 (7e2bad49...) -> 0 keys | 0 slots | 0 slaves.

什么情况,意思就是虽然它现在是主节点,但是,缺没有分配任何节点给它,也就是它现在还不负责数据存取!

那加上去有锤子用啊!!!!

莫急莫急,我们先再加入一个从节点,组成4主4从的集群模式

集群中在加入一个从节点

同上,我们先启动一个7007的redis

ps -ef|grep redis

root      5352     1  0 Oct12 ?        00:03:37 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7000 [cluster]
root      5357     1  0 Oct12 ?        00:03:36 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7001 [cluster]
root      5362     1  0 Oct12 ?        00:03:13 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7002 [cluster]
root      5367     1  0 Oct12 ?        00:03:46 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7003 [cluster]
root      5372     1  0 Oct12 ?        00:03:39 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7004 [cluster]
root      5377     1  0 Oct12 ?        00:03:16 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7005 [cluster]
root     14923     1  0 16:08 ?        00:00:01 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7006 [cluster]
root     16329     1  0 16:36 ?        00:00:00 /home/redis_cluster/redis_all/src/redis-server 10.0.14.81:7007 [cluster]

将此节点加入集群:

同理redis5

./src/redis-cli --cluster add-node 10.0.14.81:7007 10.0.14.81:7000 --cluster-slave

redis3或者redis4

./src/redis-trib.rb add-node --slave 127.0.0.1:7007 127.0.0.1:7000

再来检查一下集群信息

./src/redis-cli --cluster check 10.0.14.81:7000

10.0.14.81:7003 (b2c9485d...) -> 40 keys | 5462 slots | 1 slaves.
10.0.14.81:7005 (a0d86a09...) -> 34 keys | 5461 slots | 1 slaves.
10.0.14.81:7002 (01af0266...) -> 38 keys | 5461 slots | 1 slaves.
10.0.14.81:7006 (7e2bad49...) -> 0 keys | 0 slots | 1 slaves.
[OK] 112 keys in 4 masters.
0.01 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.14.81:7000)
S: 3d8af4254be23d4548daf361053d40f06a17e785 10.0.14.81:7000
   slots: (0 slots) slave
   replicates a0d86a09aafc2c4ae83fbecb1130919e5461d81e
M: b2c9485d8e2b3ae42444f2f56715086c8682afdb 10.0.14.81:7003
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: b181b7b9aa37bf0a11f6b0d1866124db3f84fc11 10.0.14.81:7001
   slots: (0 slots) slave
   replicates b2c9485d8e2b3ae42444f2f56715086c8682afdb
M: a0d86a09aafc2c4ae83fbecb1130919e5461d81e 10.0.14.81:7005
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 669279c3e10fd9ba2526c6fe0a4c5eba788118d4 10.0.14.81:7007
   slots: (0 slots) slave
   replicates 7e2bad498c38709068babf5b2b6fcdd26199e070
M: 01af026615e4d5ca206b51faa65fca158ac52b3d 10.0.14.81:7002
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 7e2bad498c38709068babf5b2b6fcdd26199e070 10.0.14.81:7006
   slots: (0 slots) master
   1 additional replica(s)
S: 582e7dcebca9a9701a07bbd7799dec6df9e59b22 10.0.14.81:7004
   slots: (0 slots) slave
   replicates 01af026615e4d5ca206b51faa65fca158ac52b3d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

OK,4主4从模式搭建成功!下面再来看7006作为master, (0 slots)是0的问题。

集群中在加入一个从节点节点

新加入的7006节点作为master,集群并没有自动将数据重新分片,导致加入后并没有任何数据,

这是,需要我们手动对集群进行重新分片迁移,也是这个命令:

同理redis5

./src/redis-cli --cluster reshard 10.0.14.81:7000

redis3或redis4

./src/redis-trib.rb reshard 127.0.0.1:7000

这是,redis会询问你

How many slots do you want to move (from 1 to 16384)?

它提示我们需要迁移多少slot到7006上,我们可以算一下:16384/4 = 4096,也就是说,为了平衡分配起见,我们需要移动4096个槽点到7006上。

好,那输入4096

How many slots do you want to move (from 1 to 16384)? 4096
What is the receiving node ID?

下一个问题:接受的node ID是多少,7006的id 我们通过上面就可以看到是7e2bad498c38709068babf5b2b6fcdd26199e070 :

那好,输入7e2bad498c38709068babf5b2b6fcdd26199e070

What is the receiving node ID? 7e2bad498c38709068babf5b2b6fcdd26199e070
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1:

接着,又询问重新分片的源节点(source node), 也即是, 要从哪个节点中取出 4096 个哈希槽, 并将这些槽移动到7006节点上面。

如果我们不打算从特定的节点上取出指定数量的哈希槽, 那么可以向 redis-trib 输入 all , 这样的话, 集群中的所有主节点都会成为源节点, redis-trib 将从各个源节点中各取出一部分哈希槽, 凑够 4096 个, 然后移动到7006节点上:

Source node #1: all

接下来就开始迁移了,并且会询问你是否确认:

Moving slot 12267 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12268 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12269 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12270 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12271 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12272 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12273 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12274 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12275 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12276 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12277 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12278 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12279 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12280 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12281 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12282 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12283 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12284 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12285 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12286 from 01af026615e4d5ca206b51faa65fca158ac52b3d
    Moving slot 12287 from 01af026615e4d5ca206b51faa65fca158ac52b3d
Do you want to proceed with the proposed reshard plan (yes/no)?

输入 yes 并使用按下回车之后, redis 就会正式开始执行重新分片操作, 将指定的哈希槽从源节点一个个地移动到7006节点上面!

再次检查集群:

./src/redis-cli --cluster check 10.0.14.81:7000

10.0.14.81:7003 (b2c9485d...) -> 26 keys | 4096 slots | 1 slaves.
10.0.14.81:7005 (a0d86a09...) -> 28 keys | 4096 slots | 1 slaves.
10.0.14.81:7002 (01af0266...) -> 28 keys | 4096 slots | 1 slaves.
10.0.14.81:7006 (7e2bad49...) -> 30 keys | 4096 slots | 1 slaves.
[OK] 112 keys in 4 masters.
0.01 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.14.81:7000)
S: 3d8af4254be23d4548daf361053d40f06a17e785 10.0.14.81:7000
   slots: (0 slots) slave
   replicates a0d86a09aafc2c4ae83fbecb1130919e5461d81e
M: b2c9485d8e2b3ae42444f2f56715086c8682afdb 10.0.14.81:7003
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
S: b181b7b9aa37bf0a11f6b0d1866124db3f84fc11 10.0.14.81:7001
   slots: (0 slots) slave
   replicates b2c9485d8e2b3ae42444f2f56715086c8682afdb
M: a0d86a09aafc2c4ae83fbecb1130919e5461d81e 10.0.14.81:7005
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
S: 669279c3e10fd9ba2526c6fe0a4c5eba788118d4 10.0.14.81:7007
   slots: (0 slots) slave
   replicates 7e2bad498c38709068babf5b2b6fcdd26199e070
M: 01af026615e4d5ca206b51faa65fca158ac52b3d 10.0.14.81:7002
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
M: 7e2bad498c38709068babf5b2b6fcdd26199e070 10.0.14.81:7006
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
   1 additional replica(s)
S: 582e7dcebca9a9701a07bbd7799dec6df9e59b22 10.0.14.81:7004
   slots: (0 slots) slave
   replicates 01af026615e4d5ca206b51faa65fca158ac52b3d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

我们看到7006 slots为4096,进入7006查看数据

./src/redis-cli -h 10.0.14.81 -p 7006
keys *

发现新节点已经有数据,再次查看之前老节点,发现数据已经被迁移!

缩容

redis cluster同样支持移除节点功能

同理redis5

./src/redis-cli --cluster del-node 10.0.14.81:7000 `<node-id>`

node-id为节点id,我们现在要移出7007的节点,node-id为669279c3e10fd9ba2526c6fe0a4c5eba788118d4

Redis3 或 redis4

./src/redis-trib del-node 127.0.0.1:7000 `<node-id>`

但是想删除一个节点前,他必须没有数据,且槽位必须分配到其他的节点

You can remove a master node in the same way as well, however in order to remove a master node it must be empty

当然,如果改节点有从节点,可以直接删除,如我们删除7007节点,由于他有7006位从节点,则可以直接删除:

./src/redis-cli --cluster del-node 10.0.14.81:7000 669279c3e10fd9ba2526c6fe0a4c5eba788118d4
>>> Removing node 669279c3e10fd9ba2526c6fe0a4c5eba788118d4 from cluster 10.0.14.81:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

查看集群信息: ./src/redis-cli --cluster check 10.0.14.81:7000

10.0.14.81:7003 (b2c9485d...) -> 26 keys | 4096 slots | 1 slaves.
10.0.14.81:7005 (a0d86a09...) -> 28 keys | 4096 slots | 1 slaves.
10.0.14.81:7002 (01af0266...) -> 28 keys | 4096 slots | 1 slaves.
10.0.14.81:7006 (7e2bad49...) -> 30 keys | 4096 slots | 0 slaves.
[OK] 112 keys in 4 masters.
0.01 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.14.81:7000)
S: 3d8af4254be23d4548daf361053d40f06a17e785 10.0.14.81:7000
   slots: (0 slots) slave
   replicates a0d86a09aafc2c4ae83fbecb1130919e5461d81e
M: b2c9485d8e2b3ae42444f2f56715086c8682afdb 10.0.14.81:7003
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
S: b181b7b9aa37bf0a11f6b0d1866124db3f84fc11 10.0.14.81:7001
   slots: (0 slots) slave
   replicates b2c9485d8e2b3ae42444f2f56715086c8682afdb
M: a0d86a09aafc2c4ae83fbecb1130919e5461d81e 10.0.14.81:7005
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
M: 01af026615e4d5ca206b51faa65fca158ac52b3d 10.0.14.81:7002
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
M: 7e2bad498c38709068babf5b2b6fcdd26199e070 10.0.14.81:7006
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
S: 582e7dcebca9a9701a07bbd7799dec6df9e59b22 10.0.14.81:7004
   slots: (0 slots) slave
   replicates 01af026615e4d5ca206b51faa65fca158ac52b3d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

可以看到,7007被删除,7006右从变主,并接管了7007的数据

我们继续删除7006,让集群变成3主3从

./src/redis-cli --cluster del-node 10.0.14.81:7000 7e2bad498c38709068babf5b2b6fcdd26199e070

可以看到,由于7006没从节点,且数据不为空,删除失败

>>> Removing node 7e2bad498c38709068babf5b2b6fcdd26199e070 from cluster 10.0.14.81:7000
[ERR] Node 10.0.14.81:7006 is not empty! Reshard data away and try again.

所以,我们现在要对数据重新分片:

同上redis5

./src/redis-cli --cluster reshard 10.0.14.81:7000

redis3或redis4

./src/redis-trib.rb reshard 127.0.0.1:7000

第一个询问,我们要分多少个槽点,由于7007上有4096个槽点,所以这里填写4096:

>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)?

下一步,提示我们,需要移动到哪个id上,那就填7003的吧(锁容之后,槽位可能分配不均匀):

What is the receiving node ID? b2c9485d8e2b3ae42444f2f56715086c8682afdb
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
  Source node #1:

下一步,询问我们从哪个节点去迁移数据,因为我们是要删除7006的,所以,我们就得7006的id了

Source node #1:7e2bad498c38709068babf5b2b6fcdd26199e070
Source node #2:done
Do you want to proceed with the proposed reshard plan (yes/no)? yes

ok,这样就迁移好了。我们看看7006是否为空了

[root@localhost redis_all]# ./src/redis-cli -h 10.0.14.81 -p 7006
10.0.14.81:7006> keys *
(empty list or set)

OK,再次来移出集群

./src/redis-cli --cluster del-node 10.0.14.81:7000 7e2bad498c38709068babf5b2b6fcdd26199e070

成功:

>>> Removing node 7e2bad498c38709068babf5b2b6fcdd26199e070 from cluster 10.0.14.81:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

检查集群 ./src/redis-cli --cluster check 10.0.14.81:7000

10.0.14.81:7003 (b2c9485d...) -> 56 keys | 8192 slots | 1 slaves.
10.0.14.81:7005 (a0d86a09...) -> 28 keys | 4096 slots | 1 slaves.
10.0.14.81:7002 (01af0266...) -> 28 keys | 4096 slots | 1 slaves.
[OK] 112 keys in 3 masters.
0.01 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.14.81:7000)
S: 3d8af4254be23d4548daf361053d40f06a17e785 10.0.14.81:7000
   slots: (0 slots) slave
   replicates a0d86a09aafc2c4ae83fbecb1130919e5461d81e
M: b2c9485d8e2b3ae42444f2f56715086c8682afdb 10.0.14.81:7003
   slots:[0-1364],[5461-12287] (8192 slots) master
   1 additional replica(s)
S: b181b7b9aa37bf0a11f6b0d1866124db3f84fc11 10.0.14.81:7001
   slots: (0 slots) slave
   replicates b2c9485d8e2b3ae42444f2f56715086c8682afdb
M: a0d86a09aafc2c4ae83fbecb1130919e5461d81e 10.0.14.81:7005
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
M: 01af026615e4d5ca206b51faa65fca158ac52b3d 10.0.14.81:7002
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
S: 582e7dcebca9a9701a07bbd7799dec6df9e59b22 10.0.14.81:7004
   slots: (0 slots) slave
   replicates 01af026615e4d5ca206b51faa65fca158ac52b3d
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

可以看到已移出,但是有个问题,因为刚给我们把7006的槽位移到了7003,所以可以看到7003的槽位为8192个,会造成分配不均匀,若需要均匀,需要你平均的分配槽位信息,相信有了上面的命令,这一点也没有什么难度了!

10-15 00:35