该基准测试展示了PolarDB向量索引在特定软硬件配置下,处理亿级千维向量的写入与查询性能。本文包括测试环境、数据集、关键配置参数、复现步骤及性能结果分析,为技术选型、容量规划和性能调优提供数据参考。
适用范围
性能数据基于特定的集群环境和数据集。在应用这些数据进行决策前,需确认环境与以下条件相似。
集群规格与版本
主节点:2核 8GB。
只读节点:2核 8GB。
搜索节点:32核 256GB * 3。
客户端延迟:0.097ms。
PolarDB向量索引版本:2.19.3。
数据集
分类 | 子项 | 详情 |
软件版本 | PolarDB-Vector | 2.19.3 |
数据集 | MSMARCO V2.1 | |
数据规模 | 文档总数 | 113,520,750 |
向量维度 | 1024 | |
查询集大小 | 1677 | |
算法参数 | 距离度量 | L2(欧氏距离) |
索引类型 | HNSW |
测试步骤
以下步骤描述了如何复现索引创建、数据写入和性能压测。
若您有相关需求,请提交工单与我们联系,获取测试脚本以复现当前测试流程。
创建HNSW索引并写入数据
创建索引:以下配置用于在亿级数据规模下创建索引,以平衡构建速度、内存占用和查询性能。
定义索引结构和关键参数。
number_of_shards:设置为18,以在3个搜索节点(共96个物理核心)间均匀分布数据和计算负载。ef_construction和m:HNSW索引构建时的关键参数,本次测试选择128和8作为构建速度和索引质量的平衡点。refresh_interval和durability:为最大化测试性能进行的特定优化,不建议在生产环境直接使用。 详细说明参见应用于生产环境。
执行以下命令创建索引。
curl -X PUT "http://<endpoint>:<port>/msmarco" -H 'Content-Type: application/json' -d' { "mappings": { "properties": { "docid": { "type": "keyword" }, "domain": { "type": "keyword" }, "emb": { "type": "knn_vector", "dimension": 1024, "method": { "engine": "faiss", "space_type": "l2", "name": "hnsw", "parameters": { "ef_construction": 128, "m": 8 } } }, "url": { "type": "text" } } }, "settings": { "index": { "replication": { "type": "DOCUMENT" }, "refresh_interval": "0s", "number_of_shards": "18", "translog": { "flush_threshold_size": "1gb", "sync_interval": "30s", "durability": "async" }, "knn.algo_param": { "ef_search": "64" }, "provided_name": "msmarco", "knn": "true", "number_of_replicas": "0" } } } '
写入数据:将MSMARCO V2.1数据集写入HNSW索引。
写性能
总耗时:13523.85秒(约3.75小时),此时间包含数据网络传输、写入translog以及后台HNSW索引构建的全部时间。
平均写入吞吐量:8394.11 docs/sec。
执行查询性能测试
测试不同并发度和ef_search参数组合下的查询吞吐量(QPS)、延迟(Latency)和召回率(Recall)。
concurrency:模拟从1到128个并发查询。ef_search:查询时在HNSW图中搜索的邻居节点广度。此值越大,理论上召回率越高,但计算开销也越大,会导致QPS下降和延迟升高。
压测命令
执行以下命令,对concurrency和ef_search的不同组合进行为期60秒的压测。
# 示例命令,请替换为实际脚本
python benchmark.py --concurrency 1/2/4/8/16/32/64/128 --ef-search 32/64/128/256 --max-duration 60性能测试结果

ef_search | concurrency | QPS | Avg(ms) | P99(ms) | Recall |
32 | 1 | 132.4 | 7.53 | 8.83 | 0.9585 |
32 | 16 | 878.19 | 18.13 | 30.14 | 0.9586 |
32 | 64 | 994.43 | 63.48 | 135.83 | 0.9621 |
32 | 128 | 1043.22 | 118.53 | 256.14 | 0.9693 |
64 | 1 | 132.82 | 7.5 | 8.82 | 0.9585 |
64 | 16 | 878.44 | 18.11 | 30.35 | 0.9586 |
64 | 64 | 989.47 | 63.77 | 136.55 | 0.9622 |
64 | 128 | 1062 | 116.74 | 238.94 | 0.9696 |
128 | 1 | 132.74 | 7.51 | 8.82 | 0.9585 |
128 | 16 | 884.77 | 17.99 | 29.91 | 0.9588 |
128 | 64 | 998.4 | 63.28 | 133.64 | 0.962 |
128 | 128 | 1063.91 | 116.85 | 244.43 | 0.9695 |
256 | 1 | 132.45 | 7.52 | 8.82 | 0.9585 |
256 | 16 | 881.95 | 18.05 | 30.16 | 0.9587 |
256 | 64 | 993.25 | 63.4 | 135.17 | 0.962 |
256 | 128 | 1067.68 | 116.09 | 227.54 | 0.9697 |
性能结论分析
并发扩展性:从QPS曲线可以看出,随着并发数从1增加到64,系统吞吐量(QPS)接近线性增长,表明PolarDB向量引擎具备良好的水平扩展能力。在64并发之后,QPS增长开始放缓,并在128并发时达到峰值,此时系统资源(很可能是CPU)已接近饱和,成为性能瓶颈。
延迟与并发关系:平均延迟(Avg)和P99延迟随着并发数的增加而显著升高,这符合系统负载增加的规律。在追求高QPS的场景下,需关注P99延迟是否满足业务要求。
召回率表现:在所有测试条件下,召回率均稳定在95.8%以上,表明HNSW索引在当前参数下具有较高的搜索准确性。
应用于生产环境
将测试环境的配置直接用于生产存在风险。以下内容提供关键参数的生产环境配置建议和资源规划指导。
关键参数生产建议
以下参数为追求极限测试性能而设置,在生产环境使用时需谨慎评估。
"refresh_interval": "0s"测试目的:禁用自动刷新,确保在写入测试期间数据仅写入内存和translog,在查询测试前手动
refresh,以获得不受后台任务干扰的查询性能数据。生产建议:禁止在生产环境设置为
0s。应根据业务对数据可见性的要求设置一个合理的值,例如1s,表示新写入的数据最快在1秒后可被查询到。
"durability": "async"测试目的:采用异步刷盘(translog),数据先写入内存后即返回成功,由后台线程异步持久化到磁盘,以提升写入吞吐量。
生产建议:在高数据可靠性场景下慎用。
async模式在服务器宕机等极端情况下,可能丢失最后几秒钟尚未刷盘的数据。若对数据可靠性要求高,应在生产环境使用默认的request模式。该模式会确保数据写入translog并落盘后才返回成功,但会降低写入性能。
资源利用率评估
了解系统在峰值负载下的资源消耗,对进行准确的容量规划至关重要。
写入密集型场景:在8394 docs/sec的峰值写入期间,系统瓶颈主要体现在CPU(用于索引构建)和磁盘I/O(用于translog写入)。
查询密集型场景:在128并发、1067 QPS的峰值查询期间,系统瓶颈主要为CPU密集型。