Redis 3.0集群搭建测试(二)

四、客户端集群命令

cluster集群相关命令,更多redis相关命令见文档:http://redis.readthedocs.org/en/latest/

集群
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 槽中的键。
五、redis-trib.rb操作集群

每台机器增加端口6383 redis实例节点,并启动实例。

1.添加新master节点
1)add-node  将一个节点添加到集群里面, 第一个是新节点ip:port, 第二个是任意一个已存在节点ip:port
./bin/redis-trib.rb add-node 192.168.36.54:6383 192.168.36.54:6380

>>> Adding node 192.168.36.54:6383 to cluster 192.168.36.54:6380
Connecting to node 192.168.36.54:6380: OK
Connecting to node 192.168.36.189:6380: OK
Connecting to node 192.168.36.189:6382: OK
Connecting to node 192.168.36.54:6382: OK
Connecting to node 192.168.36.54:6381: OK
Connecting to node 192.168.36.189:6381: OK
>>> Performing Cluster Check (using node 192.168.36.54:6380)
M: f6285c8a7506b224840d7b26b2b5d1671320c21f 192.168.36.54:6380
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: b1a15a3cd14ea65671a7134850e17b8919a17da5 192.168.36.189:6380
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: de4302f43ff89843675446396552fd19f741246a 192.168.36.189:6382
   slots: (0 slots) slave
   replicates 26ce71d626175f88e0416e3f45b2bfb29304c7b3
S: 83fc65283bbbb71b4c089337df05594d67f4cab6 192.168.36.54:6382
   slots: (0 slots) slave
   replicates b1a15a3cd14ea65671a7134850e17b8919a17da5
M: 26ce71d626175f88e0416e3f45b2bfb29304c7b3 192.168.36.54:6381
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 1080e423a55a2c24dae649dac03ffa09ed26d3e8 192.168.36.189:6381
   slots: (0 slots) slave
   replicates f6285c8a7506b224840d7b26b2b5d1671320c21f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Connecting to node 192.168.36.54:6383: OK
>>> Send CLUSTER MEET to node 192.168.36.54:6383 to make it join the cluster.
[OK] New node added correctly.
新节点没有包含任何数据, 因为它没有包含任何slot。新加入的加点是一个主节点, 当集群需要将某个从节点升级为新的主节点时, 这个新节点不会被选中。

2)为新节点分配slot

你只需要指定集群中其中一个节点的地址, redis-trib 就会自动找到集群中的其他节点。目前 redis-trib 只能在管理员的协助下完成重新分片的工作, 要让 redis-trib 自动将哈希槽从一个节点移动到另一个节点, 目前来说还做不到 (不过实现这个功能并不难)。
./bin/redis-trib.rb reshard 192.168.36.54:6383
设定你打算移动的哈希槽slots的数量(这里槽数量设置为1000)
How many slots do you want to move (from 1 to 16384)? 1000
除了移动的哈希槽数量之外, redis-trib 还需要知道重新分片的目标(target node), 也即是, 负责接收这 1000 个哈希槽的节点。指定目标需要使用节点的 ID , 而不是 IP 地址和端口。 比如说, 我们打算使用集群的第一个主节点来作为目标, 它的 IP 地址和端口是 192.168.36.54:6383 , 而节点 ID 则是50cd88737109d0398e35b19747cc02832f05d125 , 那么我们应该向 redis-trib 提供节点的 ID :
What is the receiving node ID?50cd88737109d0398e35b19747cc02832f05d125
redis-trib 会打印出集群中所有节点的 ID , 并且我们也可以通过执行以下命令来获得节点的运行 ID :
./bin/redis-cli -h 192.168.36.54 -p 6380 cluster nodes |grep 192.168.36.54:6383
接着, redis-trib 会向你询问重新分片的源节点(source node), 也即是, 要从哪个节点中取出 1000 个哈希槽,并将这些槽移动到目标节点上面。如果我们不打算从特定的节点上取出指定数量的哈希槽, 那么可以向 redis-trib 输入 all , 这样的话, 集群中的所有主节点都会成为源节点, redis-trib 将从各个源节点中各取出一部分哈希槽, 凑够 1000 个, 然后移动到目标节点上面:
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1:all

输入 all 并按下回车之后, redis-trib 将打印出哈希槽的移动计划, 如果你觉得没问题的话, 就可以输入 yes 并再次按下回车, redis-trib 就会正式开始执行重新分片操作, 将指定的哈希槽从源节点一个个地移动到目标节点上面。
在重新分片操作执行完毕之后, 可以使用以下命令来检查集群是否正常:
./bin/redis-trib.rb check 192.168.36.54:6380
根据检查结果显示, 集群运作正常。

2.添加新的slave节点

1)添加节点

./bin/redis-trib.rb add-node 192.168.36.189:6383 192.168.36.54:6380

2)redis-cli连接上新节点shell,输入命令:cluster replicate 对应master的node-id
./bin/redis-cli -c -h 192.168.36.189 -p 6383
>cluster replicate 50cd88737109d0398e35b19747cc02832f05d125
在线添加slave 时,需要dump整个master进程,并传递到slave,再由 slave加载rdb文件到内存,rdb传输过程中Master可能无法提供服务,整个过程消耗大量io,小心操作.
查看执行结果:
./bin/redis-cli -h 192.168.36.189 -p 6383 cluster nodes | grep slave | grep 50cd88737109d0398e35b19747cc02832f05d125
5178d6342a6470f928cfa6d43d98640b9303ad38 192.168.36.189:6383 myself,slave 50cd88737109d0398e35b19747cc02832f05d125 0 0 0 connected

3)在线reshard 数据
对于负载/数据不均匀的情况,可以在线reshard slot来解决,方法与添加新master的reshard一样,只是需要reshard的master节点是老节点。
4)删除一个slave节点
./bin/redis-trib.rb del-node 192.168.36.54:6380 5178d6342a6470f928cfa6d43d98640b9303ad38
5)删除一个master节点
删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点(目前只能把被删除master的slot迁移到一个节点上),操作和分配slot类似,指定具体的Source node即可。
然后在使用4步骤中的命令删除节点

六、集群测试

1.数据测试

使用redis客户端redis-cli进行添加数据操作。

./bin/redis-cli -c -h 192.168.36.189 -p 6380
192.168.36.189:6380> set abc 123
OK
192.168.36.189:6380> set xxx 123
-> Redirected to slot [4038] located at 192.168.36.54:6380
OK
192.168.36.54:6380> set ttt aaa
-> Redirected to slot [15942] located at 192.168.36.54:6381
OK
redis-cli 对集群的支持是非常基本的, 所以它总是依靠 Redis 集群节点来将它转向(redirect)至正确的节点。

2.故障转移测试

要触发一次故障转移, 最简单的办法就是令集群中的某个主节点进入下线状态。
首先用以下命令列出集群中的所有主节点:

 ./bin/redis-cli -h 192.168.36.189 -p 6383 cluster nodes |grep master
50cd88737109d0398e35b19747cc02832f05d125 192.168.36.54:6383 master - 0 1428823692383 7 connected 0-332 5461-5794 10923-11255
26ce71d626175f88e0416e3f45b2bfb29304c7b3 192.168.36.54:6381 master - 0 1428823692893 2 connected 11256-16383
f6285c8a7506b224840d7b26b2b5d1671320c21f 192.168.36.54:6380 master - 0 1428823693918 1 connected 333-5460
b1a15a3cd14ea65671a7134850e17b8919a17da5 192.168.36.189:6380 master - 0 1428823692893 4 connected 5795-10922
通过命令输出, 我们知道端口号为 192.168.36.54:6380、 192.168.36.54:6381、192.168.36.54:6383 和 192.168.36.189:6380的节点都是主节点, 然后我们可以通过向端口号为192.168.36.54:6380的主节点发送 DEBUG SEGFAULT 命令, 让这个主节点崩溃:
./bin/redis-cli -h 192.168.36.54 -p 6380  debug segfault
Error: Server closed the connection
我们使用 cluster nodes 命令, 查看集群在执行故障转移操作之后, 主从节点的布局情况:
./bin/redis-cli -h 192.168.36.189 -p 6383 cluster nodes
50cd88737109d0398e35b19747cc02832f05d125 192.168.36.54:6383 master - 0 1428823969555 7 connected 0-332 5461-5794 10923-11255
1080e423a55a2c24dae649dac03ffa09ed26d3e8 192.168.36.189:6381 master - 0 1428823968475 8 connected 333-5460
de4302f43ff89843675446396552fd19f741246a 192.168.36.189:6382 slave 26ce71d626175f88e0416e3f45b2bfb29304c7b3 0 1428823968886 2 connected
26ce71d626175f88e0416e3f45b2bfb29304c7b3 192.168.36.54:6381 master - 0 1428823967861 2 connected 11256-16383
83fc65283bbbb71b4c089337df05594d67f4cab6 192.168.36.54:6382 slave b1a15a3cd14ea65671a7134850e17b8919a17da5 0 1428823969555 4 connected
f6285c8a7506b224840d7b26b2b5d1671320c21f 192.168.36.54:6380 master,fail? - 1428823891006 1428823888448 1 disconnected
b1a15a3cd14ea65671a7134850e17b8919a17da5 192.168.36.189:6380 master - 0 1428823970008 4 connected 5795-10922
5178d6342a6470f928cfa6d43d98640b9303ad38 192.168.36.189:6383 myself,slave 50cd88737109d0398e35b19747cc02832f05d125 0 0 0 connected
重启了之前下线的节点192.168.36.54:6380, 该节点已经从原来的主节点变成了从节点。
 ./bin/redis-cli -h 192.168.36.189 -p 6383 cluster nodes
50cd88737109d0398e35b19747cc02832f05d125 192.168.36.54:6383 master - 0 1428824165896 7 connected 0-332 5461-5794 10923-11255
1080e423a55a2c24dae649dac03ffa09ed26d3e8 192.168.36.189:6381 master - 0 1428824166406 8 connected 333-5460
de4302f43ff89843675446396552fd19f741246a 192.168.36.189:6382 slave 26ce71d626175f88e0416e3f45b2bfb29304c7b3 0 1428824165382 2 connected
26ce71d626175f88e0416e3f45b2bfb29304c7b3 192.168.36.54:6381 master - 0 1428824165896 2 connected 11256-16383
83fc65283bbbb71b4c089337df05594d67f4cab6 192.168.36.54:6382 slave b1a15a3cd14ea65671a7134850e17b8919a17da5 0 1428824164870 4 connected
f6285c8a7506b224840d7b26b2b5d1671320c21f 192.168.36.54:6380 slave 1080e423a55a2c24dae649dac03ffa09ed26d3e8 0 1428824166920 8 connected
b1a15a3cd14ea65671a7134850e17b8919a17da5 192.168.36.189:6380 master - 0 1428824166407 4 connected 5795-10922
5178d6342a6470f928cfa6d43d98640b9303ad38 192.168.36.189:6383 myself,slave 50cd88737109d0398e35b19747cc02832f05d125 0 0 0 connected
注:cluster nodes 命令的输出有点儿复杂, 它的每一行都是由以下信息组成的:
节点 ID :例如 3fc783611028b1707fd65345e763befb36454d73 。
ip:port :节点的 IP 地址和端口号, 例如 127.0.0.1:7000 , 其中 :0 表示的是客户端当前连接的 IP 地址和端口号。
flags :节点的角色(例如 master 、 slave 、 myself )以及状态(例如 fail ,等等)。
如果节点是一个从节点的话, 那么跟在 flags 之后的将是主节点的节点 ID : 例如 127.0.0.1:7002 的主节点的节点 ID 就是 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 。
集群最近一次向节点发送 PING 命令之后, 过去了多长时间还没接到回复。
节点最近一次返回 PONG 回复的时间。
节点的配置纪元(configuration epoch):详细信息请参考 Redis 集群规范 。
本节点的网络连接情况:例如 connected 。
节点目前包含的槽:例如192.168.36.189:6380 目前包含号码为5795-10922的哈希槽。
七、集群下java客户端使用

如下以jedis为例:

package cn.slimsmart.redis.demo.cluster;

import java.util.HashSet;
import java.util.Set;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

public class RedisClusterTest {

	public static void main(String[] args) {
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(100);
		config.setMaxIdle(100);
		config.setMinIdle(100);
		config.setMaxWaitMillis(6 * 1000);
		config.setTestOnBorrow(true);

		Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
		jedisClusterNodes.add(new HostAndPort("192.168.36.54", 6380));
		jedisClusterNodes.add(new HostAndPort("192.168.36.54", 6381));
		jedisClusterNodes.add(new HostAndPort("192.168.36.54", 6382));
		jedisClusterNodes.add(new HostAndPort("192.168.36.54", 6383));

		jedisClusterNodes.add(new HostAndPort("192.168.36.189", 6380));
		jedisClusterNodes.add(new HostAndPort("192.168.36.189", 6381));
		jedisClusterNodes.add(new HostAndPort("192.168.36.189", 6382));
		jedisClusterNodes.add(new HostAndPort("192.168.36.189", 6383));

		JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, 2000, 2, config);
		try {
			for (int i = 0; i < 1000; i++) {
				long t1 = System.currentTimeMillis();
				jedisCluster.set("" + i, "" + i);
				long t2 = System.currentTimeMillis();
				String value = jedisCluster.get("" + i);
				long t3 = System.currentTimeMillis();
				System.out.println("" + value);
				System.out.println((t2 - t1) + "mills");
				System.out.println((t3 - t2) + "mills");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisCluster.close();
		}
	}
}
jedis客户端不足之处
1.cluster环境下redis的slave不接受任何读写操作
2.client端不支持keys批量操作,不支持select dbNum操作,只有一个db:select 0
3.JedisCluster 的info()等单机函数无法调用,返回(No way to dispatch this command to Redis Cluster)错误
4.JedisCluster 没有针对byte[]的API,需要自己扩展

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值