高可用Redis(十二):Redis Cluster (3)

高可用Redis(十二):Redis Cluster

[root@mysql ~]# redis-cli -p 9002 cluster keyslot hello (integer) 866

槽不命中:moved异常

[root@mysql ~]# redis-cli -p 9002 cluster keyslot php (integer) 9244

高可用Redis(十二):Redis Cluster

[root@mysql ~]# redis-cli -c -p 9002 127.0.0.1:9002> cluster keyslot hello (integer) 866 127.0.0.1:9002> set hello world -> Redirected to slot [866] located at 192.168.81.100:9003 OK 192.168.81.100:9003> cluster keyslot python (integer) 7252 192.168.81.100:9003> set python best -> Redirected to slot [7252] located at 192.168.81.101:9002 OK 192.168.81.101:9002> get python "best" 192.168.81.101:9002> get hello -> Redirected to slot [866] located at 192.168.81.100:9003 "world" 192.168.81.100:9003> exit [root@mysql ~]# redis-cli -p 9002 127.0.0.1:9002> cluster keyslot python (integer) 7252 127.0.0.1:9002> set python best OK 127.0.0.1:9002> set hello world (error) MOVED 866 192.168.81.100:9003 127.0.0.1:9002> exit [root@mysql ~]# 3.5.2 ask重定向

高可用Redis(十二):Redis Cluster

在对集群进行扩容和缩容时,需要对槽及槽中数据进行迁移

当客户端向某个节点发送命令,节点向客户端返回moved异常,告诉客户端数据对应的槽的节点信息

如果此时正在进行集群扩展或者缩空操作,当客户端向正确的节点发送命令时,槽及槽中数据已经被迁移到别的节点了,就会返回ask,这就是ask重定向机制

高可用Redis(十二):Redis Cluster

步骤:

1.客户端向目标节点发送命令,目标节点中的槽已经迁移支别的节点上了,此时目标节点会返回ask转向给客户端 2.客户端向新的节点发送Asking命令给新的节点,然后再次向新节点发送命令 3.新节点执行命令,把命令执行结果返回给客户端

moved异常与ask异常的相同点和不同点

两者都是客户端重定向 moved异常:槽已经确定迁移,即槽已经不在当前节点 ask异常:槽还在迁移中 3.5.3 smart智能客户端

使用智能客户端的首要目标:追求性能

从集群中选一个可运行节点,使用Cluster slots初始化槽和节点映射

将Cluster slots的结果映射在本地,为每个节点创建JedisPool,相当于为每个redis节点都设置一个JedisPool,然后就可以进行数据读写操作

读写数据时的注意事项:

每个JedisPool中缓存了slot和节点node的关系 key和slot的关系:对key进行CRC16规则进行hash后与16383取余得到的结果就是槽 JedisCluster启动时,已经知道key,slot和node之间的关系,可以找到目标节点 JedisCluster对目标节点发送命令,目标节点直接响应给JedisCluster 如果JedisCluster与目标节点连接出错,则JedisCluster会知道连接的节点是一个错误的节点 此时JedisCluster会随机节点发送命令,随机节点返回moved异常给JedisCluster JedisCluster会重新初始化slot与node节点的缓存关系,然后向新的目标节点发送命令,目标命令执行命令并向JedisCluster响应 如果命令发送次数超过5次,则抛出异常"Too many cluster redirection!"

高可用Redis(十二):Redis Cluster

3.6 多节点命令实现

Redis Cluster不支持使用scan命令扫描所有节点
多节点命令就是在在所有节点上都执行一条命令
批量操作优化

3.6.1 串行mget

定义for循环,遍历所有的key,分别去所有的Redis节点中获取值并进行汇总,简单,但是效率不高,需要n次网络时间

高可用Redis(十二):Redis Cluster

3.6.2 串行IO

对串行mget进行优化,在客户端本地做内聚,对每个key进行CRC16hash,然后与16383取余,就可以知道哪个key对应的是哪个槽

本地已经缓存了槽与节点的对应关系,然后对key按节点进行分组,成立子集,然后使用pipeline把命令发送到对应的node,需要nodes次网络时间,大大减少了网络时间开销

高可用Redis(十二):Redis Cluster

3.6.3 并行IO

并行IO是对串行IO的一个优化,把key分组之后,根据节点数量启动对应的线程数,根据多线程模式并行向node节点请求数据,只需要1次网络时间

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpygfy.html