redis cluster
依赖环境安装
redis 集群某些功能需要依赖 ruby 运行环境,基于yum进行安装:
$ yum install ruby*
安装redis的ruby组件:
$ gem install redis
提示:
[root@bogon redis]# gem install redis
ERROR: Could not find a valid gem 'redis' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://rubygems.org/latest_specs.4.8.gz)
解决办法
$ sudo gem sources -r https://rubygems.org
$ sudo gem sources -a http://rubygems.org
重试,发现可以安装成功,之前的 ERROR 变成了 WARNING
cluster 配置
本次实验采用4个节点来搭建 redis cluster,其中 16379, 16479, 16579 为集群的3个主节点,承担整个集群的槽位分配,16379 和 16380 为主从结构
192.168.1.160 16379 (master) <--> 192.168.1.160 16380 (slave)
192.168.1.160 16479
192.168.1.160 16579
redis 集群安装非常简单,只需要下载 redis 3.x+ 版本,并且修改下配置文件,打开集群配置即可
重启 redis 服务
$ ./src/redis-server config/redis_16379.conf
$ ./src/redis-server config/redis_16380.conf
$ ./src/redis-server config/redis_16479.conf
$ ./src/redis-server config/redis_16579.conf
连接上16379
./src/redis-cli -p 16379
将 16479 和 16579 加入集群中
> cluster meet 192.168.1.160 16479
> cluster meet 192.168.1.160 16579
cluster_state:fail # 此时整个集群还是 fail 状态,还需要为每个节点分片槽位,redis cluster 总共 16384 [0, 16383] 个槽位,只有将每个槽位都分配到具体的节点,整个集群才会为可用状态
cluster_known_nodes:3 # 说明集群中已经有三个节点
cluster_size:0 # 说明集群中还没有节点承担槽位分配
槽位分配
槽位分配的命令,如下指令将第0个槽位分配给 16379 redis 服务
$ ./src/redis-cli -h 127.0.0.1 -p 16379 cluster addslots 0
这里为了简单处理,直接通过一个 shell 脚本将 16384 个槽位均分给3个节点,具体 shell 脚本如下
#!/bin/bash
all_ports=(16379 16479 16579)
for i in {0..16383};
do
val=`expr $i % 3`
/usr/local/redis/src/redis-cli -h 127.0.0.1 -p ${all_ports[$val]} cluster addslots $i;
done
完成之后,查看集群的状态
cluster_state:ok # 此时集群为可用状态
另外可以使用 redis-trib.rb 脚本快速分配槽位,方法如下
./src/redis-trib.rb create 192.168.1.160:16379 192.168.1.160:16479 192.168.1.160:16579
注意:
1)redis 服务启动之后不需要执行 cluster meet 命令,否则提示错误
2)这里不能使用 create 127.0.0.1:16379 127.0.0.1:16479 这种 127 的地址,因为如果集群之间通讯的IP是127的地址,那么当使用 jedis 这类客户端操作 cluster 时,获取到的集群节点IP也会是127的地址,那么出现重定向请求时将出现错误
截图可以看出 0-5460 槽位分配给了 16379;5461-10922 槽位分配给了 16479 ...
结束之后查看集群状态(cluster info)看到整个集群的状态为:ok
连接并测试
> redis-cli -h 192.168.1.160 -p 16379 –c (注意:这里的 –c 参数,表示采用集群方式连接)
此时看到这里可以正常地将其他节点的请求转发出去
测试故障转移
先给 16379 添加一台从服务器 16380
$ ./redis-trib.rb add-node --slave --master-id 9c4395ebb3142a3e03d0c6892d5f17f2eac20e7d 192.168.1.160:16380 192.168.1.160:16379
其中 9c4395ebb3142a3e03d0c6892d5f17f2eac20e7d 为 16379 (master) 的 node id (集群中各个节点的 node id 可以通过 cluster nodes 命令查看到)
$ ./redis-trib.rb info 192.168.1.160:16379
16379 有一个 slave,停止 16379 的服务,查看16380的日志,验证主从切换的过程
16380 的日志中输出可以看到,当16379宕机后,16380发起了一个新的选举,并且因为这个主从结构中只有一个从,所以自己被选举成了新的主,然后整个集群的状态变成了ok
重新启动 16379 的服务,验证 16379 会成为 16380 的从节点,查看 16379 启动日志,发现 16379 会自动切换为从 Reconfiguring myself as a replica of 591a0241a417bad43afa9fc84b6c6b3958dc11a6
4251:M 02 May 18:58:30.595 * The server is now ready to accept connections on port 16379
4251:M 02 May 18:58:30.616 # Configuration change detected. Reconfiguring myself as a replica of 591a0241a417bad43afa9fc84b6c6b3958dc11a6
4251:S 02 May 18:58:30.616 # Cluster state changed: ok
4251:S 02 May 18:58:31.625 * Connecting to MASTER 192.168.1.160:16380
测试扩容迁移
先通过 cluster nodes 命令查看出集群中所有节点的 node id,如下
M: 5e2946da32a6d0b03f3805415fade827ef50561e 192.168.1.160:16379
M: 5aa58505ead83ab8e2ea46941377130d2cbdbc6e 192.168.1.160:16479
M: 41c251b110ce1bd2da908f9ef35460fc4621e138 127.0.0.1:16579
通过下面的命令生成迁移计划,然后根据提示输入相关信息,即可完成迁移
$ ./src/redis-trib.rb reshard 127.0.0.1:16579
How many slots do you want to move (from 1 to 16384) 2731 //输入被迁移的slot的数量(因为这里需要将16579所有的 slot 迁出,所以这里输入16579节点的总slot数量)
What is the receiving node ID? //输入目的地节点的id,执行第一行命的时候会打印出所有的节点信息
Please enter all the source node IDs. //输入被迁移的槽所在的节点,指定多个,入done确认入完,即将这些slot迁入到那个节点,这里迁移到了16379节点
Do you want to proceed with the proposed reshard plan (yes/no)? Yes //迁移计划确认
确认计划之后,等待计划执行完成即可
删除节点
# ./redis-trib.rb del-node 127.0.0.1:16380 591a0241a417bad43afa9fc84b6c6b3958dc11a6
提示该节点还有槽位分配,必须要将数据 rehash 后才能删除,这里为了测试直接将所有槽位移除
[root@bogon src]# ./redis-cli -h 127.0.0.1 -p 16380 -c
127.0.0.1:16380> CLUSTER flushslots
OK
[root@bogon src]# ./redis-trib.rb del-node 127.0.0.1:16380 591a0241a417bad43afa9fc84b6c6b3958dc11a6
>>> Removing node 591a0241a417bad43afa9fc84b6c6b3958dc11a6 from cluster 127.0.0.1:16380
>>> Sending CLUSTER FORGET messages to the cluster...
>>> 192.168.1.160:16379 as replica of 192.168.1.160:16579
>>> SHUTDOWN the node.
再次尝试删除16380节点,删除成功
redis cluster 相关操作命令
集群
CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
节点
CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。
CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。
槽(slot)
CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。
CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。
CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。
CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
键
CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。
来源:oschina
链接:https://my.oschina.net/u/174366/blog/668809