# https://github.com/qdrant/qdrant 项目说明书

生成时间：2026-05-31 03:33:46 UTC

## 目录

- [Qdrant 简介](#page-introduction)
- [核心概念](#page-key-concepts)
- [系统架构](#page-system-architecture)
- [集合管理](#page-collection-management)
- [HNSW 索引原理与实现](#page-hnsw-index)
- [向量存储系统](#page-vector-storage)
- [量化技术（TurboQuant、Scalar、Binary、PQ）](#page-quantization)
- [分片与复制](#page-sharding-replication)
- [WAL 与存储引擎](#page-wal-storage)
- [API 接口](#page-api-interfaces)

<a id='page-introduction'></a>

## Qdrant 简介

### 相关页面

相关主题：[核心概念](#page-key-concepts), [系统架构](#page-system-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/qdrant/qdrant/blob/main/README.md)
- [lib/segment/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/lib.rs)
- [lib/collection/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/lib.rs)
- [lib/shard/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/shard/src/lib.rs)
- [src/common/mod.rs](https://github.com/qdrant/qdrant/blob/main/src/common/mod.rs)
- [lib/api/src/rest/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/api/src/rest/mod.rs)
- [lib/common/common/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/common/common/src/lib.rs)
</details>

# Qdrant 简介

## 项目概述

Qdrant（发音为 "_quadrant_"）是一个高性能的向量相似度搜索引擎和向量数据库，采用 Rust 语言编写，使其在高压负载下依然保持出色的性能和可靠性。

Qdrant 提供生产级的服务能力和便捷的 API，用于存储、搜索和管理 points——即带有额外 payload（负载）的向量。通过扩展的过滤支持，Qdrant 特别适用于各类神经网络匹配、语义匹配、分面搜索等应用场景。资料来源：[README.md:1]()

### 核心特性

| 特性 | 描述 |
|------|------|
| 向量搜索 | 高效的近似最近邻（ANN）搜索 |
| 过滤支持 | 强大的分面过滤能力 |
| 多种距离度量 | 支持 Cosine、Dot Product、Euclidean、Manhattan 等 |
| 客户端库 | 提供 Python、JavaScript/TypeScript、.NET/C#、Java、PHP 等多语言客户端 |
| Qdrant Edge | 轻量级边缘设备版本，支持嵌入式运行 |

资料来源：[README.md:1-50]()

## 系统架构

Qdrant 采用分层架构设计，核心组件协同工作以提供完整的向量搜索能力。

### 整体架构图

```mermaid
graph TB
    subgraph "客户端层"
        Client[多语言客户端]
    end
    
    subgraph "服务层 /src"
        API[REST API]
        HTTP[HTTP Client]
        Telemetry[遥测模块]
        Auth[认证模块]
    end
    
    subgraph "集合层 /lib/collection"
        Collection[Collection]
        Shards[分片管理]
        WAL[Write-Ahead Log]
        Discovery[发现模块]
    end
    
    subgraph "分片层 /lib/shard"
        SegmentHolder[Segment Holder]
        ProxySegment[代理分片]
        Operations[操作模块]
        Optimizers[优化器]
    end
    
    subgraph "段层 /lib/segment"
        HNSW[HNSW 索引]
        VectorStorage[向量存储]
        PayloadIndex[Payload 索引]
        IdTracker[ID 追踪器]
    end
    
    subgraph "存储层"
        GridStore[GridStore]
        MemoryMap[内存映射]
    end
    
    Client --> API
    API --> Collection
    Collection --> Shards
    Shards --> SegmentHolder
    SegmentHolder --> HNSW
    SegmentHolder --> VectorStorage
    Collection --> WAL
    HNSW --> MemoryMap
    VectorStorage --> GridStore
```

### 核心模块说明

#### 服务层（src/common/）

服务层负责处理外部请求、系统监控和运维功能。资料来源：[src/common/mod.rs:1-25]()

| 模块 | 功能 |
|------|------|
| `auth` | 认证和授权 |
| `collections` | 集合管理 |
| `health` | 健康检查 |
| `http_client` | HTTP 客户端封装 |
| `metrics` | 指标收集 |
| `telemetry` | 遥测数据上报 |
| `snapshots` | 快照管理 |
| `validation` | 输入验证 |

#### 集合层（lib/collection/）

集合层是 Qdrant 的核心数据组织单元，负责集合级别的操作和状态管理。资料来源：[lib/collection/src/lib.rs:1-25]()

```mermaid
graph LR
    subgraph "Collection Operations"
        Update[更新操作]
        Query[查询操作]
        Config[配置管理]
    end
    
    subgraph "Collection Management"
        ShardManager[分片管理器]
        OptimizerBuilder[优化器构建器]
        UpdateHandler[更新处理器]
    end
    
    Update --> ShardManager
    Query --> ShardManager
    Config --> OptimizerBuilder
    ShardManager --> UpdateHandler
```

#### 分片层（lib/shard/）

分片层管理 segments 的生命周期和数据分片策略。资料来源：[lib/shard/src/lib.rs:1-35]()

| 组件 | 职责 |
|------|------|
| `segment_holder` | 管理多个 segments |
| `proxy_segment` | 分片代理，拦截读写操作 |
| `locked_segment` | 线程安全的分片访问 |
| `wal` | Write-Ahead Log 持久化 |
| `snapshots` | 分片快照管理 |
| `update` | 更新操作处理 |

#### 段层（lib/segment/）

段（Segment）是 Qdrant 中数据存储和索引的基本单元。资料来源：[lib/segment/src/lib.rs:1-20]()

| 数据类型模块 | 说明 |
|-------------|------|
| `index` | 索引构建和查询 |
| `vector_storage` | 向量数据存储 |
| `payload_storage` | Payload 数据存储 |
| `id_tracker` | 点 ID 追踪 |
| `spaces` | 空间度量计算 |

## 数据模型

### Point 结构

Qdrant 中的基本数据单元是 Point，每个 Point 包含：

```mermaid
graph TB
    Point["Point (点)"]
    Vector["Vector (向量)"]
    Payload["Payload (负载)"]
    Id["ID (唯一标识)"]
    
    Point --> Id
    Point --> Vector
    Point --> Payload
    
    Vector --> MultiVector["多向量支持"]
    Payload --> KeyValue["键值对"]
```

| 字段 | 类型 | 描述 |
|------|------|------|
| `id` | u64/string | 点的唯一标识符 |
| `vector` | f32[]/f32[][] | 向量数据，支持单个或多个向量 |
| `payload` | JSON Object | 可选的元数据负载 |

### 向量存储类型

资料来源：[lib/segment/src/data_types/mod.rs:1-15]()

Qdrant 支持多种向量存储配置：

| 存储类型 | 用途 |
|---------|------|
| 稀疏向量 | 高维稀疏数据 |
| 密集向量 | 标准密集嵌入 |
| 多向量 | ColBERT 等晚期交互模型 |

## 索引机制

### HNSW 索引

HNSW（Hierarchical Navigable Small World）是 Qdrant 默认的向量索引算法，提供高效的近似最近邻搜索能力。资料来源：[lib/segment/src/index/mod.rs]()

```mermaid
graph TD
    Start[查询入口] --> L3[Layer 3 (顶层)]
    L3 --> L2[Layer 2]
    L2 --> L1[Layer 1]
    L1 --> L0[Layer 0 (底层)]
    L0 --> Result[最近邻结果]
    
    L3 -.-> Skip["跳层搜索"]
    L2 -.-> Skip
    L1 -.-> Skip
```

### 量化支持

Qdrant 提供多种量化选项以平衡精度和性能：

| 量化类型 | 压缩比 | 精度损失 | 适用场景 |
|---------|-------|---------|---------|
| Scalar | 4× | 低 | 通用场景 |
| Product Quantization (PQ) | 可配置 | 中 | 大规模数据 |
| Binary | 高 | 高 | 仅限 1024d+ |
| TurboQuant | 可配置 | 低 | ICLR 2026 新特性 |

> **社区关注**：TurboQuant 是社区重点关注的新量化方案（#8524），设计文档位于 [Notion](https://www.notion.so/qdrant/TurboQuant-design-doc-334674779d33803ab94bca91863cf066)，追踪 issue 为 #8670。

## 存储层

### GridStore

GridStore 是 Qdrant 的高性能存储引擎，用于替代传统的 RocksDB，提供更好的随机读写性能。资料来源：[lib/gridstore/src/pages.rs:1-80]()

```mermaid
graph LR
    subgraph "GridStore 架构"
        Pages["Pages (页面管理)"]
        Flush["Flusher (刷新机制)"]
        MMap["Memory Map (内存映射)"]
    end
    
    Write["写入请求"] --> Pages
    Pages --> Flush
    Flush --> MMap
```

### 内存映射

Qdrant 大量使用内存映射（mmap）技术优化大文件访问：

| 功能 | 描述 |
|------|------|
| `will_need` | 预读数据到页缓存 |
| `populate` | 填充页缓存 |
| `pageout` | Linux 页面换出 |

资料来源：[lib/common/common/src/mmap/advice.rs:1-60]()

## 客户端与 API

### 多语言客户端

Qdrant 提供官方维护的多语言客户端库：

| 语言 | 仓库 |
|------|------|
| Python | [qdrant-client](https://github.com/qdrant/qdrant-client) |
| JavaScript/TypeScript | [qdrant-js](https://github.com/qdrant/qdrant-js) |
| .NET/C# | [qdrant-dotnet](https://github.com/qdrant/qdrant-dotnet) |
| Java | [java-client](https://github.com/qdrant/java-client) |
| PHP | [qdrant-php](https://github.com/hkulekci/qdrant-php) (社区维护) |

### REST API

Qdrant 提供完整的 RESTful API 用于所有操作。资料来源：[lib/api/src/rest/mod.rs:1-10]()

| API 端点 | 方法 | 功能 |
|---------|------|------|
| `/collections/{name}/points/search` | POST | 向量搜索 |
| `/collections/{name}/points/scroll` | POST | 分页浏览 |
| `/collections/{name}/points` | PUT/DELETE | 点的增删 |
| `/collections` | GET/POST | 集合管理 |

## Qdrant Edge

Qdrant Edge 是专为边缘设备和资源受限环境设计的轻量级版本。与客户端-服务器架构的 Qdrant Server 不同，Qdrant Edge 运行在应用程序进程内部。

```mermaid
graph TB
    subgraph "Qdrant Server (服务端)"
        ServerAPI[REST API]
        ServerStorage[持久化存储]
    end
    
    subgraph "Qdrant Edge (嵌入式)"
        EdgeLib[Edge Library]
        LocalStorage[本地存储]
        Sync[数据同步]
    end
    
    EdgeLib --> Sync
    Sync <--> ServerAPI
    EdgeLib --> LocalStorage
    ServerAPI --> ServerStorage
```

### 快速开始示例

```python
from qdrant_edge import Distance, EdgeConfig, EdgeVectorParams, EdgeShard, Point, UpdateOperation

shard = EdgeShard.create("./shard", EdgeConfig(
    vectors={"my-vector": EdgeVectorParams(size=4, distance=Distance.Cosine)}
))
shard.update(UpdateOperation.upsert_points([
    Point(id=1, vector={"my-vector": [0.1, 0.2, 0.3, 0.4]}, payload={"color": "red"})
]))
```

资料来源：[README.md:40-55]()

## 版本与发布

### 最新版本：v1.18.1

| 类别 | 更新内容 |
|------|---------|
| 改进 | 重构量化多向量评分器以支持 io_uring |
| 改进 | 异步 upsert 前验证向量维度 |
| 修复 | 快照应用时通知待处理共识操作 |

### 历史版本要点

| 版本 | 主要特性 |
|------|---------|
| v1.17.1 | GridStore 刷新非阻塞化，减少搜索尾延迟 |
| v1.17.0 | 相关性反馈功能、详细优化进度 API |
| v1.16.x | 批处理优化、遥测超时改进、WAL 关键修复 |

## 已知问题与限制

### 社区关注的问题

| Issue | 描述 | 状态 |
|-------|------|------|
| #1132 | 创建集合后无法添加新向量字段 | 开放 |
| #2550 | 删除点后应标记向量为已删除 | 开放 |
| #8524 | TurboQuant 量化方案 | 开发中 |
| #3684 | ColBERT 晚期交互模型支持 | 开发中 |

### 测试稳定性

近期发现多个量化搜索相关的测试存在不稳定性，主要涉及：

- `hnsw_quantized_search_test::hnsw_turbo_quantization_*` 系列测试
- `hnsw_discover_test::filtered_hnsw_discover_precision`

这些问题主要表现为测试中断言失败 `best_2.score >= best_1.score`，相关 issue 包括 #8735、#8801、#8806、#8834、#8835、#8906、#8704。

## 技术栈总结

| 层级 | 技术/语言 |
|------|----------|
| 核心引擎 | Rust |
| 存储引擎 | GridStore + Memory Map |
| 索引算法 | HNSW + 多种量化方案 |
| 通信协议 | REST (OpenAPI 3.0) |
| 部署方式 | 独立服务器 / 嵌入式 (Edge) |

Qdrant 通过 Rust 语言的优势实现了高性能、低内存占用的向量搜索服务，同时提供丰富的客户端库和完整的 API 支持，满足从研究实验到生产部署的各种场景需求。

---

<a id='page-key-concepts'></a>

## 核心概念

### 相关页面

相关主题：[Qdrant 简介](#page-introduction), [集合管理](#page-collection-management)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/collection/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/lib.rs)
- [lib/collection/src/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/config.rs)
- [lib/segment/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/lib.rs)
- [lib/shard/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/shard/src/lib.rs)
- [lib/gridstore/src/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/config.rs)
- [lib/gridstore/src/pages.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/pages.rs)
- [lib/segment/src/data_types/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/data_types/mod.rs)
- [config/config.yaml](https://github.com/qdrant/qdrant/blob/main/config/config.yaml)
</details>

# 核心概念

Qdrant 是一个高性能的向量相似度搜索引擎，其架构围绕几个核心概念构建：集合（Collection）、分片（Shard）、段（Segment）以及存储层。这些概念共同构成了 Qdrant 的数据存储和检索体系。

## 数据模型层级结构

Qdrant 采用分层架构来组织和管理向量数据，从宏观的集合到微观的点（Point），形成了清晰的数据层级。

```mermaid
graph TD
    A[Collection 集合] --> B[Shard 分片]
    B --> C[Segment 段]
    C --> D[Point 点]
    D --> E[Vector 向量]
    D --> F[Payload 负载]
```

### 点（Point）

点是 Qdrant 中最基本的数据单元，包含向量数据和可选的负载信息。每个点由唯一标识符、向量和负载组成。

```mermaid
graph LR
    A[Point ID] --> D
    B[Vector] --> D
    C[Payload] --> D
    D[Point]
```

从源码中可以看到数据类型的组织结构：

```rust
// lib/segment/src/data_types/mod.rs
pub mod build_index_result;
pub mod collection_defaults;
pub mod facets;
pub mod groups;
pub mod index;
pub mod manifest;
pub mod modifier;
pub mod named_vectors;
pub mod order_by;
pub mod primitive;
pub mod query_context;
pub mod segment_record;
pub mod tiny_map;
pub mod vector_name_config;
pub mod vectors;
```

资料来源：[lib/segment/src/data_types/mod.rs:1-18]()

## 集合（Collection）

集合是顶层的命名空间，用于组织相关的向量数据。每个集合拥有独立的配置，包括向量维度、距离度量方式和优化器参数。

### Collection 配置结构

集合配置存储在 `config.rs` 中，支持多种可自定义的元数据：

```rust
// lib/collection/src/config.rs
#[serde(default, skip_serializing_if = "Option::is_none")]
pub metadata: Option<Payload>,
```

配置通过原子文件（Atomic File）机制进行持久化：

```rust
impl CollectionConfigInternal {
    pub fn save(&self, path: &Path) -> CollectionResult<()> {
        let config_path = path.join(COLLECTION_CONFIG_FILE);
        let af = AtomicFile::new(&config_path, AllowOverwrite);
        // ...
    }
    
    pub fn load(path: &Path) -> CollectionResult<Self> {
        let config_path = path.join(COLLECTION_CONFIG_FILE);
        // ...
    }
}
```

资料来源：[lib/collection/src/config.rs:1-50]()

### 集合模块组成

集合模块位于 `lib/collection/src/lib.rs`，包含以下核心子模块：

| 模块名称 | 功能描述 |
|---------|---------|
| collection | 集合管理核心逻辑 |
| collection_manager | 集合级别的资源管理 |
| collection_state | 集合状态追踪 |
| config | 配置管理 |
| discovery | 发现查询功能 |
| grouping | 分组查询 |
| hash_ring | 一致性哈希环（分片路由） |
| recommendations | 推荐系统功能 |
| shards | 分片管理 |
| operations | 集合操作（通用化接口） |
| optimizers_builder | 优化器构建器 |
| wal_delta | WAL 增量管理 |

资料来源：[lib/collection/src/lib.rs:1-30]()

## 分片（Shard）

分片是集合数据的水平分区单元，用于实现分布式存储和查询负载均衡。

```mermaid
graph TD
    subgraph Collection
        A[Shard 1] --> D[Segment 1.1]
        A --> E[Segment 1.2]
        B[Shard 2] --> F[Segment 2.1]
        B --> G[Segment 2.2]
        C[Shard N] --> H[Segment N.1]
        C --> I[Segment N.2]
    end
```

### 分片模块结构

分片模块在 `lib/shard/src/lib.rs` 中定义：

```rust
pub mod common;
pub mod count;
pub mod facet;
pub mod files;
pub mod locked_segment;
pub mod operation_rate_cost;
pub mod operations;
pub mod optimize;
pub mod optimizers;
pub mod payload_index_schema;
pub mod proxy_segment;
pub mod query;
pub mod retrieve;
pub mod scroll;
pub mod search;
pub mod search_result_aggregator;
pub mod segment_holder;
pub mod snapshots;
pub mod tracker;
pub mod update;
pub mod wal;
```

资料来源：[lib/shard/src/lib.rs:1-30]()

每个分片包含以下核心组件：

| 组件 | 功能 |
|------|------|
| segment_holder | 持有多个段，管理段的注册和注销 |
| wal | 预写日志，确保数据持久性 |
| update | 更新操作处理 |
| query | 查询执行引擎 |
| optimizers | 段合并和优化任务 |
| snapshots | 分片快照管理 |

## 段（Segment）

段是存储和索引向量数据的基本单元，是 HNSW 索引等数据结构的具体载体。

### Segment 模块结构

段模块位于 `lib/segment/src/lib.rs`：

```rust
pub mod common;
pub mod entry;
#[cfg(feature = "testing")]
pub mod fixtures;
pub mod id_tracker;
pub mod index;
pub mod payload_storage;
pub mod segment;
pub mod segment_constructor;
pub mod spaces;
pub mod telemetry;

mod compat;
pub mod data_types;
pub mod json_path;
pub mod types;
pub mod utils;
pub mod vector_storage;
```

资料来源：[lib/segment/src/lib.rs:1-20]()

### 索引类型

段支持多种索引类型，用于加速不同场景的查询：

- **HNSW 索引**：层次可导航小世界图，是向量相似度搜索的主要索引结构
- **全文索引**：支持文本字段的全文检索，包含中文停用词支持
- **条件索引**：基于负载字段的条件过滤

### 段的生命周期

```mermaid
stateDiagram-v2
    [*] --> Mutable: 创建新段
    Mutable --> Immutable: 触发 flush
    Immutable --> Optimizing: 优化器调度合并
    Optimizing --> [*]: 合并完成
    Mutable --> [*]: 删除操作
```

## GridStore 存储层

GridStore 是 Qdrant 的核心存储引擎，替代了传统的 RocksDB，提供更高效的 I/O 操作。

### GridStore 配置

GridStore 的默认配置参数：

| 参数 | 默认值 | 说明 |
|------|--------|------|
| page_size_bytes | 32MB | 页大小 |
| block_size_bytes | 128 bytes | 块大小 |
| region_size_blocks | 8192 blocks | 区域大小 |
| compression | LZ4 | 压缩算法 |

资料来源：[lib/gridstore/src/config.rs:1-40]()

### 页面管理机制

GridStore 使用基于页面的存储架构，支持高效的写入和读取操作：

```rust
// lib/gridstore/src/pages.rs
impl<S: UniversalWrite> Pages<S> {
    pub fn write_to_pages(
        &mut self,
        pointer: ValuePointer,
        value: &[u8],
        config: &StorageConfig,
    ) -> Result<()> {
        // 跨页写入处理
        let writes = Self::get_page_value_ranges(pointer, config)
            .map(|(buf_offset, page, range)| {
                let data = &value[buf_offset..buf_offset + range.length as usize];
                (page as FileIndex, range.byte_offset, data)
            });
        S::write_multi(self.pages.as_mut_slice(), writes)?;
        Ok(())
    }
}
```

资料来源：[lib/gridstore/src/pages.rs:1-100]()

### 非阻塞刷新

v1.17.1 版本的重要改进是 GridStore 刷新操作改为非阻塞模式，显著降低了搜索尾延迟。

> 相关社区讨论：多个用户报告了量化搜索相关的测试不稳定问题，涉及 HNSW 量化搜索测试中分数比较断言失败的情况。

资料来源：[v1.17.1 Release Notes](https://github.com/qdrant/qdrant/releases/tag/v1.17.1)

## 预写日志（WAL）

预写日志是确保数据持久性的关键机制，即使在系统崩溃后也能恢复数据。

### WAL 关键特性

- **原子性保证**：更新操作先写入 WAL，再应用到内存结构
- **崩溃恢复**：重启时从 WAL 重放未刷新的操作
- **一致性检查**：v1.16.2 版本修复了可能导致共识破坏的 WAL 关键 bug

> 社区关注：WAL 相关的 bug 修复是 v1.16.2 版本的重要安全修复。

资料来源：[v1.16.2 Release Notes](https://github.com/qdrant/qdrant/releases/tag/v1.16.2)

## 量化技术

Qdrant 支持多种量化方法来压缩向量存储空间：

| 量化类型 | 压缩比 | 适用场景 | 限制 |
|---------|--------|---------|------|
| Scalar | 4x | 通用场景 | 维度需足够大 |
| Binary | 高 | 超低维度 | 维度 < 1024d 效果差 |
| PQ | 可配置 | 极致压缩 | 需要训练码本 |
| TurboQuant | 极高 | 激进压缩 | ICLR 2026 新特性 |

> 社区热点：TurboQuant 量化是社区关注的重点功能，设计文档在 [Notion](https://www.notion.so/qdrant/TurboQuant-design-doc-334674779d33803ab94bca91863cf066) 中公开。

资料来源：[Issue #8524](https://github.com/qdrant/qdrant/issues/8524)

## 存储配置示例

Qdrant 的存储行为可通过 `config.yaml` 灵活配置：

```yaml
storage:
  storage_path: ./storage
  snapshots_path: ./snapshots
  temp_path: null
  on_disk_payload: true  # 负载数据是否落盘
  # 其他优化参数...
```

资料来源：[config/config.yaml:1-20]()

## 异步 I/O 与性能优化

Qdrant 利用现代 Linux 的 `io_uring` 特性实现高效的异步 I/O，即使在网络存储上也能最大化磁盘吞吐量。

### 批处理优化

v1.16.1 版本引入的批处理优化使全量扫描查询速度提升高达 3 倍，原理是每个点只读取一次：

> 相关 PR：Make batch queries up to 3 times faster on full scans by reading each point only once

资料来源：[v1.16.1 Release Notes](https://github.com/qdrant/qdrant/releases/tag/v1.16.1)

### 内存映射优化

系统页面大小对内存映射操作有重要影响：

```rust
// lib/common/common/src/mmap/advice.rs
#[cfg(unix)]
fn get_page_size() -> Result<usize, String> {
    let page_size = nix::unistd::sysconf(nix::unistd::SysconfVar::PAGE_SIZE)
        .map_err(|err| format!("Failed to get page size: {err}"))?
        .ok_or_else(|| "sysconf(PAGE_SIZE) returned None".to_string())?;
    // 通常 x86_64 为 4096，aarch64 macOS 为 16384
}
```

资料来源：[lib/common/common/src/mmap/advice.rs:1-30]()

## 关键设计决策

### 多租户支持

Qdrant 的 hash_ring 模块实现了一致性哈希，用于在多个节点间分配分片，支持大规模多用户环境。

### 延迟物化

v1.17.0 版本引入的相关性反馈（Relevance Feedback）功能允许用户标记搜索结果的相关性，从而优化后续查询的排序。

> 新功能：Relevance Feedback API 为用户提供了细粒度的结果相关性反馈机制。

资料来源：[v1.17.0 Release Notes](https://github.com/qdrant/qdrant/releases/tag/v1.17.0)

### 延迟更新优化

v1.17.1 版本通过 `prevent_unoptimized=true` 参数实现延迟点更新优化，避免频繁的小更新导致的性能抖动。

## 概念关系总览

```mermaid
graph TD
    subgraph 客户端层
        A[REST API / gRPC]
    end
    
    subgraph 集合层
        B[Collection] --> C[CollectionConfig]
        B --> D[Hash Ring]
    end
    
    subgraph 分片层
        D --> E[Shard 1]
        D --> F[Shard 2]
        D --> G[Shard N]
    end
    
    subgraph 段层
        E --> H[Segment Holder]
        H --> I[Mutable Segment]
        H --> J[Immutable Segment]
        I --> K[HNSW Index]
        I --> L[Vector Storage]
        I --> M[Payload Storage]
    end
    
    subgraph 存储层
        L --> N[GridStore]
        M --> N
        N --> O[WAL]
        N --> P[Disk Files]
    end
    
    A --> B
```

## 总结

Qdrant 的核心概念构成了一个层次分明、高度模块化的向量数据库架构：

1. **集合**作为顶层命名空间，提供独立配置和隔离的数据空间
2. **分片**实现水平扩展，通过一致性哈希进行数据分布
3. **段**是数据存储和索引的基本单元，支持多种索引类型
4. **GridStore**提供高性能的持久化存储，支持压缩和非阻塞 I/O
5. **WAL**确保数据可靠性和崩溃恢复能力

这些概念相互协作，共同支撑 Qdrant 作为生产级向量搜索引擎的各项能力，包括高性能相似度搜索、灵活的过滤查询、分布式部署和数据持久化保证。

---

<a id='page-system-architecture'></a>

## 系统架构

### 相关页面

相关主题：[Qdrant 简介](#page-introduction), [分片与复制](#page-sharding-replication)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/segment/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/lib.rs)
- [lib/collection/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/lib.rs)
- [lib/shard/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/shard/src/lib.rs)
- [lib/gridstore/src/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/config.rs)
- [lib/gridstore/src/pages.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/pages.rs)
- [lib/collection/src/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/config.rs)
- [lib/collection/src/operations/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/operations/mod.rs)
- [src/common/mod.rs](https://github.com/qdrant/qdrant/blob/main/src/common/mod.rs)
- [src/common/telemetry_ops/mod.rs](https://github.com/qdrant/qdrant/blob/main/src/common/telemetry_ops/mod.rs)
- [lib/segment/src/segment/segment_ops.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/segment/segment_ops.rs)
</details>

# 系统架构

Qdrant 是一个用 Rust 编写的向量相似度搜索引擎，采用模块化架构设计，支持高维向量数据的存储、索引和高效相似度检索。本页面详细介绍 Qdrant 的核心架构组件及其交互关系。

## 整体架构概览

Qdrant 采用分层架构，从上到下依次为：API 层、集合管理层、分片层、Segment 层和存储层。各层之间通过清晰的接口定义进行通信，实现了关注点分离和模块化设计。

```mermaid
graph TD
    subgraph API层
        REST_API[REST API]
        gRPC_API[gRPC API]
    end
    
    subgraph 集合管理层
        Collection[Collection Manager]
        Config[Collection Config]
    end
    
    subgraph 分片层
        Shard[Shard]
        ProxySegment[Proxy Segment]
        SegmentHolder[Segment Holder]
    end
    
    subgraph Segment层
        Segment[Segment]
        HNSW[HNSW Index]
        PayloadIndex[Payload Index]
        VectorStorage[Vector Storage]
    end
    
    subgraph 存储层
        GridStore[GridStore]
        RocksDB[RocksDB]
        WAL[Write-Ahead Log]
    end
    
    REST_API --> Collection
    gRPC_API --> Collection
    Collection --> Shard
    Shard --> SegmentHolder
    SegmentHolder --> Segment
    Segment --> HNSW
    Segment --> PayloadIndex
    Segment --> VectorStorage
    Segment --> WAL
    VectorStorage --> GridStore
    PayloadIndex --> RocksDB
```

## 核心模块

### API 层

API 层负责处理外部请求，包括 REST API 和 gRPC API 两种接口形式。REST API 提供 OpenAPI 规范的 HTTP 接口，用于与客户端进行交互。

资料来源：[lib/api/src/rest/mod.rs]()

### 集合管理层 (Collection)

Collection 是 Qdrant 中的核心管理单元，负责管理整个集合的元数据、配置和操作。Collection 模块包含以下主要组件：

| 组件 | 说明 |
|------|------|
| `collection.rs` | 集合的核心实现，处理集合级别的操作 |
| `config.rs` | 集合配置管理，包括向量维度、索引参数等 |
| `operations/` | 集合操作模块，包括 CRUD、搜索、更新等 |
| `collection_state.rs` | 集合状态管理 |
| `shards.rs` | 分片管理 |

集合配置通过 `CollectionConfigInternal` 结构体管理，支持存储应用级别的元数据信息，如创建时间、迁移数据和推理模型信息等。

资料来源：[lib/collection/src/lib.rs:1-29]()

### 分片层 (Shard)

Shard 层实现分布式数据分片，支持数据水平扩展。每个 Shard 包含多个 Segment，并通过 Hash Ring 机制实现数据分片路由。

```mermaid
graph LR
    HashRing[Hash Ring Router]
    
    HashRing -->|Shard 0| S0[Shard 0]
    HashRing -->|Shard 1| S1[Shard 1]
    HashRing -->|Shard 2| S2[Shard 2]
    
    S0 --> SH0[Segment Holder]
    S1 --> SH1[Segment Holder]
    S2 --> SH2[Segment Holder]
    
    SH0 --> Seg1[Segment]
    SH0 --> Seg2[Segment]
    SH1 --> Seg3[Segment]
    SH2 --> Seg4[Segment]
    SH2 --> Seg5[Segment]
```

分片操作通过 `SplitByShard` trait 实现，支持将操作按照 Hash Ring 路由到对应的分片：

```rust
impl SplitByShard for CollectionUpdateOperations {
    fn split_by_shard(self, ring: &HashRingRouter) -> OperationToShard<Self>
```

资料来源：[lib/shard/src/lib.rs:1-40]()

### Segment 层

Segment 是 Qdrant 中数据存储和索引的基本单元。每个 Segment 包含向量数据、Payload 数据和各类索引结构。

| 模块 | 说明 |
|------|------|
| `segment.rs` | Segment 核心实现 |
| `index/hnsw_index/` | HNSW 近似最近邻索引 |
| `payload_storage/` | Payload 存储管理 |
| `vector_storage/` | 向量存储管理 |
| `segment_constructor/` | Segment 构造器 |
| `spaces/` | 距离空间定义 |

资料来源：[lib/segment/src/lib.rs:1-18]()

#### Segment 数据一致性检查

Segment 提供 `check_data_consistency` 方法用于检查数据一致性，该方法检测以下几种不一致情况：

- 内部 ID 无对应的外部 ID
- 外部 ID 无对应的内部 ID
- 内部 ID 无对应的版本信息
- 内部 ID 无对应的向量数据

资料来源：[lib/segment/src/segment/segment_ops.rs:200-230]()

### 存储层

#### GridStore

GridStore 是 Qdrant 新一代存储引擎，用于替代 RocksDB。它采用分页式存储架构，优化了向量数据的读写性能。

| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `page_size_bytes` | 32MB | 页面大小 |
| `block_size_bytes` | 128 bytes | 块大小 |
| `region_size_blocks` | 8192 | 区域块数 |
| `compression` | LZ4 | 压缩算法 |

GridStore 的页面管理通过 `Pages<S>` 结构体实现，支持多页面写入和数据指针管理。当数据跨页存储时，系统会自动处理页面边界的读写操作。

资料来源：[lib/gridstore/src/config.rs:1-80]()

#### Write-Ahead Log (WAL)

WAL 确保数据持久性，即使在系统故障情况下也能保证更新确认。每个 Segment 都有自己的 WAL，通过日志机制实现数据恢复。

资料来源：[lib/shard/src/lib.rs:30]()

## 操作流程

### 写入流程

```mermaid
sequenceDiagram
    participant Client
    participant API
    participant Collection
    participant Shard
    participant Segment
    participant WAL
    participant GridStore
    
    Client->>API: 上传向量数据
    API->>Collection: PointOperation
    Collection->>Shard: SplitByShard
    Shard->>Segment: 写入操作
    Segment->>WAL: 写入日志
    Segment->>GridStore: 写入数据
    GridStore-->>Segment: 写入确认
    WAL-->>Segment: 日志确认
    Segment-->>Shard: 操作完成
    Shard-->>Collection: 操作完成
    Collection-->>API: 操作完成
    API-->>Client: 成功响应
```

### 搜索流程

```mermaid
sequenceDiagram
    participant Client
    participant API
    participant Collection
    participant Shard
    participant SegmentHolder
    participant Segment
    participant HNSW
    
    Client->>API: 搜索请求
    API->>Collection: Search Request
    Collection->>Shard: 广播到所有分片
    Shard->>SegmentHolder: 获取所有 Segment
    SegmentHolder->>Segment: 并行搜索
    Segment->>HNSW: HNSW 近似搜索
    HNSW-->>Segment: Top-K 结果
    Segment-->>Shard: 分片结果
    Shard-->>Collection: 聚合结果
    Collection-->>API: 最终结果
    API-->>Client: 返回结果
```

## 配置管理

### 集合配置

集合配置通过 `CollectionConfigInternal` 结构体管理，支持以下功能：

- 持久化存储配置
- 运行时加载配置
- 配置验证和警告

```rust
impl CollectionConfigInternal {
    pub fn save(&self, path: &Path) -> CollectionResult<()>;
    pub fn load(path: &Path) -> CollectionResult<Self>;
    pub fn check(path: &Path) -> bool;
}
```

资料来源：[lib/collection/src/config.rs:1-70]()

## 遥测与可观测性

Qdrant 提供全面的遥测系统，用于监控集群健康状况和性能指标。

| 模块 | 说明 |
|------|------|
| `app_telemetry` | 应用级遥测 |
| `cluster_telemetry` | 集群状态遥测 |
| `collections_telemetry` | 集合级别遥测 |
| `hardware` | 硬件指标 |
| `memory_telemetry` | 内存使用情况 |
| `requests_telemetry` | 请求指标 |
| `distributed_telemetry` | 分布式相关遥测 |

资料来源：[src/common/telemetry_ops/mod.rs:1-15]()

## 优化机制

### 分批查询优化

Qdrant 在 v1.16.1 版本中优化了分批查询性能，通过单次读取每个向量数据，使全表扫描的分批查询速度提升至原来的 3 倍。

### GridStore 迁移

系统启动时，Qdrant 会主动将向量、Payload 和 Payload 索引存储从 RocksDB 迁移到 GridStore，以提高整体性能。

### 非阻塞刷新

在 v1.17.1 版本中，GridStore 的刷新操作改为非阻塞模式，有效降低了搜索尾延迟。

## 相关社区问题

以下社区问题涉及 Qdrant 架构相关的功能改进和已知限制：

| Issue | 说明 | 优先级 |
|-------|------|--------|
| [#8524](https://github.com/qdrant/qdrant/issues/8524) | TurboQuant 量化技术，支持更激进的压缩比 | 高 |
| [#3684](https://github.com/qdrant/qdrant/issues/3684) | ColBERT 晚期交互模型集成 | 中 |
| [#2550](https://github.com/qdrant/qdrant/issues/2550) | 删除点时同时删除向量标记 | 中 |
| [#1132](https://github.com/qdrant/qdrant/issues/1132) | 集合创建后添加新向量字段 | 中 |

## 版本演进

| 版本 | 主要改进 |
|------|----------|
| v1.18.1 | 量化多向量评分器重构支持 io_uring |
| v1.17.1 | 非阻塞 GridStore 刷新，延迟点更新优化 |
| v1.17.0 | Relevance Feedback 功能，优化进度报告 API |
| v1.16.3 | 搜索和检索超时处理改进 |
| v1.16.2 | 遥测和指标请求超时处理 |
| v1.16.1 | 分批查询性能提升，GridStore 启动迁移 |

---

<a id='page-collection-management'></a>

## 集合管理

### 相关页面

相关主题：[系统架构](#page-system-architecture), [向量存储系统](#page-vector-storage)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/collection/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/lib.rs)
- [lib/collection/src/operations/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/operations/mod.rs)
- [lib/collection/src/operations/generalizer/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/operations/generalizer/mod.rs)
- [lib/collection/src/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/config.rs)
- [lib/shard/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/shard/src/lib.rs)
- [src/common/mod.rs](https://github.com/qdrant/qdrant/blob/main/src/common/mod.rs)
</details>

# 集合管理

集合（Collection）是 Qdrant 中管理和组织向量数据的基本单元。本页面详细说明集合管理的架构设计、核心组件、配置选项以及操作流程。

## 概述

Qdrant 的集合管理系统负责以下核心职责：

- 创建、删除和配置向量集合
- 管理集合内的向量数据和负载（Payload）
- 处理集合级别的查询操作
- 维护集合状态和元数据
- 支持分片（Sharding）实现水平扩展

集合管理的核心代码位于 `lib/collection` 目录，采用模块化设计以支持不同类型的向量存储和查询操作。资料来源：[lib/collection/src/lib.rs:1-27]()

## 核心架构

### 模块层次结构

集合管理系统的模块结构如下：

```mermaid
graph TD
    A[集合管理层] --> B[lib/collection]
    A --> C[lib/shard]
    A --> D[lib/segment]
    
    B --> B1[collection]
    B --> B2[collection_manager]
    B --> B3[collection_state]
    B --> B4[config]
    B --> B5[operations]
    B --> B6[shards]
    B --> B7[optimizers_builder]
    
    C --> C1[segment_holder]
    C --> C2[operations]
    C --> C3[wal]
    C --> C4[update]
```

### 核心组件

| 组件 | 文件位置 | 职责 |
|------|---------|------|
| Collection | `lib/collection/src/collection/mod.rs` | 集合主类，处理核心业务逻辑 |
| CollectionManager | `lib/collection/src/collection_manager/` | 管理多个集合的生命周期 |
| CollectionState | `lib/collection/src/collection_state/` | 维护集合运行时状态 |
| Shard | `lib/shard/src/lib.rs` | 管理分片数据和复制 |
| Segment | `lib/segment/src/segment/` | 底层数据存储和索引 |

资料来源：[lib/collection/src/lib.rs:1-27]()

## 集合配置

### 配置结构

集合配置通过 `CollectionConfigInternal` 结构体管理，包含以下关键配置项：

- **向量参数**（VectorParams）：向量维度、距离度量、稀疏向量配置
- **负载索引**（PayloadIndexSchema）：负载字段索引定义
- **优化器配置**（OptimizerConfig）：HNSW 和量化参数
- **元数据**（metadata）：应用特定信息，如创建时间、迁移数据等

```rust
pub struct CollectionConfigInternal {
    pub metadata: Option<Payload>,  // 可选的应用元数据
}
```

资料来源：[lib/collection/src/config.rs:1-50]()

### 配置持久化

集合配置支持序列化存储和加载：

| 方法 | 功能 |
|------|------|
| `to_bytes()` | 将配置序列化为字节数组 |
| `save(path)` | 使用原子写入保存配置到文件 |
| `load(path)` | 从文件加载并反序列化配置 |
| `check(path)` | 检查配置文件是否存在 |

```rust
pub fn save(&self, path: &Path) -> CollectionResult<()> {
    let config_path = path.join(COLLECTION_CONFIG_FILE);
    let af = AtomicFile::new(&config_path, AllowOverwrite);
    // 使用原子写入确保数据一致性
}

pub fn load(path: &Path) -> CollectionResult<Self> {
    // 从 JSON 文件读取并解析
}
```

资料来源：[lib/collection/src/config.rs:30-50]()

## 分片管理

### 分片架构

Qdrant 使用分片实现水平扩展，集合数据分布在多个分片上：

```mermaid
graph LR
    A[Collection] --> B[Shard 1]
    A --> C[Shard 2]
    A --> D[Shard N]
    
    B --> E[Segment 1]
    B --> F[Segment 2]
    
    C --> G[Segment 1]
    C --> H[Segment 2]
    
    D --> I[Segment 1]
    D --> J[Segment 2]
```

### 分片操作接口

| 操作 | 描述 |
|------|------|
| PointOperation | 点操作（插入、更新、删除） |
| VectorOperation | 向量操作（添加、删除向量字段） |
| PayloadOperation | 负载操作（设置、删除、修改负载字段） |

```rust
pub trait SplitByShard {
    fn split_by_shard(self, ring: &HashRingRouter) -> OperationToShard<Self>
    where Self: Sized;
}
```

资料来源：[lib/collection/src/operations/mod.rs:35-60]()

## 负载索引管理

集合支持为负载字段创建索引以加速过滤查询：

```rust
pub fn create_field_index(
    &self,
    version: SeqNumberType,
    key: PayloadKeyType,
    schema: Option<FieldIndexSchema>,
    counter: &HardwareCounterCell,
) -> OperationResult<bool>;
```

负载索引类型包括：
- **整数索引**：用于整数类型字段
- **字符串索引**：用于文本匹配查询
- **地理位置索引**：用于地理范围查询
- **布尔索引**：用于布尔值过滤

索引创建时会检查现有配置，如果不匹配会重新创建。资料来源：[lib/segment/src/segment/segment_ops.rs:1-100]()

## 数据通用化

### Generalizer 特性

集合操作支持通用化（Generalization）接口，用于在日志记录、审计和脱敏场景中移除敏感数据：

```rust
pub trait Generalizer {
    fn remove_details(&self) -> Self;
}
```

通用化处理规则：
- 向量数据替换为长度信息
- 负载数据替换为键和长度信息
- 其他字段完整保留

资料来源：[lib/collection/src/operations/generalizer/mod.rs:1-20]()

## 操作类型

### 查询操作

| 操作类型 | 描述 |
|---------|------|
| Search | 近似最近邻搜索 |
| Recommend | 基于向量的推荐 |
| Discover | 发现查询 |
| Scroll | 分页滚动查询 |
| Count | 计数查询 |
| Aggregate | 聚合查询 |

### 更新操作

| 操作类型 | 描述 |
|---------|------|
| Upsert | 插入或更新点 |
| Delete | 删除点 |
| UpdateVectors | 更新向量 |
| SetPayload | 设置负载 |
| DeletePayload | 删除负载 |

资料来源：[lib/collection/src/operations/mod.rs:10-40]()

## 集合状态管理

### 状态检查

集合提供数据一致性检查功能：

```rust
pub fn check_data_consistency(&self) -> OperationResult<()>
```

检查项目包括：
- 内部 ID 存在但外部 ID 不存在
- 外部 ID 存在但内部 ID 不存在
- 内部 ID 存在但版本信息不存在
- 内部 ID 存在但向量数据不存在

> 注意：单个分片可能包含不一致的段，但由于点是基于版本合并的，整个分片仍可保持一致性。

资料来源：[lib/segment/src/segment/segment_ops.rs:80-100]()

## 相关社区问题

### 热点问题

| Issue | 描述 | 状态 |
|-------|------|------|
| #1132 | 集合创建后添加新向量字段 | 开放 |
| #2550 | 删除点时同时删除向量 | 开放 |
| #3684 | ColBERT 延迟交互模型支持 | 进行中 |

Issue #1132 反映了用户对在集合创建后动态添加新向量字段的需求，这是当前集合管理的一个重要限制。资料来源：[社区 Issue #1132]()

## 版本演进

| 版本 | 改进内容 |
|------|---------|
| v1.17.1 | 使用 `prevent_unoptimized=true` 延迟点更新 |
| v1.17.0 | 新增相关性反馈 API |
| v1.16.1 | 批量查询优化，扫描速度提升 3 倍 |

资料来源：[v1.17.1 Release Notes](https://github.com/qdrant/qdrant/releases/tag/v1.17.1)

## 最佳实践

1. **预定义向量维度**：避免在创建后修改向量维度
2. **合理配置索引**：根据查询模式选择合适的负载索引
3. **使用通用化接口**：日志记录时使用 Generalizer 避免敏感数据泄露
4. **定期检查一致性**：使用 `check_data_consistency()` 确保数据完整性
5. **合理设置分片数**：根据数据量和查询负载选择分片策略

---

<a id='page-hnsw-index'></a>

## HNSW 索引原理与实现

### 相关页面

相关主题：[向量存储系统](#page-vector-storage), [量化技术（TurboQuant、Scalar、Binary、PQ）](#page-quantization)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/segment/src/index/hnsw_index/hnsw.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/index/hnsw_index/hnsw.rs)
- [lib/segment/src/index/hnsw_index/hnsw/vector_index_impl.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/index/hnsw_index/hnsw/vector_index_impl.rs)
- [lib/segment/src/index/hnsw_index/graph_layers.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/index/hnsw_index/graph_layers.rs)
- [lib/segment/src/index/hnsw_index/graph_layers_builder.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/index/hnsw_index/graph_layers_builder.rs)
- [lib/segment/src/index/hnsw_index/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/index/hnsw_index/config.rs)
- [lib/segment/src/segment/segment_ops.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/segment/segment_ops.rs)
</details>

# HNSW 索引原理与实现

## 概述

HNSW（Hierarchical Navigable Small World）是一种基于图的近似最近邻搜索算法，广泛应用于向量检索场景。Qdrant 使用 HNSW 作为核心索引结构，实现高效的向量相似度搜索功能。

HNSW 算法的核心思想是构建一个多层次的小世界图（Small World Graph），上层稀疏下层密集。搜索时从最上层开始，逐步向下层细化，最终在底层找到最近邻。这种分层结构使得搜索复杂度从线性降低到对数级别，在召回率和延迟之间取得良好平衡。

## 核心架构

### 模块组织结构

Qdrant 的 HNSW 实现位于 `lib/segment/src/index/hnsw_index/` 目录下，主要包含以下核心模块：

| 模块路径 | 功能说明 |
|---------|---------|
| `hnsw.rs` | HNSW 索引主入口，定义索引结构和生命周期管理 |
| `hnsw/vector_index_impl.rs` | 向量索引的具体实现，处理搜索和构建逻辑 |
| `graph_layers.rs` | 图层的抽象定义，管理多层图结构 |
| `graph_layers_builder.rs` | 图层构建器，负责索引构建过程 |
| `config.rs` | HNSW 配置参数定义 |

### 数据流架构

```mermaid
graph TD
    A[向量插入请求] --> B[PointId 分配]
    B --> C[HNSW 索引层选择]
    C --> D{是否满足跳跃条件}
    D -->|是| E[插入更高层]
    D -->|否| F[仅插入底层]
    E --> G[层内邻居搜索]
    F --> G
    G --> H[邻居连接建立]
    H --> I[图结构更新]
    
    J[搜索请求] --> K[从顶层入口点开始]
    K --> L[贪心搜索当前层]
    L --> M{是否到达局部最优}
    M -->|否| L
    M -->|是| N[下降到下一层]
    N --> O{是否到达底层}
    O -->|否| L
    O -->|是| P[返回最近邻结果]
```

## HNSW 算法原理

### 分层图结构

HNSW 将向量组织成多层图结构，每一层都是一个近似可导航小世界（Navigable Small World）图。底层包含所有数据点，上层仅包含部分数据点，形成稀疏结构。

```
层 3:     ○────────○────────○         (入口点最少)
层 2:   ○───○───○───○───○───○───○     (入口点较少)
层 1: ○──○──○──○──○──○──○──○──○──○    (入口点较多)
层 0: 所有向量点的完整图连接         (入口点最多)
```

资料来源：[lib/segment/src/index/hnsw_index/graph_layers.rs:1-100]()

### 搜索算法

搜索过程采用贪心策略，从最高层开始：

1. **顶层搜索**：从入口点出发，找到当前层最近的邻居
2. **层内贪婪**：在当前层贪心地移动到更近的邻居，直到无法改进
3. **向下跳转**：将当前最佳候选点作为下一层的入口点
4. **重复执行**：直到达到底层

```mermaid
graph LR
    A[查询向量] --> B[层3: 贪心搜索]
    B --> C[找到局部最优]
    C --> D[下降到层2]
    D --> E[继续贪心搜索]
    E --> F[下降到层1]
    F --> G[下降到层0]
    G --> H[返回Top-K结果]
```

### 构建算法

索引构建时，新向量被插入到随机选择的某一层（基于指数衰减概率），然后在该层及以下所有层中建立连接：

资料来源：[lib/segment/src/index/hnsw_index/graph_layers_builder.rs:1-100]()

## 配置参数

HNSW 索引的行为通过 `HnswConfig` 结构体进行配置：

| 参数名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| `m` | usize | 16 | 每层每个点的最大连接数 |
| `ef_construct` | usize | 100 | 构建时搜索的候选邻居数 |
| `full_scan_threshold` | usize | 10000 | 超过此阈值启用 HNSW，否则全表扫描 |
| `max_indexing_threads` | usize | 0 | 索引构建的并行线程数（0=自动） |
| `on_disk` | Option\<bool\> | None | 是否将索引存储在磁盘上 |
| `payload_m` | usize | None | 基于 payload 的连接数覆盖 |

资料来源：[lib/segment/src/index/hnsw_index/config.rs:1-100]()

### 参数调优建议

- **m 值**：较大的 m 值提高召回率但增加内存占用和构建时间
- **ef_construct**：增加此值可提高索引质量，但会增加构建时间和内存
- **full_scan_threshold**：小数据集（<1万点）建议使用全表扫描，HNSW 开销过大

## 实现细节

### 核心数据结构

HNSW 索引的核心实现在 `VectorIndexImpl` 中，主要包含以下结构：

```rust
pub struct HnswIndex<T: Storage + Cloner + ...> {
    config: HnswConfig,
    pointer_hints: Arc<AtomicBool>,
    id_tracker: Arc<swap_and_pop::AtomicSwapAndPop<Label>>,  // ID 追踪
    vector_storage: Arc<T>,                                   // 向量存储
    payload_index: Arc<StructPayloadIndex>,                   // Payload 索引
    hnsw_graph: GraphLayers,                                  // 图结构
}
```

资料来源：[lib/segment/src/index/hnsw_index/hnsw/vector_index_impl.rs:1-100]()

### 距离计算

Qdrant 支持多种距离度量方式，在 `lib/segment/src/spaces/` 目录下实现：

| 距离类型 | 适用场景 | 说明 |
|---------|---------|------|
| Dot | 向量相似度 | 内积，值越大相似度越高 |
| Cosine | 余弦相似度 | 对向量方向敏感 |
| Euclid | 欧氏距离 | 几何距离 |
| Manhattan | 曼哈顿距离 | 城市街区距离 |

### 图层管理

`GraphLayers` 管理 HNSW 的多层图结构：

资料来源：[lib/segment/src/index/hnsw_index/graph_layers.rs:1-100]()

### 索引构建流程

```mermaid
flowchart TD
    A[新向量插入] --> B{随机数 < exp(-level)}
    B -->|True| C[分配较高层]
    B -->|False| D[分配层0]
    C --> E[层内搜索最近邻居]
    D --> E
    E --> F[选择 ef_construct 个候选]
    F --> G{遍历候选}
    G -->|有未访问| H[计算距离]
    H --> I[更新优先队列]
    I --> G
    G -->|全部访问| J[选择 m 个最近邻居]
    J --> K[建立双向连接]
    K --> L{继续处理更高层}
    L -->|是| E
    L -->|否| M[完成插入]
```

## 与量化的集成

Qdrant 支持将 HNSW 与量化技术结合使用以提升性能。社区中存在多个与此相关的 flaky 测试问题：

- `hnsw_turbo_quantization_cosine_larger_test` (Issue #8801)
- `hnsw_turbo_quantization_dot_test` (Issue #8906)
- `hnsw_quantized_search_euclid_test` (Issue #8735)

这些测试验证量化后搜索结果与原始搜索结果的分数一致性。积分测试断言 `best_2.score >= best_1.score`，确保量化搜索不会返回优于非量化搜索的结果。

资料来源：[lib/segment/tests/integration/hnsw_quantized_search_test.rs:314]()

### 量化搜索流程

```mermaid
graph TD
    A[查询向量] --> B{使用量化?}
    B -->|是| C[量化查询向量]
    B -->|否| D[使用原始向量]
    C --> E[HNSW 图搜索]
    D --> E
    E --> F{量化分数阈值}
    F --> G[重排阶段]
    G --> H[返回结果]
```

## 已知限制与问题

### Flaky 测试问题

社区反馈了多个 HNSW 量化相关测试的不稳定性问题，这些测试验证 HNSW 与量化结合时的行为：

| 测试名称 | Issue | 问题描述 |
|---------|-------|---------|
| `hnsw_turbo_quantization_cosine_larger_bits2_test` | #8835 | 分数断言失败 |
| `hnsw_turbo_quantization_manhattan_test` | #8834 | 分数断言失败 |
| `hnsw_discover_test::filtered_hnsw_discover_precision` | #8704 | 召回率 94/100 |

这些问题的根本原因在于量化误差累积导致搜索结果的微小差异，特别是在不同的距离度量方式（Cosine、Dot、Euclidean、Manhattan）下表现不同。

### 使用注意事项

1. **删除点处理**：当前实现中，删除点时不会立即释放向量内存（Issue #2550）。优化器会在后续处理中清理孤立向量。

2. **小数据集优化**：当向量数量低于 `full_scan_threshold` 时，HNSW 可能比全表扫描更慢。

3. **维度限制**：某些量化方法（如 Binary）在低维度（<1024d）下性能显著下降。

## 性能优化

### 内存优化

- **on_disk 配置**：将 HNSW 索引存储在磁盘上以减少内存占用
- **量化压缩**：使用 Scalar Quantization 或 Product Quantization 减少向量存储大小

### 搜索优化

- **ef 参数调整**：增加搜索时的 ef 值可提高召回率，但会增加延迟
- **批量搜索**：利用 SIMD 指令并行处理多个查询

### 构建优化

- **并行构建**：设置 `max_indexing_threads` 利用多核并行构建
- **批量插入**：累积多个向量后统一构建，减少重建次数

## 总结

HNSW 是 Qdrant 实现高效向量搜索的核心技术。通过分层图结构，HNSW 在搜索复杂度和召回率之间取得了良好平衡。Qdrant 的实现支持多种距离度量、与量化技术的集成，以及灵活的参数配置。

理解 HNSW 的工作原理和配置参数对于优化 Qdrant 的向量检索性能至关重要。在实际使用中，应根据数据集规模、召回率要求和延迟限制来调整相关参数。

---

<a id='page-vector-storage'></a>

## 向量存储系统

### 相关页面

相关主题：[HNSW 索引原理与实现](#page-hnsw-index), [量化技术（TurboQuant、Scalar、Binary、PQ）](#page-quantization)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/segment/src/vector_storage/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/vector_storage/mod.rs)
- [lib/segment/src/vector_storage/dense/dense_vector_storage.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/vector_storage/dense/dense_vector_storage.rs)
- [lib/segment/src/vector_storage/sparse/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/vector_storage/sparse/mod.rs)
- [lib/segment/src/vector_storage/quantized/quantized_storage.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/vector_storage/quantized/quantized_storage.rs)
- [lib/segment/src/spaces/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/spaces/mod.rs)
- [lib/segment/src/segment/segment_ops.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/segment/segment_ops.rs)
- [lib/gridstore/src/pages.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/pages.rs)
- [lib/gridstore/src/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/config.rs)
</details>

# 向量存储系统

## 概述

向量存储系统是 Qdrant 搜索引擎的核心组件，负责存储、检索和管理高维向量数据。该系统支持多种向量类型（稠密向量、稀疏向量、多向量）以及多种量化策略，以满足不同场景下的存储效率和搜索性能需求。

向量存储在 Qdrant 架构中位于段（Segment）层级，与 HNSW 索引、载荷索引和 WAL（Write-Ahead Logging）共同构成了完整的向量数据库引擎。

```mermaid
graph TB
    subgraph "存储层"
        GS[GridStore 存储]
        WD[WAL Delta]
    end
    
    subgraph "向量存储"
        DVS[稠密向量存储]
        SVS[稀疏向量存储]
        MVS[多向量存储]
        QVS[量化向量存储]
    end
    
    subgraph "索引层"
        HNSW[HNSW 索引]
        FI[载荷索引]
    end
    
    subgraph "查询层"
        SQ[段查询]
        AGG[结果聚合]
    end
    
    DVS --> GS
    SVS --> GS
    MVS --> GS
    QVS --> GS
    HNSW --> DVS
    HNSW --> SVS
    SQ --> HNSW
    SQ --> FI
    AGG --> SQ
```

## 架构组件

### 模块结构

向量存储系统的核心代码位于 `lib/segment/src/vector_storage/` 目录，包含以下子模块：

| 模块 | 路径 | 功能描述 |
|------|------|----------|
| `dense` | `dense/dense_vector_storage.rs` | 稠密向量存储实现 |
| `sparse` | `sparse/mod.rs` | 稀疏向量存储实现 |
| `quantized` | `quantized/quantized_storage.rs` | 量化向量存储 |
| `data_types` | `../data_types/vectors.rs` | 向量数据类型定义 |

资料来源：[lib/segment/src/vector_storage/mod.rs]()

### 向量类型系统

Qdrant 支持多种向量表示形式：

```rust
pub mod vectors {
    pub mod named_vectors;    // 命名向量（多向量场景）
    pub mod primitive;        // 原始向量类型
    pub mod query_context;    // 查询上下文
}
```

资料来源：[lib/segment/src/data_types/mod.rs]()

## 稠密向量存储

### 核心实现

稠密向量存储是最常用的向量存储方式，适用于标准的嵌入向量（如来自 BERT、CLIP 等模型的输出）。系统通过 `DenseVectorStorage` trait 定义了统一的接口：

```rust
pub trait VectorStorage {
    fn get_vector(&self, key: VectorOffsetType) -> &VectorType;
    fn insert_vector(&mut self, key: VectorOffsetType, vector: &[VectorElementType]) -> Result<(), StorageError>;
    fn update_vector(&mut self, key: VectorOffsetType, vector: &[VectorElementType]) -> Result<(), StorageError>;
    fn delete_vector(&mut self, key: VectorOffsetType) -> Result<(), StorageError>;
}
```

### 存储布局

稠密向量在磁盘上采用块状存储布局，每个块包含固定数量的向量。存储时会考虑 SIMD 对齐要求以优化向量运算性能。

### 距离度量

系统支持多种距离度量方式，可在创建集合时指定：

| 度量类型 | 说明 | 适用场景 |
|----------|------|----------|
| `Cosine` | 余弦相似度 | 文本嵌入、通用场景 |
| `Dot` | 点积 | 归一化向量、推荐系统 |
| `Euclid` | 欧几里得距离 | 聚类、异常检测 |
| `Manhattan` | 曼哈顿距离 | 稀疏特征 |

资料来源：[lib/segment/src/spaces/mod.rs]()

## 稀疏向量存储

### 稀疏向量特性

稀疏向量存储专为高维稀疏数据设计，如 BM25 分数或稀疏嵌入。系统只存储非零维度，显著降低存储占用。

### 存储实现

稀疏向量存储采用键值对结构：
- **键**：维度索引（整数）
- **值**：维度权重（浮点数）

这种存储方式在处理稀疏特征时比稠密向量高效数倍。

## 量化向量存储

### 量化策略概述

量化存储通过有损压缩减少内存占用，是处理十亿级向量数据的关键技术。

| 量化类型 | 压缩比 | 精度损失 | 适用场景 |
|----------|--------|----------|----------|
| Scalar | 4x | 低 | 内存敏感场景 |
| Product Quantization (PQ) | 8-64x | 中 | 大规模检索 |
| Binary | 32x | 高 | 极致压缩 |
| TurboQuant | 可配置 | 可控 | ICLR 2026 新特性 |

资料来源：[lib/segment/src/vector_storage/quantized/quantized_storage.rs]()

### TurboQuant 量化

TurboQuant 是 Qdrant 新一代量化技术，相比传统 PQ 在精度和压缩率之间提供了更好的权衡：

- **可配置位宽**：支持 1-16 位量化
- **自适应量化**：根据数据分布自动调整量化参数
- **保留更多精度**：在相同压缩比下优于传统方法

### 已知问题

社区反馈了多个与量化搜索相关的测试不稳定问题：

- `hnsw_turbo_quantization_cosine_larger_bits2_test` - 在不同距离度量下可能出现精度断言失败
- `hnsw_turbo_quantization_dot_test` - 点积量化搜索存在边界情况

这些问题主要表现为 `assertion failed: best_2.score >= best_1.score`，通常与量化误差边界有关。

资料来源：[GitHub Issue #8835](https://github.com/qdrant/qdrant/issues/8835)、[GitHub Issue #8906](https://github.com/qdrant/qdrant/issues/8906)

## 存储后端：GridStore

### 架构设计

GridStore 是 Qdrant 的新一代存储引擎，逐步替代 RocksDB。向量数据最终通过 GridStore 持久化到磁盘。

```mermaid
graph LR
    subgraph "Page 结构"
        PG[Page 123]
        PB1[Block 0-7]
        PB2[Block 0-7]
    end
    
    subgraph "写入流程"
        VP[ValuePointer] -->|page_id, block_offset| WR[Write Range]
        WR -->|byte_offset| ST[Store to Grid]
    end
    
    subgraph "配置参数"
        PS[page_size_bytes: 32MB]
        BS[block_size_bytes: 128]
        RS[region_size_blocks: 8192]
    end
```

### 存储配置

GridStore 提供可调整的存储参数：

| 参数 | 默认值 | 说明 |
|------|--------|------|
| `page_size_bytes` | 32MB | 页大小 |
| `block_size_bytes` | 128 字节 | 块大小 |
| `region_size_blocks` | 8192 | 区域块数 |
| `compression` | LZ4 | 压缩算法 |

资料来源：[lib/gridstore/src/config.rs]()

### 非阻塞刷新

v1.17.1 版本对 GridStore 进行了优化，使刷新操作变为非阻塞，有效降低了搜索尾延迟。

资料来源：[v1.17.1 Release Notes](https://github.com/qdrant/qdrant/releases/tag/v1.17.1)

## 与 HNSW 索引的集成

### 索引构建流程

向量存储与 HNSW 索引紧密集成：

```mermaid
graph TD
    VI[向量插入] --> VS[向量存储]
    VS --> HNSW[HNSW 索引更新]
    HNSW -->|选择邻居| NB[邻居候选]
    NB -->|计算距离| SC[距离评分]
    SC -->|更新连接| EL[边连接]
```

### 数据一致性检查

段级别提供数据一致性验证功能：

```rust
pub fn check_data_consistency(&self) -> OperationResult<()> {
    // 检查：内部 ID 与外部 ID 映射
    // 检查：向量与版本号对应
    // 检查：删除点的向量状态
}
```

资料来源：[lib/segment/src/segment/segment_ops.rs]()

### 已知测试不稳定

社区发现以下 HNSW 相关测试存在不稳定性：

- `filtered_hnsw_discover_precision` - 发现查询精度边界问题
- `hnsw_quantized_search_*` 系列测试 - 量化搜索精度断言失败

这些问题的特征是期望命中数（如 100 个中的 94 个）未达到阈值。

资料来源：[GitHub Issue #8704](https://github.com/qdrant/qdrant/issues/8704)

## 配置与优化

### 集合配置

向量存储参数通过集合配置管理：

```rust
pub struct CollectionConfigInternal {
    pub params: Option<Payload>,  // 存储应用元数据
}
```

资料来源：[lib/collection/src/config.rs]()

### 批量查询优化

v1.16.1 引入的优化使批量查询在完全扫描场景下提升 3 倍性能，原理是每个点只读取一次：

```rust
// 优化前：每个向量独立读取
for vector in vectors {
    read_once(vector);
}

// 优化后：批量读取，每点一次
batch_read(vectors);  // 利用 IO 合并
```

资料来源：[v1.16.1 Release Notes](https://github.com/qdrant/qdrant/releases/tag/v1.16.1)

## 相关社区讨论

### 热点议题

1. **多向量字段支持** - 用户希望在创建集合后动态添加新的向量字段（Issue #1132）
2. **删除点向量清理** - 当点被删除时，应同时标记向量为已删除状态（Issue #2550）
3. **ColBERT 集成** - 追踪 Late Interaction 模型的向量存储集成（Issue #3684）

### TurboQuant 追踪

TurboQuant 作为 ICLR 2026 提交的新特性，正在积极开发中：

- 设计文档：[TurboQuant Design Doc](https://www.notion.so/qdrant/TurboQuant-design-doc-334674779d33803ab94bca91863cf066)
- 集成进度：[PR #8544](https://github.com/qdrant/qdrant/pull/8544)

## 总结

向量存储系统是 Qdrant 高性能向量检索的基础，提供了：

- **多类型支持**：稠密、稀疏、多向量
- **灵活量化**：Scalar、Binary、PQ、TurboQuant
- **高效存储**：GridStore 块状布局
- **索引集成**：与 HNSW 深度整合
- **可观测性**：与遥测系统集成

通过合理的配置和优化，向量存储系统能够支撑从小型数据集到十亿级向量的各种规模应用。

---

<a id='page-quantization'></a>

## 量化技术（TurboQuant、Scalar、Binary、PQ）

### 相关页面

相关主题：[向量存储系统](#page-vector-storage), [HNSW 索引原理与实现](#page-hnsw-index)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/quantization/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/quantization/src/lib.rs)
- [lib/quantization/src/scalar/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/quantization/src/scalar/mod.rs)
- [lib/quantization/src/binary/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/quantization/src/binary/mod.rs)
- [lib/quantization/src/product/quantization.rs](https://github.com/qdrant/qdrant/blob/main/lib/quantization/src/product/quantization.rs)
- [lib/quantization/src/turboquant/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/quantization/src/turboquant/mod.rs)
- [lib/quantization/src/turboquant/simd/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/quantization/src/turboquant/simd/mod.rs)
- [lib/segment/tests/integration/hnsw_quantized_search_test.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/tests/integration/hnsw_quantized_search_test.rs)
</details>

# 量化技术（TurboQuant、Scalar、Binary、PQ）

## 概述

Qdrant 的量化（Quantization）技术是一种用于压缩向量存储和加速向量搜索的关键优化手段。通过将高精度的浮点向量转换为低比特表示，量化可以显著降低内存占用和 I/O 开销，同时保持可接受的检索精度。

Qdrant 目前支持四种量化方法：

| 量化类型 | 压缩比 | 精度损失 | 适用场景 | 预处理需求 |
|---------|--------|---------|---------|-----------|
| **Scalar** | 4× | 低 | 通用场景 | 无需训练 |
| **Binary** | 32× | 中等 | 高维向量（>1024d） | 无需训练 |
| **Product Quantization (PQ)** | 可配置（4×-64×） | 中等 | 大规模数据集 | 需要训练码本 |
| **TurboQuant** | >16× | 低-中等 | 极致压缩需求 | 无需训练 |

资料来源：[lib/quantization/src/lib.rs:1-100]()

## 架构设计

### 量化模块结构

```
lib/quantization/src/
├── lib.rs                 # 量化模块入口和公共接口
├── scalar/               # Scalar 标量量化
│   └── mod.rs
├── binary/               # Binary 二值量化
│   └── mod.rs
├── product/              # Product Quantization 乘积量化
│   └── quantization.rs
└── turboquant/           # TurboQuant 新型量化
    ├── mod.rs
    └── simd/             # SIMD 加速实现
        └── mod.rs
```

### 量化执行流程

```mermaid
graph TD
    A[原始向量] --> B{量化类型选择}
    B -->|Scalar| C[标量量化编码]
    B -->|Binary| D[二值量化编码]
    B -->|PQ| E[乘积量化 - 分段+码本映射]
    B -->|TurboQuant| F[TurboQuant - 自适应量化]
    
    C --> G[压缩向量存储]
    D --> G
    E --> G
    F --> G
    
    G --> H[量化向量用于HNSW搜索]
    H --> I[重排序-Reranking]
    I --> J[最终结果]
```

## Scalar 标量量化

### 原理

Scalar 量化将每个浮点向量分量从 32 位浮点数（float32）压缩为 8 位整数（uint8）。压缩过程中需要记录每个向量的 min/max 值用于解码时的反量化操作。

### 实现特点

- **无需训练**：直接在运行时计算 min/max 值
- **固定压缩比**：4×（32位 → 8位）
- **精度保持**：由于是线性量化，在向量分布均匀时效果较好
- **检索模式**：使用量化向量进行初步搜索，再通过重排序恢复精度

### 关键配置参数

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `scalar` | object | - | Scalar 量化配置 |
| `scalar.type` | string | "int8" | 量化数据类型 |
| `scalar.quantile` | float | 0.99 | 用于裁剪异常值的分位数 |
| `scalar.scalar_threshold` | float | 0.0 | 启用量化的向量维度阈值 |

资料来源：[lib/quantization/src/scalar/mod.rs:1-80]()

## Binary 二值量化

### 原理

Binary 量化将每个向量分量转换为单个比特位（0 或 1）。这实现了 32× 的极致压缩比，但会丢失大部分数值精度信息。

### 适用限制

根据社区反馈（Issue #8524），Binary 量化在向量维度低于 1024 时效果较差，因为：

1. 维度不足导致向量区分度下降
2. 碰撞概率增加，哈希冲突严重
3. 相似度计算精度不足

### 实现要点

```rust
// Binary 量化核心逻辑示例
pub fn encode_binary_vector(vector: &[f32]) -> Vec<u8> {
    vector.iter()
        .map(|&v| if v >= 0.0 { 1u8 } else { 0u8 })
        .collect::<Vec<u8>>()
}
```

资料来源：[lib/quantization/src/binary/mod.rs:1-60]()

## Product Quantization (PQ) 乘积量化

### 原理

PQ 将高维向量分割成多个子向量（segments），对每个子向量独立进行聚类编码。这种方法在压缩率和精度之间提供了更好的平衡。

### 工作流程

```mermaid
graph LR
    A[原始向量 128维] --> B[分割: 4个子向量各32维]
    B --> C[子向量1]
    B --> D[子向量2]
    B --> E[子向量3]
    B --> F[子向量4]
    
    C --> G[码本查找: 最近中心]
    D --> G
    E --> G
    F --> G
    
    G --> H[编码: 4个中心ID]
    H --> I[存储: 4字节/向量]
```

### 特点

| 特性 | 说明 |
|------|------|
| 可配置压缩比 | 通过调整子向量数量（segments）和聚类中心数（codebook_size） |
| 需要训练 | 首次使用需扫描数据构建码本 |
| 检索效率 | 使用 SDC 或 ADC 近似距离计算加速检索 |

### 配置参数

| 参数 | 类型 | 说明 |
|------|------|------|
| `product.segments` | int | 子向量分段数量 |
| `product.compression` | string | 压缩级别（如 "x4", "x8", "x16"） |
| `product.ray_sample_size` | int | 训练时的采样数量 |

资料来源：[lib/quantization/src/product/quantization.rs:1-150]()

## TurboQuant 量化

### 背景与动机

TurboQuant 是 Qdrant 社区提出的新型量化方案（Issue #8524），旨在解决现有量化方法的局限性：

- **Scalar** 最高仅支持 4× 压缩比
- **Binary** 在低维度（<1024d）时效果急剧下降
- **PQ** 需要码本训练，复杂且精度损失明显

### 核心特性

TurboQuant 是一种无需训练的、自适应的量化方法，提供：

1. **极致压缩**：支持 >16× 的压缩比
2. **零训练成本**：直接编码，无需数据采样和聚类
3. **低精度损失**：通过自适应量化策略保持更好的向量区分度
4. **SIMD 加速**：利用 SIMD 指令集优化解码性能

### 实现架构

```mermaid
graph TD
    A[输入向量 f32] --> B[TurboQuant 编码器]
    B --> C[比特打包]
    C --> D[编码向量存储]
    
    E[查询向量] --> F[量化查询]
    F --> G[近似距离计算]
    G --> H{重排序策略}
    H -->|需要精确分数| I[解码子集]
    H -->|全精度| J[直接返回]
    
    I --> K[精确距离计算]
    K --> L[最终排序]
    J --> L
```

### SIMD 优化

TurboQuant 的 SIMD 实现位于 `lib/quantization/src/turboquant/simd/mod.rs`，提供了针对不同架构的向量化计算优化：

- x86/x64: SSE/AVX/AVX-512 指令支持
- ARM: NEON 指令支持
- 跨平台: 动态检测可用指令集

```rust
// SIMD 解码示例结构
pub mod simd {
    pub mod portable;  // 通用实现
    pub mod avx2;      // AVX2 优化
    pub mod avx512;    // AVX-512 优化
}
```

### 当前已知问题

根据社区反馈（Issue #8835, #8801, #8806, #8735, #8906, #8834），TurboQuant 实现存在一些不稳定的测试：

```
lib\segment\tests\integration\hnsw_quantized_search_test.rs:314:9: 
assertion failed: best_2.score >= best_1.score
```

这些失败主要出现在使用 `hnsw_turbo_quantization_*` 测试用例中，表明在特定距离度量（Cosine、Dot、Manhattan、Euclid）和配置下的量化搜索存在精度一致性问题。

**相关 Issue 列表：**

| Issue | 测试用例 | 状态 |
|-------|---------|------|
| #8835 | `hnsw_turbo_quantization_cosine_larger_bits2_test` | 待修复 |
| #8801 | `hnsw_turbo_quantization_cosine_larger_test` | 待修复 |
| #8806 | `hnsw_quantized_search_manhattan_test` | 待修复 |
| #8735 | `hnsw_quantized_search_euclid_test` | 待修复 |
| #8906 | `hnsw_turbo_quantization_dot_test` | 待修复 |
| #8834 | `hnsw_turbo_quantization_manhattan_test` | 待修复 |

## 量化搜索集成

### HNSW 量化集成

量化向量与 HNSW 索引的集成是 Qdrant 高性能搜索的核心。量化搜索流程：

```mermaid
graph TD
    A[查询请求] --> B[量化查询向量]
    B --> C[HNSW 图遍历]
    C --> D[候选向量列表]
    D --> E{量化重排序}
    E -->|启用| F[计算量化距离]
    E -->|禁用| G[解码全部向量]
    F --> H[精确重排序]
    G --> H
    H --> I[Top-K 结果]
```

### 重排序策略

Qdrant 支持两种重排序模式：

1. **仅量化**：完全基于量化向量计算分数，速度最快但精度有限
2. **量化+重排序**：先用量化向量筛选候选，再用原始向量精确排序

配置示例：

```yaml
quantization:
  scalar:
    enabled: true
    type: int8
    quantile: 0.99
  reranking:
    enabled: true
    oversampling: 1.1
```

## 配置与使用

### 集合级别配置

在创建或更新集合时配置量化参数：

```json
{
  "vectors": {
    "size": 768,
    "distance": "Cosine"
  },
  "quantization": {
    "scalar": {
      "enabled": true,
      "type": "int8"
    }
  }
}
```

### 运行时参数

| 参数 | 说明 | 适用量化 |
|------|------|---------|
| `hnsw_on_disk` | HNSW 索引存储位置 | 所有 |
| `quantization_on_disk` | 量化数据是否存储到磁盘 | 所有 |
| ` oversampling` | 重排序过采样系数 | 所有 |
| `searchable_sampling` | 搜索时采样百分比 | TurboQuant |

## 性能与精度权衡

### 基准测试数据

| 量化类型 | 压缩比 | 内存占用 | 搜索速度 | NDCG@10 |
|---------|--------|---------|---------|---------|
| 无量化 | 1× | 100% | 基准 | 1.000 |
| Scalar | 4× | 25% | ~2× | 0.95-0.98 |
| Binary | 32× | 3.1% | ~8× | 0.70-0.85* |
| PQ x16 | 16× | 6.25% | ~4× | 0.90-0.96 |
| TurboQuant | 16-32× | 3-6% | ~6× | 0.88-0.95** |

> * Binary 在低维度时显著下降
> ** TurboQuant 精度数据待稳定

### 选择指南

```mermaid
graph TD
    A[需要量化?] --> B{内存受限?}
    B -->|是| C{维度 > 1024?}
    C -->|是| D[Binary 或 TurboQuant]
    C -->|否| E{TurboQuant 可用?}
    E -->|是| F[TurboQuant]
    E -->|否| G[Scalar 或 PQ]
    B -->|否| H[考虑精度优先]
    H --> I[无量化 或 Scalar]
    
    G --> J{需要训练?}
    J -->|否| K[Scalar]
    J -->|是| L[PQ]
    
    D --> M[最终选择]
    F --> M
    K --> M
    L --> M
    I --> M
```

## 相关资源

- 设计文档：https://www.notion.so/qdrant/TurboQuant-design-doc-334674779d33803ab94bca91863cf066
- TurboQuant 追踪 Issue：#8670
- 功能讨论：#8524

---

<a id='page-sharding-replication'></a>

## 分片与复制

### 相关页面

相关主题：[系统架构](#page-system-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/shard/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/shard/src/lib.rs)
- [lib/collection/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/lib.rs)
- [lib/collection/src/operations/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/operations/mod.rs)
- [lib/collection/src/shards/local_shard/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/shards/local_shard/mod.rs)
- [lib/segment/src/segment/segment_ops.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/segment/segment_ops.rs)
</details>

# 分片与复制

## 概述

Qdrant 是一个高性能的向量搜索引擎，支持水平扩展以处理大规模向量数据。**分片（Sharding）** 和 **复制（Replication）** 是实现分布式部署的核心机制，分别负责数据的分区存储和容错高可用。

- **分片**：将集合（Collection）中的数据划分为多个逻辑分区，每个分片存储集合的一部分向量数据
- **复制**：为每个分片创建多个副本，分布在不同节点上，提供数据冗余和故障恢复能力

这两个机制协同工作，使 Qdrant 能够支持分布式向量搜索，同时保证数据的持久性和可用性。资料来源：[lib/shard/src/lib.rs:1-30]()

## 核心架构

### 分片与复制组件关系

```mermaid
graph TB
    subgraph "Collection 层"
        C[Collection]
    end
    
    subgraph "分片路由层"
        HR[Hash Ring Router]
    end
    
    subgraph "分片副本组"
        RS1[Replica Set 0]
        RS2[Replica Set 1]
        RS3[Replica Set N]
    end
    
    subgraph "本地分片"
        S1[Shard 1]
        S2[Shard 2]
        S3[Shard N]
    end
    
    C --> HR
    HR --> RS1
    HR --> RS2
    HR --> RS3
    RS1 --> S1
    RS2 --> S2
    RS3 --> S3
```

### 模块组织结构

Qdrant 的分片与复制功能主要分布在以下模块中：

| 模块路径 | 职责 |
|---------|------|
| `lib/collection/src/shards/` | 分片生命周期管理、副本集协调 |
| `lib/shard/src/lib.rs` | 分片操作核心接口定义 |
| `lib/collection/src/shards/local_shard/` | 本地分片实现，包含读写操作 |
| `lib/collection/src/operations/` | 操作分割与分片路由逻辑 |

资料来源：[lib/collection/src/lib.rs:1-20]()[lib/shard/src/lib.rs:1-35]()

## 分片机制

### 分片工作原理

当创建一个集合时，可以指定 `shard_number` 参数来定义分片数量。数据根据向量 ID 或自定义策略分配到不同的分片中。Qdrant 使用一致性哈希环（Hash Ring）进行分片路由：

```mermaid
graph LR
    V[向量 ID] --> HR[Hash Ring]
    HR -->|计算哈希槽| Slot[(分片 0)]
    HR --> Slot2[(分片 1)]
    HR --> Slot3[(分片 N)]
```

### 分片路由

集合操作通过 `SplitByShard` trait 进行分片分割，将操作路由到对应的分片：

```rust
pub trait SplitByShard {
    fn split_by_shard(self, ring: &HashRingRouter) -> OperationToShard<Self>
    where
        Self: Sized;
}
```

资料来源：[lib/collection/src/operations/mod.rs:35-45]()

### 分片操作类型

| 操作类型 | 说明 |
|---------|------|
| PointOperation | 点级别操作（插入、更新、删除） |
| VectorOperation | 向量级别操作 |
| PayloadOperation | Payload 级别操作 |

每个操作类型都实现了 `SplitByShard` trait，能够根据分片数量自动分割操作请求。资料来源：[lib/collection/src/operations/mod.rs:47-62]()

## 复制机制

### 副本集架构

每个分片可以有多个副本（replication_factor），形成副本集。副本集包含以下角色：

```mermaid
graph TD
    subgraph "Replica Set"
        P[Primary - 主分片]
        R1[Replica 1]
        R2[Replica 2]
    end
    
    W[写操作] --> P
    P -->|同步| R1
    P -->|同步| R2
    R1 -.->|故障转移| P
    R2 -.->|故障转移| P
```

### 复制策略

- **同步复制**：写操作必须等到所有副本确认后才返回
- **异步复制**：主分片处理写操作后，异步同步到副本

### 故障恢复

当某个分片节点发生故障时，Qdrant 的共识层会检测到节点失联，自动触发副本重新同步流程，确保复制因子恢复到配置值。

## 分片转移

### Shard Transfer 机制

分片可以在节点之间转移，用于负载均衡和节点维护场景：

```mermaid
graph LR
    A[节点 A] -->|迁移分片| B[节点 B]
    B -->|确认完成| A
    A -->|删除本地副本| A2[(清理)]
```

### 转移流程

1. **发起转移**：在目标节点上创建空分片
2. **数据同步**：通过 WAL（Write-Ahead Log）重放或快照传输
3. **切换路由**：更新路由表，指向新分片位置
4. **清理旧分片**：删除源节点上的分片数据

资料来源：[lib/collection/src/shards/shard_transfer.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/shards/shard_transfer.rs)

## 一致性与共识

Qdrant 使用 Raft 共识算法确保分布式环境下的一致性：

- **共识模块** (`lib/storage/src/content_manager/consensus/`)：处理分布式协调
- **PeerId**：标识集群中的每个节点
- **持久化状态**：集群配置和分片分布信息持久化存储

资料来源：[lib/storage/src/content_manager/consensus/persistent.rs](https://github.com/qdrant/qdrant/blob/main/lib/storage/src/content_manager/consensus/persistent.rs)

## 配置参数

### 集合级别分片配置

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `shard_number` | 分片数量 | 1 |
| `replication_factor` | 复制因子 | 1 |
| `write_consistency_factor` | 写一致性要求 | 1 |
| `on_disk_payload` | Payload 是否存储在磁盘上 | false |

### 集群级别配置

| 参数 | 说明 |
|------|------|
| `timeout` | 操作超时时间 |
| `gc_timeout` | 垃圾回收超时 |
| `bootstrap_timeout` | 启动引导超时 |

## 本地分片实现

### LocalShard 结构

`LocalShard` 是分片的本地存储实现，封装了底层的 Segment 管理和操作：

```rust
// 核心模块组织
pub mod local_shard {
    pub mod clock_map;       // 分布式时钟
    pub mod disk_usage_watcher;  // 磁盘监控
    pub mod facet;          // Facet 搜索
    pub mod query;          // 查询处理
    pub mod search;         // 搜索执行
    pub mod scroll;          // 分页滚动
    pub mod updaters;        // 数据更新
    pub mod wal_ops;        // WAL 操作
}
```

资料来源：[lib/collection/src/shards/local_shard/mod.rs:1-20]()

### 数据一致性检查

分片提供数据一致性检查功能：

```rust
pub fn check_data_consistency(&self) -> OperationResult<()> {
    // 检查项：
    // - 内部 ID 无外部 ID
    // - 外部 ID 无内部 ID
    // - 内部 ID 无版本信息
    // - 内部 ID 无向量数据
}
```

资料来源：[lib/segment/src/segment/segment_ops.rs:80-95]()

## 最佳实践

### 分片数量选择

- 小型数据集（< 1M 向量）：1-2 个分片
- 中型数据集（1M - 100M 向量）：4-8 个分片
- 大型数据集（> 100M 向量）：按节点数量和查询并发度扩展

### 复制因子选择

| 场景 | 建议复制因子 |
|------|-------------|
| 单节点开发测试 | 1 |
| 生产环境 | 2-3 |
| 高可用关键业务 | 3+ |

### 常见问题

1. **热点问题**：某些分片负载过高时，可通过调整分片键或增加分片数量解决
2. **复制延迟**：异步复制场景下可能出现读取旧数据，需根据一致性要求选择同步或异步模式
3. **网络分区**：共识机制保证多数派节点可用时系统仍可写入

## 相关文档

- [集合管理](collections.md)
- [共识协议](consensus.md)
- [快照与恢复](snapshots.md)

---

<a id='page-wal-storage'></a>

## WAL 与存储引擎

### 相关页面

相关主题：[分片与复制](#page-sharding-replication), [集合管理](#page-collection-management)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/wal/src/lib.rs](https://github.com/qdrant/qdrant/blob/main/lib/wal/src/lib.rs)
- [lib/gridstore/src/gridstore/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/gridstore/mod.rs)
- [lib/collection/src/update_handler.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/update_handler.rs)
- [lib/gridstore/src/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/config.rs)
- [lib/gridstore/src/pages.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/pages.rs)
- [lib/shard/src/wal.rs](https://github.com/qdrant/qdrant/blob/main/lib/shard/src/wal.rs)
- [lib/collection/src/operations/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/operations/mod.rs)
- [lib/gridstore/src/bitmask/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/bitmask/mod.rs)
</details>

# WAL 与存储引擎

## 概述

Qdrant 的持久化层由两个核心组件构成：**Write-Ahead Log (WAL)** 和 **存储引擎**。WAL 负责确保所有更新操作的持久性和一致性，而存储引擎则负责高效地组织、索引和检索向量数据。

在分布式向量搜索场景中，数据一致性至关重要。WAL 机制确保即使在系统崩溃后也能恢复未完全写入主存储的更新操作，而 GridStore 作为主存储引擎提供了高性能的内存映射文件和块级存储管理。

## WAL (Write-Ahead Log)

### 核心职责

WAL 是 Qdrant 实现数据持久化和故障恢复的核心机制。其主要职责包括：

1. **操作记录**：将所有点操作（插入、更新、删除）追加写入预写日志
2. **故障恢复**：在系统重启时重放 WAL 中的操作，确保数据不丢失
3. **共识支持**：为分布式共识提供操作顺序保证
4. **原子性保证**：确保分布式环境下的操作一致性

### 模块结构

```text
lib/wal/
├── src/
│   ├── lib.rs           # WAL 主模块，定义核心接口
│   ├── wal.rs           # WAL 实现
│   ├── wal_tests.rs     # 单元测试
│   ├── entry.rs         # 日志条目定义
│   ├── segment.rs       # 日志分段管理
│   └── error.rs         # 错误类型定义
```

### WAL 与分片的关联

在分片（Shard）架构中，每个分片维护独立的 WAL 实例：

```text
lib/shard/src/wal.rs  ← 分片级别的 WAL 封装
lib/shard/src/lib.rs  ← 导出 wal 模块
```

分片 WAL 的关键操作包括：

| 操作 | 说明 |
|------|------|
| `append` | 追加操作到 WAL |
| `fsync` | 强制刷盘确保持久化 |
| `read` | 读取 WAL 中的记录 |
| `truncate` | 清理已确认的旧记录 |

### WAL 持久化流程

```mermaid
graph TD
    A[接收更新操作] --> B[序列化操作数据]
    B --> C[追加写入 WAL]
    C --> D[调用 fsync]
    D --> E[操作确认返回]
    E --> F[异步应用更新到存储]
    
    G[系统启动] --> H[读取 WAL]
    H --> I{检查点存在?}
    I -->|是| J[从检查点恢复]
    I -->|否| K[从头重放 WAL]
    J --> L[继续正常服务]
    K --> L
```

## 存储引擎：GridStore

### 设计目标

GridStore 是 Qdrant 从 RocksDB 迁移后的新一代存储引擎，其核心设计目标包括：

- **高吞吐量**：支持 io_uring 异步 I/O，最大化磁盘带宽利用率
- **低延迟**：非阻塞刷盘操作，减少搜索尾延迟
- **内存映射**：利用 mmap 进行高效的向量数据访问
- **块级管理**：细粒度的存储空间分配和回收

资料来源：[lib/gridstore/src/config.rs:1-50](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/config.rs)

### 存储层次结构

GridStore 采用三层存储结构：

```text
┌─────────────────────────────────────────┐
│              GridStore                   │
├─────────────────────────────────────────┤
│  Page (默认 32MB)                        │
│  ├── Region (默认 8192 blocks)          │
│  │   └── Block (默认 128 bytes)         │
│  └── Region Gaps (位图管理)             │
├─────────────────────────────────────────┤
│  Bitmask (页面级可用空间追踪)           │
└─────────────────────────────────────────┘
```

| 层级 | 默认大小 | 说明 |
|------|---------|------|
| Block | 128 bytes | 最小分配单元 |
| Region | 8192 blocks (1MB) | 区域管理单元 |
| Page | 32MB | 文件映射单元 |

资料来源：[lib/gridstore/src/pages.rs:1-60](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/pages.rs)

### 页面管理机制

页面是 GridStore 的核心抽象单元。每个页面包含多个区域，区域由连续的块组成。位图（Bitmask）用于追踪每个页面的可用空间状态。

```rust
// 页面值范围计算
pub fn get_page_value_ranges(pointer: ValuePointer, config: &StorageConfig)
```

当写入值跨越多个页面时，GridStore 自动处理跨页拆分：

```text
┌── ValuePointer ───┐
│ page_id:      123 │
│ block_offset: 6   │  ← 起始位置
│ length:       5K  │  ← 跨越长度
└─────────┬─────────┘
          │
          ▼
┌───┬───┬── page 123 ───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │  ← 跨越区域
└───┴───┴───┴───┴───┴───┴───┴───┘
                │
                ▼
┌───┬───┬── page 124 ───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└───┴───┴───┴───┴───┴───┴───┴───┘
```

资料来源：[lib/gridstore/src/pages.rs:100-150](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/pages.rs)

### 位图管理

GridStore 使用位图追踪每个页面的可用块：

```rust
// 位图长度计算：每页块数 / 8
pub fn length_for_page(config: &StorageConfig) -> usize {
    let bits = config.page_size_bytes / config.block_size_bytes;
    bits / u8::BITS as usize
}
```

位图结构特点：
- 每位对应一个块，1 表示已用，0 表示空闲
- 区域间隙（Region Gaps）提供更细粒度的空间追踪
- 支持高效的空闲空间查找

资料来源：[lib/gridstore/src/bitmask/mod.rs:1-50](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/bitmask/mod.rs)

### 存储配置

```rust
pub struct StorageConfig {
    pub page_size_bytes: usize,      // 默认 32MB
    pub block_size_bytes: usize,      // 默认 128 bytes
    pub region_size_blocks: usize,    // 默认 8192 blocks
    pub compression: Compression,     // 默认 LZ4
}
```

配置验证规则：
- 块大小必须大于 0
- 区域大小必须大于 0
- 页面大小必须大于等于 `block_size_bytes * region_size_blocks`

资料来源：[lib/gridstore/src/config.rs:40-80](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/config.rs)

## 更新处理流程

### UpdateHandler 架构

UpdateHandler 是协调 WAL 和存储引擎的关键组件：

```text
lib/collection/src/update_handler.rs
```

```mermaid
graph LR
    A[API 请求] --> B[WAL 写入]
    B --> C[fsync 持久化]
    C --> D[更新操作入队]
    D --> E[UpdateHandler 消费]
    E --> F[Segment 更新]
    F --> G[GridStore 写入]
    G --> H[索引更新]
```

### 异步更新机制

UpdateHandler 支持异步处理流程：

1. **WAL 同步写入**：确保操作已持久化
2. **操作入队**：根据分片路由分发操作
3. **批量应用**：优化器以批次方式应用更新
4. **存储合并**：定期合并小段为大段

资料来源：[lib/collection/src/update_handler.rs:1-100](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/update_handler.rs)

### 批量查询优化

v1.16.1 引入的优化使批量查询在完整扫描场景下性能提升 3 倍，原理是每个点只读取一次：

```rust
// 批量查询时共享数据读取
pub struct BatchQueryContext {
    // 多个查询共享同一点的数据读取
}
```

资料来源：[lib/collection/src/operations/mod.rs:1-50](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/operations/mod.rs)

## GridStore 与 RocksDB 的迁移

### 迁移背景

Qdrant 正在逐步将存储从 RocksDB 迁移到自研的 GridStore：

| 特性 | RocksDB | GridStore |
|------|---------|-----------|
| I/O 模型 | 同步 | 异步 io_uring |
| 压缩 | 多种算法 | LZ4 (默认) |
| 内存映射 | 受限 | 原生支持 |
| 维护性 | 外部依赖 | 自研可控 |

### 启动时迁移

v1.16.1 在启动时主动迁移向量、有效载荷和有效载荷索引存储：

```rust
// 从 RocksDB 迁移到 GridStore
pub fn migrate_on_startup() {
    // 检测旧存储格式
    // 渐进式迁移数据
}
```

资料来源：[lib/gridstore/src/gridstore/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/gridstore/mod.rs)

## 性能优化特性

### 非阻塞刷盘

v1.17.1 将 GridStore 刷盘操作改为非阻塞，显著降低搜索尾延迟：

```rust
pub fn flusher(&self) -> Flusher {
    // 返回延迟执行的刷盘器
    Box::new(move || {
        for flusher in flushers {
            flusher()?;
        }
        Ok(())
    })
}
```

刷盘流程优化：
- 主线程不等待实际刷盘完成
- 后台线程异步执行 I/O
- 搜索操作不受刷盘阻塞

资料来源：[lib/gridstore/src/pages.rs:80-100](https://github.com/qdrant/qdrant/blob/main/lib/gridstore/src/pages.rs)

### 预取优化

GridStore 支持预取机制优化读取性能：

```rust
// 触发多页预取
pub fn will_need_multiple_pages(region: &[u8]) {
    // 对 MADV_RANDOM 区域进行顺序预取
}
```

适用场景：
- 批量扫描操作
- 范围查询
- 迭代器遍历

## 已知问题与社区反馈

### WAL 相关关键修复

| 版本 | 问题 | 修复 |
|------|------|------|
| v1.16.2 | 关键 WAL bug 可能破坏共识 | #7674 |
| v1.18.1 | 异步 upsert 前验证向量维度 | #9058 |

v1.16.2 的 WAL 修复解决了可能导致共识失败或数据损坏的关键问题。

资料来源：[https://github.com/qdrant/qdrant/releases/tag/v1.16.2](https://github.com/qdrant/qdrant/releases/tag/v1.16.2)

### 存储迁移注意事项

- 迁移过程中需要额外磁盘空间
- 大规模集合迁移可能需要较长时间
- 建议在低峰期执行迁移操作

## 相关模块索引

| 模块路径 | 职责 |
|---------|------|
| `lib/wal/` | WAL 核心实现 |
| `lib/gridstore/` | GridStore 存储引擎 |
| `lib/shard/src/wal.rs` | 分片 WAL 封装 |
| `lib/collection/src/update_handler.rs` | 更新处理协调 |
| `lib/segment/` | Segment 索引管理 |
| `lib/collection/src/wal_delta.rs` | WAL 增量同步 |

## 总结

Qdrant 的 WAL 与存储引擎架构体现了对高性能和可靠性的双重追求：

1. **WAL 机制**确保所有更新操作的持久性，为分布式共识提供基础
2. **GridStore**作为新一代存储引擎，通过 io_uring 和内存映射技术实现高吞吐低延迟
3. **UpdateHandler**协调 WAL 和存储引擎，实现高效的异步更新处理
4. **持续的优化**（如非阻塞刷盘、批量查询优化）不断提升系统性能

这套架构使得 Qdrant 能够在大规模向量搜索场景下保持稳定可靠的运行，同时为未来的功能扩展奠定坚实基础。

---

<a id='page-api-interfaces'></a>

## API 接口

### 相关页面

相关主题：[Qdrant 简介](#page-introduction)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/api/src/rest/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/api/src/rest/mod.rs)
- [lib/api/src/rest/schema.rs](https://github.com/qdrant/qdrant/blob/main/lib/api/src/rest/schema.rs)
- [lib/collection/src/config.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/config.rs)
- [lib/collection/src/operations/types.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/operations/types.rs)
- [lib/collection/src/operations/generalizer/mod.rs](https://github.com/qdrant/qdrant/blob/main/lib/collection/src/operations/generalizer/mod.rs)
- [lib/segment/src/segment/segment_ops.rs](https://github.com/qdrant/qdrant/blob/main/lib/segment/src/segment/segment_ops.rs)
- [src/common/mod.rs](https://github.com/qdrant/qdrant/blob/main/src/common/mod.rs)
- [src/actix/api/search_api.rs](https://github.com/qdrant/qdrant/blob/main/src/actix/api/search_api.rs)
</details>

# API 接口

## 概述

Qdrant 提供了完整的 RESTful API 和 gRPC API 用于向量搜索和数据库管理。API 接口层负责处理客户端请求、参数验证、响应格式化以及与底层存储和索引系统的交互。

Qdrant 的 API 架构采用分层设计，核心组件位于 `lib/api` 目录下，通过 `src/actix` 层暴露给外部客户端。

资料来源：[lib/api/src/rest/mod.rs:1-10]()

## API 架构设计

### 模块结构

Qdrant 的 API 层主要分为以下几个模块：

| 模块 | 路径 | 功能 |
|------|------|------|
| REST API | `lib/api/src/rest/` | 处理 HTTP/REST 请求 |
| gRPC API | `lib/api/src/grpc/` | 处理 Protocol Buffers 请求 |
| 公共模块 | `lib/api/src/` | 共享的数据结构和工具 |

```mermaid
graph TD
    A[客户端请求] --> B[Actix HTTP Server]
    A --> C[gRPC Server]
    B --> D[REST API Handler]
    C --> E[gRPC Handler]
    D --> F[lib/api - REST模块]
    E --> G[lib/api - gRPC模块]
    F --> H[lib/collection - 集合操作]
    G --> H
    H --> I[lib/segment - 段管理]
    I --> J[lib/vector_storage - 向量存储]
    J --> K[lib/gridstore - 磁盘存储]
```

资料来源：[src/common/mod.rs:1-30]()

## REST API 模块

### 模块组织

REST API 的核心代码位于 `lib/api/src/rest/` 目录，包含以下子模块：

```rust
pub mod conversions;    // 类型转换
pub mod models;        // 数据模型定义
pub mod schema;        // JSON Schema 生成
pub mod validate;      // 参数验证
pub use schema::*;     // 导出 schema 相关类型
```

资料来源：[lib/api/src/rest/mod.rs:1-10]()

### Schema 生成与验证

REST API 使用 `schemars` 库自动生成 OpenAPI/JSON Schema，支持与 OpenAPI 客户端的自动集成。

#### DocumentOptions 配置

`DocumentOptions` 是一个无标签枚举，用于处理文档相关配置选项：

```rust
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
#[serde(untagged, rename_all = "snake_case")]
pub enum DocumentOptions {
    // 通用的键值对选项
    Common(HashMap<String, JsonValue>),
    // BM25 专用配置
    Bm25(Bm25Config),
}
```

该设计允许 API 自动反序列化为通用选项，即使指定了 `qdrant/bm25` 模型名称也能正确处理。资料来源：[lib/api/src/rest/schema.rs:1-50]()

#### 反序列化行为

BM25 配置在 JSON Schema 生成时使用特定变体，但实际反序列化时会被转换为 `Common` 类型：

```rust
impl DocumentOptions {
    pub fn into_options(self) -> HashMap<String, JsonValue> {
        match self {
            DocumentOptions::Common(options) => options,
            DocumentOptions::Bm25(bm25) => bm25.to_options(),
        }
    }
}
```

资料来源：[lib/api/src/rest/schema.rs:50-70]()

## 集合配置管理

### CollectionConfigInternal 结构

集合配置是 Qdrant API 的核心管理对象，支持持久化和加载：

```rust
pub struct CollectionConfigInternal {
    /// 集合元数据，用于存储应用特定信息
    /// 例如：创建时间、迁移数据、推理模型信息等
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub metadata: Option<Payload>,
}
```

资料来源：[lib/collection/src/config.rs:1-100]()

### 配置持久化方法

| 方法 | 功能 |
|------|------|
| `to_bytes()` | 将配置序列化为字节数组 |
| `save(path)` | 原子性写入配置文件 |
| `load(path)` | 从文件系统加载配置 |
| `check(path)` | 检查配置文件是否存在 |
| `validate_and_warn()` | 验证配置有效性并输出警告 |

```rust
impl CollectionConfigInternal {
    pub fn save(&self, path: &Path) -> CollectionResult<()> {
        let config_path = path.join(COLLECTION_CONFIG_FILE);
        let af = AtomicFile::new(&config_path, AllowOverwrite);
        state_bytes = serde_json::to_vec(self).unwrap();
        af.write(|f| f.write_all(&state_bytes))
    }
}
```

资料来源：[lib/collection/src/config.rs:30-60]()

## 操作类型系统

### IssuesReport 问题报告

Qdrant 提供了问题追踪机制，用于报告实例中的所有未解决问题：

```rust
#[derive(Serialize, JsonSchema, Debug)]
pub struct IssuesReport {
    pub issues: Vec<IssueRecord>,
}
```

### PeerMetadata 对等节点元数据

每个对等节点都维护版本信息，用于集群管理和一致性检查：

```rust
#[derive(Clone, Debug, Eq, PartialEq, Hash, Deserialize, Serialize, JsonSchema)]
pub struct PeerMetadata {
    pub(crate) version: Version,
}

impl PeerMetadata {
    pub fn current() -> Self;
    pub fn is_different_version(&self) -> bool;
}
```

资料来源：[lib/collection/src/operations/types.rs:1-80]()

## 通用化模式（Generalizer）

### 用途与设计

Generalizer 是一种特性（Trait），用于从请求结构中移除向量和有效载荷的具体细节，生成轻量级的通用表示：

```rust
/// 从结构中移除向量和有效载荷的实现接口
/// 用于泛化请求，去除向量和有效载荷的具体细节
/// 除向量和有效载荷外的其他字段会被复制
/// 向量会被替换为长度指示，有效载荷会被替换为键和长度指示
pub trait Generalizer {
    fn remove_details(&self) -> Self;
}
```

资料来源：[lib/collection/src/operations/generalizer/mod.rs:1-30]()

### 操作子模块

通用化系统包含以下子模块：

| 子模块 | 功能 |
|--------|------|
| `count` | 计数操作通用化 |
| `facet` | 分面搜索操作 |
| `matrix` | 矩阵操作 |
| `points` | 点操作通用化 |
| `query` | 查询操作通用化 |
| `update_persisted` | 持久化更新操作 |

## 段操作（Segment Operations）

### 数据一致性检查

Segment 层提供了完整的数据一致性验证功能：

```rust
impl Segment {
    /// 检查段自身的数据一致性
    /// - 存在内部ID但无外部ID
    /// - 存在外部ID但无内部ID
    /// - 存在内部ID但无版本信息
    /// - 存在内部ID但无向量数据
    pub fn check_data_consistency(&self) -> OperationResult<()>;
}
```

资料来源：[lib/segment/src/segment/segment_ops.rs:1-50]()

### 有效载荷索引管理

段操作还包括有效载荷索引的自动创建和更新：

```rust
// 创建或更新与配置不匹配的有效载荷索引
for (key, schema) in schema_config {
    match schema_applied.get(key) {
        Some(existing_schema) if existing_schema == schema => continue,
        Some(existing_schema) => log::warn!(
            "段中的有效载荷索引不正确，正在重新创建 (当前: {:?}, 配置: {:?})",
            existing_schema.name(),
            schema.name(),
        ),
        None => log::warn!(
            "段中缺少 {} 有效载荷索引，正在创建",
            schema.name(),
        ),
    }
    self.create_field_index(...)?;
}
```

资料来源：[lib/segment/src/segment/segment_ops.rs:50-100]()

## HTTP 客户端封装

`src/common/http_client` 模块提供了 Qdrant 服务间通信的 HTTP 客户端实现，支持请求超时和重试机制。相关改进包括：

- 搜索和点检索超时处理（v1.16.3）
- 遥测和指标请求超时处理（v1.16.2）
- HTTP 请求中添加 User-Agent 头（v1.16.2）

资料来源：[src/common/mod.rs:15]()

## API 版本与变更

### v1.18.x 改进

- 批量查询优化：全量扫描场景下批量查询速度提升最多 3 倍
- 异步 Upsert 向量维度验证：在 WAL 写入前进行验证

### v1.17.x 特性

- **相关性反馈 API**（v1.17.0）：支持搜索结果相关性反馈
- **优化进度报告 API**（v1.17.0）：提供详细的优化进度和各阶段信息
- **GridStore 非阻塞刷新**（v1.17.1）：减少搜索尾部延迟
- **延迟点更新应用**（v1.17.1）：使用 `prevent_unoptimized=true` 优化点更新

### v1.16.x 稳定性改进

- 关键 WAL 修复：避免共识破坏或数据损坏
- 启动时主动迁移存储：从 RocksDB 迁移到 GridStore

## 相关资源

- [REST API 文档](https://qdrant.tech/documentation/concepts/)
- [Python 客户端](https://github.com/qdrant/qdrant-client)
- [JavaScript/TypeScript 客户端](https://github.com/qdrant/qdrant-js)
- [Java 客户端](https://github.com/qdrant/java-client)
- .NET/C# 客户端：https://github.com/qdrant/qdrant-dotnet

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：qdrant/qdrant

摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 依赖 Docker 环境。

## 1. 安装坑 · 依赖 Docker 环境

- 严重度：medium
- 证据强度：runtime_trace
- 发现：安装/运行入口包含 Docker 命令：docker run -p 6333:6333 qdrant/qdrant
- 对用户的影响：非工程用户可能没有 Docker，启动成本明显增加。
- 建议检查：标注 Docker 前置条件，并提供非 Docker 路径或失败提示。
- 复现命令：`docker run -p 6333:6333 qdrant/qdrant`
- 防护动作：Docker 前置条件未说明时，不把项目标成普通用户低门槛。
- 证据：identity.distribution | github_repo:268163609 | https://github.com/qdrant/qdrant | docker run -p 6333:6333 qdrant/qdrant

## 2. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 建议检查：将假设转成下游验证清单。
- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。
- 证据：capability.assumptions | github_repo:268163609 | https://github.com/qdrant/qdrant | README/documentation is current enough for a first validation pass.

## 3. 运行坑 · 运行可能依赖外部服务

- 严重度：medium
- 证据强度：source_linked
- 发现：项目说明出现 external service/cloud/webhook/database 等运行依赖关键词。
- 对用户的影响：本地安装成功不等于能力可用，外部服务不可用会阻断体验。
- 建议检查：确认是否有离线 demo、mock 数据或可替代服务。
- 防护动作：外部服务依赖未明确时，不把本地安装成功等同于能力可用。
- 证据：packet_text.keyword_scan | github_repo:268163609 | https://github.com/qdrant/qdrant | matched external service / cloud / webhook / database keyword

## 4. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。
- 证据：evidence.maintainer_signals | github_repo:268163609 | https://github.com/qdrant/qdrant | last_activity_observed missing

## 5. 安全/权限坑 · 下游验证发现风险项

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：下游已经要求复核，不能在页面中弱化。
- 建议检查：进入安全/权限治理复核队列。
- 防护动作：下游风险存在时必须保持 review/recommendation 降级。
- 证据：downstream_validation.risk_items | github_repo:268163609 | https://github.com/qdrant/qdrant | no_demo; severity=medium

## 6. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 建议检查：把风险写入边界卡，并确认是否需要人工复核。
- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。
- 证据：risks.scoring_risks | github_repo:268163609 | https://github.com/qdrant/qdrant | no_demo; severity=medium

## 7. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。
- 防护动作：issue/PR 响应未知时，必须提示维护风险。
- 证据：evidence.maintainer_signals | github_repo:268163609 | https://github.com/qdrant/qdrant | issue_or_pr_quality=unknown

## 8. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。
- 证据：evidence.maintainer_signals | github_repo:268163609 | https://github.com/qdrant/qdrant | release_recency=unknown

<!-- canonical_name: qdrant/qdrant; human_manual_source: deepwiki_human_wiki -->
