#amazon-web-services #amazon-dynamodb
#amazon-web-services #amazon-dynamodb
Вопрос:
Я пытаюсь отсканировать и обновить все записи с определенным значением атрибута в моей таблице Amazon DynamoDB, это будут одноразовые операции, а параметр, который я запрашиваю, не является индексом.
Если я правильно понял, мой единственный вариант — выполнить сканирование всей таблицы Amazon DynamoDB, и всякий раз, когда встречается эта запись, я должен их обновлять.
Размер моей таблицы составляет около 2 ГБ, а в моей таблице более 8,5 миллионов записей.
Ниже приведен фрагмент моего скрипта:
scan_kwargs = {
'FilterExpression': Key('someKey').eq(sometargetNumber)
}
matched_records = my_table.scan(**scan_kwargs)
print 'Number of records impacted by this operations: ' str(matched_records['Count'])
user_response = raw_input('Would you like to continue?n')
if user_response == 'y':
for item in matched_records['Items']:
print 'nTarget Record:'
print(item)
updated_record = my_table.update_item(
Key={
'sessionId': item['attr0']
},
UpdateExpression="set att1=:t, att2=:s, att3=:p, att4=:k, att5=:si",
ExpressionAttributeValues={
':t': sourceResponse['Items'][0]['att1'],
':s': sourceResponse['Items'][0]['att2'],
':p': sourceResponse['Items'][0]['att3'],
':k': sourceResponse['Items'][0]['att4'],
':si': sourceResponse['Items'][0]['att5']
},
ReturnValues="UPDATED_NEW"
)
print 'nUpdated Target Record:'
print(updated_record)
else:
print('Operation terminated!')
Я протестировал приведенный выше сценарий (некоторые значения изменяются при публикации в stackoverflow) в тестовой среде (<1000 записей), и все работает нормально, но когда я тестирую их в РАБОЧЕЙ среде с 8,5 миллионами записей и 2 ГБ данных. Скрипт сканирует 0 записей.
Нужно ли мне выполнять сканирование по-другому, и я что-то упускаю? или это просто ограничение операции «сканирования» в DynamoDB?
Комментарии:
1. сканирование возвращает не более 1 МБ данных, и необходимо продолжать вызывать API путем передачи
LastEvaluatedKey
, чтобы получать все больше и больше.2. @BaluVyamajala да, я верю, что это сработает, спасибо!
Ответ №1:
Похоже, ваша проблема связана с тем, как DynamoDB фильтрует данные и разбивает результаты на страницы. Чтобы рассмотреть, что здесь происходит, рассмотрите порядок операций при выполнении операции сканирования / запроса DynamoDB во время фильтрации. DynamoDB выполняет следующие действия в этом порядке:
- Считывает элементы из таблицы
- Применить фильтр
- Возвращает результаты
DynamoDB query
и scan
операции возвращают до 1 МБ данных одновременно. Все, что выходит за рамки этого, будет разбито на страницы. Вы знаете, что ваши результаты разбиваются на страницы, если DynamoDB возвращает элемент LastEvaluatedKey в вашем ответе.
Фильтры применяются после ограничения в 1 МБ. Это критический шаг, который часто застает людей врасплох. В вашей ситуации происходит следующее:
Выполняется операция сканирования, которая считывает 1 МБ данных из таблицы. Вы применяете фильтр к ответу размером 1 МБ, в результате чего все записи на первом шаге удаляются из ответа. DDB возвращает оставшиеся элементы с элементом LastEvaluatedKey, что указывает на наличие дополнительных данных для поиска. Другими словами, ваш фильтр не применяется ко всей таблице. Оно применяется к 1 МБ таблицы за раз. Чтобы получить искомые результаты, вам нужно будет многократно выполнять операцию сканирования, пока вы не дойдете до последней «страницы» таблицы.
Комментарии:
1. Да, это может сработать, как мы можем определить, что он достиг последней страницы из всех 8,5 миллионов записей? Есть ли какой-либо конкретный ключ json, возвращаемый DynamoDB? Интересно, будет ли LastEvaluatedKey даже для этой последней страницы? Спасибо за помощь
2. DynamoDB вернет a
LastEvaluatedKey
, когда будет больше страниц для выборки. Как только вы дойдете до конца результатов, разбитых на страницы,LastEvaluatedKey
поле не будет присутствовать. Дополнительная информация здесь: docs.aws.amazon.com/amazondynamodb/latest/developerguide /…