以下介绍redis的集群情况
Redis 集群介绍
Redis Cluster 提供一种Redis安装方式:数据自动在多个Redis节点间分片。
Redis Cluster 提供一定程度的高可用,在实际的环境中当某些节点失败或者不能通讯的情况下能够继续提供服务。大量节点失败的情况下集群也会停止服务(例如大多数主节点不可用)。
Redis集群提供的能力:
- 自动切分数据集到多个节点上。
- 当部分节点故障或不可达的情况下继续提供服务。
Redis 集群的端口
每个Redis集群节点需要打开两个TCP连接。端口6379提供给客户端连接,外加上一个端口16379,记起来也比较容易,在6379的基础上加10000。
端口16379提供给集群总线使用,总线用来集群节点间通信,使用的是二进制协议。集群总线的作用:失败检测、配置升级、故障转移授权等。客户端只能连接6379端口,不能连接端口16379。防火墙需要确保打开这两个端口,否则集群节点之间不能通信。
命令端口和总线端口之间总是相差10000 。
每个节点的端口原则:
- 客户端通讯端口需要开放给所有与集群交互的客户端,和集群内的其它节点(主要是用来做keys迁移)。
- 集群总线端口(命令端口+10000)需要被所有其它集群节点能访问到。
集群总线使用二进制协议(不同于跟客户端通信协议)来进行节点之间数据交换,这个协议更适合节点间使用小的带宽和处理时间来交换数据。
Redis 集群和数据分片
Redis集群不是使用一致性哈希,而是使用哈希槽。整个redis集群有16384个哈希槽,决定一个key应该分配到那个槽的算法是:计算该key的CRC16结果再模16834。
集群中的每个节点负责一部分哈希槽,比如集群中有3个节点,则:
- 节点A存储的哈希槽范围是:0 – 5500
- 节点B存储的哈希槽范围是:5501 – 11000
- 节点C存储的哈希槽范围是:11001 – 16384
这样的分布方式方便节点的添加和删除。比如,需要新增一个节点D,只需要把A、B、C中的部分哈希槽数据移到D节点。同样,如果希望在集群中删除A节点,只需要把A节点的哈希槽的数据移到B和C节点,当A节点的数据全部被移走后,A节点就可以完全从集群中删除。
因为把哈希槽从一个节点移到另一个节点是不需要停机的,所以,增加或删除节点,或更改节点上的哈希槽,也是不需要停机的。
集群支持通过一个命令(或事务, 或lua脚本)同时操作多个key。通过"哈希标签"的概念,用户可以让多个key分配到同一个哈希槽。哈希标签在集群详细文档中有描述,这里做个简单介绍:如果key含有大括号"{}",则只有大括号中的字符串会参与哈希,比如"this{foo}"和"another{foo}"这2个key会分配到同一个哈希槽,所以可以在一个命令中同时操作他们。
Redis 集群主从模式
为了保证在部分节点故障或网络不通时集群依然能正常工作,集群使用了主从模型,每个哈希槽有一(主节点)到N个副本(N-1个从节点)。
在我们刚才的集群例子中,有A,B,C三个节点,如果B节点故障集群就不能正常工作了,因为B节点中的哈希槽数据5501-11000没法操作。
但是,如果我们给每一个节点都增加一个从节点,就变成了:A,B,C三个节点是主节点,A1, B1, C1 分别是他们的从节点,当B节点宕机时,我们的集群也能正常运作。
B1节点是B节点的副本,如果B节点故障,集群会提升B1为主节点,从而让集群继续正常工作。但是,如果B和B1同时故障,集群就不能继续工作了。
Redis 集群一致性保证
Redis集群不能保证强一致性。一些已经向客户端确认写成功的操作,会在某些不确定的情况下丢失。
产生写操作丢失的第一个原因,是因为主从节点之间使用了异步的方式来同步数据。
一个写操作是这样一个流程:
- 客户端向主节点B发起写的操作
- 主节点B回应客户端写操作成功
- 主节点B向它的从节点B1,B2,B3同步该写操作
从上面的流程可以看出来,主节点B并没有等从节点B1,B2,B3写完之后再回复客户端这次操作的结果。所以,如果主节点B在通知客户端写操作成功之后,但同步给从节点之前,主节点B故障了,其中一个没有收到该写操作的从节点会晋升成主节点,该写操作就这样永远丢失了。
就像传统的数据库,在不涉及到分布式的情况下,它每秒写回磁盘。为了提高一致性,可以在写盘完成之后再回复客户端,但这样就要损失性能。这种方式就等于Redis集群使用同步复制的方式。
基本上,在性能和一致性之间,需要一个权衡。
如果真的需要,Redis集群支持同步复制的方式,通过WAIT 指令来实现,这可以让丢失写操作的可能性降到很低。但就算使用了同步复制的方式,Redis集群依然不是强一致性的,在某些复杂的情况下,比如从节点在与主节点失去连接之后被选为主节点,不一致性还是会发生。
这种不一致性发生的情况是这样的,当客户端与少数的节点(至少含有一个主节点)网络联通,但他们与其他大多数节点网络不通。比如6个节点,A,B,C是主节点,A1,B1,C1分别是他们的从节点,一个客户端称之为Z1。
当网络出问题时,他们被分成2组网络,组内网络联通,但2组之间的网络不通,假设A,C,A1,B1,C1彼此之间是联通的,另一边,B和Z1的网络是联通的。Z1可以继续往B发起写操作,B也接受Z1的写操作。当网络恢复时,如果这个时间间隔足够短,集群仍然能继续正常工作。如果时间比较长,以致B1在大多数的这边被选为主节点,那刚才Z1发给B的写操作都将丢失。
注意,Z1给B发送写操作是有一个限制的,如果时间长度达到了大多数节点那边可以选出一个新的主节点时,少数这边的所有主节点都不接受写操作。
这个时间的配置,称之为节点超时(node timeout),对集群来说非常重要,当达到了这个节点超时的时间之后,主节点被认为已经宕机,可以用它的一个从节点来代替。同样,在节点超时时,如果主节点依然不能联系到其他主节点,它将进入错误状态,不再接受写操作。
Redis 集群参数配置
我们后面会部署一个Redis集群作为例子,在那之前,先介绍一下集群在redis.conf中的参数。
- cluster-enabled
<yes/no>
: 如果配置"yes"则开启集群功能,此redis实例作为集群的一个节点,否则,它是一个普通的单一的redis实例。 - cluster-config-file
<filename>
: 注意:虽然此配置的名字叫"集群配置文件",但是此配置文件不能人工编辑,它是集群节点自动维护的文件,主要用于记录集群中有哪些节点、他们的状态以及一些持久化参数等,方便在重启时恢复这些状态。通常是在收到请求之后这个文件就会被更新。 - cluster-node-timeout
<milliseconds>
: 这是集群中的节点能够失联的最大时间,超过这个时间,该节点就会被认为故障。如果主节点超过这个时间还是不可达,则用它的从节点将启动故障迁移,升级成主节点。注意,任何一个节点在这个时间之内如果还是没有连上大部分的主节点,则此节点将停止接收任何请求。 - cluster-slave-validity-factor
<factor>
: 如果设置成0,则无论从节点与主节点失联多久,从节点都会尝试升级成主节点。如果设置成正数,则cluster-node-timeout乘以cluster-slave-validity-factor得到的时间,是从节点与主节点失联后,此从节点数据有效的最长时间,超过这个时间,从节点不会启动故障迁移。假设cluster-node-timeout=5,cluster-slave-validity-factor=10,则如果从节点跟主节点失联超过50秒,此从节点不能成为主节点。注意,如果此参数配置为非0,将可能出现由于某主节点失联却没有从节点能顶上的情况,从而导致集群不能正常工作,在这种情况下,只有等到原来的主节点重新回归到集群,集群才恢复运作。 - cluster-migration-barrier
<count>
:主节点需要的最小从节点数,只有达到这个数,主节点失败时,它从节点才会进行迁移。更详细介绍可以看本教程后面关于副本迁移到部分。 - cluster-require-full-coverage <yes/no>:在部分key所在的节点不可用时,如果此参数设置为"yes"(默认值), 则整个集群停止接受操作;如果此参数设置为"no",则集群依然为可达节点上的key提供读操作。
手动创建和使用Redis集群
注意:手动部署Redis集群能够很好的了解它是如何运作的,但如果你希望尽快的让集群运行起来,可以跳过本节和下一节,直接到"使用create-cluster脚本创建Redis集群"章节。
要创建集群,首先需要以集群模式运行的空redis实例。也就说,以普通模式启动的redis是不能作为集群的节点的,需要以集群模式启动的redis实例才能有集群节点的特性、支持集群的指令,成为集群的节点。
下面是最小的redis集群的配置文件:
port 7000 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes
复制
开启集群模式只需打开cluster-enabled配置项即可。每一个redis实例都包含一个配置文件,默认是nodes.conf,用于存储此节点的一些配置信息。这个配置文件由redis集群的节点自行创建和更新,不能由人手动地去修改。
一个最小的集群需要最少3个主节点。第一次测试,强烈建议你配置6个节点:3个主节点和3个从节点。
开始测试,步骤如下:先进入新的目录,以redis实例的端口为目录名,创建目录,我们将在这些目录里运行我们的实例。
类似这样:
mkdir /usr/local/redis/cluster/cluster-test/{7000,7001,7002,7003,7004,7005} -p
复制
在7000-7005的每个目录中创建配置文件redis.conf,内容就用上面的最简配置做模板,注意修改端口号,改为跟目录一致的端口。
root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test# tree . ├── 7000 │ └── redis_clsuter.conf ├── 7001 │ └── redis_clsuter.conf ├── 7002 │ └── redis_clsuter.conf ├── 7003 │ └── redis_clsuter.conf ├── 7004 │ └── redis_clsuter.conf └── 7005 └── redis_clsuter.conf
复制
在每个终端启动一个redis实例,指令类似这样:
root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7000# redis-server /usr/local/redis/cluster/cluster-test/7000/redis_clsuter.conf & [1] 34066 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7000# 34066:C 08 Aug 2022 17:29:11.310 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 34066:C 08 Aug 2022 17:29:11.310 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=34066, just started 34066:C 08 Aug 2022 17:29:11.310 # Configuration loaded 34066:M 08 Aug 2022 17:29:11.310 * Increased maximum number of open files to 10032 (it was originally set to 1024). 34066:M 08 Aug 2022 17:29:11.310 * monotonic clock: POSIX clock_gettime 34066:M 08 Aug 2022 17:29:11.310 * Node configuration loaded, I'm cfd4e630fc4da55276309eff488329616474631d 34066:M 08 Aug 2022 17:29:11.311 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.7 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in cluster mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 7000 | `-._ `._ / _.-' | PID: 34066 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | https://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 34066:M 08 Aug 2022 17:29:11.311 # Server initialized 34066:M 08 Aug 2022 17:29:11.311 * Ready to accept connections root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test# cd 7001 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7001# redis-server /usr/local/redis/cluster/cluster-test/7001/redis_clsuter.conf & [2] 34634 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7001# 34634:C 08 Aug 2022 17:32:45.390 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 34634:C 08 Aug 2022 17:32:45.390 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=34634, just started 34634:C 08 Aug 2022 17:32:45.390 # Configuration loaded 34634:M 08 Aug 2022 17:32:45.390 * Increased maximum number of open files to 10032 (it was originally set to 1024). 34634:M 08 Aug 2022 17:32:45.390 * monotonic clock: POSIX clock_gettime 34634:M 08 Aug 2022 17:32:45.391 * Node configuration loaded, I'm f2f9c3688535d09cec9ed8f3954c0620da5da519 34634:M 08 Aug 2022 17:32:45.391 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.7 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in cluster mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 7001 | `-._ `._ / _.-' | PID: 34634 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | https://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 34634:M 08 Aug 2022 17:32:45.391 # Server initialized 34634:M 08 Aug 2022 17:32:45.391 * Ready to accept connections root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7001# cd ../7002 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7002# redis-server /usr/local/redis/cluster/cluster-test/7002/redis_clsuter.conf & [3] 34685 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7002# 34685:C 08 Aug 2022 17:32:59.138 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 34685:C 08 Aug 2022 17:32:59.138 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=34685, just started 34685:C 08 Aug 2022 17:32:59.138 # Configuration loaded 34685:M 08 Aug 2022 17:32:59.139 * Increased maximum number of open files to 10032 (it was originally set to 1024). 34685:M 08 Aug 2022 17:32:59.139 * monotonic clock: POSIX clock_gettime 34685:M 08 Aug 2022 17:32:59.139 * No cluster configuration found, I'm ce6fb3ce7042d5a088e78ba329d20d15b3b5bcda 34685:M 08 Aug 2022 17:32:59.143 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.7 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in cluster mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 7002 | `-._ `._ / _.-' | PID: 34685 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | https://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 34685:M 08 Aug 2022 17:32:59.143 # Server initialized 34685:M 08 Aug 2022 17:32:59.144 * Ready to accept connections root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7002# cd ../7003 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7003# redis-server /usr/local/redis/cluster/cluster-test/7003/redis_clsuter.conf & [4] 34721 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7003# 34721:C 08 Aug 2022 17:33:08.887 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 34721:C 08 Aug 2022 17:33:08.887 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=34721, just started 34721:C 08 Aug 2022 17:33:08.887 # Configuration loaded 34721:M 08 Aug 2022 17:33:08.888 * Increased maximum number of open files to 10032 (it was originally set to 1024). 34721:M 08 Aug 2022 17:33:08.888 * monotonic clock: POSIX clock_gettime 34721:M 08 Aug 2022 17:33:08.888 * No cluster configuration found, I'm 5de8937314a3cc44493e4f89f3b7c0639af82d8d 34721:M 08 Aug 2022 17:33:08.892 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.7 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in cluster mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 7003 | `-._ `._ / _.-' | PID: 34721 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | https://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 34721:M 08 Aug 2022 17:33:08.892 # Server initialized 34721:M 08 Aug 2022 17:33:08.893 * Ready to accept connections root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7003# cd ../7004 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7004# redis-server /usr/local/redis/cluster/cluster-test/7004/redis_clsuter.conf & [5] 34743 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7004# 34743:C 08 Aug 2022 17:33:16.573 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 34743:C 08 Aug 2022 17:33:16.573 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=34743, just started 34743:C 08 Aug 2022 17:33:16.573 # Configuration loaded 34743:M 08 Aug 2022 17:33:16.573 * Increased maximum number of open files to 10032 (it was originally set to 1024). 34743:M 08 Aug 2022 17:33:16.573 * monotonic clock: POSIX clock_gettime 34743:M 08 Aug 2022 17:33:16.573 * No cluster configuration found, I'm 39400185cf995ba64c720122e55de2913b989aa7 34743:M 08 Aug 2022 17:33:16.576 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.7 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in cluster mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 7004 | `-._ `._ / _.-' | PID: 34743 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | https://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 34743:M 08 Aug 2022 17:33:16.576 # Server initialized 34743:M 08 Aug 2022 17:33:16.577 * Ready to accept connections root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7004# cd ../7005 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7005# redis-server /usr/local/redis/cluster/cluster-test/7005/redis_clsuter.conf & [6] 34758 root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7005# 34758:C 08 Aug 2022 17:33:25.060 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 34758:C 08 Aug 2022 17:33:25.060 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=34758, just started 34758:C 08 Aug 2022 17:33:25.060 # Configuration loaded 34758:M 08 Aug 2022 17:33:25.061 * Increased maximum number of open files to 10032 (it was originally set to 1024). 34758:M 08 Aug 2022 17:33:25.061 * monotonic clock: POSIX clock_gettime 34758:M 08 Aug 2022 17:33:25.061 * No cluster configuration found, I'm 7b92082b4ee5d4968fe8d914ff1eb9145802e8a3 34758:M 08 Aug 2022 17:33:25.064 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.7 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in cluster mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 7005 | `-._ `._ / _.-' | PID: 34758 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | https://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 34758:M 08 Aug 2022 17:33:25.064 # Server initialized 34758:M 08 Aug 2022 17:33:25.065 * Ready to accept connections
复制
特别注意的是,需要到每个自己的目录启动该集群实例
在日志中我们可以看到,由于没有nodes.conf文件不存在,每个节点都给自己一个新的ID(创建出来一个新的nodes.conf
并存于此)
34758:M 08 Aug 2022 17:33:25.061 * No cluster configuration found, I'm 7b92082b4ee5d4968fe8d914ff1eb9145802e8a3
复制
这个ID将一直被此节点使用,作为此节点在整个集群中的唯一标识。节点区分其他节点也是通过此ID来标识,而非IP或端口。IP可以改,端口可以改,但此ID不能改,直到这个节点离开集群。这个ID称之为节点ID(Node ID)。
创建集群
现在6个实例已经运行起来了,我们需要给节点写一些有意义的配置来创建集群。Redis5通过redis-cli就可以创建集群。``
Redis5:
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
复制
Redis3或4需要使用redis集群的命令工具redis-trib。redis-trib是一个用ruby写的脚,用于给各节点发指令创建集群、检查集群状态或给集群重新分片等。redis-trib在Redis源码的src目录本下,需要gem redis来运行redis-trib。
gem install redis ./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
复制
我们使用 create 创建新的集群。选项 --cluster-replicas 1
表示为每一个主服务器配一个重服务器。其余的参数是要创建的集群中各实例的地址列表。
我们创建的集群有3个主节点和3个从节点。
root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/7005# 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
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:7004 to 127.0.0.1:7000
Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
Adding replica 127.0.0.1:7003 to 127.0.0.1:7002
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: cfd4e630fc4da55276309eff488329616474631d 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
M: f2f9c3688535d09cec9ed8f3954c0620da5da519 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
M: ce6fb3ce7042d5a088e78ba329d20d15b3b5bcda 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
S: 5de8937314a3cc44493e4f89f3b7c0639af82d8d 127.0.0.1:7003
replicates ce6fb3ce7042d5a088e78ba329d20d15b3b5bcda
S: 39400185cf995ba64c720122e55de2913b989aa7 127.0.0.1:7004
replicates cfd4e630fc4da55276309eff488329616474631d
S: 7b92082b4ee5d4968fe8d914ff1eb9145802e8a3 127.0.0.1:7005
replicates f2f9c3688535d09cec9ed8f3954c0620da5da519
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
..............
复制

…

…

Redis-cli will 会给你一些配置建议,输入yes表示接受。集群会被配置并彼此连接好,意思是各节点实例被引导彼此通话并最终形成集群。最后,如果一切顺利,会看到类似下面的信息:
[OK] All 16384 slots covered
复制
这表示,16384个哈希槽都被主节点正常服务着。
create-cluster 脚本创建集群
如果你不想像上面解释的那样通过手动配置和执行单个实例来创建一个Redis集群,有一个更简单的系统(但你不会学到同样多的操作细节)。只需检查Redis发行版中的utils/create-cluster目录。其中有一个名为create-cluster的脚本(与包含它的目录同名),它是一个简单的bash脚本。为了启动包含3个主3个从的6个节点的集群,只需输入以下命令:
1,create-cluster start
2,create-cluster create
当redis-cli实用程序希望你接受集群布局时,在步骤2中回复yes。
您现在可以与集群交互,默认情况下第一个节点将从30001端口启动。完成之后,用以下命令停止集群:
1,create-cluster stop
.
请阅读此目录内的README以获得更多关于如何运行该脚本的信息。
实操:
root@VM-2-10-ubuntu:/usr/local/src/redis-6.2.7# cp utils/create-cluster/create-cluster /usr/local/redis/bin/
root@VM-2-10-ubuntu:/usr/local/redis/db/db_cluster1# cd /usr/local/src/redis-6.2.7utils/create-cluster/
root@VM-2-10-ubuntu:/usr/local/src/redis-6.2.7/utils/create-cluster# create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
root@VM-2-10-ubuntu:/usr/local/src/redis-6.2.7/utils/create-cluster# create-cluster create
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 9f18fe40c564959d9361d9bdf14107c22e645f49 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
M: dbeace86b8a39b14e34d5e09bd4c987a370adb3a 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
M: 13e9aea7efe2e5c594b536e9fdd6ccaf7b19eaa1 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
S: dd6ade06fbd7ab5005e60f228fb6fa2257bdc082 127.0.0.1:30004
replicates dbeace86b8a39b14e34d5e09bd4c987a370adb3a
S: 260c539eb22db89a6c1e5411d554afdc62686da3 127.0.0.1:30005
replicates 13e9aea7efe2e5c594b536e9fdd6ccaf7b19eaa1
S: 3c19f20c55947707daf854257ae7ec28b4e6a368 127.0.0.1:30006
replicates 9f18fe40c564959d9361d9bdf14107c22e645f49
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 127.0.0.1:30001)
M: 9f18fe40c564959d9361d9bdf14107c22e645f49 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 13e9aea7efe2e5c594b536e9fdd6ccaf7b19eaa1 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: dbeace86b8a39b14e34d5e09bd4c987a370adb3a 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 3c19f20c55947707daf854257ae7ec28b4e6a368 127.0.0.1:30006
slots: (0 slots) slave
replicates 9f18fe40c564959d9361d9bdf14107c22e645f49
S: 260c539eb22db89a6c1e5411d554afdc62686da3 127.0.0.1:30005
slots: (0 slots) slave
replicates 13e9aea7efe2e5c594b536e9fdd6ccaf7b19eaa1
S: dd6ade06fbd7ab5005e60f228fb6fa2257bdc082 127.0.0.1:30004
slots: (0 slots) slave
replicates dbeace86b8a39b14e34d5e09bd4c987a370adb3a
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
root@VM-2-10-ubuntu:/usr/local/src/redis-6.2.7/utils/create-cluster# redis-cli -c -p 30001
127.0.0.1:30001> set t1 12345
-> Redirected to slot [8943] located at 127.0.0.1:30002
OK
127.0.0.1:30002> set mytest1 username
-> Redirected to slot [1742] located at 127.0.0.1:30001
OK
127.0.0.1:30001> get t1
-> Redirected to slot [8943] located at 127.0.0.1:30002
"12345"
127.0.0.1:30002> get mytest1
-> Redirected to slot [1742] located at 127.0.0.1:30001
"username"
127.0.0.1:30001> quit
复制
测试集群
查看集群状态\停止主库\再次查看状态,操作\再启动原来的主库
root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/clu_7005# redis-cli -c -p 7000
127.0.0.1:7000> CLUSTER SLOTS
1) 1) (integer) 0
2) (integer) 5460
3) 1) "127.0.0.1"
2) (integer) 7000
3) "4ac4777badfc86d442f572114370618db7fa8f56"
4) 1) "127.0.0.1"
2) (integer) 7005
3) "b286ccca3af4209ed5a3584050d68478fbc79d24"
2) 1) (integer) 5461
2) (integer) 10922
3) 1) "127.0.0.1"
2) (integer) 7001
3) "0137527f43a2f44033c78dfa952c0bc7f53fd8fe"
4) 1) "127.0.0.1"
2) (integer) 7003
3) "4df501dfca85c2b1ee4e638cc9c5efe400549f2b"
3) 1) (integer) 10923
2) (integer) 16383
3) 1) "127.0.0.1"
2) (integer) 7002
3) "cdbce9ff41726164df568582886020613755405c"
4) 1) "127.0.0.1"
2) (integer) 7004
3) "dcc384d8b49540af89a42a9463943ce37a388aa6"
127.0.0.1:7000> exit
root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/clu_7005# redis-cli -c -p 7000 shutdown
[1] Done redis-server /usr/local/redis/cluster/cluster-test/clu_7000/redis_clsuter.conf (wd: /usr/local/redis/cluster/cluster-test/clu_7000)
(wd now: /usr/local/redis/cluster/cluster-test/clu_7005)
root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/clu_7005# redis-cli -c -p 7005
127.0.0.1:7005> CLUSTER SLOTS
1) 1) (integer) 0
2) (integer) 5460
3) 1) "127.0.0.1"
2) (integer) 7005
3) "b286ccca3af4209ed5a3584050d68478fbc79d24"
2) 1) (integer) 5461
2) (integer) 10922
3) 1) "127.0.0.1"
2) (integer) 7001
3) "0137527f43a2f44033c78dfa952c0bc7f53fd8fe"
4) 1) "127.0.0.1"
2) (integer) 7003
3) "4df501dfca85c2b1ee4e638cc9c5efe400549f2b"
3) 1) (integer) 10923
2) (integer) 16383
3) 1) "127.0.0.1"
2) (integer) 7002
3) "cdbce9ff41726164df568582886020613755405c"
4) 1) "127.0.0.1"
2) (integer) 7004
3) "dcc384d8b49540af89a42a9463943ce37a388aa6"
127.0.0.1:7005> set t1 1
-> Redirected to slot [8943] located at 127.0.0.1:7001
OK
127.0.0.1:7001> set t2 2
-> Redirected to slot [4748] located at 127.0.0.1:7005
OK
127.0.0.1:7005> set t3 3
OK
127.0.0.1:7005> set t4 4
-> Redirected to slot [12874] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set t5 5
-> Redirected to slot [8811] located at 127.0.0.1:7001
OK
127.0.0.1:7001> set t6 6
-> Redirected to slot [4616] located at 127.0.0.1:7005
OK
复制
启动原来主库7000:
root@VM-2-10-ubuntu:/usr/local/redis/cluster/cluster-test/clu_7000# redis-server /usr/local/redis/cluster/cluster-test/clu_7000/redis_clsuter.conf &
复制
7005实例日志:
622845:M 11 Aug 2022 10:53:08.220 * Replica 127.0.0.1:7000 asks for synchronization 622845:M 11 Aug 2022 10:53:08.220 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for 'a4bb91c6464ba85cce2c5e9ae75fa16f8d3287e7', my replication IDs are '2081849887c5c197af0af9c7bd7a06e3375fc108' and '94900cc118f0508084589f989051a58057ad4a98') 622845:M 11 Aug 2022 10:53:08.220 * Starting BGSAVE for SYNC with target: disk 622845:M 11 Aug 2022 10:53:08.220 * Background saving started by pid 623498 623498:C 11 Aug 2022 10:53:08.224 * DB saved on disk 623498:C 11 Aug 2022 10:53:08.224 * RDB: 0 MB of memory used by copy-on-write 622845:M 11 Aug 2022 10:53:08.269 * Background saving terminated with success 622845:M 11 Aug 2022 10:53:08.269 * Synchronization with replica 127.0.0.1:7000 succeeded 622845:M 11 Aug 2022 10:53:08.273 * Clear FAIL state for node 4ac4777badfc86d442f572114370618db7fa8f56: master without slots is reachable again.
复制
7000日志:
623491:C 11 Aug 2022 10:53:08.212 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 623491:C 11 Aug 2022 10:53:08.212 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=623491, just started 623491:C 11 Aug 2022 10:53:08.212 # Configuration loaded 623491:M 11 Aug 2022 10:53:08.212 * Increased maximum number of open files to 10032 (it was originally set to 1024). 623491:M 11 Aug 2022 10:53:08.212 * monotonic clock: POSIX clock_gettime 623491:M 11 Aug 2022 10:53:08.213 * Node configuration loaded, I'm 4ac4777badfc86d442f572114370618db7fa8f56 623491:M 11 Aug 2022 10:53:08.213 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. 623491:M 11 Aug 2022 10:53:08.213 * Running mode=cluster, port=7000. 623491:M 11 Aug 2022 10:53:08.213 # Server initialized 623491:M 11 Aug 2022 10:53:08.213 * Ready to accept connections 623491:M 11 Aug 2022 10:53:08.215 # Configuration change detected. Reconfiguring myself as a replica of b286ccca3af4209ed5a3584050d68478fbc79d24 623491:S 11 Aug 2022 10:53:08.215 * Before turning into a replica, using my own master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer. 623491:S 11 Aug 2022 10:53:08.215 * Connecting to MASTER 127.0.0.1:7005 623491:S 11 Aug 2022 10:53:08.215 * MASTER <-> REPLICA sync started 623491:S 11 Aug 2022 10:53:08.215 # Cluster state changed: ok 623491:S 11 Aug 2022 10:53:08.220 * Non blocking connect for SYNC fired the event. 623491:S 11 Aug 2022 10:53:08.220 * Master replied to PING, replication can continue... 623491:S 11 Aug 2022 10:53:08.220 * Trying a partial resynchronization (request a4bb91c6464ba85cce2c5e9ae75fa16f8d3287e7:1). 623491:S 11 Aug 2022 10:53:08.220 * Full resync from master: 2081849887c5c197af0af9c7bd7a06e3375fc108:163 623491:S 11 Aug 2022 10:53:08.221 * Discarding previously cached master state. 623491:S 11 Aug 2022 10:53:08.269 * MASTER <-> REPLICA sync: receiving 199 bytes from master to disk 623491:S 11 Aug 2022 10:53:08.269 * MASTER <-> REPLICA sync: Flushing old data 623491:S 11 Aug 2022 10:53:08.269 * MASTER <-> REPLICA sync: Loading DB in memory 623491:S 11 Aug 2022 10:53:08.272 * Loading RDB produced by version 6.2.7 623491:S 11 Aug 2022 10:53:08.272 * RDB age 0 seconds 623491:S 11 Aug 2022 10:53:08.272 * RDB memory usage when created 2.55 Mb 623491:S 11 Aug 2022 10:53:08.272 # Done loading RDB, keys loaded: 3, keys expired: 0. 623491:S 11 Aug 2022 10:53:08.273 * MASTER <-> REPLICA sync: Finished with success 623491:S 11 Aug 2022 10:53:08.273 * Background append only file rewriting started by pid 623500 623491:S 11 Aug 2022 10:53:08.299 * AOF rewrite child asks to stop sending diffs. 623500:C 11 Aug 2022 10:53:08.299 * Parent agreed to stop sending diffs. Finalizing AOF... 623500:C 11 Aug 2022 10:53:08.299 * Concatenating 0.00 MB of AOF diff received from parent. 623500:C 11 Aug 2022 10:53:08.299 * SYNC append only file rewrite performed 623500:C 11 Aug 2022 10:53:08.299 * AOF rewrite: 0 MB of memory used by copy-on-write 623491:S 11 Aug 2022 10:53:08.315 * Background AOF rewrite terminated with success 623491:S 11 Aug 2022 10:53:08.315 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB) 623491:S 11 Aug 2022 10:53:08.315 * Background AOF rewrite finished successfully
复制
查看redis集群状态:
127.0.0.1:7005> CLUSTER SLOTS 1) 1) (integer) 0 2) (integer) 5460 3) 1) "127.0.0.1" 2) (integer) 7005 3) "b286ccca3af4209ed5a3584050d68478fbc79d24" 4) 1) "127.0.0.1" 2) (integer) 7000 3) "4ac4777badfc86d442f572114370618db7fa8f56" 2) 1) (integer) 5461 2) (integer) 10922 3) 1) "127.0.0.1" 2) (integer) 7001 3) "0137527f43a2f44033c78dfa952c0bc7f53fd8fe" 4) 1) "127.0.0.1" 2) (integer) 7003 3) "4df501dfca85c2b1ee4e638cc9c5efe400549f2b" 3) 1) (integer) 10923 2) (integer) 16383 3) 1) "127.0.0.1" 2) (integer) 7002 3) "cdbce9ff41726164df568582886020613755405c" 4) 1) "127.0.0.1" 2) (integer) 7004 3) "dcc384d8b49540af89a42a9463943ce37a388aa6" 127.0.0.1:7005>
复制