Redis Cluster 即 Redis 集群,是 Redis 官方在 3.0 版本推出的一套分布式存储方案。完全去中心化,由多个节点组成,所有节点彼此互联。Redis 客户端可以直接连接任何一节点获取集群中的键值对,不需要中间代理,如果该节点不存在用户所指定的键值,其内部会自动把客户端重定向到键值所在的节点。
Redis 集群是一个网状结构,每个节点都通过 TCP 连接跟其他每个节点连接。在一个有 N 个节点的集群中,每个节点都有 N-1 个流出的 TCP 连接,和 N-1 个流入的连接,这些 TCP 连接会永久保持。
Redis Cluster 同其他分布式存储系统一样,主要具备以下两个功能
16384
个哈希槽slot,同时会根据节点的数量大致均等的将 16384 个哈希槽映射到不同的节点上。当用户存储key-value时,集群会先对key进行 CRC16 校验然后对 16384 取模来决定key-value放置哪个槽,从而实现自动分割数据到不同的节点上。关于 Redis Cluster 详细介绍以及实现原理请参见 Redis Cluster 教程 和 Redis Cluster 规范,在此不再赘述。
https://redis.io/topics/cluster-tutorial
https://redis.io/topics/cluster-spec
实验环境信息:
Linux 版本:CentOS Linux release 7.9.2009
Redis 版本:5.0.9
先在服务器或虚拟机中安装一个单机 Redis,如果已安装可以跳过本节,未安装过的正好学习下。
进入 Redis 待安装目录。
cd /usr/local
下载、解压 Redis 源代码压缩包
wget http://download.redis.io/releases/redis-5.0.9.tar.gz tar -zxvf redis-5.0.9.tar.gz
然后进入解压后的目录并使用 make 命令执行编译安装 Redis。
cd redis-5.0.9 make && make install
不要高兴,因为你极有可能会遇到因为 GCC 编译器未安装导致编译失败的情况。不要着急,请顺序执行如下命令。
yum -y install gcc make distclean make && make install
Redis 基于 C 语言开发,故编译源码需要 GCC(Linux下的一个编译器,这里需要用来编译.c文件)的支持。如机器上未安装需要先执行命令yum -y install gcc安装 GCC 编译工具,然后make distclean清除之前生成的文件,最后make && make install重新编译安装。
最终出现类似下文输出则表示 Redis 安装成功。
如果源码编译无误且执行结果正确,make install命令会将程序安装至系统预设的可执行文件存放路径,一般是/usr/local/bin目录,可以通过如下终端输出确认。当然,也可以使用make install PREFIX=
[root@localhost redis-5.0.9]# cd /usr/local/bin [root@localhost bin]# ll 总用量 32772 -rwxr-xr-x. 1 root root 4367088 6月 16 16:53 redis-benchmark -rwxr-xr-x. 1 root root 8125392 6月 16 16:53 redis-check-aof -rwxr-xr-x. 1 root root 8125392 6月 16 16:53 redis-check-rdb -rwxr-xr-x. 1 root root 4808080 6月 16 16:53 redis-cli lrwxrwxrwx. 1 root root 12 6月 16 16:53 redis-sentinel -> redis-server -rwxr-xr-x. 1 root root 8125392 6月 16 16:53 redis-server
至此,单机 Redis 安装完成
依据 Redis Cluster 内部故障转移实现原理,Redis 集群至少需要 3 个主节点,而每个主节点至少有 1 从节点,因此搭建一个集群至少包含 6 个节点,三主三从,并且分别部署在不同机器上。
目前 Redis Cluster 的搭建有两种方式:
两种方式原理一样,自动搭建方式只是将手动搭建方式中需要执行的 Redis 命令封装到了可执行程序。生产环境下推荐使用第二种方式,简单快捷,不易出错。不过本文实战演示两种方式都会提及。
搭建集群的第一步就是要先把参与搭建集群的每个节点启动起来。
准备192.168.108.11、192.168.108.12、192.168.108.13、192.168.108.14、192.168.108.15、192.168.108.16
六台服务器,其中11、12、13为主节点其他三台为从节点。
根据上述规划,可以先通过如下命令创建各个节点启动配置文件的存放目录
mkdir /usr/local/redis-cluster
进入 Redis 源码包目录并将默认配置文件redis.conf分别复制到节点配置存放目录中,作为各自节点启动配置文件
cd /usr/local/redis-5.0.9 cp redis.conf /usr/local/redis-cluster
接下来需要分别修改每个节点的配置文件。下面贴的是节点11的配置文件/usr/local/redis-cluster/redis.conf
中启用或修改的一些必要参数,其他节点参照修改
bind 192.168.108.11 # 设置当前节点主机地址 port 6379 # 设置客户端连接监听端口 pidfile /var/run/redis_6379.pid # 设置 Redis 实例 pid 文件 daemonize yes # 以守护进程运行 Redis 实例 cluster-enabled yes # 启用集群模式 cluster-node-timeout 15000 # 设置当前节点连接超时毫秒数 cluster-config-file nodes-6379.conf # 设置当前节点集群配置文件路径
完成上述工作就可以通过如下命令启动待搭建集群中的 6 个节点了。
/usr/local/bin/redis-server /usr/local/redis-cluster/redis.conf
最后通过ps -ef|grep redis命令确认各个节点服务是否已经正常运行。
如上输出可以看出11节点已启动成功,同理查看其他节点,保证6个节点全部启动成功。
虽然上面 6 个节点都启用了群集支持,但默认情况下它们是不相互信任或者说没有联系的。节点握手就是在各个节点之间创建链接(每个节点与其他节点相连),形成一个完整的网格,即集群。
节点握手的命令如下:
cluster meet ip port
但为了创建群集,不需要发送形成完整网格所需的所有 cluster meet 命令。只要能发送足够的cluster meet消息,可以让每个节点都可以通过一系列已知节点到达每个其他节点,缺失的链接将被自动创建。
例如,如果我们通过cluster meet将节点 A 与节点 B 连接起来,并将 B 与 C 连接起来,则 A 和 C 会自己找到握手方式并创建链接。
我们的创建的 6 个节点可以通过 redis-cli 连接到 11 节点执行如下五组命令完成握手。
cluster meet 192.168.108.12 6379 cluster meet 192.168.108.13 6379 cluster meet 192.168.108.14 6379 cluster meet 192.168.108.15 6379 cluster meet 192.168.108.16 6379
如上述命令正常执行输出结果如下。
接下来可以通过 cluster nodes
命令查看节点之间 的链接状态。我随机找了两个节点 12 和 13 测试,输出结果如下所示。
/usr/local/bin/redis-cli -h 192.168.108.12 cluster nodes
可以看到,节点 12 和节点 13 都已经分别和其他 5 个节点建立链接。
至此,节点握手完成。
此时 Redis 集群还并没有处于上线状态,可以在任意一节点上执行 cluster info 命令来查看目前集群的运行状态。
上面输出cluster_state:fail表示当前集群处于下线状态。因为只有给集群中所有主节点分配好槽位(即哈希槽slot,本文第一小节有提及)集群才能上线。
分配槽位的命令如下:
cluster addslots slot [slot …]
根据预先规划,这一步需要使用 cluster addslots 命令手动将 16384 个哈希槽大致均等分配给主节点 11、12、13。
在11上执行
/usr/local/bin/redis-cli -h 192.168.108.11 cluster addslots {0..5461}
在12上执行
/usr/local/bin/redis-cli -h 192.168.108.12 cluster addslots {5462..10922}
在13上执行
/usr/local/bin/redis-cli -h 192.168.108.13 cluster addslots {10923..16383}
上面三组命令执行完毕,可以再次查看目前集群的一些运行参数。
如上输出cluster_state:ok证明 Redis 集群成功上线。
Redis 集群成功上线,不过还没有给主节点指定从节点,此时如果有一个节点故障,那么整个集群也就挂了,也就无法实现高可用。详细了解点这里:Redis主从复制以及主从复制原理
集群中需要使用 cluster replicate 命令手动给从节点配置主节点。
集群复制命令如下:
cluster replicate node-id
集群中各个节点的node-id可以用cluster nodes
命令查看,如下输出6c262f4d37b8a3cc795ea9add82727e37a3ef7ab即是主节点 11 的node-id。
根据预先规划,11主14从;12主15从;13主16从。执行如下三组命令分别为从节点 14、15、16 指定其主节点,使群集可以自动完成主从复制。
/usr/local/bin/redis-cli -h 192.168.108.14 cluster replicate 6c262f4d37b8a3cc795ea9add82727e37a3ef7ab /usr/local/bin/redis-cli -h 192.168.108.15 cluster replicate e6a8952c2deaed325b0afbb67d36724ed516f71d /usr/local/bin/redis-cli -h 192.168.108.16 cluster replicate 1fe02ba68c2b8cc59accf2369d987e5eae402e7d
命令执行成功后,我们便算以手动方式成功搭建了一个 Redis 集群。
最后,再来查看一下集群中的节点信息。
Redis 3.0 版本之后官方发布了一个集群管理工具 redis-trib.rb,集成在 Redis 源码包的src目录下。其封装了 Redis 提供的集群命令,使用简单、便捷。
不过 redis-trib.rb 是 Redis 作者使用 Ruby 语言开发的,故使用该工具之前还需要先在机器上安装 Ruby 环境。后面作者可能意识到这个问题,Redis 5.0 版本开始便把这个工具集成到 redis-cli 中,以–cluster参数提供使用,其中create命令可以用来创建集群。
启动节点
使用集群管理工具搭建集群之前,也是需要先把各个节点启动起来的。节点的启动方式请参见本文「手动方式创建」-「启动节点」一节,此处不再赘述。
集群管理工具搭建
如果您安装的 Redis 是 3.x 和 4.x 的版本可以使用 redis-trib.rb 搭建,不过之前需要安装 Ruby 环境。
先使用 yum 安装 Ruby 环境以及其他依赖项。
yum -y install ruby ruby-devel rubygems rpm-build
确认安装版本。
[root@localhost redis-cluster]# ruby -v ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
再使用 redis-trib.rb 脚本搭建集群,具体命令如下所示。
/usr/local/redis-5.0.3/src/redis-trib.rb create --replicas 1 192.168.108.11:6379 192.168.108.12:6379 192.168.108.13:6379 192.168.108.14:6379 192.168.108.15:6379 192.168.108.16:6379
不过,本文实验环境使用的 Redis 版本是 5.0.9,所以我可以直接使用redis-cli --cluster create命令搭建,具体命令如下所示。
/usr/local/bin/redis-cli --cluster create 192.168.108.11:6379 192.168.108.12:6379 192.168.108.13:6379 192.168.108.14:6379 192.168.108.15:6379 192.168.108.16:6379 --cluster-replicas 1
主节点在前,从节点在后。其中–cluster-replicas参数用来指定一个主节点带有的从节点个数,如上–cluster-replicas 1即表示 1 个主节点有 1 个从节点。
命令执行成功会有类似如下输出。
OK,搭建完成!一条命令搞定
快速搭建分布式缓存 Redis 集群