8.1 KiB
Sao Lưu & Khôi Phục Thảm Họa
Mục Tiêu RTO / RPO
| Chỉ số | Mục tiêu | Ghi chú |
|---|---|---|
| RPO (Mục tiêu Điểm Khôi phục) | ≤ 24 giờ | Sao lưu hàng ngày lúc 02:00 UTC; trường hợp xấu nhất là mất toàn bộ dữ liệu trong một ngày |
| RTO (Mục tiêu Thời gian Khôi phục) | ≤ 30 phút | Khôi phục từ bản sao lưu volume cục bộ; lâu hơn nếu lấy từ nơi lưu trữ ngoài site |
Để giảm RPO hơn nữa, hãy xem xét lưu trữ WAL cho PostgreSQL (khôi phục liên tục theo thời gian thực) và lên lịch sao lưu thường xuyên hơn.
Sao Lưu PostgreSQL
Tổng quan
Sao lưu PostgreSQL tự động hàng ngày chạy bên trong Docker container pg-backup bằng pg_dump với nén định dạng tùy chỉnh. Các bản sao lưu được lưu trữ trong Docker volume pg_backups.
Cấu Hình Sao Lưu
| Thiết lập | Mặc định | Biến môi trường |
|---|---|---|
| Lịch | Hàng ngày lúc 02:00 UTC | Cron trong service pg-backup |
| Thời gian lưu | 7 ngày | BACKUP_RETENTION_DAYS |
| Định dạng | Tùy chỉnh (pg_dump --format=custom) |
— |
| Nén | Mức 6 | — |
| Lưu trữ | Docker volume pg_backups |
— |
Liệt Kê Các Bản Sao Lưu
docker exec goodgo-pg-backup ls -lh /backups/
Sao Lưu Thủ Công
docker exec goodgo-pg-backup /scripts/pg-backup.sh
Quy Trình Khôi Phục
1. Xác định bản sao lưu cần khôi phục
docker exec goodgo-pg-backup ls -lht /backups/
2. Dừng các service ứng dụng
docker compose stop ai-services
# Stop any NestJS API processes
3. Chạy lệnh khôi phục
docker exec -it goodgo-pg-backup /scripts/pg-restore.sh /backups/goodgo_YYYYMMDD_HHMMSS.sql.gz
Script khôi phục sẽ:
- Chấm dứt các kết nối cơ sở dữ liệu đang hoạt động
- Xóa và tạo lại cơ sở dữ liệu
- Khôi phục từ bản sao lưu đã chọn
4. Xác minh khôi phục
docker exec goodgo-postgres psql -U goodgo -d goodgo -c '\dt'
docker exec goodgo-postgres psql -U goodgo -d goodgo -c 'SELECT count(*) FROM "User";'
5. Chạy migration Prisma (nếu cần)
pnpm prisma migrate deploy
6. Khởi động lại các service
docker compose up -d
Xác Minh Bản Sao Lưu
Kiểm tra log sao lưu:
docker exec goodgo-pg-backup cat /var/log/pg-backup.log
Xác minh tính toàn vẹn của bản sao lưu mà không cần khôi phục:
docker exec goodgo-pg-backup pg_restore --list /backups/goodgo_YYYYMMDD_HHMMSS.sql.gz
Sao Lưu & Khôi Phục Redis
Redis được cấu hình với tính năng bền vững AOF (--appendonly yes). Dữ liệu được lưu trong Docker volume redis_data.
Snapshot Thủ Công
# Trigger an RDB snapshot
docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" BGSAVE
# Wait for completion
docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" LASTSAVE
Sao Lưu Volume
# Stop Redis to ensure consistent snapshot
docker compose stop redis
# Copy volume data to a backup location
docker run --rm -v goodgo-platform-ai_redis_data:/data -v $(pwd)/backups:/backup \
alpine tar czf /backup/redis_$(date +%Y%m%d_%H%M%S).tar.gz -C /data .
docker compose start redis
Khôi Phục Redis
docker compose stop redis
# Clear existing data and restore
docker run --rm -v goodgo-platform-ai_redis_data:/data -v $(pwd)/backups:/backup \
alpine sh -c "rm -rf /data/* && tar xzf /backup/redis_YYYYMMDD_HHMMSS.tar.gz -C /data"
docker compose start redis
Lưu ý: Redis được dùng làm cache với chính sách loại bỏ
allkeys-lru. Mất toàn bộ dữ liệu không nghiêm trọng — API sẽ tự động nạp lại các mục cache theo yêu cầu. Việc khôi phục chỉ cần thiết khi dữ liệu phiên hoặc trạng thái hàng đợi phải được giữ nguyên.
Sao Lưu & Khôi Phục Typesense
Dữ liệu Typesense được lưu trữ trong Docker volume typesense_data.
Tạo Snapshot
# Typesense built-in snapshot API
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/operations/snapshot?snapshot_path=/data/snapshots/$(date +%Y%m%d)"
Sao Lưu Volume
docker compose stop typesense
docker run --rm -v goodgo-platform-ai_typesense_data:/data -v $(pwd)/backups:/backup \
alpine tar czf /backup/typesense_$(date +%Y%m%d_%H%M%S).tar.gz -C /data .
docker compose start typesense
Khôi Phục Typesense
docker compose stop typesense
docker run --rm -v goodgo-platform-ai_typesense_data:/data -v $(pwd)/backups:/backup \
alpine sh -c "rm -rf /data/* && tar xzf /backup/typesense_YYYYMMDD_HHMMSS.tar.gz -C /data"
docker compose start typesense
Xây Dựng Lại Từ Nguồn
Nếu bản sao lưu không có sẵn, Typesense có thể được xây dựng lại bằng cách lập chỉ mục lại từ PostgreSQL:
# After Typesense restarts with empty data:
pnpm run typesense:reindex
Sổ Tay Khôi Phục Thảm Họa
Kịch bản 1: Lỗi PostgreSQL (container crash hoặc hỏng dữ liệu)
- Đánh giá:
docker logs goodgo-postgres— kiểm tra tình trạng hỏng dữ liệu hoặc OOM - Dừng service:
docker compose stop api ai-services - Thử khởi động lại:
docker compose restart postgres - Nếu khởi động lại thất bại (hỏng dữ liệu):
docker compose stop postgres- Xóa volume:
docker volume rm goodgo-platform-ai_postgres_data - Tạo lại:
docker compose up -d postgres - Khôi phục từ bản sao lưu:
docker exec goodgo-pg-backup /scripts/pg-restore.sh /backups/<latest>.sql.gz - Xác minh:
docker exec goodgo-postgres psql -U goodgo -d goodgo -c '\dt' - Chạy migration:
pnpm prisma migrate deploy
- Khởi động lại các service:
docker compose up -d - Xác minh: Kiểm tra API health tại
http://localhost:3000/health
RTO dự kiến: ~15 phút (sao lưu cục bộ), ~30 phút (sao lưu ngoài site)
Kịch bản 2: Service Bị Crash (API, AI-services hoặc Web)
- Kiểm tra log:
docker compose logs --tail=100 <service> - Khởi động lại service:
docker compose restart <service> - Nếu crash lặp lại:
- Kiểm tra giới hạn tài nguyên:
docker stats - Kiểm tra biến môi trường:
docker compose config - Rollback về image tag trước nếu triển khai gần đây gây ra sự cố
- Kiểm tra giới hạn tài nguyên:
- Xác minh: Kiểm tra các endpoint health
RTO dự kiến: ~5 phút
Kịch bản 3: Hỏng Toàn Bộ Máy Chủ
- Cung cấp máy chủ mới với Docker + Docker Compose
- Clone repo và thiết lập
.envtừ secrets manager - Pull image:
docker compose pull - Khôi phục bản sao lưu PostgreSQL từ nơi lưu trữ ngoài site
- Khởi động tất cả service:
docker compose up -d - Kích hoạt lập chỉ mục lại Typesense:
pnpm run typesense:reindex - Xác minh tất cả endpoint health
RTO dự kiến: ~60 phút (phụ thuộc vào tốc độ truyền bản sao lưu)
Kịch bản 4: Hỏng Dữ Liệu (cấp độ ứng dụng)
- Xác định phạm vi: những bảng/bản ghi nào bị ảnh hưởng
- Nếu hạn chế: khôi phục các bảng cụ thể bằng
pg_restore --table=<name> - Nếu diện rộng: khôi phục toàn bộ từ bản sao lưu tốt cuối cùng được biết đến
- Xóa cache Redis:
docker exec goodgo-redis redis-cli -a "$REDIS_PASSWORD" FLUSHALL - Lập chỉ mục lại Typesense:
pnpm run typesense:reindex
Tổng Hợp Log
Log được tổng hợp qua Loki + Promtail và có thể xem trong Grafana:
- Grafana: http://localhost:3002 (dashboard: "GoodGo - Logs")
- Loki: http://localhost:3100
- Thời gian lưu log: 15 ngày (được cấu hình trong
monitoring/loki/loki-config.yml)