0%

Redis cluster 客户端路由

MOVED重定向

槽命中:直接返回

算出key的slot值

1
>127.0.0.1> 6379 cluster keyslot hello

返回结果:

1
(integer) 866

槽不命中:moved异常

算出key的slot值

1
>127.0.0.1> 6379 cluster keyslot php

返回结果:

1
(integer) 9244

看一个小例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
redis-cli -c -p 7000    //集群模式
127.0.0.1:7000> cluster keyslot hello
(integer) 866
127.0.0.1:7000> set hello word
OK
127.0.0.1:7000> cluster keyslot php
(integer) 9244
127.0.0.1:7000> set php best
-> Redirected to slot [9244] located at 127.0.0.1:7001
OK
127.0.0.1:7001> get php
"best"
127.0.0.1:7001>
redis-cli -p 7000
127.0.0.1:7000> cluster keyslot php
(integer) 9244
127.0.0.1:7000> set php best
(error) MOVED 9244 127.0.0.1:7001
127.0.0.1:7000>

ASK重定向

在集群缩容扩容的时候,要对槽进行迁移,槽迁移过程中要遍历进行migrate,迁移时间比较长,
此时在此过程中访问一个key,但是key已经迁移到目标节点,就需要一个新的方案来解决这个问题,redis cluster 对这个问题已经有解决方案

我们来看它的一个实现演示:

moved & ask

  • 两者都是客户端重定向
  • moved:槽已确定迁移
  • ask:槽还在迁移中

smart客户端

基本原理

追求性能:

  1. 从集群中选一个可运行的节点,使用cluster slots 初始化槽和节点映射
  2. 将cluster slots结果映射到本地,为每个节点创建redisPool
  3. 执行命令

基本流程:

关于redis cluster 客户端使用可参考
redis-go-cluster

批量操作优化

批量操作怎么实现?meget meset必须在一个槽

串行mget

串行IO

并行IO

hash_tag

四种方案优缺点对比

方案优点缺点网络IO
串行mget编程简单,少量keys满足需求大量keys请求延迟严重O(keys)
串行IO编程简单,少量节点满足需求大量node延迟严重O(nodes)
并行IO利用并行特性,延迟取决于最慢的节点编程复杂,超市定位问题难O(max(node))
hash_tag性能最高读写增加tag维护成本,tag分布易出现数据倾斜O(1))