以下是我的个人学习总结,如果想深入学习,请参考下面两个文档:
中文文档
官方文档
简介
Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。
Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令。
Redis 集群的优势:
- 自动分割数据到不同的节点上。
- 整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
Redis集群的数据分片
Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念。
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取余来决定放置哪个槽,集群的每个节点负责一部分哈希槽。这种结构很方便添加或删除节点。
一个例子:
假如有三个节点 A、B、C,每个节点都负责一部分哈希槽,当添加个新的节点D进去,则需要从A、B、C中取出部分哈希槽分配给D,反之,当删除节点D时,则需要将D负责的哈希槽移到A、B、C节点上,最后将D节点从集群中移除即可。
这样子做有一个好处,对节点的删除和添加实际上是在移动哈希槽(或者说在改变某个节点的哈希槽数量),这不会导致集群处于不可用的状态。
Redis Cluster 集群搭建
这里使用手动部署Redis集群的方式,如果要尽快建立集群并允许,可以参考官方文档的使用create-cluster脚本创建Redis集群相关介绍。
注意:最小群集要求至少包含三个主节点,同时每个主节点都至少有一个从节点
准备配置文件
官方给出的最小Redis集群配置文件:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
当然我们实际上不只要配置上面的配置,还有其他配置需要更改,如下:
protected-mode no # 关闭保护模式 用于公网访问
port 7000
cluster-enabled yes # 开启集群模式
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes # 后台启动
pidfile /var/run/redis_7000.pid
logfile "7000.log"
#dir /redis/data
#bind 127.0.0.1
masterauth 123456 # 设置连接主节点密码
requirepass 123456 # 设置redis密码,各个节点密码保持一致
搭建流程
-
创建Redis节点安装目录
mkdir -p /usr/local/redis_cluster # -p 表示目录不存在就创建目录
-
在redis_cluster目录下,创建6个文件夹,分别命名7000、7001、7002、7003、7004、7005
mkdir 7000 7001 7002 7003 7004 7005
- 修改redis.conf配置文件
cp /opt/redis-5.0.7/redis.conf /usr/local/redis_cluster/7000
cd /usr/local/redis_cluster/7000
vim redis.conf
------------- 更改配置文件 -----------
protected-mode no
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
#bind 127.0.0.1
pidfile /var/run/redis_7000.pid
logfile "7000.log"
masterauth 123456
requirepass 123456
------------------------------------
# 依次复制和修改其他文件夹中的redis.conf
cp ./7000/redis.conf ./7001/
vim ./7001/redis.conf
# 执行替换命令
:%s/7000/7001/g
:wq
-
依次启动6个节点
将安装的redis目录下的src复制到redis_cluster下,方便启动服务端
cd /opt/redis-5.0.7 cp -r ./src/ /usr/local/redis_cluster/
启动
./src/redis-server ./7000/redis.conf ./src/redis-server ./7001/redis.conf ./src/redis-server ./7002/redis.conf ./src/redis-server ./7003/redis.conf ./src/redis-server ./7004/redis.conf ./src/redis-server ./7005/redis.conf
-
查看是否启动成功
ps -ef | grep -i redis # 输出如下: root 2842 1 0 09:43 ? 00:00:00 ./src/redis-server *:7000 [cluster] root 2847 1 0 09:43 ? 00:00:00 ./src/redis-server *:7001 [cluster] root 2852 1 0 09:43 ? 00:00:00 ./src/redis-server *:7002 [cluster] root 2857 1 0 09:43 ? 00:00:00 ./src/redis-server *:7003 [cluster] root 2862 1 0 09:43 ? 00:00:00 ./src/redis-server *:7004 [cluster] root 2867 1 0 09:43 ? 00:00:00 ./src/redis-server *:7005 [cluster] root 2872 2228 0 09:43 pts/0 00:00:00 grep --color=auto -i redis
创建集群
Redis5版本后通过redis-cli客户端命令来创建集群
在redis_cluster目录下执行下面命令
./src/redis-cli --cluster create -a 123456 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
此处使用的命令是create,因为我们要创建一个新集群。该选项--cluster-replicas 1
意味着我们希望为每个创建的主机都提供一个从机。其他参数是我要用于创建新集群的实例的地址列表。
显然,满足我们要求的唯一设置是创建具有3个主设备和3个从设备的集群。
输出结果如下:
可以看到我圈出来的地方,自动给3个节点分配了共16383个哈希槽
最下面的M:代表master主节点,S:代表从节点
集群的验证
redis cluster在设计的时候就考虑到了去中心化和去中间件,所以集群中每个节点都是平等的关系。
每个节点都保存各自的数据和整个集群的状态。
每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。
每个Redis节点都有一个ID值,该ID将被此特定redis实例永久使用,以便实例在集群上下文中具有唯一的名称。
每个节点都会记住使用此ID的每个其它节点,而不是通过IP或端口(可能会发生改变)。
在某台机器上连接集群的7001端口的节点:
进入redis_cluster/进行下面命令
./src/redis-cli -h 127.0.0.1 -c -p 7001 -a 123456 # -c:可连接到集群
通过info replication
这个命令可以查看当前节点的信息
通过cluster nodes
这个命令可以查看所有节点的信息
接着,我们测试一下
输入set aa 123
可以得到如下结果:
127.0.0.1:7001> set aa 123
-> Redirected to slot [1180] located at 127.0.0.1:7000
OK
127.0.0.1:7000>
继续测试
127.0.0.1:7000> keys *
1) "aa"
127.0.0.1:7000> set bb 123
-> Redirected to slot [8620] located at 127.0.0.1:7001
OK
127.0.0.1:7001> get aa
-> Redirected to slot [1180] located at 127.0.0.1:7000
"123"
127.0.0.1:7000> keys *
1) "aa"
127.0.0.1:7000> get bb
-> Redirected to slot [8620] located at 127.0.0.1:7001
"123"
127.0.0.1:7001> keys *
1) "bb"
127.0.0.1:7001> get aa
-> Redirected to slot [1180] located at 127.0.0.1:7000
"123"
127.0.0.1:7000>
通过分析结果可以看到,主从节点的数据共享,写入数据会在主节点写入。
关闭集群
在/usr/local/redis_cluster
目录下编写脚本文件
vi shutdowm.sh
# 内容如下
/usr/local/redis_cluster/src/redis-cli -c -h 127.0.0.1 -p 7000 -a 123456 shutdown
/usr/local/redis_cluster/src/redis-cli -c -h 127.0.0.1 -p 7001 -a 123456 shutdown
/usr/local/redis_cluster/src/redis-cli -c -h 127.0.0.1 -p 7002 -a 123456 shutdown
/usr/local/redis_cluster/src/redis-cli -c -h 127.0.0.1 -p 7003 -a 123456 shutdown
/usr/local/redis_cluster/src/redis-cli -c -h 127.0.0.1 -p 7004 -a 123456 shutdown
/usr/local/redis_cluster/src/redis-cli -c -h 127.0.0.1 -p 7005 -a 123456 shutdown
将shutdown.sh变成可执行文件
chmod u+x shutdown.sh
运行脚本文件
./shutdown.sh
开启集群
在/usr/local/redis_cluster
目录下编写脚本文件
vi start.sh
# 内容如下
/usr/local/redis_cluster/src/redis-server ./7000/redis.conf
/usr/local/redis_cluster/src/redis-server ./7001/redis.conf
/usr/local/redis_cluster/src/redis-server ./7002/redis.conf
/usr/local/redis_cluster/src/redis-server ./7003/redis.conf
/usr/local/redis_cluster/src/redis-server ./7004/redis.conf
/usr/local/redis_cluster/src/redis-server ./7005/redis.conf
将shutdown.sh变成可执行文件
chmod u+x start.sh
运行脚本文件
./start.sh
小总结
Redis cluster 为了保证数据的高可用性,加入主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当主节点挂了,就会有从这些从节点中选取一个来充当主节点,保证集群不会挂掉。
一个集群有A、B、C三个主节点,如果这三个节点都没有加入从节点,如果B挂了,就无法访问整个集群了,A和C的slot也无法访问,所以我们在建立集群的时候一定要为每个主节点都添加从节点。
Redis Cluster容错
容错性是指软件检测应用程序所运行的软件或硬件中发生的错误并恢复的能力,通常可以从系统的可靠性、可用性、可测性等几个方面来衡量。
Redis Cluster采用投票机制来判断某一master节点是不是不可用了
所有master参与投票,如果半数以上master节点与该master节点通信超时,则认为该master节点挂了
什么时候集群不可用了
如果集群任意master节点挂了,并且该节点没有salve节点,集群则进入fail状态。
如果集群超过半数以上的master节点挂掉,无论是否slave节点,集群进入fail状态。