排查DynamoDB重复记录:确认是否由Lambda或DynamoDB导致
问题描述
我有一个Lambda(Function URL),功能运行正常,代码如下:
def lambda_handler(event,context): raw_query_string = event['rawQueryString'] dynamodb = boto3.resource('dynamodb') dt = datetime.datetime.now() seq = dt.strftime("%y%m%d%H%M%S") table = dynamodb.Table('activitylg') response = table.put_item( Item={ "id": int(raw_query_string[:10]), "dt": int(seq), "code": int(raw_query_string[10:]), } )
但它偶尔会向DynamoDB的activitylg表中添加重复记录,例如以下数据中存在两条重复项:
2023-08-26 08:39:44,2,0 2023-08-26 13:38:44,1,0 2023-08-26 14:44:55,2,0 2023-08-26 14:44:57,2,0 2023-08-27 08:01:40,2,1 2023-08-27 14:58:07,2,0 2023-08-27 14:58:08,2,0 2023-08-28 07:12:23,2,1 2023-09-20 11:39:57,2,1 2023-09-22 09:01:27,2,1 2023-10-03 08:30:33,2,1 2023-10-03 08:30:35,2,1 2023-10-03 08:31:52,1,1 2023-10-03 08:33:15,4,1 2023-10-03 08:33:36,3,1
重复项为:
2023-08-26 14:44:57,2,0 2023-10-03 08:30:35,2,1
原本以为是客户端误发重复请求,但怀疑可能与Lambda冷启动问题有关。以下是CloudWatch中首次请求和未主动发起的重复请求的日志:
首次请求日志:
2023-08-26T14:44:54.160+05:30 INIT_START Runtime Version: python:3.11.v9 Runtime Version ARN: arn:aws:lambda:us-east-1::runtime:dabfb8de4b8bf97622f4c7eb46aed5a92c68ee3b72a98d1682a2dead82f52d15 2023-08-26T14:44:54.424+05:30 START RequestId: 4c792dc6-3cc9-4fd1-ac04-0341411fd5a1 Version: $LATEST 2023-08-26T14:44:56.226+05:30 END RequestId: 4c792dc6-3cc9-4fd1-ac04-0341411fd5a1 2023-08-26T14:44:56.226+05:30 REPORT RequestId: 4c792dc6-3cc9-4fd1-ac04-0341411fd5a1 Duration: 1802.76 ms Billed Duration: 1803 ms Memory Size: 128 MB Max Memory Used: 74 MB Init Duration: 263.11 ms
重复请求日志:
2023-08-26T14:44:57.412+05:30 START RequestId: e65b0ac1-bca3-486b-b767-8f96e6596794 Version: $LATEST 2023-08-26T14:44:57.649+05:30 END RequestId: e65b0ac1-bca3-486b-b767-8f96e6596794 2023-08-26T14:44:57.649+05:30 REPORT RequestId: e65b0ac1-bca3-486b-b767-8f96e6596794 Duration: 236.94 ms Billed Duration: 237 ms Memory Size: 128 MB Max Memory Used: 75 MB
客户端Kotlin代码多数时间运行正常,仅偶现重复,想确认该重复记录问题是否由DynamoDB或Lambda引发?
问题分析与结论
Lambda冷启动不会引发重复记录
两次请求的RequestId完全不同,说明是两个独立的Lambda调用,并非同一请求的重复执行。冷启动仅会延长单次请求的执行时长,不会自动触发额外请求或重复执行代码逻辑,因此可以排除Lambda冷启动的原因。DynamoDB按正常逻辑执行,无异常
从代码和数据来看,写入的条目使用id+dt作为复合主键(否则put_item会覆盖而非新增记录)。重复项的dt值存在时间差(如14:44:55和14:44:57),DynamoDB会将其视为不同条目正常写入,不存在自身逻辑导致重复的问题。大概率是客户端重复请求导致
首次冷启动请求耗时1.8秒,若客户端设置的超时时间较短,可能会触发自动重试;或者网络波动导致请求重发,最终生成两条独立的Lambda调用,写入两条记录。结合客户端偶现重复的情况,这是最可能的原因。解决方案建议
- 调整Lambda Function URL和客户端的超时设置,避免因冷启动超时触发重试;
- 在客户端实现幂等机制,比如每次请求携带唯一请求ID,Lambda侧先校验该ID是否已处理,避免重复写入;
- 利用DynamoDB的条件写入(
ConditionExpression),比如添加判断逻辑,仅当不存在相同id+code的近期记录时才执行写入。
内容的提问来源于stack exchange,提问作者shantanuo
相关产品推荐
相关产品推荐

