我正在将代码从dynamodb
迁移到dynamodb2
。代码执行批量写入,我遇到的一个主要问题是检测未处理的消息。我的代码不断地从队列中提取消息,然后将它们批量插入到DynamoDB表中。看来,大量的项目(约20%)从未进入表格,而我没有得到任何关于它的错误消息。所以我的问题是如何捕获项目未插入的内容以及如何重新处理它们?这是我的dynamodb
代码块,它可以执行此操作:
def do_batch_write(items,conn,table,diagn):
batch_list = conn.new_batch_write_list()
batch_list.add_batch(table, puts=items)
iTry = 0
rems = []
while True:
iTry = iTry + 1
try:
response = conn.batch_write_item(batch_list)
except Exception, e:
tRetry = 5
log.error("Error while attempting batch_write_item, try %d, retrying after %d secs: %s" % (iTry, tRetry, str(e)))
time.sleep(tRetry)
continue
unprocessed = response.get('UnprocessedItems', None)
if not unprocessed:
if len(items) == 1 and diagn:
log.info("Trivial batch processed")
break
batch_list = conn.new_batch_write_list()
unprocessed_list = unprocessed[table.name]
items = []
for u in unprocessed_list:
item_attr = u['PutRequest']['Item']
item = table.new_item( attrs=item_attr)
items.append(item)
rems.append(len(items))
batch_list.add_batch(table, puts=items)
return iTry
这是我要修改的dynamodb2
代码块,用于处理未处理/放弃的项目。
with table.batch_write() as batch:
while True:
m = inq.read()
mStr = json.dumps(m)
pid = m['primaryId']
sid = m['secondaryId']
item_data = {"primaryId" : pid, "secondaryId"] : sid, "message"] : mStr}
batch.put_item(data=item_data)
我看了this page,但没有找到任何帮助。你能帮我弄清楚如何修改它吗? THX
更新:我仍然遇到丢失物品的问题。我修改了上面的块如下:
i = 0
with table.batch_write() as batch:
while True:
m = inq.read()
i = i + 1
mStr = json.dumps(m)
pid = m['primaryId']
sid = m['secondaryId']
item_data = {"primaryId" : pid, "secondaryId"] : sid, "message"] : mStr}
batch.put_item(data=item_data)
if i == 25:
batch.resend_unprocessed()
i = 0
但是,在仔细记录所有传入数据后我发现了(上面的代码片段中没有包含日志打印语句以节省空间),我看到,至少在一种情况下,我看到了以下内容:
put_item
resend_unprocessed()
时,会报告0个未处理的项目因此,当它表示成功将项目写入表格时,我似乎无法真正信任boto
。看起来像一个错误,或者这是dynamodb2
的某种“功能”?
我之前忘记提到的一件事:我在同一个AWS EC2实例上并行运行了几个相同的“工作”进程,从同一输入队列读取并写入相同的Dynamo表。我创建了几个以跟上传入数据量。我的印象是他们不应该争取进入桌面,即使他们之间存在某种冲突,也必须“在dynamodb
引擎盖下解决”。即使这导致某些项目以某种方式被删除,也不应该在resend_unprocessed()
中报告所有内容都已成功处理。
答案 0 :(得分:2)
似乎这是可能的。
批量写入可能无法写入“所有”项目。在这种情况下,API成功,但未写入的项在响应中显示为“UnprocessedItems”。您需要查看此内容并再次重试这些项目。
发生这种情况的典型原因是您的表吞吐量超出(可能还有其他原因)。
添加相关的代码段(由于以下要点):
while True:
response = dynamodb_conn.batch_write_item(batch_list)
unprocessed = response.get('UnprocessedItems', None)
if not unprocessed:
break
batch_list = dynamodb_conn.new_batch_write_list()
unprocessed_list = unprocessed[table_name]
items = []
for u in unprocessed_list:
item_attr = u['PutRequest']['Item']
item = dynamodb_table.new_item(
attrs=item_attr
)
items.append(item)
batch_list.add_batch(dynamodb_table, puts=items)
这些额外的读数将告诉你细节 - 最后一个也是一个python代码。
答案 1 :(得分:1)
上述答案与dynamodb2无关。
我正在使用resend_unprocessed(),它确实有效。
boto日志:
2015-11-03 08:45:13,427 INFO: table.resend_unprocessed (1491): 1424-MainThread: Re-sending 11 unprocessed items.
2015-11-03 08:45:13,427 INFO: table.resend_unprocessed (1502): 1424-MainThread: Sending 11 items
2015-11-03 08:45:13,428 DEBUG: connection._mexe (910): 1424-MainThread: Method: POST
2015-11-03 08:45:13,428 DEBUG: connection._mexe (911): 1424-MainThread: Path: /
2015-11-03 08:45:13,428 DEBUG: connection._mexe (912): 1424-MainThread: Data: {"RequestItems": {"user_feed": [{"PutRequest": XXXXXXXXXXXXX }
2015-11-03 08:45:13,429 DEBUG: connection._mexe (913): 1424-MainThread: Headers: {'Host': 'dynamodb.us-east-1.amazonaws.com', 'Content-Type': 'application/x-amz-json-1.0', 'Content-Length': '1540', 'X-Amz-Target': 'DynamoDB_20120810.BatchWriteItem'}
2015-11-03 08:45:13,453 DEBUG: layer1._retry_handler (2746): 1424-MainThread: Saw HTTP status: 200
2015-11-03 08:45:13,453 DEBUG: layer1._retry_handler (2778): 1424-MainThread: Validating crc32 checksum for body: {"UnprocessedItems":{}}
2015-11-03 08:45:13,453 DEBUG: layer1.make_request (2733): 1424-MainThread: {"UnprocessedItems":{}}
2015-11-03 08:45:13,453 INFO: table.resend_unprocessed (1506): 1424-MainThread: 0 unprocessed items left
但写作AT http://boto.readthedocs.org/en/latest/ref/dynamodb2.html
“由Table用作批量写入的上下文管理器。
您可能不想尝试直接使用此对象。“
你不应该使用resend_unprocessed。上下文管理器在处理请求时执行此操作。 (看看你的boto日志)
像:
2015-11-03 08:43:43,551 INFO: table.handle_unprocessed (1483): 1424-MainThread: 23 items were unprocessed. Storing for later.
2015-11-03 08:43:43,551 INFO: table.resend_unprocessed (1506): 1424-MainThread: 51 unprocessed items left