Files
ewoooc/docs/adr/ADR-009-embedding-retry-queue-persistence.md
ogt 1b4f3a7bbe
Some checks failed
CD Pipeline / deploy (push) Failing after 59s
feat: EwoooC 初始化 — 完整專案推版至 Gitea
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml)
- 部署模式: rsync Python 檔案至 188 → docker restart (volume mount)
- Dockerfile/requirements 變動時自動重建 Docker image
- 部署通知: Telegram (開始/成功/失敗)
- 健康檢查: https://mo.wooo.work/health (最多 5 次重試)
- 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 01:21:13 +08:00

87 lines
2.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-009Embedding Retry Queue 持久化DB-backed
- **Status**: Accepted
- **Date**: 2026-04-19
- **Decision Maker**: 統帥
- **Author**: Claude
## Context
ADR-007AI 學習雙寫規範)要求 `store_insight()` 必須同時寫入 `ai_insights` DB 表與 `embedding` 欄位。
初版實作2026-04-18使用 Python `queue.Queue()` 記憶體佇列 + daemon thread worker
```python
_embedding_queue = Queue() # 記憶體
threading.Thread(target=_embedding_worker, daemon=True).start()
```
**破洞**
- Python 進程重啟K8s Pod 滾動重啟、gunicorn reload、OOM kill→ queue 全部遺失
- Ollama 主機 192.168.0.111 短暫斷線 → 該筆 insight 永遠沒 embedding
- 違反 ADR-007「雙寫必達」精神DB 有寫但 KM 沒寫 → RAG 永遠找不到這筆洞察
## Decision
**Embedding queue 改為 DB 持久化**`embedding_retry_queue`worker 改為輪詢批次處理。
| 面向 | 記憶體 Queue | DB Queue |
|---|---|---|
| 持久化 | ❌ 重啟遺失 | ✅ 持久化 |
| Retry | ❌ 無 | ✅ attempts 欄位 + 上限 5 次 |
| 觀測性 | ❌ 無法查詢 | ✅ SQL 即可 |
| 跨進程 | ❌ 每 Pod 各自一份 | ✅ 多 Pod 共享同一 queue |
| 吞吐 | ✅ 最快 | ✅ 批次 10 筆/分鐘已足夠 |
## SchemaMigration 011
```sql
CREATE TABLE embedding_retry_queue (
id SERIAL PRIMARY KEY,
target_table VARCHAR(50) NOT NULL, -- ai_insights / conversations
target_id INTEGER NOT NULL,
text_content TEXT NOT NULL,
model VARCHAR(50) DEFAULT 'bge-m3:latest',
status VARCHAR(20) DEFAULT 'pending', -- pending / processing / done / failed
attempts INTEGER DEFAULT 0,
last_error TEXT,
created_at TIMESTAMP,
updated_at TIMESTAMP,
processed_at TIMESTAMP
);
```
## Worker 流程
```
Worker Loop (每 60 秒):
SELECT * FROM embedding_retry_queue
WHERE status='pending' AND attempts < 5
ORDER BY created_at LIMIT 10
對每筆:
UPDATE status='processing'
呼叫 Ollama bge-m3 生成 embedding
成功 → UPDATE target SET embedding = vec;
UPDATE retry_queue SET status='done', processed_at=NOW()
失敗 → UPDATE retry_queue SET attempts=attempts+1, last_error=...
若 attempts ≥ 5 → status='failed'(人工處理)
```
## Consequences
### Positive
- 即使 Pod 重啟也不會丟 embedding 任務
- 失敗累積可視化(可寫 Grafana 面板監控 `status='failed'` 數量)
- 多 Pod 共用同一 queue不重複處理processing 狀態互斥)
### Negative
- 延遲從「毫秒」拉長到「最多 60 秒」(輪詢間隔)
- 緩解AI 洞察不需要即時 embeddingRAG 查詢 < 1 分鐘延遲可接受
- DB 需多一張表(小幅維運成本)
## Related ADRs
- ADR-007雙寫規範本 ADR 是其 Step 4 的持久化實作
- ADR-003本地 embeddingworker 呼叫的後端