【赵渝强老师】Redis Cluster分布式集群
主从复制是Redis集群实现的一种方式,而Redis集群的另一种实现方式就是Redis Cluster。它是Redis提供的数据分布式存储解决方案。
一、 什么是Redis Cluster?
日常在对于Redis的使用中经常会遇到一些问题,例如:如何保证Redis的持续高可用性?如何实现单实例Redis扩充?如何提升高并发时的性能问题?针对这些问题,在Redis 3.0版本中推出了Redis Cluster。它是Redis的分布式解决方案,并有效解决了Redis分布式方面的需求。当遇到单机的内存、并发和流量等瓶颈时,可以采用Redis Cluster架构达到负载均衡的目的。Redis Cluster主要具有以下的优势:
- 官方推荐,毋庸置疑。
- 去中心化,集群最大可增加1000个节点,性能随节点增加而线性扩展。
- 管理方便,后续可自行增加或摘除节点,移动分槽等等。
- 简单,易上手。
二、 Redis Cluster的体系架构
分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。常见的分区规则有哈希分区和顺序分区。Redis Cluster采用哈希分区规则。哈希分区的原理如下图所示。
虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。比如Redis Cluster槽的范围是0 ~ 16383。槽是集群内数据管理和迁移的基本单位。
Redis Cluster采用虚拟槽分区,所有的键根据哈希函数映射到0 ~ 16383,计算公式:slot = CRC16(key)&16383。每一个节点负责维护一部分槽以及槽所映射的键值数据。以6个节点为例,来介绍Redis Cluster的体系架构,其中:三个为master节点,另外三个为slave节点。体系架构如下图所示。
视频讲解如下 |
---|
【赵渝强老师】Redis Cluster集群的架构 |
三、 部署Redis Cluster
部署Redis Cluster可以通过手动编辑配置文件来完成,这种方式比较灵活也是在生产环境中使用的方式;另一方面,Redis提供了一个命令脚本create-cluster帮助快速部署一个Redis Cluster,但这种方式多用于开发和测试环境中。
3.1 【实战】手动部署Redis Cluster
(1)复制6份Redis的配置文件。
cp redis.conf /root/training/redis/conf/redis6379.conf
cp redis.conf /root/training/redis/conf/redis6380.conf
cp redis.conf /root/training/redis/conf/redis6381.conf
cp redis.conf /root/training/redis/conf/redis6382.conf
cp redis.conf /root/training/redis/conf/redis6383.conf
cp redis.conf /root/training/redis/conf/redis6384.conf
(2)以redis6379.conf为例修改配置文件的内容,需要修改的参数如下:
daemonize yes
port 6379
cluster-enabled yes
cluster-config-file nodes/nodes-6379.conf
cluster-node-timeout 15000
dbfilename dump6379.rdb
appendonly yes
appendfilename "appendonly6379.aof"
(3)按照同样的方式修改其他的Redis Cluster配置文件,如redis6380.conf的修改内容如下:
daemonize yes
port 6380
cluster-enabled yes
cluster-config-file nodes/nodes-6380.conf
cluster-node-timeout 15000
dbfilename dump6380.rdb
appendonly yes
appendfilename "appendonly6380.aof"
(4)创建Redis Cluster节点配置信息保存的目录。
mkdir /root/training/redis/nodes
(5)启动所有的Redis实例。
bin/redis-server conf/redis6379.conf
bin/redis-server conf/redis6380.conf
bin/redis-server conf/redis6381.conf
bin/redis-server conf/redis6382.conf
bin/redis-server conf/redis6383.conf
bin/redis-server conf/redis6384.conf
(6)通过ps命令确定Redis实例的进程信息。
ps -ef|grep redis# 输出的信息如下:
root 5383 ... bin/redis-server 127.0.0.1:6379 [cluster]
root 5385 ... bin/redis-server 127.0.0.1:6380 [cluster]
root 5387 ... bin/redis-server 127.0.0.1:6381 [cluster]
root 5397 ... bin/redis-server 127.0.0.1:6382 [cluster]
root 5403 ... bin/redis-server 127.0.0.1:6383 [cluster]
root 5413 ... bin/redis-server 127.0.0.1:6384 [cluster]
(7)初始化Redis Cluster。
bin/redis-cli --cluster create --cluster-replicas 1 \
127.0.0.1:6379 \
127.0.0.1:6380 \
127.0.0.1:6381 \
127.0.0.1:6382 \
127.0.0.1:6383 \
127.0.0.1:6384 # 输出的信息如下:
>>> 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:6383 to 127.0.0.1:6379
Adding replica 127.0.0.1:6384 to 127.0.0.1:6380
Adding replica 127.0.0.1:6382 to 127.0.0.1:6381
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 24840361406aa8ba5ab2d03f28bdb21dd5362d4f 127.0.0.1:6379slots:[0-5460] (5461 slots) master
M: 8aba2fafcfa5161315ff1dd645db3b75607128a6 127.0.0.1:6380slots:[5461-10922] (5462 slots) master
M: 41780e8f30a91c644cfec889bfce6cb02f977943 127.0.0.1:6381slots:[10923-16383] (5461 slots) master
S: 97119cfb5c5cc8eea385a8aca9b665f1498bced4 127.0.0.1:6382replicates 24840361406aa8ba5ab2d03f28bdb21dd5362d4f
S: 9abfeb7da0d9f8017ea5de5114b5bd57a0b8f851 127.0.0.1:6383replicates 8aba2fafcfa5161315ff1dd645db3b75607128a6
S: a1b8e2ab26a4b7c9ec20c62e61992e9efca39476 127.0.0.1:6384replicates 41780e8f30a91c644cfec889bfce6cb02f977943# 下面这里输入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 for the cluster to join>>> Performing Cluster Check (using node 127.0.0.1:6379)
M: 24840361406aa8ba5ab2d03f28bdb21dd5362d4f 127.0.0.1:6379slots:[0-5460] (5461 slots) master1 additional replica(s)
S: a1b8e2ab26a4b7c9ec20c62e61992e9efca39476 127.0.0.1:6384slots: (0 slots) slavereplicates 41780e8f30a91c644cfec889bfce6cb02f977943
S: 97119cfb5c5cc8eea385a8aca9b665f1498bced4 127.0.0.1:6382slots: (0 slots) slavereplicates 24840361406aa8ba5ab2d03f28bdb21dd5362d4f
M: 8aba2fafcfa5161315ff1dd645db3b75607128a6 127.0.0.1:6380slots:[5461-10922] (5462 slots) master1 additional replica(s)
M: 41780e8f30a91c644cfec889bfce6cb02f977943 127.0.0.1:6381slots:[10923-16383] (5461 slots) master1 additional replica(s)
S: 9abfeb7da0d9f8017ea5de5114b5bd57a0b8f851 127.0.0.1:6383slots: (0 slots) slavereplicates 8aba2fafcfa5161315ff1dd645db3b75607128a6
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
(8)使用Redis客户端连接Redis Cluster。
bin/redis-cli -c
(9)查看Redis Cluster的统计信息。
127.0.0.1:6379> cluster info# 输出的信息如下:
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:152
cluster_stats_messages_pong_sent:151
cluster_stats_messages_sent:303
cluster_stats_messages_ping_received:146
cluster_stats_messages_pong_received:152
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:303
3.2 【实战】使用脚本部署Redis Cluster
(1)进入Redis源码的utils/create-cluster目录,将脚本create-cluster复制到Redis安装目录的bin目录下。
cd /root/tools/redis-6.2.6/utils/create-cluster
cp create-cluster /root/training/redis/bin/
(2)查看脚本create-cluster的内容。
more /root/training/redis/bin/create-cluster# 输出的信息如下:
#!/bin/bash# Settings
BIN_PATH="/root/training/redis/bin"
CLUSTER_HOST=127.0.0.1
PORT=30000
TIMEOUT=2000
NODES=6
REPLICAS=1
PROTECTED_MODE=yes
ADDITIONAL_OPTIONS=""
......
(3)编辑脚本create-cluster设置Redis的bin路径。
......
# Settings
BIN_PATH="/root/training/redis/bin"
......
(4)启动Redis Cluster的节点。
bin/create-cluster start# 输出的信息如下:
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
(5)通过ps命令查看Redis的后台进程信息。
ps -ef |grep redis-server# 输出的信息如下:
... 4398 ... /root/training/redis/bin/redis-server *:30001 [cluster]
... 4400 ... /root/training/redis/bin/redis-server *:30002 [cluster]
... 4402 ... /root/training/redis/bin/redis-server *:30003 [cluster]
... 4412 ... /root/training/redis/bin/redis-server *:30004 [cluster]
... 4418 ... /root/training/redis/bin/redis-server *:30005 [cluster]
... 4424 ... /root/training/redis/bin/redis-server *:30006 [cluster]
(6)初始化Redis Cluster。
bin/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: 2b348de30e8145e8d6c5eb3e1d1a38b1ccb6b147 127.0.0.1:30001slots:[0-5460] (5461 slots) master
M: 39b81f4a37933ae7805c3f611ddb869acc8446a4 127.0.0.1:30002slots:[5461-10922] (5462 slots) master
M: 804594da6fb9338610737086e3f1d9bcdba3944e 127.0.0.1:30003slots:[10923-16383] (5461 slots) master
S: 6cae403b057c7e4e17f86d78c245a8bf7358287c 127.0.0.1:30004replicates 39b81f4a37933ae7805c3f611ddb869acc8446a4
S: 405154d64389b69335fab2cb1e029aa29344d7de 127.0.0.1:30005replicates 804594da6fb9338610737086e3f1d9bcdba3944e
S: 27039bdc08fcb9452ba009adaf31db28d184a528 127.0.0.1:30006replicates 2b348de30e8145e8d6c5eb3e1d1a38b1ccb6b147# 下面这里输入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 for the cluster to join>>> Performing Cluster Check (using node 127.0.0.1:30001)
M: 2b348de30e8145e8d6c5eb3e1d1a38b1ccb6b147 127.0.0.1:30001slots:[0-5460] (5461 slots) master1 additional replica(s)
M: 804594da6fb9338610737086e3f1d9bcdba3944e 127.0.0.1:30003slots:[10923-16383] (5461 slots) master1 additional replica(s)
S: 6cae403b057c7e4e17f86d78c245a8bf7358287c 127.0.0.1:30004slots: (0 slots) slavereplicates 39b81f4a37933ae7805c3f611ddb869acc8446a4
S: 27039bdc08fcb9452ba009adaf31db28d184a528 127.0.0.1:30006slots: (0 slots) slavereplicates 2b348de30e8145e8d6c5eb3e1d1a38b1ccb6b147
M: 39b81f4a37933ae7805c3f611ddb869acc8446a4 127.0.0.1:30002slots:[5461-10922] (5462 slots) master1 additional replica(s)
S: 405154d64389b69335fab2cb1e029aa29344d7de 127.0.0.1:30005slots: (0 slots) slavereplicates 804594da6fb9338610737086e3f1d9bcdba3944e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
(7)使用Redis客户端连接Redis Cluster
bin/redis-cli -c -p 30001
(8)查看Redis Cluster的统计信息。
127.0.0.1:30001> cluster info# 输出的信息如下:
cluster_state:ok 集群状态
cluster_slots_assigned:16384 已分配的slot数量
cluster_slots_ok:16384 ok状况的slot数量
cluster_slots_pfail:0 可能失效的slot数量
cluster_slots_fail:0 已失效的slot数量
cluster_known_nodes:6 集群中节点的数量
cluster_size:3 分片的数量
cluster_current_epoch:6 集群中的版本数量。
cluster_my_epoch:1 当前节点的版本数。
cluster_stats_messages_ping_sent:478 发送ping数量
cluster_stats_messages_pong_sent:480 发送pong数量
cluster_stats_messages_sent:958 总发送的数量
cluster_stats_messages_ping_received:475 接收ping数量
cluster_stats_messages_pong_received:478 接收pong数量
cluster_stats_messages_received:958 总接收数量