-
Notifications
You must be signed in to change notification settings - Fork 1.2k
pika集群迁移slot命令
pika支持codis sync slot迁移设计实现 为兼容pika官方版本,所以pika支持codis slot迁移实现是修改pika实现的,而不是修改pika的存储库nemo实现。 实现方法是,增加slot key(共1024个),set类型,用户发过来的每个key在进行修改操作(set, del, incr, hset, sadd , lpush, zadd......)时,根据slot = crc32(key)%1024计算出该key对应的的slot,然后将该key sadd或者srem到该slot对应的set key;迁移时,指定slot,从该slot spop(由于pika的spop会触发compact,所以是通过sscan和srem实现spop)出一个key然后迁移到目的的pika server。该实现的优点是和官方版本数据兼容,可以直接进行替换升级,不需要洗数据等,回退也方便。不足之处是每次修改操作均要有额外的set操作,降低了性能(大概降低10%~20%),增加了存储(增加30%左右),为了解决性能降低,存储增加的问题,所以增加了pika支持slot迁移的开关,开关关闭时,性能及存储使用和官方版本一致,打开开关时支持slot迁移。
##slot迁移开关## 开关可以通过配置文件配置conf/pika.conf:
slotmigrate : yes 也可以通过命令行config set进行配置:
$ redis-cli -h 127.0.0.1 -p 9221 config set slotmigrate yes pika迁移codis添加命令说明: #####slotsinfo [start] [count]#####
命令说明:获取 redis 中 slot 的个数以及每个 slot 的大小
命令参数:缺省查询 [0, MAX_SLOT_NUM)
start - 起始的 slot 序号
缺省 = 0
count - 查询的区间的大小,即查询范围为 [start, start + count)
缺省 = MAX_SLOT_NUM
返回结果:返回结果是 slotinfo 的 array;slotinfo 本身也是一个 array。
response := []slotinfo{slot1, slot2, slot3, ...}
slotinfo := []int{slotnum, slotsize}
其中:
INT slotnum : slot 序号
INT slotsize : slot 内数据个数
例如:
localhost:6379> slotinfo 0 128
1) 1) (integer) 23
2) (integer) 2
2) 1) (integer) 29
2) (integer) 1
#####slotsdel slot1 [slot2 …]#####
命令说明:删除 redis 中若干 slot 下的全部 key-value 命令参数:接受至少 1 个 slotnum 作为参数 返回结果:格式参见 slotsinfo,不同的是:slotsize 表示删除后剩余大小,通常为 0。 例如: localhost:6379> slotsdel 1013 990 1) 1) (integer) 1013 2) (integer) 0 2) 1) (integer) 990 2) (integer) 0 ####数据迁移#### 以下4个命令是一族命令:
slotsmgrtslot - O(1) 随机在某个 slot 下迁移一个 key-value 到目标机器 slotsmgrtone - O(1) 将指定的 key-value 迁移到目标机 slotsmgrttagslot - O(n) 随机在某个 slot 下选择一个 key,并将与之有相同 tag 的 key-value 对全部迁移到目标机 slotsmgrttagone - O(n) 将与指定 key 具有相同 tag 的所有 key-value 对迁移到目标机 #####slotsmgrtslot host port timeout slot#####
命令说明:随机选择 slot 下的 1 个 key-value 到迁移到目标机(同步 IO 操作) 如果当前 slot 已经空了或者选择的 key 刚好过期,返回 0 如果当前 slot 下面还有 key 则选择一个进行迁移 同时返回当前 slot 剩余 key 的个数 迁移过程在目标机器调用 slotsrestore 命令,迁移会 覆盖旧值 命令参数: host:port - 目标机 redis 内部缓存到 host:port 的连接 30s,超时或错误则关闭
timeout - 操作超时,单位 ms 过程需要 3 个同步操作:
建立连接(可被缓存优化) 发送 key-value 数据 接受目标机返回 指令保证每个操作不超过 timeout
slot - 指定迁移的 slot 序号
返回结果: 操作返回 int response := []int{succ,size}
其中: INT succ : 表示迁移是否成功。 0 表示当前 slot 已经空了(迁移成功个数=0) 1 表示迁移一个 key 成功,并从本地删除(迁移成功个数=1) INT size : 表示 slot 下剩余 key 的个数 例如: localhost:6379> set a 100 # set <a, 100> OK localhost:6379> slotsinfo # slot 大小为 1 1) 1) (integer) 579 2) (integer) 1 localhost:6379> slotsmgrt 127.0.0.1 6380 100 579 (integer) 1 # 成功迁移 value localhost:6379> slotsinfo (empty list or set) localhost:6379> slotsmgrt 127.0.0.1 6380 100 579 1 (integer) 0 # 成功成功个数为 0;当前 slot 已经空了 #####slotsmgrtone host port timeout key#####
命令说明:迁移 key 到目标机,与 slotsmgrtslot 相同 命令参数:参见 slotsmgrtslot 返回结果: 操作返回 整数 (int) response := int(succ)
其中: INT succ : 与 slotsmgrtslot 相似 例如: localhost:6379> set a 100 # set <a, 100> OK localhost:6379> slotsinfo 1) 1) (integer) 579 2) (integer) 1 localhost:6379> slotsmgrtone 127.0.0.1 6380 100 a (integer) 1 # 迁移成功 localhost:6379> slotsmgrtone 127.0.0.1 6380 100 a (integer) 0 # 放弃迁移,本地已经不存在了 #####slotsmgrttagone host port timeout key#####
命令说明:迁移与 key 有相同的 tag 的所有 key 到目标机 当 key 中不包含合法 tag 时,命令退化为 slotsmgrtone 当 key 中包含合法 tag 时,命令扫描对应 slot 下的所有 key,找到所有含有相同 tag 的 key-value,一次原子的迁移到目标机 操作需要遍历整个 slot,复杂度 O(n) ,如果对应 key 不包含 tag 则退化为 O(1) 命令参数:参见 slotsmgrtone 返回结果: 操作返回 整数 (int) response := int(succ)
其中: INT succ : 表示成功迁移的 key 的个数。 例如: localhost:6379> set a{tag} 100 # set <a{tag}, 100> OK localhost:6379> set b{tag} 100 # set <b{tag}, 100> OK localhost:6379> slotsmgrttag 127.0.0.1 6380 1000 {tag} (integer) 2 localhost:6379> scan 0 # 迁移成功,本地不存在了 1) "0" 2) (empty list or set) localhost:6380> scan 0 # 数据一次成功迁移到目标机 1) "0" 2) 1) "a{tag}" 2) "b{tag}" #####slotsmgrttagslot host port timeout slot#####
命令说明:与 slotsmgrtslot 对应的迁移指令 其他说明参考 slotsmgrtslot 以及 slotsmgrttagone 的解释即可 #####slotsrestore key1 ttl1 val1 [key2 ttl2 val2 …]#####
命令说明:该命令是对 redis-2.8 的 restore 命令的扩展 可以对 restore 多个 key-value 过程是原子的。 备注:与 restore 不同的是,slotsrestore 只支持 replace,即一定 覆盖旧值 。如果旧值已经存在,那么只可能是 redis-slots 或者 proxy 的实现 bug,程序会通过 redisLog 打印一条冲突记录。 ####调试相关#### #####slotshashkey key1 [key2 …]#####
命令说明:计算并返回给定 key 的 slot 序号 命令参数:输入为 1 个或多个 key 返回结果: 操作返回 array response := []int{slot1, slot2...}
其中: INT slot : 表示对应 key 的 slot 序号,即 hash32(key) % NUM_OF_SLOTS 例如: localhost:6379> slotshashkey a b c # 计算 <a,b,c> 的 slot 序号 1) (integer) 579 2) (integer) 1017 3) (integer) 879 pika支持semi-async的迁移命令 除了pika支持sync迁移的一些如slotsinfo,slotsdel等,又添加了四个迁移命令:分别是slotsmgrttagslot-async,slotsmgrt-exec-wrapper,slotsmgrt-async-status,slotsmgrt-async-cancel:
slotsmgrttagslot-async: semi-async模式批量迁移key,使用方法如下:
127.0.0.1:9221> SLOTSMGRTTAGSLOT-ASYNC pika1 9221 5000 200 33554432 518 500 slotsmgrt-exec-wrapper: semi-async模式处理请求的key属于正在迁移slot的请求,使用方法如下:
127.0.0.1:9221> slotsmgrt-exec-wrapper test1 set test1 100 slotsmgrt-async-status: semi-async模式,查看迁移的状态,使用方法如下:
127.0.0.1:9221> slotsmgrt-async-status pika支持后台清理slot数据命令 前面介绍了slotsreload命令,该命令会遍历数据库里面所有的key,并根据hash算法函数,将key分别添加到对应slot的set slotkey里面。而pika添加的后台清理slot数据命令slotscleanup,则是遍历数据库里面的key时,如果发现属于被删除slot的key,则删除该key。由于遍历数据库所有的key会对系统产生一些压力,所以在一些压力大的情况下需要将slotscleanup停止掉,则可以执行slotscleanupoff命令,具体如下: slotscleanup: 后台清理不需要的slot的key,该命令执行后会立即返回,具体清除操作会在后台执行,可以通过info命令查看。如要清除slot 10,11,12,13,14,15的key,则可按如下执行:
127.0.0.1:9221> slotscleanup 10 11 12 13 14 15 slotscleanupoff: 停止后台执行的slot清除操作,使用方法如下:
127.0.0.1:9221> slotscleanupoff 127.0.0.1:9221> slotsreload
该命令是一个在后台运行的命令,类似bgsave模式,可以通过info命令查看slotsreload是否运行结束,在运行结束后才可以进行迁移。
如果数据库使用的场景中,有大量过期数据,大量使用expire等设置key过期的命令,建议不要在配置文件中打开开关(那些过期的数据,在slot里面没有进行过期删除,会导致数据累积,后面会考虑改进这点),可以考虑在需要迁移前在命令行打开开关,然后运行slotsreload命令,在slotsreload命令运行结束后,进行迁移,迁移完成后在命令行运行slotsdel命令进行收尾工作(释放磁盘占用),命令后面跟需要清理掉slot,如下方式
- 安装使用
- 支持的语言和客户端
- 当前支持的Redis接口以及兼容情况
- 配置文件说明
- 数据目录说明
- info信息说明
- 部分管理指令说明
- 差异化命令
- Pika Sharding Tutorials
- Pika订阅
- 配合sentinel(哨兵)实现pika自动容灾
- 如何升级到Pika3.0
- 如何升级到Pika3.1或3.2
- Pika多库版命令、参数变化参考
- Pika分片版本命令
- 副本一致性使用说明
- Pika内存使用
- Pika最佳实践
- 整体架构
- 线程模型
- 全同步
- 增量同步
- 副本一致性
- 快照式备份
- 锁的应用
- nemo存储引擎数据格式
- blackwidow存储引擎数据格式
- Pika源码学习--pika的通信和线程模型
- Pika源码学习--pika的PubSub机制
- Pika源码学习--pika的命令执行框架
- Pika源码学习--pika和rocksdb的对接
- pika-NoSQL原理概述
- pika在codis中的探索
- Pika 笔记
- pika 主从同步原理