案例 #1759:腾讯向量库 Replica 环境变量
对齐标杆 case-1828 · 写作标准
PR:#1759 | 9 文件 +91/-8 | 2026-06-22 合入 | langcaiye
结论先行
腾讯 VectorDB 创建 Collection 时需要 replica_number(读副本数,影响 HA/吞吐)。修复前,env-store 部署(用 .env 配向量库、无 UI 注册 store)只能走硬编码默认 1 — 单节点 QA 集群若设 replica≥1 会 CreateCollection 失败或资源浪费;运维也无法在不改 YAML 的情况下统一调副本。
本 PR 新增 TENCENT_VECTORDB_REPLICA_NUMBER:默认仍为 1;允许显式 0(单节点 QA);解析逻辑同时写入 tencentvectordb/repository.go(运行时建库) 与 types/vectorstore.go(注册 UI 元数据默认值)。
适合谁读:改 Tencent VectorDB adapter、Helm/docker env-store 部署、Ch30 向量库配置的贡献者。
与 case-1668:同目录 tencentvectordb/ — #1668 是 CopyIndices ID;#1759 是 CreateCollection replica — 合读可覆盖「腾讯向量库冷路径」。
链 Ch30 向量库适配器 · Ch43 检索栈 · Ch42 增量。
1. 问题现象(What)
1.1 部署场景
| 场景 | 集群形态 | 期望 replica | 修复前 |
|---|---|---|---|
| 生产 HA | 多节点 Tencent VectorDB | ≥1(常 1–3) | 默认 1,一般可用 |
| 单节点 QA / dev | 1 节点、env-store | 0 | 仍默认 1 → 可能 建库失败 或多余副本要求 |
| 运维统一调参 | 只改 .env 不重打镜像 |
0 或 3 | 无 env 入口,只能改 IndexConfig YAML |
1.2 用户可见现象
- docker-compose / K8s 单节点联调:向量库初始化或 首次 ingest 报错(Collection 创建阶段)
- 管理 UI「向量库类型」里 Tencent 的 Replicas 默认值 与
.env实际不一致 — 运维困惑
1.3 修复前 / 修复后
| 配置 | 修复前 replicasNum |
修复后 |
|---|---|---|
| 无 env、无 IndexConfig | 1 | 1(不变) |
TENCENT_VECTORDB_REPLICA_NUMBER=0 |
1 | 0 |
TENCENT_VECTORDB_REPLICA_NUMBER=3 |
1 | 3 |
IndexConfig replica_number: 2 |
2 | 2(仍 优先于 env) |
| env=0 + IndexConfig replica=2 | 2 | 2(IndexConfig 赢) |
env=abc 非法 |
1 | 回退 1 |
2. 定位步骤
# 1. 腾讯向量库建库参数从哪来
rg "replicasNum|ReplicaNumber|replica_number" \
internal/application/repository/retriever/tencentvectordb/
# 2. UI / API 展示的向量库类型默认值
rg "GetVectorStoreTypes|tencent_vectordb" internal/types/vectorstore.go
# 3. 环境变量文档
rg "TENCENT_VECTORDB" .env.example docs/
阅读顺序:
tencentvectordb/structs.go— env 常量名tencentvectordb/repository.go—resolveReplicaNumber(运行时)types/vectorstore.go—resolveTencentVectorDBReplicaNumber(元数据/UI)*_test.go— 优先级与 env=0 契约
3. 根因分析(Why)
3.1 类比
建仓库时要填「备用货架份数」(replica)。单门店仓库(单节点)填 0 份备用 才合法;平台默认写 1 且 不能从 .env 改 — 像合同模板锁死了备用货架数,QA 环境只能改代码而不能改配置。
3.2 配置解析链(双入口)
WeKnora 向量库配置有两条消费路径,必须一致:
flowchart TD
E[TENCENT_VECTORDB_REPLICA_NUMBER<br/>.env / K8s ConfigMap]
I[IndexConfig.replica_number<br/>YAML / 注册 UI]
E --> R[resolveReplicaNumber<br/>repository.go]
I --> R
R --> C[CreateCollection<br/>replicasNum]
E --> T[resolveTencentVectorDBReplicaNumber<br/>vectorstore.go]
T --> U[GetVectorStoreTypes<br/>UI 字段 Default]
C --> V[(Tencent VectorDB)]
根因:修复前只有 indexCfg.GetReplicaNumber(1) — env-store 部署 往往没有 per-store YAML,Replica 无法从环境注入;UI 元数据写死 Default: 1,与运维 env 不同步。
3.3 Milvus vs 腾讯 VectorDB 注释修正
PR 更新 GetReplicaNumber 文档:
- Milvus:replica 在 LoadCollection
- Tencent VectorDB:replica 在 CreateCollection
同一字段 replica_number 跨引擎 语义阶段不同 — 贡献者改 IndexConfig 时必须看引擎。
4. 解决方案(How)
4.1 环境变量
# .env.example(PR 新增注释)
# Tencent VectorDB 集合副本数(可选,默认 1;单节点 QA 环境可设为 0)
# TENCENT_VECTORDB_REPLICA_NUMBER=1
常量(structs.go):
envTencentVectorDBReplicaNum = "TENCENT_VECTORDB_REPLICA_NUMBER"
defaultReplicaNumber = 1
4.2 运行时:resolveReplicaNumber(repository.go)
func resolveReplicaNumber(indexCfg *types.IndexConfig) int {
if indexCfg != nil && indexCfg.ReplicaNumber > 0 {
return indexCfg.ReplicaNumber
}
if raw := strings.TrimSpace(os.Getenv(envTencentVectorDBReplicaNum)); raw != "" {
replicas, err := strconv.Atoi(raw)
if err == nil && replicas >= 0 {
return replicas
}
}
return defaultReplicaNumber
}
优先级(单测锁定):
IndexConfig.ReplicaNumber > 0— 显式 YAML/UI 配置优先- 环境变量(含 0)
- 默认 1
注意:
ReplicaNumber == 0在 IndexConfig 里 不会 走第一条(条件> 0),会落到 env — 设计上是「0 主要通过 env 表达 QA 默认」。
4.3 元数据/UI:resolveTencentVectorDBReplicaNumber
func resolveTencentVectorDBReplicaNumber(lookup EnvLookupFunc) int {
raw := strings.TrimSpace(lookup(envTencentVectorDBReplicaNumber))
if raw == "" {
return defaultTencentVectorDBReplicaNumber // 1
}
replicas, err := strconv.Atoi(raw)
if err != nil || replicas < 0 {
return defaultTencentVectorDBReplicaNumber
}
return replicas // 含 0
}
GetVectorStoreTypes() 里 Tencent 的 replica_number 字段 Default 改为动态值 — UI 与 env 一致。
4.4 为何允许 replica=0?
PR Summary:explicit 0 for single-node QA deployments — 腾讯云单节点实例无法/不需多副本;设为 0 避免 CreateCollection 参数与集群能力不匹配。
4.5 为何改两处(repository + types)?
| 位置 | 否则的问题 |
|---|---|
| 仅 repository | UI 仍显示 Default 1,运维设 env=0 但界面误导 |
| 仅 types | 实际建库仍用旧逻辑,env 不生效 |
同 case-1808:配置必须 runtime + 展示双端对齐。
4.6 逐文件改动表(9 文件)
| 文件 | ± | 说明 |
|---|---|---|
tencentvectordb/structs.go |
+2 | env 常量 + default |
tencentvectordb/repository.go |
+15/-1 | resolveReplicaNumber |
tencentvectordb/repository_test.go |
+15 | env 0/3、与 IndexConfig 优先级 |
types/vectorstore.go |
+27/-5 | UI 解析 + 注释 |
types/vectorstore_test.go |
+20 | env 影响 Default |
.env.example |
+3 | 文档 |
docs/api/vector-store.md |
+5/-2 | API 文档 |
docs/wiki/.../集成向量数据库.md |
+2 | 中文 wiki |
docs/使用其他向量数据库.md |
+2 | 部署指南 |
4.7 验证命令
go test ./internal/application/repository/retriever/tencentvectordb/ -v
go test ./internal/types/ -run 'TestGetVectorStoreTypes|TencentVectorDB' -v
关键单测名:
TestTencentVectorDBUsesEnvReplicaNumber— env=0 → replicasNum 0TestTencentVectorDBUsesConfiguredReplicaNumber— IndexConfig 2 覆盖 env 0tencent vectordb replica default follows env— UI Default 0
5. Review 与合入
PR 四段式
| 段 | 内容 |
|---|---|
| What | env-store 无法调 Tencent replica;QA 单节点需要 0 |
| Why | 仅 IndexConfig 路径,缺 env override |
| How | env + 双端解析 + 文档 |
| Test | 上述 go test 包 |
维护者 checklist
- env 0 与 正整数 均测?
- IndexConfig >0 仍覆盖 env?
- 非法 env 回退 1?
GetVectorStoreTypesDefault 与 repository 一致?- 文档三处(.env、api、wiki)同步?
作者 langcaiye — 向量库领域维护者;91 行净增,小 PR 高运维价值。
PR 四段式
| What | Why | How | Test |
|---|---|---|---|
| QA 单节点 replica 不可配 | 仅 IndexConfig 默认 1 | TENCENT_VECTORDB_REPLICA_NUMBER + 双端解析 |
go test tencentvectordb + types |
6. 与 RAG 管线
| 阶段 | 关系 |
|---|---|
| 建库 / 首次 Upsert | replica 在 CreateCollection — ingest 之前 必须成功 |
| Retrieve | replica 影响读扩展与 HA,不改正文 chunk 逻辑 |
| 换 embed Ch30 | 新 collection 仍带 replica 参数 — 与维度/runbook 独立 |
| 复制 KB case-1668 | CopyIndices 假设 collection 已存在 — replica 配错会导致 建库阶段就失败,根本走不到复制 |
7. 可复用模式
- env-store 部署 = 运维只改
.env— 关键参数需 env 一等公民,不能只藏在 YAML UI - runtime 与 UI 元数据双写 —
GetVectorStoreTypes与 repository 各一份解析,测试 两边 lock 行为 - 显式 0 的语义 — 用
>= 0而非> 0判断 env;与「未设置用默认 1」区分 - 跨引擎同字段不同语义 — 注释写清 Milvus Load vs Tencent Create
8. 常见误区
错误认知:replica 只影响性能,配错也能检索。
正确:CreateCollection 阶段就可能 失败,ingest 无法进行。
错误认知:env=0 和「未设置 env」一样。
正确:未设置 → 1;显式 0 → QA 单节点 — 单测区分。
错误认知:只改 repository 就够了。
正确:UI Default 不对会误导注册 second store — 见 §4.3。
错误认知:IndexConfig replica=0 会生效。
正确:代码路径 ReplicaNumber > 0 — 0 走 env;设计意图是 QA 用 env 全局设。
9. Staging / 部署 playbook
- 单节点 QA:
.env设TENCENT_VECTORDB_REPLICA_NUMBER=0 - 重启 WeKnora →
go test或看启动日志中建库参数 - 创建知识库 + ingest 小文档 → hybrid-search 命中
- GET 向量库 types API(若有)→
replica_number.Default应为 0 - 生产改回
1或2,确认 CreateCollection 与集群规格一致
10. 思考点
- 若支持 UI 显式 replica=0,应改
> 0判断还是新增*int指针字段? - Qdrant 的
replication_factor是否也应 env 化?grep 现有模式。 - case-1668 分页 Copy + 本 PR 建库 replica — 写「腾讯 VectorDB 贡献 checklist」还应含哪条?
- Helm values 与
.env冲突时,应以谁为准?(WeKnora env-store 惯例)
章末自检
- 画出 IndexConfig vs env 的 优先级(含 env=0)
- 说清 replica 在 Tencent 是 CreateCollection 而非 Milvus Load
- 解释为何改
vectorstore.go和repository.go - 写出两条
go test路径
延伸阅读
- case-1668 · case-1828 标杆 · Ch30 · Ch43
- 写作标准