Files
awoooi/docs/adr/ADR-007-data-retention-policy.md
OG T 7478dc0254 feat(phase6-9): Complete modular architecture and Agent Teams
Phase 6.4 - Modular Architecture:
- Add lewooogo-brain adapters for LLM providers
- Add lewooogo-data dual memory (Redis + PostgreSQL)
- Implement consensus engine for multi-agent decisions
- Add incident memory service for historical context

Phase 9 - Agent Teams (Claude Agent SDK):
- Add base agent class with Claude Sonnet 4 integration
- Implement action planner, blast radius, and security agents
- Add agent API endpoints and proposal workflow
- Integrate ADR-009 OpenClaw Agent Teams architecture

DevOps & CI/CD:
- Add GitHub Actions CI/CD workflows (ci.yaml, cd.yaml)
- Add pre-commit hooks and secrets baseline
- Add docker-compose for local development
- Update Kubernetes network policies

Frontend Improvements:
- Add auto-healing error boundary component
- Update i18n messages for agent features
- Enhance dual-state incident card with execution feedback

Documentation:
- Add 7 ADRs covering MCP, design system, architecture decisions
- Update ARCHITECTURE_MEMORY.md with modular design
- Add GLOBAL_RULES.md and SOUL.md for project identity

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 18:40:36 +08:00

7.5 KiB
Raw Blame History

ADR-007: 資料保留策略

狀態: 已接受 日期: 2026-03-20 決策者: CEO, CTO, CIO


背景

需要定義各類型資料的保留時間 (TTL),確保:

  1. 系統效能不因資料累積而下降
  2. 重要資料有足夠的回溯時間
  3. 儲存成本可控

CEO 指示 #7

熱資料 (Redis/即時查詢) TTL 7 天 => 初期是否也保留 6 個月?要確認數據量有多大?


決策

資料分層策略

┌─────────────────────────────────────────────────────────┐
│ Layer 1: 熱資料 (Redis)                                 │
│ TTL: 7-30 天                                            │
│ 用途: 即時查詢、快取、Session                            │
│ 預估容量: ~500MB                                        │
└─────────────────────────────────────────────────────────┘
                        │ 過期後
                        ▼
┌─────────────────────────────────────────────────────────┐
│ Layer 2: 溫資料 (PostgreSQL)                            │
│ TTL: 6 個月 (CEO 指示)                                  │
│ 用途: 歷史查詢、報表、分析                               │
│ 預估容量: ~5GB/月                                       │
└─────────────────────────────────────────────────────────┘
                        │ 過期後
                        ▼
┌─────────────────────────────────────────────────────────┐
│ Layer 3: 冷資料 (歸檔)                                  │
│ TTL: 永久 (審計日誌) / 1 年 (一般)                       │
│ 用途: 合規、稽核、法律要求                               │
│ 預估容量: ~10GB/年                                      │
└─────────────────────────────────────────────────────────┘

各資料類型 TTL 定義

Redis 熱資料 (Layer 1)

資料類型 TTL 說明 預估大小
Session Token 7 天 用戶登入狀態 ~1KB/session
Dashboard 快取 5 分鐘 即時指標聚合 ~10KB
主機狀態快取 30 秒 即時健康狀態 ~2KB/host
AI 回應快取 1 小時 相同問題快取 ~5KB/entry
限流計數器 1 分鐘 Rate Limiting ~100B/user

Redis 容量評估:

  • 4 台主機 × 2KB = 8KB (即時狀態)
  • 100 用戶 × 1KB = 100KB (Session)
  • Dashboard 快取 = 50KB
  • AI 快取 (1000 條) = 5MB
  • 總計: ~10MB (遠低於 Redis 16GB 容量)

結論: Redis 熱資料保持短 TTL (7-30 天) 是合理的,不需要延長至 6 個月。 Redis 用於快取和即時查詢,歷史資料應存放在 PostgreSQL。

PostgreSQL 溫資料 (Layer 2)

資料類型 TTL 說明 預估大小
監控指標 6 個月 CPU/Memory/Disk 歷史 ~1GB/月
告警記錄 6 個月 歷史告警 ~100MB/月
部署記錄 6 個月 Pipeline 執行歷史 ~50MB/月
工單記錄 6 個月 處理歷史 ~20MB/月
AI 對話記錄 6 個月 Copilot 歷史 ~500MB/月
用戶操作記錄 6 個月 行為追蹤 ~200MB/月

PostgreSQL 容量評估:

  • 每月增量: ~2GB
  • 6 個月累計: ~12GB
  • 總計 (含索引): ~20GB

結論: PostgreSQL 溫資料保留 6 個月,符合 CEO 指示,容量可控。

冷資料歸檔 (Layer 3)

資料類型 TTL 說明
審計日誌 永久 合規要求,不可刪除
財務記錄 7 年 法律要求
安全事件 3 年 資安稽核
系統設定變更 1 年 變更追蹤

資料清理機制

自動清理 Job

# apps/api/app/jobs/data_cleanup.py

from datetime import datetime, timedelta
from app.database import get_db
from app.models import Metric, Alert, Deployment, AIConversation

async def cleanup_expired_data():
    """每日凌晨 3:00 執行"""
    six_months_ago = datetime.utcnow() - timedelta(days=180)

    async with get_db() as db:
        # 清理過期監控指標
        deleted_metrics = await db.execute(
            delete(Metric).where(Metric.created_at < six_months_ago)
        )
        logger.info(f"Deleted {deleted_metrics.rowcount} expired metrics")

        # 清理過期告警 (保留 acknowledged 狀態)
        deleted_alerts = await db.execute(
            delete(Alert).where(
                Alert.created_at < six_months_ago,
                Alert.status != 'archived'  # 保留歸檔的告警
            )
        )
        logger.info(f"Deleted {deleted_alerts.rowcount} expired alerts")

        # ... 其他資料類型

        await db.commit()

    # 更新 Prometheus 指標
    cleanup_records_deleted.labels(type="metrics").inc(deleted_metrics.rowcount)
    cleanup_records_deleted.labels(type="alerts").inc(deleted_alerts.rowcount)

K8s CronJob

# k8s/jobs/data-cleanup-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: awoooi-data-cleanup
  namespace: awoooi-prod
spec:
  schedule: "0 3 * * *"  # 每日凌晨 3:00
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: cleanup
              image: awoooi-api:latest
              command: ["python", "-m", "app.jobs.data_cleanup"]
          restartPolicy: OnFailure

資料量監控

Prometheus 指標

# k8s/monitoring/prometheus/data-alerts.yaml
groups:
  - name: data-storage-alerts
    rules:
      # PostgreSQL 容量警告
      - alert: PostgreSQLHighUsage
        expr: |
          pg_database_size_bytes{datname="awoooi"} > 15 * 1024 * 1024 * 1024
        labels:
          severity: warning
        annotations:
          summary: "PostgreSQL 容量已達 15GB"
          description: "目前使用 {{ $value | humanize1024 }},建議檢查資料清理 Job"

      # Redis 容量警告
      - alert: RedisHighMemory
        expr: |
          redis_memory_used_bytes{db="10"} > 1 * 1024 * 1024 * 1024
        labels:
          severity: warning
        annotations:
          summary: "Redis DB 10 記憶體使用超過 1GB"

儲存成本評估

層級 6 個月容量 儲存類型 成本
Redis (熱) ~10MB 內存 包含在伺服器
PostgreSQL (溫) ~20GB SSD 包含在伺服器
歸檔 (冷) ~10GB/年 HDD/S3 ~$0.5/月

結論: 採用自建伺服器,儲存成本基本為 $0 (已攤提)。


影響

正面

  • 資料保留策略明確,符合 CEO 6 個月要求
  • Redis 維持高效能 (短 TTL)
  • 歷史資料可追溯
  • 儲存成本可控

需要注意

  • 清理 Job 需要監控,確保正常執行
  • 歸檔資料需要定期備份
  • 審計日誌不可刪除,需永久保留

變更記錄

日期 版本 變更 作者
2026-03-20 v1.0 初版建立 CTO

此 ADR 記錄資料保留策略的決策過程與實作規範。