4.4 持久化、备份与压缩 生命周期的最后一站是保护。承接 4.3 的落盘与墓碑话题,本节讲三件事:数据怎么持久化才不怕断电崩溃,备份恢复方案怎么设计才敢真出事时用,以及内存不够时压缩档位怎么选。旧版教程的"持久化与备份""数据压缩技术"两节在此合并——它们共同回答同一个问题:怎么用有限的硬件,把数据的durability和可用性兜住。 持久化:日志先行 向量库的持久化骨架与传统数据库同源:写前日志先行,写入请求先追加日志并按策略刷盘(每次确认都刷最安全、定期刷吞吐高),日志可靠后才算写入确认;内存段定期封段落盘成不可变文件;崩溃恢复时,重放日志把未落盘的增量补回来。理解这套机制对运维的直接价值是两个判断:一是写入确认等级的选择——金融级对账场景选强刷盘,内容类场景选组提交换吞吐;
生命周期的最后一站是保护。承接 4.3 的落盘与墓碑话题,本节讲三件事:数据怎么持久化才不怕断电崩溃,备份恢复方案怎么设计才敢真出事时用,以及内存不够时压缩档位怎么选。旧版教程的"持久化与备份""数据压缩技术"两节在此合并——它们共同回答同一个问题:怎么用有限的硬件,把数据的durability和可用性兜住。
向量库的持久化骨架与传统数据库同源:写前日志先行,写入请求先追加日志并按策略刷盘(每次确认都刷最安全、定期刷吞吐高),日志可靠后才算写入确认;内存段定期封段落盘成不可变文件;崩溃恢复时,重放日志把未落盘的增量补回来。理解这套机制对运维的直接价值是两个判断:一是写入确认等级的选择——金融级对账场景选强刷盘,内容类场景选组提交换吞吐;二是恢复时长的估算——恢复时间约等于"加载最近快照/段文件加重放增量日志",日志保留窗口越长,可恢复到的时间点越多,但恢复重放也越久。
内存映射是向量场景的常客:把段文件映射进进程地址空间,让操作系统的页缓存代替应用层缓存,热数据自然驻留内存、冷数据按需换入。它让"内存装不下"的集合也能跑,代价是页缺失抖动——冷启动或缓存被挤时会看到延迟毛刺,第五章 5.4 的缓存预热正是针对它。

备份设计只有一条铁律:没有演练过的备份等于没有备份。方案设计按三步走。第一步选恢复目标:能接受丢多少数据(恢复点目标)与能接受停多久(恢复时间目标),前者决定日志保留窗口与备份频率,后者决定快照与恢复工具的效率。第二步选层次:集合级快照覆盖误删误改,是日常主力;跨地域复制应对机房级故障;对象存储归档满足低成本长保留。第三步排演练:季度级恢复演练,量出真实恢复时长,校准文档里的承诺。向量库备份还有一个特有细节:向量与索引都要进备份。只备了原始向量没备索引,恢复后要全量重建,恢复时间目标直接爆表;主流系统的快照机制都含段文件(即已含索引),自己搭的导出脚本则常在这一步漏项。
压缩的数学很朴素:内存等于条数乘维度乘每维字节数。一亿条 768 维向量,单精度是每维四字节,约 288 GB;八位标量量化砍到约 72 GB;乘积量化把每维成本摊进码本,能压到几个 GB;二值量化每维一比特,再乘以重排余量的开销,依然是极省的档位。选择时的决策树也朴素:先问这个集合能不能整体放进单机内存,能则量化只在需要更多余量时启用;不能则先算量化后能否装下,装不下再上磁盘索引或分片。同时记住 3.2 的补偿原则:压缩档位越激进,越要配"扩大候选集加原始向量重排"的组合,把召回买回来。
备份方案的两个参数——恢复点目标(最多能丢多久的数据)与恢复时间目标(最多能停多久)——必须算出来而不是感觉出来。算术如下:恢复点目标约等于日志保留窗口与备份频率的较小者,日志按小时归档、快照按天制作,最坏丢失时长约等于一个归档周期;恢复时间目标约等于"恢复最近的快照耗时加重放日志耗时加验证耗时",前两项随数据量线性增长,验证环节(抽查询比对、探针召回检查)最容易被漏算却常占去三成时间。把这两个数字反推到配置上:业务说"最多丢十分钟",日志归档周期就得压到十分钟以内;业务说"最多停两小时",快照加日志的恢复链路就必须在预发实测出九十分钟以内的成绩——剩下三十分钟留给验证与决策。算术不性感,但它把合规部门抽象的要求翻译成了可执行的配置项。
| 层次 | 对象与频率 | 覆盖的故障 |
|---|---|---|
| 写前日志归档 | 实时或分钟级 | 崩溃恢复、分钟级恢复点 |
| 集合快照 | 每日,含段文件与索引 | 误删集合、坏段、日常回滚 |
| 跨区复制快照 | 每日或每周 | 机房级故障 |
| 冷归档 | 每周或每月,低成本介质 | 长期留存与审计要求 |
四层配方里最常被砍掉的是冷归档,而监管问询与勒索场景里它恰恰是最后的底牌——在线备份被误删或被加密时,离线冷档是唯一干净副本。每层的恢复流程都要有书面脚本并演练过,"能恢复"的定义永远以最近一次演练结果为准。
先说清"选错"的两种形态。档位过重(压缩太狠、召回不达标):不必全量重建——多数系统支持在量化参数不变时只调精修候选倍数,用延迟换回召回;如果码本本身欠拟合,那就要重训码本,走 3.3 的双索引切换。档位过轻(内存吃紧):先调低精修倍数省运行时内存,再把部分分片迁到量化更深的档位灰度验证,最后全量切换。两条补救路径共同的前提是 5.5 的基准在档位变更前后各跑一次——没有基线的档位调整等于蒙眼开车。
看工作集的形态。查询热点集中(头部内容占了绝大多数流量)时,显式缓存把热点钉在内存里,命中率可控、延迟平稳,是默认优选;查询热点分散或集合远超内存时,内存映射让操作系统按需换页,省掉自建缓存的复杂度,代价是冷启动毛刺与缓存抖动。两者也能叠加:段文件走内存映射承载长尾,热点向量再显式缓存一层。判断依据照旧是数据——把查询键的访问分布画出来,头部集中度一目了然。
主流实现有两种答案,语义差别很大。写时复制式快照:快照时刻冻结引用,新写入进新段,快照看到的是"那一刻"的一致视图,恢复点清晰;暂停式快照:制作期间短暂阻塞写入,窗口通常秒级,但高峰期会形成写入毛刺。使用前要弄清自己的产品属于哪种——把每日快照排在写入高峰,暂停式实现会让写入延迟曲线每天准时出现一个鼓包。另外快照的存储成本按"基线加增量"计,相邻快照共享未变更段,所以加频快照的边际成本远低于直觉,恢复点目标要求高时可以大方加密频率。
不会破坏语义,但会改变分数的"味道"。量化后的距离是原始距离的有噪版本,排序大体保持、数值漂移——这直接冲击 2.2 里辛苦标定的阈值:为原始分数定的阈值,在量化分数上要么过松要么过紧。补救是把阈值标定流程重跑在压缩后的分数分布上,或干脆让阈值判断使用精修后的原始距离。这条提醒与第五章重排的"精修用原始向量"是同一原则的两个侧面:压缩只负责粗筛,涉及分数精度的判断都交给原始数据。
系统视角至此完整。下一章回到查询侧:请求落到这些组件之后,引擎内部怎么把它跑到毫秒级。