基于磁盘的向量索引, 如果索引较大(大于内存), 在搜索或rerank(精排)时, 也算是比较重IO的操作.
为了降低IO操作的延迟, PG 17开始引入了异步IO接口, 在文末有响应文章介绍.
vectorchord 从0.4.0版本开始也支持了AIO(包括通过模拟AIO覆盖了PG 17以前的版本).
详见: https://docs.vectorchord.ai/vectorchord/usage/prefetch.html
IO策略通过几个参数来控制, 分别对应vectorchord的rabitq和graph索引接口search和rerank阶段的IO策略.
vchordrq.io_searchvchordrq.io_rerankvchordg.io_searchvchordg.io_rerank可设置的值如下
IO策略 | 描述 | 支持的 PostgreSQL 版本 |
|---|---|---|
read_stream | PostgreSQL 中的异步 I/O 接口 | PostgreSQL 17 |
prefetch_buffer | VectorChord 的模拟异步 I/O 接口, 用作旧版 PostgreSQL | PostgreSQL 13、14、15、16、17 |
read_buffer | PostgreSQL 中的同步 I/O 接口 | PostgreSQL 13、14、15、16、17 |
三种策略的原理如下, 以io_search为例.
vchordrq索引的io_search参数支持三种配置模式,每种模式对应不同的I/O优化策略和实现细节:
io_search参数通过PostgresIo枚举定义了三种模式 :
read_buffer → Io::Plainprefetch_buffer → Io::Simpleread_stream → Io::Stream(仅PostgreSQL 17+支持)参数转换在vchordrq_io_search()函数中实现 。
使用同步的缓冲区读取,没有预取优化 。在搜索阶段使用make_h1_plain_prefetcher和make_h0_plain_prefetcher,在重排序阶段使用PlainPrefetcher 。
使用异步预取缓冲区优化I/O性能 。搜索阶段使用make_h0_simple_prefetcher进行H0元组的预取,重排序阶段使用SimplePrefetcher 。
利用PostgreSQL 17+的ReadStream API进行流式读取 。使用StreamPrefetcher和Hints::default()配置 。
PostgresReadStream结构体实现了流式读取功能 ,通过PostgreSQL的read_stream_begin_relationAPI创建流 。
默认配置根据PostgreSQL版本自动选择 :
PrefetchBufferReadStream这三种模式在maxsim搜索中也有相同的实现模式。io_rerank参数使用相同的配置选项但应用于重排序阶段。每种模式的选择影响内存使用、I/O性能和CPU开销的平衡。
《PG vectorchord 向量索引预热(prewarm)原理》
https://deepwiki.com/search/vchordrqiosearchreadbuffer-pre_9031b9bb-a774-4a7c-ad35-0c0f58dd6714
https://docs.vectorchord.ai/vectorchord/usage/prefetch.html
《PostgreSQL 19 preview - 合理合并 AIO io_uring 的内存映射》
《PostgreSQL 18 preview - bitmap Heap Scan支持AIO批量读》
《PostgreSQL 18 preview - AIO增强 : 增加监控工具、增强测试能力、清理代码、改进错误诊断》
《PostgreSQL 18 AIO & DIO 顶层设计》
《PostgreSQL 18 preview - 异步IO(AIO)应用到缓冲区管理器层面》
《AIO (asynchronous IO) and DIO (direct IO) support for PostgreSQL》