Redis部署集群详解(附带实例)
Redis 集群是一个分布式的、容错的内存键值对服务,集群模式可以使用普通单机模式下 Redis 所能使用的功能的一个子集。例如,Redis 集群并不支持处理多个键的命令。
Redis 集群有以下几个重要特征:

图 1 Redis 集群的架构
可以看出,Redis 集群有以下几个细节:
1) 准备节点。Redis 集群一般由不少于 6 个的节点组成,因为这样才能保证集群的高可用。每个节点需要启动 cluster-enabled yes 配置,让其 Redis 运行在集群模式下。
注意,建议让集群内所有节点的目录保持一致,一般包括 3 个目录:conf、data、log,分别存储配置信息、数据和日志相关文件。我们以 6 个节点为例,将它们的配置信息统一存储在 conf 目录下。
2) 创建 Redis 各实例目录,代码如下:
3) Redis 配置文件管理,代码如下:
配置 redis-6379.conf,代码如下:
4) 准备部署环境。首先,安装 Ruby 环境,代码如下:
然后,准备 rubygem redis 依赖,代码如下:
最后,拷贝 redis-trib.rb 文件到集群根目录。redis-trib.rb 文件是 Redis 官方推出的管理 Redis 集群的工具,集成在 Redis 的源码 rc 目录下,能够将 Redis 提供的集群命令封装成简单、便捷、实用的操作工具。
5) 安装集群。启动 Redis 节点,执行如下命令。至此,Redis 将以集群模式进行启动。
代码如下:
具体示例如下:
Redis 集群有以下几个重要特征:
- Redis 集群的分片特征体现在将键空间分拆了 16384 个槽位,每一个节点负责其中一些槽位;
- Redis 提供一定程度的可用性,在某个节点死机或者不可达的情况下,可以使用其他节点来正常工作。只要集群中大多数 Master 节点可达且失效的 Master 节点下至少有一个 Slave 节点可达,集群都是可用;
- Redis 集群中不存在中心节点或者代理节点,具有线性可扩展性。
Redis集群的架构
Redis 集群的架构如下图所示:
图 1 Redis 集群的架构
可以看出,Redis 集群有以下几个细节:
- Redis 集群中的所有节点彼此互联(通过 Ping-Pong 机制),集群内部使用二进制协议优化传输速度和带宽;
- 节点的失效状态只有当集群中超过半数的节点检测失效时才会生效;
- 客户端与 Redis 节点的连接不需要代理层,也不需要连接集群所有节点,而是连接集群中任何一个可用节点即可;
- Redis 集群把所有的物理节点映射到 0~16383 槽位上,并负责维护。
部署Redis集群模式
部署 Redis 集群模式的步骤如下:1) 准备节点。Redis 集群一般由不少于 6 个的节点组成,因为这样才能保证集群的高可用。每个节点需要启动 cluster-enabled yes 配置,让其 Redis 运行在集群模式下。
注意,建议让集群内所有节点的目录保持一致,一般包括 3 个目录:conf、data、log,分别存储配置信息、数据和日志相关文件。我们以 6 个节点为例,将它们的配置信息统一存储在 conf 目录下。
2) 创建 Redis 各实例目录,代码如下:
$ sudo mkdir -p /usr/local/redis-cluster $ cd /usr/local/redis-cluster $ sudo mkdir conf data log $ sudo mkdir -p data/redis-6379 data/redis-6389 data/redis-6380 data/redis-6390 data/redis-6381 data/redis-6391
3) Redis 配置文件管理,代码如下:
# Redis后台运行 daemonize yes # 绑定的主机端口 bind 127.0.0.1 # 数据存储目录 dir /usr/local/redis-cluster/data/redis-6379 # 进程文件 pidfile /var/run/redis-cluster/${自定义}.pid # 日志文件 logfile /usr/local/redis-cluster/log/${自定义}.log # 端口号 port 6379 # 开启集群模式,把注释符号#去掉 cluster-enabled yes # 集群的配置,配置文件首次启动时会自动生成 cluster-config-file /usr/local/redis-cluster/conf/${自定义}.conf # 请求超时,设置时间为10 s cluster-node-timeout 10000 # 开启aof日志 appendonly yes
配置 redis-6379.conf,代码如下:
daemonize yes bind 127.0.0.1 dir /usr/local/redis-cluster/data/redis-6379 pidfile /var/run/redis-cluster/redis-6379.pid logfile /usr/local/redis-cluster/log/redis-6379.log port 6379 cluster-enabled yes cluster-config-file /usr/local/redis-cluster/conf/node-6379.conf cluster-node-timeout 10000 appendonly yes
4) 准备部署环境。首先,安装 Ruby 环境,代码如下:
$ sudo brew install ruby
然后,准备 rubygem redis 依赖,代码如下:
$ sudo gem install redis Password: Fetching: redis-4.0.2.gem (100%) Successfully installed redis-4.0.2 Parsing documentation for redis-4.0.2 Installing ri documentation for redis-4.0.2 Done installing documentation for redis after 1 seconds 1 gem installed
最后,拷贝 redis-trib.rb 文件到集群根目录。redis-trib.rb 文件是 Redis 官方推出的管理 Redis 集群的工具,集成在 Redis 的源码 rc 目录下,能够将 Redis 提供的集群命令封装成简单、便捷、实用的操作工具。
$ sudo cp /usr/local/redis-4.0.11/src/redis-trib.rb /usr/local/redis-cluster # 查看 redis-trib.rb 命令环境是否正确,输出如下内容 $ ./redis-trib.rb Usage: redis-trib <command> <options> <arguments...> create host1:port1 ... hostN:portN --replicas <arg> check host:port info host:port fix host:port --timeout <arg> reshard host:port --from <arg> --to <arg> --slots <arg> --yes --timeout <arg> --pipeline <arg> rebalance host:port --weight <arg> --auto-weights --use-empty-masters --timeout <arg> --simulate --pipeline <arg> --threshold <arg> add-node new_host:new_port existing_host:existing_port --slave --master-id <arg> del-node host:port node_id set-timeout host:port milliseconds call host:port command arg arg .. arg import host:port --from <arg> --copy --replace help (show this help)方法
5) 安装集群。启动 Redis 节点,执行如下命令。至此,Redis 将以集群模式进行启动。
sudo redis-server conf/redis-6379.conf sudo redis-server conf/redis-6389.conf sudo redis-server conf/redis-6380.conf sudo redis-server conf/redis-6390.conf sudo redis-server conf/redis-6381.conf sudo redis-server conf/redis-6391.conf
Redis集群模式应用
1) 关联集群节点
Redis 集群包含的 6 个节点按照从主到从的顺序依次排序后,redis-trib 先将 16384 个哈希槽(哈希槽的实质是数组空间)分配给 3 个 Master 节点,然后让各个 Slave 节点指向 Master 节点,进行数据同步。代码如下:
# 指定任意一个节点作为redis服务器 >>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 Adding replica 127.0.0.1:6390 to 127.0.0.1:6379 Adding replica 127.0.0.1:6391 to 127.0.0.1:6380 Adding replica 127.0.0.1:6389 to 127.0.0.1:6381
2) 同步Master节点的日志
Slave 节点(redis-6389)通过 BGSAVE 命令,在后台异步地从 Master 节点(redis-6379)进行数据同步。代码如下:$ cat log/redis-6379.log 1907:C 05 Sep 16:59:52.960 # Redis正在启动 1907:C 05 Sep 16:59:52.961 # Redis 版本为4.0.11, 字节为 = 64 bit, 没有修改文本,进程号是1907 1907:C 05 Sep 16:59:52.961 # 加载配置文件 1908:M 05 Sep 16:59:52.964 * Increased maximum number of open files to 10032 (it was originally set to 256). 1908:M 05 Sep 16:59:52.965 * No cluster configuration found, I'm ad4b9ffceba062 492ed67ab336657426f55874b7 1908:M 05 Sep 16:59:52.967 * 运行模式为Cluster, 端口号为6379. 1908:M 05 Sep 16:59:52.967 # 服务初始化 1908:M 05 Sep 16:59:52.967 * 准备接受连接 1908:M 05 Sep 17:01:17.782 # 通过CLUSTER SET-CONFIG-EPOCH设置配置迭代为1 1908:M 05 Sep 17:01:17.812 # IP地址更新为127.0.0.1 1908:M 05 Sep 17:01:22.740 # 保存集群状态 1908:M 05 Sep 17:01:23.681 * Slave 127.0.0.1:6389 asks for synchronization 1908:M 05 Sep 17:01:23.681 * Partial resynchronization not accepted: Replication ID mismatch (Slave asked for '4c5afe96cac51cde56039f96383ea7217ef2af41', my r eplication IDs are '037b661bf48c80c577d1fa937ba55367a3692921' and '000000000000 0000000000000000000000000000') 1908:M 05 Sep 17:01:23.681 * Starting BGSAVE for SYNC with target: disk 1908:M 05 Sep 17:01:23.682 * Background saving started by pid 1952 1952:C 05 Sep 17:01:23.683 * DB saved on disk 1908:M 05 Sep 17:01:23.749 * Background saving terminated with success 1908:M 05 Sep 17:01:23.752 * Synchronization with slave 127.0.0.1:6389 succeeded
3) 检测Redis集群的完整性
使用 redis-trib.rb check 命令检测所创建的集群是否成功,该命令只需要集群中任意一个节点的 IP 地址,便可以完成整个集群完整性的检查工作。具体示例如下:
$ ./redis-trib.rb check 127.0.0.1:6379 #当最后输出如下信息,提示集群所有的槽都已分配到节点 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.