redis 集群某些功能须要依赖 ruby 运行环境,基于yum进行安装:node
$ yum install ruby*
安装redis的ruby组件:redis
$ gem install redis
提示:shell
[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)
解决办法ruby
$ sudo gem sources -r https://rubygems.org $ sudo gem sources -a http://rubygems.org
重试,发现能够安装成功,以前的 ERROR 变成了 WARNINGbash
本次实验采用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 16479spa
192.168.1.160 165793d
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节点,删除成功
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 将节点的配置文件保存到硬盘里面。
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 槽中的键。