RDS / ElastiCache / DynamoDB:你的資料該託管還是自管?
你有一個 PostgreSQL 跑在 EC2 上,半夜三點 disk full 你被叫起來修。或者你的 Redis 掛了整個 App 跟著掛。託管資料庫能救你的睡眠,但要先搞懂差異和成本。
先講結論
RDS 是託管的關聯式資料庫,支援 PostgreSQL、MySQL、MariaDB、Oracle、SQL Server。它幫你處理 patch、備份、failover,讓你專心寫 SQL。ElastiCache 是託管的 Redis/Memcached,適合 session、cache、排行榜。DynamoDB 是 NoSQL(Key-Value),毫秒級延遲、自動擴展,適合高流量但查詢模式固定的場景。大多數 App 的最佳起點是 RDS PostgreSQL + ElastiCache Redis。
RDS:託管的關聯式資料庫
為什麼不自己裝 PostgreSQL?
| 你自己管 | RDS 幫你管 |
|---|---|
| OS patch | 自動 |
| 備份 | 自動每日 snapshot、最多 35 天保留 |
| Failover | Multi-AZ 自動切換 |
| Read Replica | 一鍵建立 |
| 監控 | Performance Insights 內建 |
| 版本升級 | 排程自動升級 |
你省下來的時間,拿去優化 SQL query 更有價值。
建立 RDS PostgreSQL
# 建立 Subnet Group(RDS 需要至少兩個 AZ 的 subnet)
aws rds create-db-subnet-group --db-subnet-group-name prod-db-subnet \
--db-subnet-group-description "Production DB subnets" \
--subnet-ids subnet-private-1a subnet-private-1c
# 建立 RDS Instance
aws rds create-db-instance \
--db-instance-identifier prod-postgres \
--db-instance-class db.t3.medium \
--engine postgres \
--engine-version 16.4 \
--master-username dbadmin \
--master-user-password 'YourSecurePassword!' \
--allocated-storage 100 \
--storage-type gp3 \
--vpc-security-group-ids sg-db \
--db-subnet-group-name prod-db-subnet \
--multi-az \
--backup-retention-period 14 \
--storage-encrypted \
--performance-insights-enabled \
--monitoring-interval 60 \
--monitoring-role-arn arn:aws:iam::123456789012:role/rds-monitoring-roleMulti-AZ:高可用的關鍵
Multi-AZ 會在另一個 AZ 建立一個 Standby replica。主庫掛了,AWS 自動在 60-120 秒內切換到 Standby。你的 App 不用改 connection string——DNS 會自動指向新的主庫。
# 確認 Multi-AZ 狀態
aws rds describe-db-instances --db-instance-identifier prod-postgres \
--query "DBInstances[0].MultiAZ"踩坑:Multi-AZ failover 的時候,你的 App 會看到約 60 秒的 connection error。所以 App 的 DB driver 一定要設好 retry 和 connection pool 的重連機制。
Read Replica
讀多寫少的場景(報表、搜尋),把讀流量分到 Read Replica:
# 建立 Read Replica
aws rds create-db-instance-read-replica \
--db-instance-identifier prod-postgres-read \
--source-db-instance-identifier prod-postgres \
--db-instance-class db.t3.medium
# App 端設定(以 Node.js pg 為例)
# 寫入用主庫 endpoint,讀取用 Read Replica endpointAurora:RDS 的進化版
Aurora 是 AWS 自研的 DB engine,相容 PostgreSQL/MySQL,但底層儲存架構完全不同:
- 效能比標準 RDS PostgreSQL 快 3 倍(官方說法,實測約 1.5-2 倍)
- 儲存自動擴展到 128 TB
- 6 份 replica 跨 3 個 AZ
- 更貴(約比 RDS 貴 20-30%)
什麼時候選 Aurora? 當你的 DB 超過 1 TB、或需要超過 5 個 Read Replica 的時候。
ElastiCache:託管的 Redis
自架 Redis vs ElastiCache
| 面向 | 自架 Redis | ElastiCache Redis |
|---|---|---|
| 安裝 | 自己裝 | 一鍵 |
| Cluster Mode | 自己設 | 內建 |
| Failover | Sentinel 自己設 | 自動 |
| 備份 | 自己 RDB/AOF | 自動 snapshot |
| 監控 | 自己接 Prometheus | CloudWatch 內建 |
| 版本升級 | 自己來 | 排程升級 |
# 建立 ElastiCache Subnet Group
aws elasticache create-cache-subnet-group \
--cache-subnet-group-name prod-redis-subnet \
--cache-subnet-group-description "Production Redis subnets" \
--subnet-ids subnet-private-1a subnet-private-1c
# 建立 Redis Cluster(Cluster Mode Disabled,適合大多數場景)
aws elasticache create-replication-group \
--replication-group-id prod-redis \
--replication-group-description "Production Redis" \
--engine redis \
--engine-version 7.1 \
--cache-node-type cache.t3.medium \
--num-cache-clusters 2 \
--automatic-failover-enabled \
--cache-subnet-group-name prod-redis-subnet \
--security-group-ids sg-redis \
--at-rest-encryption-enabled \
--transit-encryption-enabled常見用途
- Session Store:使用者登入 session 放 Redis,多台 App Server 共享
- Cache:DB query 結果快取,TTL 設 5 分鐘
- Rate Limiting:用 INCR + EXPIRE 做 API 限流
- 排行榜:Sorted Set 天生適合
DynamoDB:高流量的 NoSQL 選擇
DynamoDB 適合:查詢模式固定、流量高、需要自動擴展。不適合:需要複雜 JOIN、查詢模式不確定、需要事後 ad-hoc 分析。
# 建立 DynamoDB Table
aws dynamodb create-table \
--table-name UserSessions \
--attribute-definitions \
AttributeName=userId,AttributeType=S \
AttributeName=sessionId,AttributeType=S \
--key-schema \
AttributeName=userId,KeyType=HASH \
AttributeName=sessionId,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST \
--tags Key=Environment,Value=production
# 寫入
aws dynamodb put-item --table-name UserSessions \
--item '{"userId": {"S": "user-123"}, "sessionId": {"S": "sess-abc"}, "ttl": {"N": "1700000000"}}'
# 查詢
aws dynamodb query --table-name UserSessions \
--key-condition-expression "userId = :uid" \
--expression-attribute-values '{":uid": {"S": "user-123"}}'DynamoDB 計費模式
| 模式 | 適合 | 費用 |
|---|---|---|
| On-Demand | 流量不穩定 | 按讀寫次數計費 |
| Provisioned | 流量穩定 | 預設 RCU/WCU + Auto Scaling |
大多數新專案選 On-Demand,等流量穩定後再切 Provisioned 省錢。
選型決策框架
你的資料需要 JOIN / 複雜查詢嗎?
├─ 是 → RDS(PostgreSQL 或 MySQL)
│ └─ 超過 1TB / 需要多 Read Replica? → Aurora
├─ 否 → 查詢模式固定嗎?
│ ├─ 是 → DynamoDB
│ └─ 否 → 還是 RDS(彈性最大)
│
另外,你需要 Cache 嗎?
├─ Session / 快取 / 限流 → ElastiCache Redis
└─ 全文搜尋 → OpenSearch Service
自架 vs AWS
| 面向 | 自架 | AWS 託管 |
|---|---|---|
| PostgreSQL | 自己裝 + pgbouncer + barman | RDS + 內建連線池 + 自動備份 |
| Redis | 自己裝 + Sentinel | ElastiCache + 自動 failover |
| 備份 | cron + pg_dump + S3 | 自動每日 snapshot |
| 升版 | 自己停機升級 | 排程、零停機(Read Replica 先升) |
| 費用 | EC2 費用 | RDS 溢價 20-40% |
| DBA 時間 | 多 | 少很多 |
如果你讀過 Infra 系列的 PostgreSQL 和 PostgreSQL Advanced,RDS 就是幫你把那些 WAL 歸檔、replication、vacuum 的事都自動化了。Database Landscape 裡的選型框架在這裡依然適用。
K8s 映射
| AWS DB | K8s 對應 |
|---|---|
| RDS | StatefulSet + PVC(但不推薦,用託管 DB 吧) |
| ElastiCache | Redis Helm Chart / Redis Operator |
| DynamoDB | 沒有直接對應(K8s 上用 CockroachDB/TiDB) |
| Multi-AZ failover | Pod anti-affinity + PDB |
| Read Replica | 應用層讀寫分離 |
認真建議:在 K8s 上跑 StatefulSet PostgreSQL 可以,但你得自己處理備份、failover、升版。如果你在 AWS 上,用 RDS 然後讓 K8s Pod 連 RDS endpoint 是最省心的做法。
系列導覽
| 上一篇 | 下一篇 |
|---|---|
| S3 | Container Insights |
資料庫是你的 App 最值錢的部分——省什麼都不要省 DB 的穩定性。