Pika 分片模式 API 实战指南:Table、Slot 与 pkcluster 命令体系全解析 数据库KV存储后端【免费下载链接】pikaPikiwidb is a Redis-Compatible database developed by Qihoos infrastructure team.项目地址https://gitcode.com/gh_mirrors/pi/pika点击查看免费下载导读本文以 PikaPikiwidb奇虎 360 基础设施团队开源的 Redis 兼容数据库官方分片 API 文档 docs/ops/shardingAPI_en.md 为核心骨架系统讲解 Pika 分片模式下 Table 与 Slot 的核心概念、从 3.1.2 到 3.3 版本逐步演进的管理命令pkcluster家族、slaveof、动态建表并结合仓库源码conf/pika.conf、include/pika_slot_command.h、src/pika_slot_command.cc、src/pika_command.cc与集成测试tests/integration/slotmigrate_test.go验证命令的底层实现与真实用法。读完本文你将掌握 Pika 分片集群的建表、分片划分、主从同步配置的完整命令集以及分片模式下命令兼容性的边界与规避方案。一、分片模型Table、Slot 与 Key 路由从 Pika 3.1.2 起Pika 引入了完整的分片sharding支持并为此增加了一系列专用命令。分片模式的核心抽象是Table一个 Table 下可以挂载若干个SlotSlot 数量受配置文件中的default-slot-num限制客户端读写请求会根据 Key 进行映射如果当前 Pika 实例负责该 Slot那么这个 Key 会落到对应的 Slot 上执行以分片模式启动时Pika 会自动创建一个默认 Table名为db0用户可以执行addslots命令向这个 Table 增加 SlotPika 会将 Table 的 Slot 信息记录到db-path目录下的meta文件中实现分片元信息的持久化不同 Pika 实例之间的 Slot 可以同步数据一个 Slot 的身份可以是主master、从slave也可以既是主又是从一旦某个 Slot 具有了从的身份它就是不可写的。1.1 Key 到 Slot 的路由算法从源码看Pika 的数据分布采用取模哈希策略。include/pika_data_distribution.h 中定义了HashModulo数据分布类并保留了一个 CRC32 的多项式魔数// polynomial reserved Crc32 magic num const uint32_t IEEE_POLY 0xedb88320; class PikaDataDistribution { public: virtual ~PikaDataDistribution() default; virtual void Init() 0; }; class HashModulo : public PikaDataDistribution { public: ~HashModulo() override default; void Init() override; };也就是说Key 会被计算为 CRC32 哈希值后再对 Slot 总数取模从而映射到某个 Slot。该结论可以从集成测试中得到印证tests/integration/slotmigrate_test.go 中通过slotshashkey命令验证了具体 Key 的归属slotshashkey : clientMaster.Do(ctx, slotshashkey, key1) Expect(slotshashkey.Val()).To(Equal([]interface{}{int64(80)})) slotshashkey1 : clientMaster.Do(ctx, slotshashkey, key2) Expect(slotshashkey1.Val()).To(Equal([]interface{}{int64(490)})) slotshashkey2 : clientMaster.Do(ctx, slotshashkey, key3) Expect(slotshashkey2.Val()).To(Equal([]interface{}{int64(380)}))可以看到key1、key2、key3被分别映射到 Slot 80、490、380验证了“Key 经过哈希后确定所属 Slot”的路由机制。1.2 配置项default-slot-num在 conf/pika.conf 中default-slot-num的默认配置为# The slot number of pika when used with codis. default-slot-num : 1024注释明确说明该参数服务于 Pika 与 Codis 协同使用的场景默认值为 1024。这意味着一个 Table 的 Slot ID 合法区间为[0, default-slot-num - 1]即默认情况下为[0, 1023]。分片 API 文档中所有addslots/delslots命令的 ID 取值范围均以此为准。二、分片模式的必备配置要运行分片模式除了default-slot-numconf/pika.conf 中还有一组与 Slot 迁移、分片运维直接相关的配置# slotmigrate is mainly used to migrate slots, usually we will set it to no. # When you migrate slots, you need to set it to yes, and reload slotskeys before. # slotmigrate [yes | no] slotmigrate : no # slotmigrate thread num slotmigrate-thread-num : 1 # thread-migrate-keys-num 1/8 of the write_buffer_size_ thread-migrate-keys-num : 64slotmigrate [yes | no]是否开启 Slot 迁移。日常运行建议为no执行 Slot 迁移前需先置为yes并提前执行 slotskeys 重载reload操作slotmigrate-thread-numSlot 迁移使用的线程数默认 1thread-migrate-keys-num迁移线程单批处理的 Key 数量默认 64。这些参数支持运行时动态调整tests/integration/server_test.go 中通过CONFIG GET slotmigrate、CONFIG SET slotmigrate yes、CONFIG SET slotmigrate-thread-num 4验证了动态读写能力。三、pkcluster 命令家族单 Table 时代的核心操作Pika 3.1.2 起以下命令自 Pika 3.1.2 引入均作用于默认 Tabledb0。3.1pkcluster info查看 Slot 同步信息作用展示 Slot 的同步信息包括 Binlog 偏移量、主从身份等。命令含义pkcluster info slot查看默认 Table 中所有 Slot 的同步信息pkcluster info slot db0:0-6,7,8查看 table0db0下 ID 为 0-6、7、8 对应 Slot 的同步信息pkcluster info table 1查看 table1 的信息包括 QPS、Table 分片个数等需要注意 Slot 列表的写法0-6,7,8表示区间与单个 ID 混合的列表形式这一写法与后续addslots/delslots的 ID 语法一脉相承。3.2pkcluster addslots向默认 Table 添加 Slot作用在默认 Table 中添加指定 ID 的 SlotID 区间为[0, default-slot-num - 1]支持三种指定 ID 的语法pkcluster addslots 0-2 # 添加 id 为 0,1,2 的 3 个 slot pkcluster addslots 0-2,3 # 添加 id 为 0,1,2,3 的 4 个 slot pkcluster addslots 0,1,2,3,4 # 添加 id 为 0,1,2,3,4 的 5 个 slot三种语法分别是区间写法0-2、区间与单值混合0-2,3、纯单值列表0,1,2,3,4。3.3pkcluster delslots从默认 Table 删除 Slot作用在默认 Table 中删除指定 ID 的 SlotID 区间同样为[0, default-slot-num - 1]语法与addslots完全一致pkcluster delslots 0-2 # 删除 id 为 0,1,2 的 3 个 slot pkcluster delslots 0-2,3 # 删除 id 为 0,1,2,3 的 4 个 slot pkcluster delslots 0,1,2,3,4 # 删除 id 为 0,1,2,3,4 的 5 个 slot3.4pkcluster slotsslaveofSlot 级主从同步作用用于默认 Table 下某些 Slot 向其他 Pika 实例的对应 Slot 发起数据同步请求或取消同步请求。指定 Slot 的语法与addslots/delslots类似但额外支持all表示默认 Table 下的所有 Slot。pkcluster slotsslaveof no one [0-3,8-11 | all] # 指定 slot 断开主从同步 pkcluster slotsslaveof ip port [0-3,8,9,10,11 | all] # 指定 slot 建立主从同步ip 为目标 Pika 实例地址port 为其端口 pkcluster slotsslaveof ip port [0,2,4,6,7,8,9 | all] force # 指定 slot 进行全量同步force 关键字触发全同步三个变体的语义分别为断开同步no one、建立增量同步ip port、强制全量同步ip port ... force。3.5slaveof全局主从的快捷方式slaveof命令等价于pkcluster slotsslave ip port all即对整个默认 Table 的所有 Slot 建立主从同步。这条等价关系意味着在分片模式下传统的整实例主从复制slaveof ip port其实就是对全部 Slot 逐一建立同步的语法糖底层复用同一套 Slot 同步机制。四、多 Table 动态管理Pika 3.3 起自 Pika 3.3 开始分片模式支持动态创建 Table。为了保持向后兼容并降低未使用多 Table 用户的学习成本Pika 默认会自动创建 table 0Slot 数为配置文件中的default-slot-num使用其他 Table 时需要手动创建。4.1pkcluster addtable创建 Table作用创建 Table创建时需指定table-id和default-slot-num默认 table-id 为 0。pkcluster addtable 1 64 # 创建 table-id 为 1、default-slot-num 为 64 的表这意味着每个 Table 可以拥有自己独立的 Slot 总数而不是共享全局的default-slot-num。4.2pkcluster deltable删除 Table作用删除指定table-id的表并删除该表中所有 Slot。pkcluster deltable 1 # 删除 table-id 为 1 的表及其全部 slot4.3pkcluster addslots多 Table 版本作用在指定 table-id 的表中添加指定 ID 的 SlotID 区间为[0, default-slot-num - 1]不指定 table-id 时在默认表中添加即与 3.1.2 时代语法兼容。pkcluster addslots 0-2 1 # 在 table-id 为 1 的表中添加 id 为 0,1,2 的 3 个 slot pkcluster addslots 0-2,3 1 # 在 table-id 为 1 的表中添加 id 为 0,1,2,3 的 4 个 slot pkcluster addslots 0,1,2,3,4 1 # 在 table-id 为 1 的表中添加 id 为 0,1,2,3,4 的 5 个 slot注意参数顺序slot ID 列表在前table-id 在后。4.4pkcluster delslots多 Table 版本作用在指定 table-id 的表中删除指定 ID 的 SlotID 区间为[0, default-slot-num - 1]三种语法与addslots对称pkcluster delslots 0-2 1 # 在 table-id 为 1 的表中删除 id 为 0,1,2 的 3 个 slot pkcluster delslots 0-2,3 1 # 在 table-id 为 1 的表中删除 id 为 0,1,2,3 的 4 个 slot pkcluster delslots 0,1,2,3,4 1 # 在 table-id 为 1 的表中删除 id 为 0,1,2,3,4 的 5 个 slot4.5pkcluster slotsslaveof多 Table 版本作用用于指定 table-id 的表下某些 Slot 向其他 Pika 实例对应 Slot 发起或取消数据同步请求同样支持all表示该 Table 下的所有 Slot。table-id 参数置于命令末尾pkcluster slotsslaveof no one [0-3,8-11 | all] 1 # 断开 table-id 为 1 的表中指定 slot 的主从同步 pkcluster slotsslaveof ip port [0-3,8,9,10,11 | all] 1 # 建立 table-id 为 1 的表中指定 slot 的主从同步 pkcluster slotsslaveof ip port [0,2,4,6,7,8,9 | all] force 1 # 对 table-id 为 1 的表中指定 slot 执行全量同步五、分片模式的命令兼容性边界分片模式对命令的支持遵循明确边界官方文档在 docs/ops/shardingAPI_en.md 中给出了权威说明在分片模式下Pika 全面支持输入参数为单个 Key的命令对于输入参数可以是多个 Key的命令分片模式下进行了部分支持。5.1 当前分片模式不支持的命令以下命令在分片模式下不被支持———MsetnxScanKeysScanxPKScanRangePKRScanRangeRPopLPushZUnionstoreZInterstoreSUnionSUnionstoreSInterSInterstoreSDiffSDiffstoreSMoveBitOpPfAddPfCountPfMergeGeoAddGeoPosGeoDistGeoHashGeoRadiusGeoRadiusByMember这张清单覆盖了几类典型的“跨 Key/全局空间”操作全局扫描类Scan、Keys、Scanx、PKScanRange、PKRScanRange——它们遍历的是整个 Keyspace无法限定在单个 Slot 内执行跨 Key 集合运算ZUnionstore、ZInterstore、SUnion、SUnionstore、SInter、SInterstore、SDiff、SDiffstore、SMove——多个 Key 的参与方可能落在不同 Slot跨 Key 原子写Msetnx、RPopLPush位图/HLL/Geo 聚合类BitOp、PfAdd、PfCount、PfMerge、GeoAdd、GeoPos、GeoDist、GeoHash、GeoRadius、GeoRadiusByMember。5.2 命令支持计划hash tags 控制数据分布官方文档明确的分片支持方针如下基础设施支持基于 hash tags 的数据分片。用户可以为具体使用场景在一定程度上控制数据在集群中的分布基本方针针对涉及多个 Key 的命令这些 Key 必须位于同一分片上即只支持分片内的操作而全局空间的命令暂不支持示例要支持RPOPLPUSH src dst需要src和dst两个列表位于同一分片上用户可以通过为两个 Key 添加相同的 hash tag 来实现这一目标。hash tag 的机制是对 Key 中{...}花括号内的部分计算哈希从而让包含相同 tag 的多个 Key 必然映射到同一 Slot。这为多 Key 命令在分片模式下的使用提供了工程化路径——业务上需要“原子绑定”的 Key 组都应通过相同的 hash tag 显式约束其分布。六、源码级透视分片命令的注册与实现6.1 命令注册表分片相关的底层命令注意并非全部以pkcluster开头还包括slotsinfo、slotsdel、slotshashkey、slotsscan、slotsmgrtslot等统一在 src/pika_command.cc 中注册。以其中若干为例// Slots related std::unique_ptrCmd slotsinfoptr std::make_uniqueSlotsInfoCmd(kCmdNameSlotsInfo, -1, kCmdFlagsRead | kCmdFlagsAdmin | kCmdFlagsSlow); cmd_table-insert(std::pairstd::string, std::unique_ptrCmd(kCmdNameSlotsInfo, std::move(slotsinfoptr))); std::unique_ptrCmd slotmgrtasynccancel std::make_uniqueSlotsMgrtAsyncCancelCmd( kCmdNameSlotsMgrtAsyncCancel, 1, kCmdFlagsRead | kCmdFlagsAdmin | kCmdFlagsSlow); cmd_table-insert(std::pairstd::string, std::unique_ptrCmd(kCmdNameSlotsMgrtAsyncCancel, std::move(slotmgrtasynccancel))); std::unique_ptrCmd slotsdelptr std::make_uniqueSlotsDelCmd(kCmdNameSlotsDel, -2, kCmdFlagsRead | kCmdFlagsAdmin | kCmdFlagsSlow); cmd_table-insert(std::pairstd::string, std::unique_ptrCmd(kCmdNameSlotsDel, std::move(slotsdelptr))); std::unique_ptrCmd slotshashkeyptr std::make_uniqueSlotsHashKeyCmd(kCmdNameSlotsHashKey, -2, kCmdFlagsRead | kCmdFlagsAdmin | kCmdFlagsSlow); cmd_table-insert(std::pairstd::string, std::unique_ptrCmd(kCmdNameSlotsHashKey, std::move(slotshashkeyptr))); std::unique_ptrCmd slotsreloadptr std::make_uniqueSlotsReloadCmd(kCmdNameSlotsReload, 1, kCmdFlagsRead | kCmdFlagsAdmin | kCmdFlagsSlow); cmd_table-insert(std::pairstd::string, std::unique_ptrCmd(kCmdNameSlotsReload, std::move(slotsreloadptr))); std::unique_ptrCmd slotscleanupptr std::make_uniqueSlotsCleanupCmd(kCmdNameSlotsCleanup, -2, kCmdFlagsRead | kCmdFlagsAdmin | kCmdFlagsSlow); cmd_table-insert(std::pairstd::string, std::unique_ptrCmd(kCmdNameSlotsCleanup, std::move(slotscleanupptr)));可以看到这些命令大多带有kCmdFlagsAdmin管理命令与kCmdFlagsSlow慢命令标记说明它们属于运维管理面需要按管理命令的权限模型执行。6.2 内部迁移 Key 与迁移客户端include/pika_slot_command.h 中定义了 Slot 迁移过程中使用的内部 Key 前缀与迁移客户端核心类const std::string SlotKeyPrefix _internal:slotkey:4migrate:; const std::string SlotTagPrefix _internal:slottag:4migrate:; const size_t MaxKeySendSize 10 * 1024;_internal:slotkey:4migrate:与_internal:slottag:4migrate:是迁移过程中登记 Slot 内 Key 清单的专用内部 Key 前缀这也是slotmigrate开启前需要 reload slotskeys 的原因——先由SlotsReloadCmd将 Slot 的 Key 关系重建到这些内部 Key 中后续迁移才能按图索骥PikaMigrate类负责管理发往目标实例的迁移客户端连接src/pika_slot_command.cc 中的GetMigrateClient会按host:port复用已建立的net::NetCli连接并设置收发超时默认取自配置timeout见CleanMigrateClient中的超时清理逻辑提前 20 秒回收空闲连接。此外PikaMigrate针对不同数据类型提供了独立的解析入口ParseKKeyKV、ParseZKeyZSet、ParseSKeySet、ParseHKeyHash、ParseLKeyList、ParseMKeyStream/多字段类型说明 Slot 迁移是逐 Key 按类型序列化后发送到目标实例执行的。6.3 迁移命令的实际形态集成测试 tests/integration/slotmigrate_test.go 展示了异步 Slot 迁移命令的真实调用方式slotsmgrttagslotasync : clientMaster.Do(ctx, slotsmgrttagslot-async, 127.0.0.1, 9231, 5000, 200, 33554432, 51, 1024) Expect(slotsmgrttagslotasync.Val()).To(Equal([]interface{}{int64(0), int64(1)}))参数依次为目标 IP、目标端口、超时5000ms、单批最大 Key 数200、单批最大字节数33554432 即 32MB、起始 Slot ID、Slot 总数返回[0, 1]表示迁移进度。测试前置流程SlotMigrateEnv也印证了文档描述的操作顺序先slaveof no one断开同步、清空双方 DB、再将slotmigrate置为yes测试结束后恢复为no。七、验证与排障建议确认 Key 归属用slotshashkey key查询某个 Key 映射到的 Slot 编号与pkcluster info slot中该 Slot 的归属状态对照判断读写是否被路由到正确实例检查同步状态用pkcluster info slot db0:0-6,7,8查看目标 Slot 的 Binlog 偏移量与主从角色一旦 Slot 处于从属状态写入会失败需要先确认业务 Key 是否被路由到了非从属 Slot迁移前准备将slotmigrate置为yes并执行 slotskeys 重载slotsreload后再发起slotsmgrtslot-async类迁移命令完成后恢复slotmigrate no多 Key 命令规避避免在分片模式下使用 5.1 节 清单中的命令必须使用的场景通过 hash tags 将相关 Key 约束到同一 Slot仅执行分片内操作。八、延伸阅读分片 API 英文版docs/ops/shardingAPI_en.md中文版docs/ops/shardingAPI.md分片教程含多实例部署与数据分布实践docs/ops/shardingTutorials_en.md中文版 docs/ops/shardingTutorials.mdSlot 迁移命令专项文档docs/ops/migrateslotCommand_en.md中文版 docs/ops/migrateslotCommand.md命令差异对照含分片模式支持情况docs/ops/APIDifference_en.md中文版 docs/ops/APIDifference.md相关配置default-slot-num、slotmigrate等conf/pika.conf分片命令源码实现include/pika_slot_command.h、src/pika_slot_command.cc、命令注册表 src/pika_command.cc集成测试示例tests/integration/slotmigrate_test.go、tests/integration/server_test.go。赞分享数据库KV存储后端【免费下载链接】pikaPikiwidb is a Redis-Compatible database developed by Qihoos infrastructure team.项目地址https://gitcode.com/gh_mirrors/pi/pika点击查看免费下载相关推荐Pika 分片模式Sharding Mode实战指南Slot 概念、配置调参与 Codis 集群接入Pika 分片模式Sharding Mode实战指南Slot 概念、配置调参与 Codis 集群接入 本文是 Pika 分片模式Sharding Mod数据库KV存储后端Apache ShenYu Wasm 插件实战编译 Rust 实现的 Discovery Handlerwasm32-wasi 构建与类路径命名规范Apache ShenYu Wasm 插件实战编译 Rust 实现的 Discovery Handlerwasm32 wasi 构建与类路径命名规范 本篇数据库KV存储后端terraform-provider-aws 标识符大小写规范解析names/caps 初短词命名规则与 semgrep 强制机制terraform provider aws 标识符大小写规范解析names/caps 初短词命名规则与 semgrep 强制机制 在 terraform p数据库KV存储后端上一篇Charts.css图表类型实战柱状图与条形图下一篇FBCTF多语言支持与国际化设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考