内容提要
本文记录hypatia系统从DuckDB+SQLite组合迁移至纯SQLite的架构升级。原架构因DuckDB的OLAP特性与记忆系统的OLTP负载错配,导致5GB存储中98%为死空间且并发受限。新架构利用SQLite的WAL模式支持多Agent并发,通过单事务保证原子性,向量索引外置为可重建文件。迁移后空间降至100MB,验证了“人守语义契约,AI完成方言翻译”的工作模式。
延伸解读
OLAP与OLTP的错配:为什么DuckDB不适合记忆系统
文章指出,DuckDB的列存、向量化执行等OLAP特性在hypatia的OLTP负载下成为负担:大量点查、高频小事务和并发访问正是DuckDB的弱项。5GB存储中98%为死空间,源于OLAP引擎未针对频繁增删设计空间回收。这提醒我们,选型需匹配实际负载模式,而非仅看技术亮点。
SQLite的并发与原子性优势
SQLite的WAL模式支持多读者与单写者并行,写写冲突由busy_timeout自动重试,适合多Agent共享书架的场景。更重要的是,单事务保证数据与索引原子生效,避免了旧架构跨库写入的撕裂态。这体现了在特定场景下,简单技术可能比复杂组合更可靠。
向量索引外置:权衡与取舍
向量检索是迁移中的硬骨头。作者评估了多种方案后,选择将embedding存于SQLite(源真相),HNSW索引外置为可重建文件,既获得真正的ANN,又不牺牲单源真相。这展示了在技术不成熟时,通过分离数据与索引来平衡性能与一致性的务实思路。
空间节省的量化与局限
迁移后空间从5GB降至100MB,但其中约三分之二为embedding的固有成本,无法节省。usearch快照另占80MB,可删除重建。这表明简化带来的空间收益主要来自消除死空间,而非数据本身。若未来数据量达亿级,仍需依赖pgvector等外部方案。
Q&A
hypatia系统为什么从DuckDB+SQLite组合迁移到纯SQLite?
因为DuckDB的OLAP特性与hypatia记忆系统的OLTP负载不匹配,导致存储空间浪费和并发受限。迁移到SQLite后,空间从5GB降至100MB,并支持多Agent并发。
DuckDB在hypatia系统中存在哪些问题?
DuckDB是单进程单写者,缺乏成熟的并发控制,不适合高频小事务和并发访问。此外,其列存和向量化执行对点查和过滤操作无优势,且空间回收机制不完善,导致大量死空间。
SQLite的WAL模式如何支持多Agent并发?
SQLite的WAL模式允许多读者与单写者并行,读写互不阻塞,写写冲突由busy_timeout自动重试,从而支持多个Agent在同一机器上无冲突协作。
新架构如何保证数据写入的原子性?
新架构将一次CRUD操作放在SQLite的单个事务中,源表、文档锚点、JSON倒排、全文索引同时生效,避免了旧架构跨库写入的撕裂态。向量索引作为可重建的缓存,不参与源真相。
hypatia的向量索引是如何实现的?
向量索引采用外置文件系统快照(usearch,Apache-2.0),embedding以BLOB列存储在SQLite中作为源真相,HNSW图作为派生结构可随时从BLOB重建。未来将接入官方vec1扩展。
迁移后存储空间从5GB降到100MB,这100MB主要由什么构成?
100MB中约三分之二是embedding本身(每条1024维float32),这是数据的固有成本;其余为其他数据。usearch快照另计约80MB,可删除重建。
hypatia的JSE指令集在迁移中扮演什么角色?
JSE指令集是hypatia与存储层之间的契约,固定为二十个算子。指令集稳定后,语义与实现分离,AI可以根据语义在SQLite上重新实现,验证了“人守语义契约,AI完成方言翻译”的工作模式。
新架构中全文检索和递归查询如何实现?
全文检索使用FTS5(jieba预分词+porter词干),递归查询使用递归CTE,它们与JSON倒排、向量检索都在同一个SQLite连接和事务边界内完成,共享文档锚点,实现一致检索。