1、Redis 集群介绍
1.1 引入
前面文章部署了redis主从,解决了redis单点问题,但是没有实现redis状态监控及故障自动切换,于是后来又引入了sentinel(哨兵)解决此问题。但是依然没能解决数据的并发读写问题,那么Redis 集群就是来解决此问题的,它是一个提供在多个Redis节点间共享数据的程序集。 Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下可以继续处理命令。
1.2 集群优点
自动分割数据到不同的节点上。
整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
要让集群正常运作至少需要三个主节点,为了实现主节点的高可用, 强烈建议使用六个节点: 其中三个为主节点, 而其余三个则是各个主节点的从节点。
1.3 集群工作原理
Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念。 Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。集群的每个节点负责一部分hash槽。举个例子,比如当前集群有3个节点,那么:
节点 A 包含 0 到 5460号哈希槽.,节点 B 包含5461到10922号哈希槽, 节点 C 包含10923到16383号哈希槽。 这种结构很容易添加或者删除节点,如果想新添加个节点D,需要从节点 A, B, C中分配部分槽到 D上,如果想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。
1.4 Redis 集群的主从复制模型
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型, 每个节点都会有N-1个复制品。 在上面具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会因为缺少5461到10922这个范围的槽而不可用。
然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1、B1、C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了,不过当B和B1 都失败后,集群仍然是不可用的。
2、Redis cluster 部署
2.1 创建redis实例
下面使用单台机器创建多个redis实例进行集群模拟。
首先可以选择创建一个新的 redis-cluster 目录,并在此目录中创建六个以端口号为名字的子目录,然后在每个目录中运行一个 Redis 实例, 命令如下:
# 创建redis-cluster目录:
mkdir /usr/local/redis-cluster/
cd /usr/local/redis-cluster/
# 创建六个实例目录:
mkdir 7000 7001 7002 7003 7004 7005
以下方式执行六次,创建六个redis实例
[root@localhost redis-cluster]# cp /usr/src/redis-5.0.5/redis.conf /usr/local/redis-cluster/7000/7000.conf
[root@localhost redis-cluster]# /usr/src/redis-5.0.5/utils/install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379] 7000
Please select the redis config file name [/etc/redis/7000.conf] /usr/local/redis-cluster/7000/7000.conf
Please select the redis log file name [/var/log/redis_7000.log] /usr/local/redis-cluster/7000/7000.log
Please select the data directory for this instance [/var/lib/redis/7000] /usr/local/redis-cluster/7000/
Please select the redis executable path [] /usr/local/redis/bin/redis-server
Selected config:
Port : 7000
Config file : /usr/local/redis-cluster/7000/7000.conf
Log file : /usr/local/redis-cluster/7000/7000.log
Data dir : /usr/local/redis-cluster/7000/
Executable : /usr/local/redis/bin/redis-server
Cli Executable : /usr/local/redis/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/7000.conf => /etc/init.d/redis_7000
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
2.2 开启redis集群模式
分别修改六个redis实例的配置文件
[root@localhost redis-cluster]# vim /usr/local/redis-cluster/7000/7000.conf
appendonly yes
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
2.3 启动redis实例
[root@localhost redis-cluster]# /usr/local/redis/bin/redis-server /usr/local/redis-cluster/7000/7000.conf
[root@localhost redis-cluster]# /usr/local/redis/bin/redis-server /usr/local/redis-cluster/7001/7001.conf
[root@localhost redis-cluster]# /usr/local/redis/bin/redis-server /usr/local/redis-cluster/7002/7002.conf
[root@localhost redis-cluster]# /usr/local/redis/bin/redis-server /usr/local/redis-cluster/7003/7003.conf
[root@localhost redis-cluster]# /usr/local/redis/bin/redis-server /usr/local/redis-cluster/7004/7004.conf
[root@localhost redis-cluster]# /usr/local/redis/bin/redis-server /usr/local/redis-cluster/7005/7005.conf
2.4 搭建集群
现在已经有了六个正在运行中的 Redis 实例, 接下来就可以直接使用这些实例来创建集群, 并为每个节点编写配置文件。如果使用的是Redis 5的版本,可以直接使用redis-cli命令创建新集群,检查或重新硬化现有集群等等。对于Redis版本3或4,使用redis-trib.rb创建集群,它是一个Ruby程序。可以在Redis源代码的src目录找到它。
# --cluster-replicas 1 创建副本级,表示为集群中的每个主节点创建一个从节点。
#其中指定了6个redis的ip:port,3个master3个slave。 命令回车执行后,当我们输入yes,redis-cli就会将这份配置应用到集群当中,让各个节点开始互相通讯,最后可以得到如下信息:
[root@localhost redis-cluster]# /usr/local/redis/bin/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: 8297cbf316bdedb66ecc86279f567cbb170d1e66 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
M: 1025b46b6a7aa0232668a74750296a35e9d622ad 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
M: bde56c5a2c993221d52739e702d5092d5e2f6e18 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
S: 4133c463306ee40a9592b186e0c490f1517751ad 127.0.0.1:7003
replicates 1025b46b6a7aa0232668a74750296a35e9d622ad
S: f82e71428976764275e344fff452564f55728683 127.0.0.1:7004
replicates bde56c5a2c993221d52739e702d5092d5e2f6e18
S: 79b81b6cbddde8160e4f5ff9b3a16bd7ddab95c1 127.0.0.1:7005
replicates 8297cbf316bdedb66ecc86279f567cbb170d1e66
# 输入yes
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 fo