ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

如何配置 Dragonfly 把 HNSW 向量索引复制到副本(序列化与重建两条路径)

如何配置 Dragonfly 把 HNSW 向量索引复制到副本(序列化与重建两条路径) 如何配置 Dragonfly 把 HNSW 向量索引复制到副本序列化与重建两条路径【免费下载链接】dragonflyA modern replacement for Redis and Memcached项目地址: https://gitcode.com/GitHub_Trending/dr/dragonfly在 Dragonfly 里用FT.CREATE ... VECTOR HNSW建了向量索引之后如果给主节点挂副本副本上的 HNSW 图不会“自动变出来”HNSW 图是每个(index, field)一张、跨所有 shard 共享的全局结构而全同步 RDB 流是逐 shard 发送的副本侧必须把“图”和“各 shard 的键空间”两块状态重新拼起来。Dragonfly 为此提供了两条互斥的落地路径序列化路径主节点把图结构序列化成 RDB opcode 随全同步流出副本直接恢复shard 数不同时还会重映射GlobalDocId重建路径副本跳过图数据仅凭键流把索引从头重建一遍。下面按“建索引 → 配副本 → 验证”的顺序给出两条路径的完整配置和核对方法。机制细节以 docs/hnsw-index-replication.md 为准复制协议以 docs/replication.md 为准。先弄清两条路径由什么条件决定复制线路上涉及三类数据理解路径选择前先看它们各自的门槛数据载体门槛索引定义FT.CREATE参数AUX 字段search-index无条件写入 summary flow副本幂等地执行FT.CREATE图结构节点、层级、邻居链接表RDB_OPCODE_VECTOR_INDEXopcode 222仅 shard 0 发送、仅非空图发送主节点--serialize_hnsw_index 副本能力VER6各 shard 的 key→DocId 映射RDB_OPCODE_SHARD_DOC_INDEXopcode 223每个 shard 发送同上路径判定依据 docs/hnsw-index-replication.md §4、§6、§7条件副本实际走的路径主节点--serialize_hnsw_index关闭默认即关闭重建跳过步骤 2、3副本从键流重建所有索引主节点开启但副本--deserialize_hnsw_index关闭重建副本到达时直接跳过两个 opcode双方都开启且副本握手时上报的能力达到VER6序列化恢复副本能力低于VER6重建副本只通过 summary flow 收到FT.CREATE定义索引完全靠键流重建序列化开启但主/副本 shard 数不一致且重映射失败或该索引没有收到映射该索引回退到重建两个 flag 都默认false见 snapshot.cc 与 rdb_load.cc 中的 flag 定义所以不显式配置时走的就是重建路径。序列化路径必须主、副本两侧同时打开。第一步启动主节点并创建 HNSW 索引按 docs/quick-start/README.md 的 Docker 方式起一个实例并加上序列化 flag--serialize_hnsw_indextrue。Linux 与 macOS 的网络参数不同下面用带端口映射的写法两种系统都适用两个实例各占一个宿主机端口# 主节点宿主机端口 6379 docker run -p 6379:6379 --ulimit memlock-1 \ docker.dragonflydb.io/dragonflydb/dragonfly --serialize_hnsw_indextrue连上主节点建一个带 HNSW 向量字段的索引再写入文档。以下命令取自仓库测试 search_test.py 中test_replicate_all_index_types的真实用例FT.CREATE all_types_idx ON HASH PREFIX 1 item: \ SCHEMA name TEXT price NUMERIC SORTABLE category TAG location GEO \ embedding VECTOR HNSW 6 TYPE FLOAT32 DIM 2 DISTANCE_METRIC L2# embedding 字段的值是 DIM 个 float32 的原始字节本例 DIM2即 8 字节。 # 仓库测试用 numpy 生成np.array([x, y], dtypenp.float32).tobytes() HSET item:0 name Product 0 price 0 category electronics location -122.0,37.0 embedding 2 个 float32 的原始字节两个占位符需要你自己替换2 个 float32 的原始字节是向量原始字节由客户端侧用 numpy 之类的库生成后写入。注意一个明确限制单个索引目前不支持多个 HNSW 向量字段见 hnsw-index-replication.md 的 Open Issues。第二步启动副本并挂到主节点路径 A序列化恢复主路径副本启动参数加--deserialize_hnsw_indextrue它镜像主节点 flag 的作用关闭时副本对两个 opcode 一律跳过# 副本宿主机端口 6380容器内仍是 6379 docker run -p 6380:6379 --ulimit memlock-1 \ docker.dragonflydb.io/dragonflydb/dragonfly --deserialize_hnsw_indextrue然后在副本上挂主。仓库测试用的是运行期命令等价于通过 redis-cli 执行redis-cli -h 副本地址 -p 6380 REPLICAOF 主节点地址 6379测试中也有用启动参数replicaoflocalhost:主节点端口在副本启动时就挂主节点的写法两种方式等价任选其一即可。路径 B从键流重建替代路径如果不想传图比如索引很小、或想规避 shard 数不一致带来的重映射就不开 flag副本只带--replicaof或执行REPLICAOF主节点也可以不开--serialize_hnsw_index。副本收完键流后会自己把整个 HNSW 索引建出来。关于 shard 数副本与主节点 shard 数相同时映射按 shard id 原位恢复不一致时副本会先建重映射表、改写图里所有global_id再恢复因为GlobalDocId高 32 位编码的是主节点的 shard id。某索引无法完整重映射时该索引的图被丢弃、回退重建——这是文档明确给出的行为不是需要规避的错误。第三步验证副本上的索引与 KNN 结果按下面的顺序核对每一步的判断标准都来自仓库文档与测试确认复制进入稳定状态。主节点INFO REPLICATION会把会话状态报成preparation、full_sync、stable_sync之一副本侧INFO的相位会经历FULL_SYNC_IN_PROGRESS/INITIAL_SYNC再到STABLE_SYNC见 replication.md 的 Observability 一节。等到主节点显示stable_sync再继续。确认索引定义已落到副本。在副本上执行FT._LIST返回里应包含all_types_idx测试即以此判断索引存在。用同一条 KNN 查询对比主、副本结果。测试用的查询形式$vec传入 2 个 float32 的原始字节如[50.0, 50.0]FT.SEARCH all_types_idx *[KNN 10 embedding $vec] PARAMS 2 vec 查询向量原始字节在STABLE_SYNC后对主、副本各跑一次。判断标准参照仓库测试副本应返回同样数量的结果KNN 10 对应计数 10且两侧结果键集合一致。测试特意把两侧键排序后再比较因为浮点距离并列时返回顺序可能有细微差异——所以核对时应比较键集合而不是逐位比返回顺序。可选确认副本实际走了哪条路径。副本日志里有明确的路径标记仓库测试正是靠这几个字符串断言的示例字符串非固定预期日志Restored HNSW index—— 同 shard 数下从序列化图恢复global_ids remapped—— 不同 shard 数下经重映射恢复Will rebuild from scratch伴随 HNSW 字样—— 走了重建路径。测试里用logbuflevel-1强制 glog 每行立即刷盘这样在进程日志文件里才能读到 INFO 行如果你也要从日志文件核对副本加这个启动参数。边界与限制空图不传输主节点不发送空索引的图块副本从空的键流直接重建属正常行为。磁盘 RDB 不含索引数据search-index数据只出现在复制用的 RDB 流里RDB 保存到磁盘时会整体省略——向量索引是“复制态”的概念不要把“RDB 文件里没有索引”当成数据丢失。重建路径的语义差异全重建时加载期间缓冲的操作会被丢弃而不是回放重建本来就会从键流重索引所有文档而序列化恢复路径下这些操作会在全部分片完成水合后统一 drain 回放。这解释了为什么两条路径的加载耗时特征不同重建时间与文档量成正比。版本门槛低于VER6能力的副本只收到FT.CREATE定义无论 flag 如何配置都走重建。更底层的线格式HnswNodeData结构、MRMW 锁、借用向量不变量、状态机kProhibit/kRestoring/kBuilding/kSerializing都在 hnsw-index-replication.md 中日常配置不需要接触复制握手、全同步/部分同步的完整机制见 replication.md。【免费下载链接】dragonflyA modern replacement for Redis and Memcached项目地址: https://gitcode.com/GitHub_Trending/dr/dragonfly创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进