zhiqiang-hhhh opened a new pull request, #386:
URL: https://github.com/apache/doris-thirdparty/pull/386
## feature Support IVF on-disk index with FAISS PreadInvertedLists
### Background
当前 Doris 的 FAISS ANN 索引仅支持内存模式——索引数据全量加载到内存。对于大规模向量数据(数十亿级别),内存占用是主要瓶颈。本 PR
实现 IVF on-disk 索引:索引的 inverted list 数据保留在磁盘(compound file)上,查询时按需读取,配合 LRU
cache 实现热数据缓存。
### FAISS 侧修改(contrib/faiss, 6 个文件, +472 行)
基于 faiss v1.11.0(commit `0276f0bb7e4`),新增 1 个 commit。所有修改均以上游代码风格编写、使用 MIT
license header,保留未来提交到 FAISS 社区的可能性。
#### 1. 新增 `faiss/impl/random_access_reader.h/.cpp` — 随机读取抽象
- `ReadRef`:零拷贝读取句柄,持有借出数据的生命周期(可以是 cache pin、mmap 区域或堆内存)
- `RandomAccessReader`:positional read 抽象接口
- `read_at(offset, ptr, nbytes)`:纯虚,拷贝读取
- `borrow(offset, nbytes)`:虚方法,默认实现 alloc + read_at;cache-backed 子类可
override 返回零拷贝指针
- `FileRandomAccessReader`:基于 POSIX `pread(2)` 的默认实现
**设计说明**:与上游已有的 `IOReader`(顺序流,用于序列化/反序列化)正交。`RandomAccessReader`
是运行时数据访问接口,支持并发无状态位置读取。
#### 2. 新增 `faiss/invlists/PreadInvertedLists.h/.cpp` — 基于 pread 的只读倒排表
替代 `OnDiskInvertedLists`(依赖 mmap),适用于:
- 数据在 compound file 内(没有独立 fd 可 mmap)
- 需要用户态 cache 介入
- 后端是远程存储
核心设计:
- 复用 `OnDiskOneList` 元数据布局,与 `OnDiskInvertedLists` 完全兼容
- `set_reader()` 注入 `RandomAccessReader`,实现存储解耦
- Iterator 路径(`use_iterator = true`)在构造时一次性 `borrow()` 整个 list 的 codes 和
ids,对 cache-backed reader 实现零拷贝
- `prefetch_lists()` 留空——iterator 构造时的 `borrow()` 已完成整个 list 的读取,同步 prefetch
是重复 I/O
- 提供 `replace_with_pread_invlists()` 辅助函数:从磁盘 read_index 后一行替换
#### 3. 修复 IndexIVF.cpp — iterate_codes/iterate_codes_range 缺失 IDSelector 过滤
上游 bug:`scan_codes` 路径正确处理了 `IDSelector`,但 `iterate_codes` 和
`iterate_codes_range`(`use_iterator=true` 时走的路径)完全跳过了 IDSelector 检查。本修复在 3 处添加
`if (sel != nullptr && !sel->is_member(...)) { continue; }`。
#### 4. CMakeLists.txt — 注册新文件
### Doris 侧修改(40 个文件, +1221/-54 行)
- **`CachedRandomAccessReader`**(`faiss_ann_index.cpp`):基于 CLucene
IndexInput + LRU page cache 的 `RandomAccessReader` 实现
- `borrow()` 走 page cache,命中时零拷贝返回 pinned page
- cache miss 时从 compound file 读取并插入 LRU cache
- **`ann_index_ivf_list_cache`**:IVF list 数据专用 LRU
cache,容量可配(`ann_index_ivf_list_cache_limit`,默认 70% 物理内存)
- **IVF on-disk 索引构建 & 查询全链路**
- **FE 侧 index properties 校验**
- **回归测试**:`ivf_on_disk_index_test.groovy`
### 未来 FAISS 上游提交计划
FAISS 侧的修改可拆为 3 个独立 PR 提交到社区:
1. **Bugfix PR**:IndexIVF.cpp iterate_codes IDSelector 修复(独立、容易被接受)
2. **New abstraction PR**:`impl/random_access_reader.h/.cpp`(独立 I/O 抽象)
3. **New inverted lists PR**:`invlists/PreadInvertedLists.h/.cpp`(依赖 PR 2)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]