Chroma 教程

磁盘上到底有什么

🎉摘要:本文详细解析Chroma持久化库的磁盘结构,包括chroma.sqlite3元数据库(含collections、segments、embeddings等表)和HNSW索引二进制文件(header.bin、data_level0.bin、link_lists.bin),并说明写入先写日志后异步建索引的机制,确保查询立即可见但需注意WAL堆积影响性能。适合备份与排查场景。

要看明白 Chroma 在磁盘上到底存了些什么,可以使用 PersistentClient 建个本地持久化库,然后塞点数据,观察目录结构。

例如:

import chromadb

client = chromadb.PersistentClient(path="./chroma_data")
col = client.get_or_create_collection("notes", embedding_function=None)
col.add(ids=["id1", "id2", "id3"],
        embeddings=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
        documents=["a", "b", "c"])

运行示例,我本机实测后,当前目录下面多了一个 chroma_data 数据,结构如下图:

其中:

  • chroma.sqlite3:元数据库。存集合定义、记录 id、metadata、写入日志(WAL)。用 sqlite 打开(也可以使用其他工具,如 DBeaver)能看到如下图的这些表

其中:

作用
collections集合定义,含 name、dimension、config_json_str,如下图:
segments段(segment)定义,分 VECTOR 段和 METADATA 段
embeddings记录 id 到段的映射
embedding_metadataembedding_metadata_arraymetadata 的标量值和数组值
embeddings_queue写前日志(WAL),还没落进索引的写入
embedding_fulltext_search*SQLite FTS5 的虚表,给 where_document 用
max_seq_idmigrations序列号和迁移记录
  • e9024eb6-2b34-42e9-932f-a02cff6af50a:这就是集合的 UUID,里面是 HNSW 索引的二进制文件(header.bin 存元信息,data_level0.bin 存第 0 层的向量,link_lists.bin 存图的连接关系)。

为什么要了解磁盘存储结构?理解磁盘结构对下面两件事有用:

  1. 备份:直接拷整个目录就行,但要在没有写入的时候拷,或者用 chroma vacuum 先整理(第 10 章)。

  2. 排查:chroma.sqlite3 可以直接用 sqlite 打开看,查集合配置、查记录数都很方便,比写代码快。

sqlite3 chroma_data/chroma.sqlite3 "SELECT id, name, dimension FROM collections;"


写入什么时候能查到?

Chroma 的写入是“先写日志,再异步建索引”:

  1. add 调用返回时,数据已经进了 SQLite 的 embeddings_queue(WAL)

  2. 后台线程把 WAL 里的向量批量刷进 HNSW 索引,刷的时机由 sync_threshold 控制(默认累计 1000 条)

  3. 查询时会同时查索引和 WAL,所以不会出现"刚写进去查不到"

所以你不用担心一致性问题,add 返回后立刻 query 一定能查到。

但要知道 WAL 里的数据走的是暴力扫描,WAL 堆太多会拖慢查询 —— 批量灌完数据之后,可以等一会儿或者重启一下让它刷完。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号