DynamoDB - самый эффективный / дешевый способ получения объектов из списка ключей раздела? - PullRequest
1 голос
/ 10 мая 2019

Допустим, в моем клиенте у меня есть список ПК:

PKs = [uuid1, uuid2, uuid3, uuid4, ...]

И мне нужно получить объекты, которые имеют эти соответствующие PK.

Я могу придумать 3 способа:

Сделка

Используя TransactGetItems, я могу получать по 10 элементов за раз, поэтому я просто получаю каждый элемент по отдельности, пока не получу их все

Пакетное получение предметов

То же, что и Транзакция, но не транзакционная, и я могу получить 25 элементов одновременно.

Запрос с фильтром (возможно, грязный)

Вместо этого я мог бы иметь GSI, который имеет неизменный атрибут в качестве ключа раздела, и установить исходный ключ раздела в качестве атрибута, и я мог бы просто связать связку "ИЛИ" в выражении условия.

Например (boto3):

table.query(
    KeyConditionExpression=Key('gsi1_pk').eq('metadata'),
    #Bunch of ORs togheter
    FilterExpression=Attr('pk').eq('uuid1') | Attr('pk').eq('uuid2') ...
    Index='GSI1-Index1'
)

Теперь, согласно странице с ценами:

DynamoDB взимает одну единицу запроса на чтение для каждого строго согласованного чтение (до 4 КБ), две единицы запроса на чтение для каждого транзакционного чтения, и половина запроса на чтение для каждого в конечном итоге непротиворечивого чтения

Я не уверен, что такое 1 чтение, учитывает ли оно каждый возвращенный объект или каждый проверенный объект? Будет ли каждый отдельный запрос как минимум 1 RCU или они будут суммироваться, пока не достигнут 1 RCU?

Какой из 3 приведенных выше примеров будет самой дешевой после системы ценообразования DynamoDB? Есть ли другой способ сделать это?

Бонусные баллы за расчет.

1 Ответ

1 голос
/ 11 мая 2019

Хорошо, транзакции должны быть последним вариантом, поскольку это не имеет ничего общего с транзакционной логикой.

BatchGetItems потребляет 1RCU на элемент, однако Query использует RCU в зависимости от общего размера элементов запрашивается (не возвращается !!).Если бы вы запросили таблицу и вернули 100 элементов, но с размером 1 КБ каждый (без фильтра), это было бы 400 КБ и, следовательно, потреблялось 10 RCU (вычисления могут быть неправильными, писать очень быстро, но вы понимаете).Так что запрос гораздо дешевле во многих случаях, кроме ваших.В вашем случае вы просто сканируете всю таблицу, поскольку HASH - это что-то статичное, насколько я понимаю.

Ваш лучший вариант - BatchGetItems, но есть большой однако здесь ...

Как вы в итоге получаете только идентификаторы того, что вы хотите?Это не шаблон NoSQL.Что вы, вероятно, делаете, это нормализует данные, которые не предназначены для DynamoDB.Вы должны денормализовать его так, чтобы, где вы можете получить этот список идентификаторов, вы также получили их релевантные атрибуты.Если вы запрашиваете что-то и получаете идентификаторы, тогда другой запрос идентификаторов просто говорит, что его NORMALIZED и DynamoDB не подходят для этого.

Я бы посоветовал вам пересмотреть структуру данных и схемы доступа.

...