QuestDB Business Continuity
QuestDB Time Series Business Continuity BCP RPO RTO Backup Replication Disaster Recovery WAL Snapshot Failover Monitoring
| Component | RPO | RTO | Method | Cost |
|---|---|---|---|---|
| WAL + Snapshot | ~1 นาที | 15-30 นาที | Local Backup | ต่ำ |
| Incremental Backup | 15 นาที | 30 นาที | rsync + S3 | ต่ำ-ปานกลาง |
| Replication (Enterprise) | ~0 วินาที | 1-5 นาที | Built-in Replication | สูง (License) |
| Cross-region DR | 15-60 นาที | 30-60 นาที | S3 Cross-region + Restore | ปานกลาง |
| Multi-site Active | ~0 วินาที | ~0 วินาที | App-level Dual Write | สูง (2x Resource) |
Backup Configuration
# === QuestDB Backup Strategy ===
# #!/bin/bash
# # questdb_backup.sh - Run via cron
# # */15 * * * * /opt/scripts/questdb_backup.sh incremental
# # 0 2 * * * /opt/scripts/questdb_backup.sh full
#
# BACKUP_TYPE=$1
# QUESTDB_DATA="/var/lib/questdb/db"
# BACKUP_DIR="/backup/questdb"
# S3_BUCKET="s3://company-backups/questdb"
# DATE=$(date +%Y%m%d_%H%M%S)
#
# if [ "$BACKUP_TYPE" = "full" ]; then
# # Full backup with snapshot
# curl -G http://localhost:9000/exec --data-urlencode "query=SNAPSHOT PREPARE"
# tar -czf "$BACKUP_DIR/full_$DATE.tar.gz" "$QUESTDB_DATA"
# curl -G http://localhost:9000/exec --data-urlencode "query=SNAPSHOT COMPLETE"
# aws s3 cp "$BACKUP_DIR/full_$DATE.tar.gz" "$S3_BUCKET/full/"
# else
# # Incremental backup (WAL + recent changes)
# rsync -av --delete "$QUESTDB_DATA/wal/" "$BACKUP_DIR/incremental/wal/"
# tar -czf "$BACKUP_DIR/incr_$DATE.tar.gz" "$BACKUP_DIR/incremental/"
# aws s3 cp "$BACKUP_DIR/incr_$DATE.tar.gz" "$S3_BUCKET/incremental/"
# fi
#
# # Cleanup old backups
# find "$BACKUP_DIR" -name "full_*.tar.gz" -mtime +30 -delete
# find "$BACKUP_DIR" -name "incr_*.tar.gz" -mtime +7 -delete
#
# echo "[$BACKUP_TYPE] Backup completed: $DATE"
from dataclasses import dataclass
@dataclass
class BackupSchedule:
backup_type: str
frequency: str
retention: str
rpo: str
storage: str
schedules = [
BackupSchedule("Full Snapshot",
"ทุกวัน 02:00",
"30 วัน",
"24 ชั่วโมง",
"S3 Standard ~$0.023/GB/month"),
BackupSchedule("Incremental (WAL)",
"ทุก 15 นาที",
"7 วัน",
"15 นาที",
"S3 Standard ~$0.023/GB/month"),
BackupSchedule("WAL Continuous",
"Real-time (Streaming)",
"3 วัน",
"~1 นาที",
"S3 + Transfer Cost"),
BackupSchedule("Weekly Archive",
"ทุกสัปดาห์",
"12 สัปดาห์",
"1 สัปดาห์",
"S3 Glacier ~$0.004/GB/month"),
BackupSchedule("Monthly Archive",
"ทุกเดือน",
"12 เดือน",
"1 เดือน",
"S3 Glacier Deep ~$0.00099/GB/month"),
]
print("=== Backup Schedule ===")
for b in schedules:
print(f" [{b.backup_type}] Frequency: {b.frequency}")
print(f" Retention: {b.retention} | RPO: {b.rpo}")
print(f" Storage: {b.storage}")
Replication Setup
# === QuestDB Replication (Open Source) ===
# Option 1: rsync-based Replication
# #!/bin/bash
# # replicate.sh - Run every 5 minutes
# QUESTDB_DATA="/var/lib/questdb/db"
# REPLICA_HOST="replica.internal"
# REPLICA_PATH="/var/lib/questdb/db"
#
# # Sync data to replica (WAL-safe approach)
# rsync -avz --delete \
# -e "ssh -p 22" \
# "$QUESTDB_DATA/" \
# "$REPLICA_HOST:$REPLICA_PATH/"
#
# # Restart replica QuestDB to pick up changes
# ssh $REPLICA_HOST "systemctl restart questdb"
# Option 2: Application-level Dual Write
# import questdb.ingress as qi
#
# primary = qi.Sender("primary.internal", 9009)
# replica = qi.Sender("replica.internal", 9009)
#
# def write_metric(table, columns, timestamp):
# for sender in [primary, replica]:
# try:
# sender.row(table, columns=columns, at=timestamp)
# except Exception as e:
# log.error(f"Write failed: {sender.host}: {e}")
@dataclass
class ReplicationOption:
method: str
rpo: str
rto: str
complexity: str
limitation: str
options = [
ReplicationOption("QuestDB Enterprise Replication",
"~0 วินาที (Streaming)",
"1-5 นาที (Auto-failover)",
"ต่ำ (Built-in)",
"ต้อง Enterprise License"),
ReplicationOption("rsync Periodic Sync",
"5-15 นาที",
"10-30 นาที (Manual)",
"ต่ำ",
"ต้อง Restart Replica อาจสูญข้อมูลระหว่าง Sync"),
ReplicationOption("Application Dual Write",
"~0 วินาที",
"~0 วินาที (Active-Active)",
"ปานกลาง",
"Application ต้อง Handle Failure ข้อมูลอาจไม่ตรงกัน"),
ReplicationOption("Storage Replication (EBS/ZFS)",
"ขึ้นกับ Sync Interval",
"15-30 นาที",
"ปานกลาง",
"ขึ้นกับ Cloud Provider Storage Layer"),
ReplicationOption("Kafka + Dual Consumer",
"~0 วินาที",
"1-5 นาที",
"สูง",
"ต้องมี Kafka Infrastructure เพิ่ม Complexity"),
]
print("=== Replication Options ===")
for o in options:
print(f" [{o.method}]")
print(f" RPO: {o.rpo} | RTO: {o.rto}")
print(f" Complexity: {o.complexity}")
print(f" Limitation: {o.limitation}")
DR Testing
# === Disaster Recovery Testing ===
@dataclass
class DRTest:
test: str
scenario: str
frequency: str
success_criteria: str
runbook_step: str
dr_tests = [
DRTest("Full Restore Test",
"Restore QuestDB จาก Full Backup ล่าสุด",
"ทุกเดือน",
"Restore ภายใน 30 นาที Query ทำงานปกติ Data ครบ",
"1.Stop QuestDB 2.Restore 3.Start 4.Verify"),
DRTest("Incremental Restore",
"Restore Full + Apply Incremental Backups",
"ทุก 2 สัปดาห์",
"Data ครบถึง 15 นาทีก่อน Failure",
"1.Restore Full 2.Apply WAL 3.Verify Timeline"),
DRTest("Failover to Replica",
"จำลอง Primary ล่ม Failover ไป Replica",
"ทุกไตรมาส",
"Failover ภายใน 5 นาที Application เชื่อมต่อ Replica",
"1.Stop Primary 2.Promote Replica 3.Update DNS"),
DRTest("Cross-region DR",
"จำลอง Region ล่มทั้ง Region",
"ทุก 6 เดือน",
"DR Site ทำงานภายใน 60 นาที",
"1.Detect 2.DNS Failover 3.Restore DR 4.Verify"),
DRTest("Data Integrity Check",
"ตรวจสอบข้อมูล Backup ถูกต้องครบถ้วน",
"ทุกสัปดาห์ (Automated)",
"Row Count ตรง Checksum ตรง No Corruption",
"1.Restore to Test 2.Count Rows 3.Compare Checksums"),
]
print("=== DR Tests ===")
for d in dr_tests:
print(f"\n [{d.test}] Frequency: {d.frequency}")
print(f" Scenario: {d.scenario}")
print(f" Success: {d.success_criteria}")
print(f" Steps: {d.runbook_step}")
เคล็ดลับ
- SNAPSHOT: ใช้ SNAPSHOT PREPARE/COMPLETE สำหรับ Consistent Backup
- S3: Upload Backup ไป S3 ป้องกัน Disk Failure
- Test: ทดสอบ Restore ทุกเดือน ไม่ใช่แค่ Backup
- Monitor: ตั้ง Alert เมื่อ Backup Fail Replica Lag สูง
- Runbook: เขียน Runbook ชัดเจน วัด RTO จริงเทียบ Target
Business Continuity คืออะไร
BCP แผนรองรับระบบล่ม RPO สูญข้อมูลกี่นาที RTO กลับมากี่นาที WAL Snapshot Replication Failover DR Site Drill Runbook
Backup Strategy ทำอย่างไร
SNAPSHOT PREPARE COMPLETE rsync S3 Full ทุกวัน Incremental 15 นาที Retention 30 วัน Glacier Archive Cron Job Verify Restore
Replication ทำอย่างไร
Enterprise Built-in rsync Sync Dual Write Application Kafka Storage EBS ZFS Primary Replica Failover Promote DNS Active-Active
Disaster Recovery ทำอย่างไร
DR Plan RPO 15 นาที RTO 30 นาที DR Site Cross-region Restore Verify DNS Failover DR Drill ทุกไตรมาส Runbook Integrity Check
สรุป
QuestDB Time Series Business Continuity BCP RPO RTO Backup Snapshot WAL Replication Failover DR Site Monitoring Production
