1. Important Points#
DynamoDB 是 serverless NoSQL database,适合 key-value / document OLTP workload。它的核心不是“建表后随便查”,而是先确定 access pattern,再设计 partition key、sort key 和 secondary index。
good fit:
predictable access pattern
high traffic OLTP
low latency read/write
event / session / cart / order state / metadata
not good fit:
ad-hoc query
complex join
heavy analytical query
frequently changing query dimensions
large cross-item relational transaction
core principles:
先设计 access pattern,再设计 table / key / index
Query 优先,Scan 尽量避免
partition key 要高基数并且流量均匀
GSI 是额外写入成本和额外容量面,不是免费的 query helper
hot key / hot partition 是 DynamoDB 最常见生产问题
PITR / deletion protection / least privilege 应该默认打开2. Service Configuration#
table#
| Item | Recommendation |
|---|---|
| Table name | <env>-<service>-<entity>,例如 prod-order-orders |
| Primary key | 优先 composite key: pk + sk |
| Billing mode | 流量不可预测用 PAY_PER_REQUEST;稳定大流量用 provisioned + auto scaling |
| Deletion protection | production table 默认打开 |
| PITR | production table 默认打开,恢复窗口 1-35 days |
| TTL | 临时数据 / session / cache / event retention 可以打开 |
| SSE | 默认全量加密;敏感数据用 customer managed KMS key |
| Tags | env, service, owner, cost-center, data-classification |
capacity mode#
| Mode | When To Use | 注意项 |
|---|---|---|
| On-demand | 新业务、流量不可预测、低运维成本优先 | 单表默认 quota 仍然存在;突发上量前要确认 Service Quotas |
| Provisioned | 流量稳定、成本敏感、可预测峰值 | 需要 auto scaling / reserved capacity / 告警 |
on-demand:
优点:
不需要提前估算 RCU / WCU
适合 spike / early stage workload
注意:
不是无限吞吐
hot partition 仍然会 throttle
大促 / migration 前要提前压测和检查 quota
provisioned:
优点:
成本更可控
稳定大流量可以更便宜
注意:
auto scaling 有 CloudWatch 评估和 UpdateTable 延迟
sudden spike 可能先 throttle 再扩容
GSI 也要单独配置容量和 auto scalingOn-demand table 可以设置 Maximum read request units / Maximum write request units,这是 table 每秒吞吐上限,用来控制成本和防止异常流量打爆使用量。它不是 provisioned capacity,也不是预留容量,而是 cap / throttle limit。
Maximum read request units: 这张 on-demand table 每秒最多允许消耗多少 read request units
Maximum write request units: 这张 on-demand table 每秒最多允许消耗多少 write request units
example:
Maximum read request units = 1000
strong read 4 KB item: max about 1000 reads/s
strong read 8 KB item: max about 500 reads/s
eventual read 8 KB item: max about 1000 reads/s
Maximum write request units = 1000
write 900 B item: max about 1000 writes/s
write 1.2 KB item: max about 500 writes/s
exceed limit:
read exceeds maximum read request units: read requests are throttled
write exceeds maximum write request units: write requests are throttled
注意:
AWS SDK may retry throttled requests
sustained throttling still increases latency or causes failures
hot partition can throttle even when table total throughput is below this limitWarm throughput 不是 enable / disable 开关,也不是 on-demand maximum throughput。它表示 table / secondary index 当前已经 warm 好、可以马上承接的 read/write 吞吐能力;如果预计大促、迁移、批量导入等峰值流量,可以提前调高 warm throughput。
Maximum read/write request units: on-demand table 的最高上限,超过会 throttle
Warm throughput: 当前可立即支撑的吞吐能力 / 可预热目标,不是 capcapacity units#
| Term | Meaning | How To Read |
|---|---|---|
| RCU | Read Capacity Unit,读容量单位 | 1 秒内读取最多 4 KB item 的能力 |
| WCU | Write Capacity Unit,写容量单位 | 1 秒内写入最多 1 KB item 的能力 |
| read request unit | On-demand 读请求计费单位 | 计算方式和 RCU 类似,但不需要提前 provision |
| write request unit | On-demand 写请求计费单位 | 计算方式和 WCU 类似,但不需要提前 provision |
| consumed capacity | 实际消耗的容量 | CloudWatch 里看 ConsumedReadCapacityUnits / ConsumedWriteCapacityUnits |
| provisioned capacity | 配置的容量上限 | CloudWatch 里看 ProvisionedReadCapacityUnits / ProvisionedWriteCapacityUnits |
RCU 计算:
eventually consistent read: 0.5 RCU per 4 KB
strongly consistent read: 1 RCU per 4 KB
transactional read: 2 RCU per 4 KB
rounding: item size 按 4 KB 向上取整
examples:
read 3 KB item, eventual consistency: 0.5 RCU
read 8 KB item, eventual consistency: 1 RCU
read 8 KB item, strong consistency: 2 RCU
read 64 KB item, eventual consistency: 8 RCU
read 64 KB item, strong consistency: 16 RCUWCU 计算:
standard write: 1 WCU per 1 KB
transactional write: 2 WCU per 1 KB
rounding: item size 按 1 KB 向上取整
examples:
write 900 B item: 1 WCU
write 1.2 KB item: 2 WCU
transactional write 1.2 KB item: 4 WCUGSI / LSI 影响:
GSI:
table write 会同时写入匹配的 GSI
GSI projected attributes 越大,写入 GSI 的 WCU 越高
读 GSI 消耗 GSI 自己的 read capacity
provisioned mode 下,GSI 要单独配置 capacity / auto scaling
LSI:
和 base table 共用 capacity
只支持 strong / eventual read,不支持跨 partition queryquotas#
常见 quota:
item max size: 400 KB
LSI per table: 5
GSI per table: default 20
projected attributes across secondary indexes: 100
tables per account per region: default 2500
default table-level throughput quota:
on-demand: 40000 read request units / 40000 write request units
provisioned: 40000 RCU / 40000 WCU
default account-level provisioned quota: 80000 RCU / 80000 WCU per region
hot partition limit:
one partition max:
3000 RCU / second
1000 WCU / second
注意:
quota 是 per region
default quota 不是架构上限,可以申请提高
hot partition 不能只靠提高 table quota 解决3. Data Modeling Best Practices#
DynamoDB Primary Key
DynamoDB 的 primary key 决定两件事:
1. item 的唯一性
2. 最基础的查询方式
Primary key 有两种形式:
simple primary key:
只设置 partition key
partition key 一个字段决定唯一性
composite primary key:
同时设置 partition key + sort key
partition key + sort key 两个字段一起决定唯一性Partition key
partition key 是 DynamoDB 用来决定 item 属于哪个分区 / 分组的 key。
可以简单理解为:
partition key 决定大分组
例子:
pk = USER#u1
含义:
这个 item 属于 USER#u1 这个用户分组Sort key
sort key 只在 composite primary key 里存在。
可以简单理解为:
sort key 决定这个分组里的具体 item
sort key 也支持排序 / 范围查询
例子:
pk = USER#u1
sk = ORDER#o1001
含义:
USER#u1 这个用户分组下的一条订单唯一性规则
simple primary key:
pk 必须唯一
example:
pk = USER#u1
表里不能同时有两条:
pk = USER#u1
pk = USER#u1
composite primary key:
pk + sk 组合必须唯一
example:
pk = USER#u1, sk = ORDER#o1001
表里可以有:
pk = USER#u1, sk = PROFILE
pk = USER#u1, sk = ORDER#o1001
pk = USER#u1, sk = ORDER#o1002
但不能重复:
pk = USER#u1, sk = ORDER#o1001
pk = USER#u1, sk = ORDER#o1001一句话总结
只设置 partition key:
simple primary key
一个字段决定唯一性
同时设置 partition key + sort key:
composite primary key
两个字段组合决定唯一性
partition key:
决定大分组
sort key:
决定分组里的具体 item
支持排序 / 范围查询4. Query / Write Best Practices#
Query vs Scan#
Query:
必须指定 partition key
可以用 sort key condition
适合在线请求
Scan:
会读很多 item
filter expression 是读完后过滤,不会减少读取容量
只适合 backfill / admin job / small table
production rule:
API request path 不要做 full table scan
如果必须 scan:
limit page size
use pagination
run in background
rate limit
monitor consumed capacity and throttleread consistency#
Read consistency 不是 table 创建时固定的配置,而是每次读请求选择。GetItem / Query / Scan 可以通过 ConsistentRead=true 请求 strong consistency;不设置时默认 eventual consistency。GSI 只支持 eventual consistency。
DynamoDB 是分布式存储。为了高可用、低延迟和扩展性,数据会放在多个副本 / 节点上。写入成功表示 DynamoDB 已经接受并持久化这次写入,但不同副本看到最新值可能有短暂的传播窗口。
eventual consistency:
允许读请求命中一个短暂落后的副本
优点是成本低、延迟低、吞吐 / 可用性更好
缺点是刚写完立刻读,可能短暂看到旧值
strong consistency:
读路径要保证返回最新成功写入后的值
优点是 read-after-write 更可靠
缺点是成本更高、限制更多,比如 GSI 不支持 strong readeventually consistent read:
default
cost = 0.5 RCU per 4 KB
suitable for most read path
strongly consistent read:
cost = 1 RCU per 4 KB
only table / LSI support
GSI / streams do not support strong consistency
transactional read:
cost = 2 RCU per 4 KB
only use when real transaction semantics are needed
decision:
default use eventual consistency
read-after-write correctness required: use strong consistency on table / LSI
reading from GSI: design for eventual consistency
multi-item atomic correctness required: use transaction
DynamoDB replica example:
initial value: PRODUCT#p1 stock = 10
B writes stock = 9
write success means DynamoDB has durably accepted the write, not that every read replica must already show it
replica state may briefly be:
replica-1: stock = 9
replica-2: stock = 9
replica-3: stock = 10
eventual read:
A may read replica-3 and briefly see stock = 10
this does not mean B's write failed
it means eventual read can read a briefly stale replica
strong read:
A reads base table with ConsistentRead=true
DynamoDB must return stock = 9 after B's write succeeds
transactional read:
A reads multiple items such as PRODUCT#p1 and ORDER#o1001 in one transaction
DynamoDB returns a transactionally consistent snapshot instead of a mixed viewwrite#
Write 没有像 read 那样的 eventual / strong consistency 开关,也不提供用户可配置的 write consistency level。DynamoDB 返回写入成功,就表示服务端已经按自己的复制和持久化协议接受这次写入;standard / transactional write 讲的是写入范围和原子性,不是几个副本确认才算成功。
standard write:
PutItem / UpdateItem / DeleteItem 写单个 item
适合普通单 item 写入
conditional write:
单个 item 写入,但带条件,防止并发错误
example: stock > 0 才能扣库存
transactional write:
多个 item 一起写
example: 扣库存 + 创建订单 + 写 payment record
任意一步失败,整体失败
related eventual paths:
GSI index read 是 eventual consistency
Global Tables 跨 Region 复制是 eventual consistencywrite capacity:
1 WCU = one write per second for item up to 1 KB
item size is rounded up
each GSI projection adds write cost
best practices:
use UpdateExpression instead of rewriting large item
keep item small
avoid frequently changing huge attributes
do not store large blob in DynamoDB; store in S3 and keep pointer
use ReturnConsumedCapacity during test to estimate costconditional write#
use condition expression for correctness:
create only if not exists
update only if version matched
decrement stock only if quantity > 0
avoid lost updateaws dynamodb update-item \
--table-name prod-order-orders \
--key '{"pk":{"S":"ORDER#1001"},"sk":{"S":"META"}}' \
--update-expression "SET #status = :paid, version = version + :one" \
--condition-expression "version = :expected AND #status = :pending" \
--expression-attribute-names '{"#status":"status"}' \
--expression-attribute-values '{
":paid":{"S":"PAID"},
":pending":{"S":"PENDING"},
":expected":{"N":"1"},
":one":{"N":"1"}
}' \
--return-values ALL_NEWretries#
client should retry:
ProvisionedThroughputExceededException
ThrottlingException
InternalServerError
ServiceUnavailable
TransactionConflictException
retry policy:
exponential backoff
jitter
max attempts
idempotency token for write path
do not retry blindly:
ConditionalCheckFailedException
ValidationException
AccessDeniedException5. Index Best Practices#
GSI vs LSI#
GSI = Global Secondary Index,LSI = Local Secondary Index。GSI / LSI 是创建 index 时选择的类型,不是 DynamoDB 根据 key 是否相同自动分类。GSI 可以使用和 table partition key 一样的 attribute,例如 table 是 pk = user_id, sk = created_at,GSI 可以是 GSI partition key = user_id, GSI sort key = status;这看起来像 LSI,但 GSI 不能完全替代 LSI。
| 对比 | LSI | GSI |
|---|---|---|
| Partition key | 必须和 table partition key 相同 | 可以相同,也可以不同 |
| Sort key | 必须不同 | 可选,可不同 |
| 创建时间 | 只能建表时创建,之后不能加 | 可以建表后新增 / 删除 |
| 一致性读取 | 支持 strongly consistent read | 只支持 eventually consistent read |
| 容量 | 使用 table 的读写容量 | 有自己的容量,On-demand 下也独立计费 / 消耗 |
| 数据同步 | 和 base table 更紧密 | 异步复制到 GSI |
| 大小限制 | 同一个 partition key 下 item collection 有 10GB 限制 | 没有这个 LSI item collection 限制 |
LSI 有价值的场景:
同一个 table partition key
只是换一个 sort key 排序 / 范围查询
需要 strongly consistent read
建表时就确定索引
GSI 更适合:
后续可以新增索引
换不同 partition key 查询
不需要强一致读
更灵活地扩展查询模式
简单判断:
同一个 pk + 需要强一致读 + 建表时就确定索引 -> LSI
其他大多数情况 -> GSIGSI#
GSI 用于新的 access pattern:
base table key 无法支持时才加
GSI key 也必须防 hot partition
GSI read is eventually consistent
GSI 有自己的 throttling / capacity / metrics
projection:
KEYS_ONLY:
cheapest
only need keys
INCLUDE:
selected attributes
good default for query result list
ALL:
convenient but expensive
write amplification and storage cost high
注意:
base table write 会同步写 GSI
GSI backfill 可能消耗大量写容量
GSI throttle can throttle base table writeLSI#
LSI:
must be created with table
same partition key as base table
different sort key
supports strong consistent read
max 5 per table
practical rule:
不确定就不要先加 LSI
后续可变 access pattern 通常用 GSIsparse index#
sparse index:
only items with GSI key attributes appear in index
useful for status / workflow / pending items
example:
unpaid orders only have:
gsi2pk = TENANT#<tenant_id>#STATUS#UNPAID
gsi2sk = CREATED#<created_at>#ORDER#<order_id>
paid orders remove gsi2pk / gsi2sk6. Security Best Practices#
IAM#
principle:
use IAM role, not long-term access key
least privilege
separate read role / write role / migration role / admin role
allow table ARN and index ARN explicitly
avoid dynamodb:* in application role{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAppReadWriteOrders",
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Query",
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem"
],
"Resource": [
"arn:aws:dynamodb:ap-east-1:123456789012:table/prod-order-orders",
"arn:aws:dynamodb:ap-east-1:123456789012:table/prod-order-orders/index/*"
]
}
]
}resource-based policy#
use cases:
cross-account access
restrict source VPC endpoint
central data account
注意:
explicit deny 优先级最高
policy size has limit
cross-account 要同时检查 principal policy and resource policy{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAccessUnlessFromVpce",
"Effect": "Deny",
"Principal": "*",
"Action": "dynamodb:*",
"Resource": [
"arn:aws:dynamodb:ap-east-1:123456789012:table/prod-order-orders",
"arn:aws:dynamodb:ap-east-1:123456789012:table/prod-order-orders/index/*"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpce": "vpce-0123456789abcdef0"
}
}
}
]
}VPC endpoint#
recommendation:
EC2 / ECS / Lambda in VPC -> use DynamoDB VPC endpoint
add endpoint policy
add IAM/resource policy condition with aws:SourceVpce when appropriate
gateway endpoint:
common for DynamoDB access from VPC
no NAT gateway needed for DynamoDB traffic
interface endpoint / PrivateLink:
use when architecture requires interface endpoint behavior
client may need endpoint URL configurationencryption#
at rest:
DynamoDB encrypts all data at rest
default uses AWS owned key
sensitive / compliance workload use customer managed KMS key
in transit: use HTTPS/TLS
application side:
对特别敏感字段可以 client-side encryption
但加密字段通常不能直接作为 query keydata protection#
production defaults:
PITR enabled
deletion protection enabled
CloudTrail enabled
AWS Config / Security Hub rule reviewed
backup restore runbook tested
PITR notes:
recovery window: 1-35 days
restore creates a new table
LatestRestorableDateTime usually lags current time by about 5 minutes7. TTL / Streams / Global Tables#
TTL#
TTL:
attribute must be Number
value is Unix epoch time in seconds
expired item is deleted asynchronously
expired item can still appear before background deletion
filter expired items in read path if correctness requires it
good use cases:
session
idempotency record
temporary token
cache item
short-lived event
not good:
precise scheduled deletion
compliance deletion with strict second-level SLAstreams#
DynamoDB Streams:
near real-time change capture
common integration with Lambda
use for projection / async workflow / audit / cache invalidation
stream view types:
KEYS_ONLY
NEW_IMAGE
OLD_IMAGE
NEW_AND_OLD_IMAGES
注意:
Lambda consumer must handle duplicate/retry
downstream processing should be idempotentglobal tables#
global tables:
multi-region active-active
replication is eventually consistent
conflict reconciliation is last writer wins
use when:
low latency read/write in multiple regions
regional resilience is required
注意:
not a replacement for relational global transaction
conflict model must be acceptable
monitor replication latency and pending replication
TTL replicated deletes may incur replicated write cost in replica regions8. Monitoring#
important metrics#
Some DynamoDB metrics are sparse / event-driven. For example, throttle and error metrics may not appear in CloudWatch / YACE until the corresponding event happens. Detailed datapoint conditions are covered in DynamoDB YACE Dashboard.
| Area | Metrics | What To Watch |
|---|---|---|
| Capacity | ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits |
consumed vs provisioned / quota |
| Throttle | ThrottledRequests, ReadThrottleEvents, WriteThrottleEvents |
any non-zero spike on production |
| Hot partition | ReadKeyRangeThroughputThrottleEvents, WriteKeyRangeThroughputThrottleEvents |
key range / partition bottleneck |
| Provisioned throttle | ReadProvisionedThroughputThrottleEvents, WriteProvisionedThroughputThrottleEvents |
provisioned capacity insufficient |
| Account limit | ReadAccountLimitThrottleEvents, WriteAccountLimitThrottleEvents |
account-level quota hit |
| On-demand max | ReadMaxOnDemandThroughputThrottleEvents, WriteMaxOnDemandThroughputThrottleEvents |
on-demand table max hit |
| Latency | SuccessfulRequestLatency |
p90 / p95 / p99 by operation |
| Errors | SystemErrors, UserErrors |
AWS side vs client side errors |
| Conditional | ConditionalCheckFailedRequests |
optimistic locking / business conflict |
| Transaction | TransactionConflict |
high contention transaction |
| Result size | ReturnedItemCount, ReturnedBytes |
query efficiency |
| TTL | TimeToLiveDeletedItemCount |
TTL deletion activity |
| GSI backfill | OnlineIndexPercentageProgress, OnlineIndexThrottleEvents, OnlineIndexConsumedWriteCapacity |
adding GSI impact |
| Global table | ReplicationLatency, PendingReplicationCount, AgeOfOldestUnreplicatedRecord |
replica lag |
alert rules#
critical:
SystemErrors > 0 for 5m
ReadThrottleEvents / WriteThrottleEvents > 0 for 5m on critical table
ReadAccountLimitThrottleEvents / WriteAccountLimitThrottleEvents > 0
ReplicationLatency above RPO expectation
warning:
ConsumedReadCapacityUnits > 80% provisioned for 10m
ConsumedWriteCapacityUnits > 80% provisioned for 10m
SuccessfulRequestLatency p95 above service SLO
ConditionalCheckFailedRequests sudden spike
ReturnedItemCount too high for online querydashboard#
dashboard should include:
request latency p50 / p95 / p99 by operation
read/write consumed capacity
read/write throttle events
key range throttle events
system errors / user errors
top application errors from logs
GSI capacity and throttles
table size / item count
TTL deletes
global table replication latency, if usedPrometheus / YACE#
apiVersion: v1alpha1
discovery:
jobs:
- type: AWS/DynamoDB
regions:
- ap-east-1
customTags:
- key: environment
value: uat
metrics:
- name: ConsumedReadCapacityUnits
statistics: [Sum]
period: 60
length: 300
- name: ConsumedWriteCapacityUnits
statistics: [Sum]
period: 60
length: 300
- name: ReadThrottleEvents
statistics: [Sum]
period: 60
length: 300
- name: WriteThrottleEvents
statistics: [Sum]
period: 60
length: 300
- name: SuccessfulRequestLatency
statistics: [Average, p95]
period: 60
length: 300
- name: SystemErrors
statistics: [Sum]
period: 60
length: 300
dimensionNameRequirements:
- TableName9. Hands-on#
create table#
export AWS_PAGER=""
export AWS_REGION="ap-east-1"
export TABLE_NAME="dev-order-orders"
aws dynamodb create-table \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}" \
--billing-mode PAY_PER_REQUEST \
--attribute-definitions \
AttributeName=pk,AttributeType=S \
AttributeName=sk,AttributeType=S \
AttributeName=gsi1pk,AttributeType=S \
AttributeName=gsi1sk,AttributeType=S \
--key-schema \
AttributeName=pk,KeyType=HASH \
AttributeName=sk,KeyType=RANGE \
--global-secondary-indexes '[
{
"IndexName": "gsi1",
"KeySchema": [
{"AttributeName": "gsi1pk", "KeyType": "HASH"},
{"AttributeName": "gsi1sk", "KeyType": "RANGE"}
],
"Projection": {"ProjectionType": "INCLUDE", "NonKeyAttributes": ["status", "amount", "created_at"]}
}
]' \
--deletion-protection-enabled \
--tags \
Key=env,Value=dev \
Key=service,Value=order \
Key=owner,Value=platformenable PITR#
aws dynamodb update-continuous-backups \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}" \
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true,RecoveryPeriodInDays=35aws dynamodb describe-continuous-backups \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}" \
--query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription'enable TTL#
aws dynamodb update-time-to-live \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}" \
--time-to-live-specification Enabled=true,AttributeName=expire_atput items#
aws dynamodb put-item \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}" \
--condition-expression "attribute_not_exists(pk) AND attribute_not_exists(sk)" \
--item '{
"pk": {"S": "USER#u-1001"},
"sk": {"S": "ORDER#2026-05-29T10:00:00Z#o-1001"},
"gsi1pk": {"S": "ORDER#o-1001"},
"gsi1sk": {"S": "META"},
"order_id": {"S": "o-1001"},
"user_id": {"S": "u-1001"},
"status": {"S": "PENDING"},
"amount": {"N": "99.90"},
"version": {"N": "1"},
"created_at": {"S": "2026-05-29T10:00:00Z"},
"expire_at": {"N": "1790599200"}
}'query by user#
aws dynamodb query \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}" \
--key-condition-expression "pk = :pk AND begins_with(sk, :prefix)" \
--expression-attribute-values '{
":pk": {"S": "USER#u-1001"},
":prefix": {"S": "ORDER#"}
}' \
--return-consumed-capacity TOTALquery by order id through GSI#
aws dynamodb query \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}" \
--index-name gsi1 \
--key-condition-expression "gsi1pk = :pk AND gsi1sk = :sk" \
--expression-attribute-values '{
":pk": {"S": "ORDER#o-1001"},
":sk": {"S": "META"}
}' \
--return-consumed-capacity TOTALcloudwatch alarms#
aws cloudwatch put-metric-alarm \
--region "${AWS_REGION}" \
--alarm-name "dynamodb-${TABLE_NAME}-write-throttle" \
--namespace AWS/DynamoDB \
--metric-name WriteThrottleEvents \
--statistic Sum \
--period 60 \
--evaluation-periods 5 \
--threshold 0 \
--comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--dimensions Name=TableName,Value="${TABLE_NAME}"aws cloudwatch put-metric-alarm \
--region "${AWS_REGION}" \
--alarm-name "dynamodb-${TABLE_NAME}-system-errors" \
--namespace AWS/DynamoDB \
--metric-name SystemErrors \
--statistic Sum \
--period 60 \
--evaluation-periods 5 \
--threshold 0 \
--comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--dimensions Name=TableName,Value="${TABLE_NAME}"aws cloudwatch put-metric-alarm \
--region "${AWS_REGION}" \
--alarm-name "dynamodb-${TABLE_NAME}-p95-latency" \
--namespace AWS/DynamoDB \
--metric-name SuccessfulRequestLatency \
--extended-statistic p95 \
--period 60 \
--evaluation-periods 5 \
--threshold 50 \
--comparison-operator GreaterThanThreshold \
--treat-missing-data notBreaching \
--dimensions Name=TableName,Value="${TABLE_NAME}" Name=Operation,Value=Querycleanup#
# production table 不要直接执行 cleanup
aws dynamodb update-table \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}" \
--no-deletion-protection-enabled
aws dynamodb delete-table \
--region "${AWS_REGION}" \
--table-name "${TABLE_NAME}"10. Production Checklist#
before launch:
access patterns reviewed
partition key distribution tested
item size measured
ReturnConsumedCapacity sampled in load test
on-demand/provisioned mode decided
Service Quotas checked
PITR enabled
deletion protection enabled
IAM least privilege reviewed
KMS key policy reviewed, if using customer managed key
VPC endpoint / resource policy reviewed
CloudWatch alarms created
dashboard created
backup restore tested
migration / backfill has rate limit
when incident happens:
check throttle reason first
check table and GSI metrics separately
check key range throttle events for hot partition
check account limit throttle events for quota issue
check app retry and timeout
check recent GSI creation / backfill / migration