作业16 · 向量恢复演练 Runbook(一页)
场景:知识库索引/检索异常,怀疑向量层数据丢失或损坏。在隔离环境演练:删测试集合 → 从备份恢复 → 抽检查询。
生产 207 现网为 Weaviate;Milvus 用 compose
milvusprofile 隔离演练。
0. 何时启动本 Runbook
| 信号 | 说明 |
|---|---|
Dify 文档 completed 但检索空 | PG 与向量不一致 |
milvus_querynode_entity_num = 0 | Milvus 实体丢失 |
| Weaviate class 对象数为 0 | 向量卷损坏或未恢复 |
| ES cluster red / knn errors 飙升 | RAGFlow/ES 路径 |
先排除:Worker 宕机(作业15)、embedding 不可用(专题二)、Weaviate 网络(专题六)。
1. 演练前检查清单
- [ ] 目标环境为隔离(
dify-hw15/ 独立 milvus),非 207 生产:80 - [ ] 已有备份:作业15 清单中向量卷 + PG +
app/storage - [ ] 记录 baseline:
entity_num/ object count / 命中测试 query - [ ] 变更窗口内通知(即使隔离也养成习惯)
2. Milvus 分支(推荐动手路径)
2.1 备份(演练前或日常)
cd /opt/dify-hw15 # 或你的隔离根目录
docker compose --project-name dify-hw15 stop milvus-standalone minio etcd
TS=$(date +%Y%m%d_%H%M%S)
tar -czf "/tmp/milvus_volumes_${TS}.tar.gz" volumes/milvus/
docker compose --project-name dify-hw15 start etcd minio milvus-standalone2.2 创建测试数据(首次)
# 健康
curl -sS http://127.0.0.1:9091/healthz
# Python(需 pymilvus)
python - <<'PY'
from pymilvus import Collection, CollectionSchema, DataType, FieldSchema, connections, utility
connections.connect("default", host="127.0.0.1", port="19530")
name = "hw16_test"
if utility.has_collection(name):
utility.drop_collection(name)
fields = [
FieldSchema("id", DataType.INT64, is_primary=True),
FieldSchema("vec", DataType.FLOAT_VECTOR, dim=4),
]
schema = CollectionSchema(fields, "hw16 drill")
c = Collection(name, schema)
c.insert([[1, 2], [[0.1, 0.2, 0.3, 0.4], [0.2, 0.1, 0.0, 0.5]]])
c.flush()
print("entities", c.num_entities)
PY2.3 ① 删测试集合
python - <<'PY'
from pymilvus import connections, utility
connections.connect("default", host="127.0.0.1", port="19530")
utility.drop_collection("hw16_test")
print("dropped", not utility.has_collection("hw16_test"))
PY2.4 ② 从备份恢复
docker compose --project-name dify-hw15 stop milvus-standalone minio etcd
# 还原(示例路径按你的备份文件改)
rm -rf volumes/milvus
mkdir -p volumes
tar -xzf /tmp/milvus_volumes_YYYYMMDD_HHMMSS.tar.gz -C .
docker compose --project-name dify-hw15 start etcd minio milvus-standalone
sleep 30
curl -sS http://127.0.0.1:9091/healthz2.5 ③ 抽检查询
python scripts_cursor/作业16_向量监控与知识同步/hw16_02_恢复演练抽检查询.py \
--backend milvus --collection hw16_test
# Prometheus 指标(可选)
curl -sS http://127.0.0.1:9091/metrics | grep -E 'milvus_querynode_entity_num|milvus_proxy_search'通过:脚本 "ok": true,num_entities >= 1。
3. Weaviate 分支(207 现网对照 — 仅隔离卷演练)
# 备份
docker compose stop weaviate weaviate_relay
tar -czf /tmp/weaviate_$(date +%Y%m%d).tar.gz volumes/weaviate/
# 模拟丢失:清空卷(隔离目录!)
rm -rf volumes/weaviate/*
# 恢复
tar -xzf /tmp/weaviate_YYYYMMDD.tar.gz -C .
docker compose start weaviate weaviate_relay
python scripts_cursor/作业16_向量监控与知识同步/hw16_02_恢复演练抽检查询.py \
--backend weaviate --class-name Document \
--weaviate-endpoint http://127.0.0.1:8080Dify 侧:知识库 命中测试 应返回 segment(与恢复前抽样一致)。
4. Elasticsearch kNN 分支(RAGFlow 等)
# 备份索引(示例)
curl -X PUT "http://127.0.0.1:9200/_snapshot/my_repo/snap_hw16?wait_for_completion=true"
# ① 删测试索引
curl -X DELETE "http://127.0.0.1:9200/hw16_test"
# ② 恢复
curl -X POST "http://127.0.0.1:9200/_snapshot/my_repo/snap_hw16/_restore"
# ③ 抽查
curl "http://127.0.0.1:9200/hw16_test/_count"
curl "http://127.0.0.1:9200/_cluster/health"
python scripts_cursor/作业16_向量监控与知识同步/hw16_02_恢复演练抽检查询.py --backend es --index hw16_testkNN 监控:GET /_opendistro/_knn/stats(OpenSearch 路径可能为 /_knn/stats)。
5. 失败时
| 现象 | 可能原因 | 动作 |
|---|---|---|
| 恢复后 entity=0 | 备份时间点早于 insert | 重新 insert 或换备份 |
| milvus 起不来 | etcd/minio 未同步恢复 | 三目录一起恢复 |
| Dify 仍检索空 | 只恢复了向量,PG 未恢复 | 按作业15 恢复 PG + storage |
| spot check ok 但 Dify 不行 | collection/class 名与 Dify 配置不一致 | 查 VECTOR_STORE 配置 |
6. 与告警联动
知识同步失败模板:hw16_01_知识同步失败告警文案.py 状态进入 manual 时,工单必须带:dataset_id, document_id, task_id, trace_id。
7. 记录模板
演练日期:____ 环境:隔离 hw15 / milvus
备份文件:____ 删除对象:collection/index ____
恢复耗时:____ spot check:ok / fail
entity/count 恢复前:____ 恢复后:____
备注:____