Tổng quan
High Availability (HA) và Disaster Recovery (DR) là hai trụ cột để đảm bảo hệ thống luôn hoạt động và có khả năng phục hồi khi xảy ra sự cố. Hai khái niệm này thường đi chung nhưng giải quyết vấn đề khác nhau:
| Khái niệm | Mục tiêu | Phạm vi |
|---|---|---|
| High Availability | Giảm thiểu downtime trong vận hành bình thường | Component-level, region-level |
| Disaster Recovery | Phục hồi sau sự cố nghiêm trọng (thiên tai, mất data center) | Region-level, global-level |
RTO và RPO
Recovery Time Objective (RTO) - thời gian tối đa chấp nhận được để khôi phục hệ thống sau sự cố.
Recovery Point Objective (RPO) - lượng dữ liệu tối đa chấp nhận mất (tính theo thời gian).
Cách tính RTO/RPO cho hệ thống thực tế
Ví dụ: E-commerce platform
- Doanh thu trung bình: 500 triệu VND/giờ
- Chi phí mỗi giờ downtime: ~500 triệu + uy tín thương hiệu
- Business yêu cầu: mất tối đa 1 giờ doanh thu
=> RTO = 1 giờ (phải restore trong 1 giờ)
=> RPO = 15 phút (chấp nhận mất data 15 phút gần nhất)
| Tier | RTO | RPO | Ví dụ | Chi phí tương đối |
|---|---|---|---|---|
| Tier 1 | < 1 phút | 0 | Payment gateway | $$$$$ |
| Tier 2 | < 15 phút | < 5 phút | Order management | $$$$ |
| Tier 3 | < 1 giờ | < 15 phút | Product catalog | $$$ |
| Tier 4 | < 4 giờ | < 1 giờ | Reporting, analytics | $$ |
HA Patterns
Active-Active
Cả hai (hoặc nhiều) instance đều xử lý traffic đồng thời. Data được replicate giữa các node.
Ưu điểm: Zero downtime failover, tận dụng tối đa resource, giảm latency theo geo.
Nhược điểm: Phức tạp trong data consistency, chi phí cao gấp đôi, conflict resolution khó.
Active-Passive
Chỉ primary instance xử lý traffic. Secondary instance ở trạng thái standby, chỉ nhận replicated data.
Ưu điểm: Đơn giản hơn, không có conflict, chi phí thấp hơn (secondary có thể dùng SKU nhỏ).
Nhược điểm: Failover mất thời gian (thường 2-10 phút), resource secondary bị lãng phí.
So sánh
| Tiêu chí | Active-Active | Active-Passive |
|---|---|---|
| Failover time | Gần như 0 | 2-10 phút |
| Chi phí | Cao (2x resource) | Thấp hơn (standby SKU nhỏ) |
| Data consistency | Eventual consistency | Strong consistency |
| Complexity | Cao | Trung bình |
| Phù hợp | Tier 1, mission-critical | Tier 2-3, cost-sensitive |
Azure DR Toolkit
Geo-Replication cho SQL Database
bash# Tạo secondary replica ở region khác
az sql db replica create \
--resource-group myRG \
--server primary-server \
--name myDB \
--partner-server secondary-server \
--partner-resource-group myRG-dr
# Failover manual khi cần
az sql failover-group set-primary \
--resource-group myRG \
--server secondary-server \
--name my-failover-group
Traffic Manager
bash# Tạo Traffic Manager profile với priority routing
az network traffic-manager profile create \
--resource-group myRG \
--name my-tm-profile \
--routing-method Priority \
--unique-dns-name myapp-tm \
--monitor-protocol HTTPS \
--monitor-path "/health" \
--monitor-port 443
# Thêm primary endpoint (priority 1)
az network traffic-manager endpoint create \
--resource-group myRG \
--profile-name my-tm-profile \
--name primary-endpoint \
--type azureEndpoints \
--target-resource-id /subscriptions/.../webapps/myapp-primary \
--priority 1
# Thêm secondary endpoint (priority 2)
az network traffic-manager endpoint create \
--resource-group myRG \
--profile-name my-tm-profile \
--name secondary-endpoint \
--type azureEndpoints \
--target-resource-id /subscriptions/.../webapps/myapp-secondary \
--priority 2
Azure Paired Regions
Azure paired regions đảm bảo ít nhất một region trong pair được ưu tiên recovery. Một số pair phổ biến:
| Primary | Secondary |
|---|---|
| East Asia (Hong Kong) | Southeast Asia (Singapore) |
| Japan East | Japan West |
| Australia East | Australia Southeast |
Health Checks và Circuit Breakers
Health Check trong ASP.NET Core
csharp// Program.cs
builder.Services.AddHealthChecks()
.AddSqlServer(
connectionString: builder.Configuration.GetConnectionString("DefaultConnection"),
name: "sql-server",
tags: new[] { "db", "critical" })
.AddRedis(
redisConnectionString: builder.Configuration["Redis:ConnectionString"],
name: "redis",
tags: new[] { "cache" })
.AddUrlGroup(
new Uri("https://external-api.com/health"),
name: "external-api",
tags: new[] { "external" });
app.MapHealthChecks("/health", new HealthCheckOptions
{
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
// Endpoint riêng cho liveness (dùng cho k8s hoặc Traffic Manager)
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
Predicate = _ => false // Chỉ check app có running không
});
// Endpoint cho readiness (check dependencies)
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("critical")
});
Circuit Breaker với Polly
csharp// Đăng ký HttpClient với Circuit Breaker
builder.Services.AddHttpClient("ExternalApi", client =>
{
client.BaseAddress = new Uri("https://external-api.com");
})
.AddTransientHttpErrorPolicy(policy =>
policy.CircuitBreakerAsync(
handledEventsAllowedBeforeBreaking: 3, // Mở circuit sau 3 lỗi liên tiếp
durationOfBreak: TimeSpan.FromSeconds(30), // Mở circuit 30 giây
onBreak: (outcome, timespan) =>
{
Log.Warning("Circuit opened for {Duration}s due to: {Error}",
timespan.TotalSeconds, outcome.Exception?.Message);
},
onReset: () => Log.Information("Circuit closed, resuming calls"),
onHalfOpen: () => Log.Information("Circuit half-open, testing...")
))
.AddTransientHttpErrorPolicy(policy =>
policy.WaitAndRetryAsync(new[]
{
TimeSpan.FromMilliseconds(200),
TimeSpan.FromMilliseconds(500),
TimeSpan.FromSeconds(1)
}));
Azure Site Recovery Playbook
Checklist triển khai DR
- Identify - Phân loại workload theo tier (RTO/RPO)
- Design - Chọn pattern (Active-Active / Active-Passive) phù hợp từng tier
- Implement - Setup replication, failover group, Traffic Manager
- Test - DR drill hàng quý, đo thực tế RTO/RPO
- Document - Runbook cho từng scenario, contact list, escalation path
- Automate - Infrastructure as Code cho cả primary và DR site
DR Drill Template
DR Drill Report - Q1 2026
──────────────────────────
Scenario: Primary region (East Asia) hoàn toàn unavailable
Target RTO: 15 phút | Actual RTO: 12 phút ✅
Target RPO: 5 phút | Actual RPO: 3 phút ✅
Steps Executed:
1. Detect failure via Azure Monitor alert - 2 phút
2. Confirm và initiate failover - 3 phút
3. SQL Failover Group auto-failover - 4 phút
4. Traffic Manager DNS propagation - 3 phút
5. Verify health checks pass on secondary - 2 phút
Issues Found:
- Redis cache cold start gây latency spike 5s đầu tiên
- 2 background jobs cần manual restart
Action Items:
- Implement Redis warm-up script cho DR site
- Automate background job failover
Trade-off Analysis
| Quyết định | Lựa chọn A | Lựa chọn B | Recommendation |
|---|---|---|---|
| Replication mode | Synchronous (RPO=0) | Asynchronous (RPO>0) | Async cho cross-region (sync quá chậm) |
| Failover trigger | Automatic | Manual | Auto cho Tier 1, Manual cho Tier 2+ (tránh false positive) |
| DR site size | Full capacity | Scaled down | Scaled down + auto-scale rules (tiết kiệm 40-60%) |
| Data strategy | Full replication | Selective replication | Selective - chỉ replicate critical data |