一、演示环境:

在 Ubuntu 23.10 x64 系统中,3 主 3 从 MySQL 架构,主节点独立,从节点共用一台机器。

主机名 私有IP Redis 端口
master1 10.104.0.2 6001
master2 10.104.0.3 6002
master3 10.104.0.4 6003
slave 10.104.0.5 7001、7002、7003

二、环境准备:

1
sudo apt-get install build-essential autoconf automake libtool zlib1g-dev pkg-config libjemalloc-dev

后续操作均在此路径下进行:/opt

master 操作

1
2
3
cd /opt
wget https://github.com/redis/redis/archive/7.2.3.tar.gz
tar -xzvf 7.2.3.tar.gz

分别主3个 master 节点解压 Redis 压缩包后将文件名都改成redis-7.2.3-master即可

img

slvae 操作

1
2
3
cd /opt
wget https://github.com/redis/redis/archive/7.2.3.tar.gz
tar -xzvf 7.2.3.tar.gz

下载然后将解压出来的 Redis 文件夹重命名为 redis-7.2.3-7001

然后再创建两个文件夹:redis-7.2.3-7002``redis-7.2.3-7003

最后得到如下图所示三个文件夹

img

三、搭建 master

下方的操作需要在三台 master 机器上都依次执行

3.1 目录准备

进入文件夹内:cd /opt/redis-7.2.3-master/

创建 data 和 log:mkdir data log

3.2 构建安装

1
2
make distclean
make & make install

3.3 修改配置文件

修改 redis.config 配置文件。下方的配置文件可用直接使用,需要修改的配置项有带注释:

这里我三台 master 端口有做相应修改,设备独立的不改也可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# bind 127.0.0.1 -::1   这个指明,只能在本地(运行的节点)访问redis
# 如果改为其他的,比如 bind * -::* 或者 bind *0.0.0.0 这都全网可访问了~~~
# bind 127.0.0.1 -::1
bind 0.0.0.0

# 监听端口
port 6001

# 当Redis以上述守护进程方式运行时,Redis默认会把进程文件写入/var/run/redis_6379.pid文件
pidfile /opt/redis-7.2.3-master/data/redis_6001.pid

# 默认用户设置密码
masterauth Ye6k5sld4KaO

# 所有用户设置密码
requirepass Ye6k5sld4KaO

# 持久化文件名,默认dump.rdb
dbfilename dump.rdb

# 持久化的工作目录,AOF文件也会写在这里。
dir /opt/redis-7.2.3-master/data/

# 指定日志文件记录的位置。logfile “”:标准输出。则日志将会发送给/dev/null
logfile "/opt/redis-7.2.3-master/log/redis_6001.log"


protected-mode yes
timeout 0
daemonize yes
supervised no
always-show-logo no
save 900 1
save 300 10
save 60 10000
maxclients 10000
maxmemory 4g
rdb-del-sync-files no
appendfsync always
cluster-enabled yes
cluster-config-file nodes-6001.conf
cluster-node-timeout 15000
activedefrag yes

3.4 启动 Redis

命令:redis-server /opt/redis-master/redis.conf

3.5 检查是否启动

输入:netstat -ntpl查看 Redis 端口是否均已起

img

这里可能会有小伙伴问,为什么会多一个16003端口?

因为在 Redis 集群模式中,每个节点都有一个唯一的 ID,范围从 0 到 16383。但是,当你在配置文件中指定节点 ID 时,你需要在 ID 上加上 1000。这是因为 Redis 集群模式使用了一个名为集群总线 (cluster bus) 的内部通信机制,而集群总线使用端口号来标识每个节点。集群总线端口号是节点 ID 加上 1000。

这是 Redis 集群模式的一个设计决策,目的是为了避免与其他使用端口号 0 到 16383 的服务冲突。

3.6 连接 Redis

1
2
3
master1:redis-cli -h 10.104.0.2 -p 6001 -a Ye6k5sld4KaO
master2:redis-cli -h 10.104.0.3 -p 6002 -a Ye6k5sld4KaO
master3:redis-cli -h 10.104.0.4 -p 6003 -a Ye6k5sld4KaO

3.7 检测状态

连接后输入 PING,正常则返回 PONG 即可

img

四、搭建 slave

其实 slave 操作和 master 操作类似,需要主要修改配置文件

4.1 目录准备

进入文件夹内:cd /opt/redis-7.2.3-7001/

创建 data 和 log:mkdir data log

4.2 构建安装

1
2
make distclean
make & make install

4.3 修改配置文件

修改 redis.config 配置文件。下方的配置文件可用直接使用,需要修改的配置项有带注释:

注意:三个 slave 的 port、pidfile、dir、logfile 需要对应修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# bind 127.0.0.1 -::1   这个指明,只能在本地(运行的节点)访问redis
# 如果改为其他的,比如 bind * -::* 或者 bind *0.0.0.0 这都全网可访问了~~~
# bind 127.0.0.1 -::1
bind 0.0.0.0

# 监听端口
port 6001

# 当Redis以上述守护进程方式运行时,Redis默认会把进程文件写入/var/run/redis_6379.pid文件
pidfile /opt/redis-7.2.3-7001/data/redis_6001.pid

# 默认用户设置密码
masterauth Ye6k5sld4KaO

# 所有用户设置密码
requirepass Ye6k5sld4KaO

# 持久化文件名,默认dump.rdb
dbfilename dump.rdb

# 持久化的工作目录,AOF文件也会写在这里。
dir /opt/redis-7.2.3-7001/data/

# 指定日志文件记录的位置。logfile “”:标准输出。则日志将会发送给/dev/null
logfile "/opt/redis-7.2.3-7001/log/redis_6001.log"


protected-mode yes
timeout 0
daemonize yes
supervised no
always-show-logo no
save 900 1
save 300 10
save 60 10000
maxclients 10000
maxmemory 4g
rdb-del-sync-files no
appendfsync always
cluster-enabled yes
cluster-config-file nodes-6001.conf
cluster-node-timeout 15000
activedefrag yes

4.4 启动 Redis

1
2
3
redis-server /opt/redis-7.2.3-7001/redis.conf
redis-server /opt/redis-7.2.3-7002/redis.conf
redis-server /opt/redis-7.2.3-7003/redis.conf

4.5 检查是否启动

输入:netstat -ntpl查看三个 Redis 端口是否均已起

img

4.5 连接 Redis

1
2
3
redis-cli -h 10.104.0.5 -p 7001 -a Ye6k5sld4KaO
redis-cli -h 10.104.0.5 -p 7002 -a Ye6k5sld4KaO
redis-cli -h 10.104.0.5 -p 7003 -a Ye6k5sld4KaO

4.7 检测状态

连接任意 Redis 后输入 PING,正常则返回 PONG 即可

img

五、创建 Redis 集群

节点创建完毕后,各个节点实际上是独立的,并没有组成一个集群,还需要下面的操作。

方法一:一键执行

下面这条命令是指定三主三从,前三个节点是主节点,后三个节点是从节点。

1
redis-cli --cluster create 127.0.0.1:6001 10.104.0.3:6002 10.104.0.4:6003 10.104.0.5:7001 10.104.0.5:7002 10.104.0.5:7003 --cluster-replicas 1

当程序提示: Can I set the above configuration? (type 'yes' to accept) 时,键入 yes 回车,然后集群搭建完毕!

然后连接任意 Redis 后,输入 CLIENT NODES 即可查看集群节点关联关系

img

数据解析:

1
2
3
4
5
6
7
8
9
节点 ID: 6d959d3d8e669c9416b4f1dd4e910b05b3357704
地址: 10.104.0.4:6003
端口: 16003
角色: master
主节点 ID:
槽分配: 10923-16383
配置纪元: 0
集群状态纪元: 1704532133000
连接状态: 已连接

方法二:指定主从关系

**注意!**当只有 3 台物理节点时,若要指定主从关系以保证高可用,则需要手动操作。

  1. 创建具有三个主节点的集群,没有从节点。
  2. 使用添加节点的命令添加从节点,并在添加时指定它们的主节点,建立主从对应关系。

创建主节点

使用命令创建:redis-cli -a Ye6k5sld4KaO --cluster create 10.104.0.2:6001 10.104.0.3:6002 10.104.0.4:6003 --cluster-replicas 0

填写三个主节点对应的 IP、端口和密码即可

增加从节点

命令:redis-cli -a xxx --cluster add-node --cluster-slave --cluster-master-id {id}

  • a:密码
  • slave:表示添加从节点
  • cluster-master-id:要添加到对应的主节点 ID(节点ID获取方法,往上翻一下就有)
  • 127.0.0.1:7001:从节点
  • 127.0.0.1:6001:原集群中已存在的任意节点

这里我将三个 slave 分别添加至三台 master,命令如下:

1
2
3
4
5
redis-cli -a Ye6k5sld4KaO --cluster add-node 10.104.0.5:7001 10.104.0.2:6001 --cluster-slave --cluster-master-id c8e40723b1838dcd9bcc96ec9a258b082eccfd22

redis-cli -a Ye6k5sld4KaO --cluster add-node 10.104.0.5:7002 10.104.0.3:6002 --cluster-slave --cluster-master-id cfb8aa52153a704e09dd80dfe4d20dfee96dbe2a

redis-cli -a Ye6k5sld4KaO --cluster add-node 10.104.0.5:7003 10.104.0.4:6003 --cluster-slave --cluster-master-id 6d959d3d8e669c9416b4f1dd4e910b05b3357704

然后连接任意 Redis 后,输入 CLIENT NODES 即可查看集群节点关联关系

img

可以发现,我们所有的 从节点 对应的都是我们给他指定的 主节点

动态增删节点

1、增加 master

1
2
3
4
redis-cli -a Ye6k5sld4KaO --cluster add-node 10.104.0.5:7004 10.104.0.2:6001

- 10.104.0.5:7004 需要向集群添加新的节点
- 10.104.0.2:6001 原集群中已存在的任意节点

2、给新的 master 分配哈希槽

节点已加入集群,但没有数据:

  • 因为它还没有分配到 hash slots,所以它还没有数据
  • 因为它是还没有 hash slots 的主节点,所以它不会参与到从节点升级到主节点的选举中

我们只需要指定任意一个节点,redis 会自动发现其他节点

使用命令:redis-cli -a Ye6k5sld4KaO --cluster reshard 10.104.0.2:6001可以重新分配哈希槽,执行之后会出现提醒:

1
2
3
4
5
6
7
8
9
10
11
How many slots do you want to move (from 1 to 16384)?
这里是输入想要迁移多少个哈希槽。这里我输入30个。

What is the receiving node ID?
这里是接受哈希槽迁移的节点id。这里就是7006节点的id。可以使用命令redis-cli -h 127.0.0.1 -p 7000 cluster nodes查看。

Source node #1:
这里是输入迁出哈希槽的节点id。输入一个回车之后,可以继续输入。这里我输入其他3个master的节点id,完成之后输入done执行下一步。

Do you want to proceed with the proposed reshard plan (yes/no)?
这里输入yes,确认迁移。

然后开始迁移,每迁移一个key就会输出一个点。待所有迁移完成后,执行下面的指令查看集群是否正常:

1
redis-cli -a Ye6k5sld4KaO --cluster check 10.104.0.2:6001

3、增加 slave

1
2
3
4
redis-cli --cluster add-node 127.0.0.5:7004 127.0.0.2:6001 --cluster-slave

- 10.104.0.5:7004 需要向集群添加新的节点
- 10.104.0.2:6001 原集群中已存在的任意节点

该指令与增加主节点语法一致,与添加主节点不同的是,显式指定了是从节点。

这会为该从节点随机分配一个主节点,优先从那些从节点数目最少的主节点中选取,当然这一步也能和上面一样,给他指定 master-id。

4、删除节点

注意,只能删除从节点或者空的主节点

1
2
3
4
redis-cli -a Ye6k5sld4KaO --cluster del-node 127.0.0.2:6001 {node-id}

- 127.0.0.1:7000 为集群中任意节点
- node-id 为要删除的节点的id

如果想删除有数据的主节点,必须先执行 resharding 把它的数据分配到其他节点后再删除。

六、配置文件解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
############################## GENERAL(通配)##################################

# bind 127.0.0.1 -::1 这个指明,只能在本地(运行的节点)访问redis
# 如果改为其他的,比如 bind * -::* 或者 bind *0.0.0.0 这都全网可访问了~~~
# 监听IP
# bind 127.0.0.1 -::1
bind 0.0.0.0

# 监听端口
port 6003

# 保护模式是一个避免你在互联网(外网)访问redis的机制。
# 当启用保护模式,而且没有密码时,服务器只接受来自IPv4地址(127.0.0.1)、IPv6地址(::1)或Unix套接字本地连接。(没密码+保护模式启动=本地访问)
# 默认是开启的。(如果你要从外部访问它,甚至没有认证(不设置密码,不绑定可访问ip)的去访问, 那就弄成 no 自己负责!)
protected-mode yes

# 连接超时时间,单位秒;超过timeout,服务端会断开连接,为0则服务端不会主动断开连接,不能小于0
timeout 0

# 默认情况下,Redis不作为守护进程运行(老版本默认)。如果需要可以修改daemonize为‘yes’
daemonize yes

# 是否从upstart或systemd运行Redis,默认no
supervised no

# 当Redis以上述守护进程方式运行时,Redis默认会把进程文件写入/var/run/redis_6379.pid文件
pidfile /root/redis-master1/data/redis_6003.pid

# 指定日志文件记录的位置。logfile “”:标准输出。则日志将会发送给/dev/null

logfile "/root/redis-master1/log/redis_6003.log"

# 默认情况下,Redis只有在开始登录到标准输出时,以及如果标准输出是TTY并且syslog日志记录被禁用时,才会显示ASCII艺术徽标。基本上,这意味着通常只有在交互式会话中才会显示徽标。但是,通过将以下选项设置为yes,可以强制执行4.0之前的行为,并始终在启动日志中显示ASCII艺术徽标。
always-show-logo no

# RDB持久化配置
# 服务器在900s内对数据库进行了了至少1次修改,BGSAVE命令就会被执行。
save 900 1
# 服务器在300s之内对数据库进行了至少10次修改,BGSAVE命令就会被执行。
save 300 10
# 服务器在60s之内对数据库进行了至少10000次修改,BGSAVE命令就会被执行。
save 60 10000

# 默认用户设置密码
masterauth Ye6k5sld4KaO

# 所有用户设置密码
requirepass Ye6k5sld4KaO

# maxclients设置同时连接的客户端的最大数量。默认情况下为10000个,但是,如果受限于机器资源限制,则允许的客户端的最大数量将设置为当前文件限制减去32(因为Redis需要保留一些文件描述符供内部使用)。
# 一旦达到限制,Redis将关闭所有新连接,并发送错误“达到最大客户端数”。
# 重要提示:使用Redis集群时,最大连接数也与集群总线共享:集群中的每个节点都将使用两个连接,一个传入,另一个传出。在非常大的集群的情况下,相应地调整限制大小是很重要的
maxclients 10000

# 内存限制等配置
maxmemory 4g

############################## APPEND ONLY MODE(AOF持久化配置) ###############################

# 在未启用持久性的实例中删除复制使用的RDB文件。默认情况下,此选项处于禁用状态。注意,此选项仅适用于同时禁用AOF和RDB持久性的实例,否则将被完全忽略。
rdb-del-sync-files no

# 持久化文件名,默认dump.rdb
dbfilename dump.rdb

# 持久化的工作目录,AOF文件也会写在这里。
dir /root/redis-master1/data/

#AOF持久化三种同步策略:
# 1) no:不同步(不执行fsync),数据不会持久化
# 2) always:每次有数据发生变化时都会写入appendonly.aof(慢,安全)
# 3) everysec:每秒同步一次到appendonly.aof,可能会导致丢失这1s数据(折中选择,默认值)
appendfsync always

################################ REDIS CLUSTER (集群配置) ###############################
# 一个最小的集群需要最少3个主节点。
# 普通Redis实例不能是Redis集群的一部分;只有作为集群节点启动的节点才能。为了将Redis实例作为集群节点启动,可以配置cluster-enabled值为yes
cluster-enabled yes

# cluster-config-file是每个集群节点都有的单独一个集群配置文件。此文件不可手动编辑。它由Redis节点创建和更新。每个Redis Cluster节点都需要不同的群集配置文件。请确保在同一系统中运行的实例没有重叠的群集配置文件名。
cluster-config-file nodes-6003.conf

#这是集群中的节点能够失联的最大时间,超过这个时间,该节点就会被认为故障。如果主节点超过这个时间还是不可达,则用它的从节点将启动故障迁移,升级成主节点。注意,任何一个节点在这个时间之内如果还是没有连上大部分的主节点,则此节点将停止接收任何请求。
cluster-node-timeout 15000

#集群节点端口是集群总线将侦听入站连接的端口。当设置为默认值0时,它将绑定到命令端口+10000。设置此值要求在执行群集相遇时指定集群总线端口。
activedefrag yes