boto3 put_item成功,但未显示记录



我在任何地方都找不到答案,希望SO最终能提供帮助。

我有一个lambda函数,它处理一条记录,然后将其写入一个dynamodb表。从所有的意图和目的来看,put_item调用似乎是成功的,然而,当我检查发电机表时,记录没有出现在其中。

import json
import boto3
import uuid
import urllib3
from botocore.exceptions import ClientError
def lambda_handler(event, context):

apiResponse = {}
for record in event['Records']:
decoded = json.loads(record['body'])
listId = int(decoded['queryParams']['rec_id'])
apiCall = "INTERNAL API"
http = urllib3.PoolManager()
request = http.request('GET', apiCall)
apiResponse = json.loads(request.data.decode('utf-8'))
try:
client = boto3.resource('dynamodb')
table = client.Table('HistoryAuditTable')
saveStatus = table.put_item(Item={
'UUID': uuid.uuid4().hex,
'RecId': listId,
'MessageType': decoded['queryParams']['type'],
'MessageTimestampUTC': record['attributes']['SentTimestamp'],
'Message': apiResponse
})
print("STATUS")
print(saveStatus) # This prints out a 200 status code in CloudWatch
except ClientError as e:
# This error never happens.
print("ERROR")
print(e.response["Error"]['Message'])

# Response Status
response = {}
response["body"] = json.dumps(decoded)
return response

我的apiResponse是一个简单的json负载,其中包含一些审计数据,每当记录更改时,我们都会跟踪这些数据。

我的发电机表有以下字段:

UUID: self-explanatory, 
RecId: an internal record identifier (we keep this separate from the PK because the same record might be updated again and again),
MessageType: String representing if the record was a "SEED_VALUE", "CREATE", "UPDATE", "ARCHIVE", or "SOFT_DELETE"
MessageTimestampUTC: self-explanatory
Message: JSON blob containing the record details

我不得不用我们数据的当前状态(大约400k条记录(的初始负载为这个表进行种子设定——种子设定过程使用了相同的aws lambda函数。我的第一个迹象是,在400k条记录中,只有大约100k条记录真正进入了表中,尽管所有400k行都返回了200响应代码,但在我注意到这一点后,我决定尝试触发将单个记录推入表中的进程,我可以看到我的函数正在正确启动,我可以看出我的api调用正在正确返回,我可以看到saveStatus似乎是成功的,但我没有在发电机表中看到我的记录。我想我有几个问题:

  1. 是否存在对dynamodb表的写入限制?最初我是否可能向其中推送了太多数据,而在我的限制重置之前,我根本无法推送任何新数据?(我在网上找不到直接的答案(
  2. 我是不是做错了什么?我的流程几乎完全是从AWS文档中复制的,但AWS的文档是出了名的糟糕
  3. 是否有某种错误/写入日志记录可以通过cloudwatch为dynamodb启用?(我在任何地方都找不到这方面的任何信息(

我检查过的其他几件事:

  • UUID没有冲突(我不太可能知道,但我已经绝望了(
  • 个人记录完全低于400 kb DynamoDB的限制(我见过的最大记录是5 kb(

老实说,我很不知所措,我不明白这个过程是如何/为什么对10万张唱片起作用的,然后突然决定不再起作用。

一般来说,一些建议、指针和观察结果,如果您回答评论中的问题,可能会变得更加具体。

看看DynamoDB中的读写容量模式以及分区。本质上,每个分区1000次写入的上限为1KB。根据你的钥匙设置,你可能会碰到它。您可以在表中的度量中发现是否存在这种情况。另外:对于失败的写入,您会得到异常,这将引出我的下一点。

在您的代码中,您基本上将DynamoDB的编写视为拥有。如果它成功了,那就太好了,如果没有成功,你只需记录错误并继续。这不是一个理想的调试设置,在这种情况下,您可以考虑将对DynamoDB的写入卸载到一个单独的Lambda中,例如将它们存储在SQS中并批量处理。如果写作对你的客户很重要;静音";错误,引发一个适当的异常并向客户端发出出错的信号。在一百万次成功的日志中寻找奇怪的错误并不有趣;-(

好消息是,你并没有完全做错,但你可以优化一些东西。实例化boto3资源和客户端是一项成本相对较高的操作,如果您关心性能,可以缓存这些资源和客户端。考虑使用批处理来减少网络请求的数量。

您可以在表的"度量"选项卡中监视潜在限制的数量以及读/写错误。这些指标被称为:

  • Throttled [write|read] requests
  • Throttled [write|read] events
  • System errors [write|read]

最新更新