生产级数据库架构
应用层
应用实例(写)
应用实例(读)
报表服务
连接治理
RDS Proxy(写端点)
RDS Proxy(读端点)
连接池复用
数据库层
主实例 AZ-a
备实例 AZ-b(同步)
只读副本 AZ-c
跨区域副本
保护层
自动备份 35 天
手动快照
PITR 时间点恢复
跨账号备份复制
RDS Proxy 能把故障切换时的连接中断从 60-120 秒压缩到 20 秒以内,Serverless 与 Lambda 场景尤其明显。
高可用设计要点
- 写请求走主实例,读请求走只读副本,应用层显式区分读写数据源
- RDS Proxy 承接连接管理,避免 Lambda 高并发打爆数据库连接数
- 参数组与主实例保持一致,避免切换后行为不一致
- 维护窗口设在业务低谷,小版本升级走蓝绿部署
- 监控 ReplicaLag,超过 5 秒告警,避免读到过期数据
- 每季度手动触发一次故障切换演练,记录实际切换时间与应用侧表现
多可用区 + 只读副本 + Proxy(Terraform)
resource "aws_db_instance" "primary" {
identifier = "mushan-prod-mysql"
engine = "mysql"
engine_version = "8.0"
instance_class = "db.r7g.xlarge" # Graviton,同性能便宜约 20%
allocated_storage = 200
max_allocated_storage = 2000 # 存储自动扩容上限
storage_type = "gp3"
storage_encrypted = true
kms_key_id = aws_kms_key.rds.arn
multi_az = true # 同步备实例,自动故障切换
db_subnet_group_name = aws_db_subnet_group.private.name
vpc_security_group_ids = [aws_security_group.rds.id]
backup_retention_period = 35
backup_window = "17:00-18:00" # UTC,对应北京时间凌晨
maintenance_window = "sun:18:00-sun:19:00"
copy_tags_to_snapshot = true
auto_minor_version_upgrade = false # 手动控制升级窗口
performance_insights_enabled = true
performance_insights_retention_period = 465
enabled_cloudwatch_logs_exports = ["error", "slowquery", "audit"]
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "mushan-prod-mysql-final"
tags = {
CostCenter = "core-db"
Tier = "critical"
}
}
resource "aws_db_instance" "replica" {
count = 2
identifier = "mushan-prod-mysql-ro-${count.index + 1}"
replicate_source_db = aws_db_instance.primary.identifier
instance_class = "db.r7g.large"
availability_zone = element(var.azs, count.index)
performance_insights_enabled = true
skip_final_snapshot = true
tags = { Role = "read-replica" }
}
resource "aws_db_proxy" "main" {
name = "mushan-prod-proxy"
engine_family = "MYSQL"
role_arn = aws_iam_role.proxy.arn
vpc_subnet_ids = var.private_subnet_ids
vpc_security_group_ids = [aws_security_group.proxy.id]
require_tls = true
idle_client_timeout = 1800
max_connections_percent = 90
auth {
auth_scheme = "SECRETS"
iam_auth = "DISABLED"
secret_arn = aws_secretsmanager_secret.db_credentials.arn
}
}