#performance #azure #azure-table-storage
#Производительность #azure #azure-table-storage
Вопрос:
Я полный новичок в Azure! Цель состоит в том, чтобы возвращать строки на основе метки времени, хранящейся в RowKey. Поскольку с каждым запросом связана транзакционная стоимость, я хочу минимизировать количество транзакций / запросов при сохранении производительности
Это предлагаемые ключи раздела и строки:
- Ключ раздела: TextCache_(AccountId)_(ParentMessageId)
- Ключ строки: (DateOfMessage)_(MessageId)
Легенда:
- AccountId — это целое число
- ParentMessageId — родительский MessageId, если он есть, пустой, если он родительский
- DateOfMessage — Дата создания сообщения — формат будет DateTime.Отметки.toString(«d19»)
- MessageId — уникальный идентификатор сообщения
Я хотел бы получить обратно из одного запроса строки и любые дочерние элементы, которые > или < DateOfMessage_MessageId
Можно ли это сделать с помощью предложенных мной PartitionKeys и RowKeys?
ie .. (в псевдокоде)
var results = ctx.PartitionKey.StartsWith(TextCache_AccountId)
amp;amp; ctx.RowKey > (TimeStamp)_MessageId
Во-вторых, если у меня есть несколько учетных записей, и я хочу вернуть только первые 10, можно ли это сделать с помощью одного запроса
ie .. (в псевдокоде)
var results = (
(
ctx.PartitionKey.StartsWith(TextCache_(AccountId1)) amp;amp;
amp;amp; ctx.RowKey > (TimeStamp1)_MessageId1 )
)
||
(
ctx.PartitionKey.StartsWith(TextCache_(AccountId2)) amp;amp;
amp;amp; ctx.RowKey > (TimeStamp2)_MessageId2 )
) ...
)
.Take(10)
Ответ №1:
Краткий ответ на ваши вопросы — да, но есть некоторые вещи, на которые вам нужно обратить внимание.
Хранилище таблиц Azure не имеет прямого эквивалента .StartsWith()
. Если вы используете библиотеку хранилища в сочетании с LINQ, вы можете использовать .CompareTo()
(> и < не переводите должным образом), что будет означать, что если вы запустите поиск для учетной записи 1 и попросите запрос вернуть 1000 результатов, но для учетной записи 1 есть только 600 результатов, последние 400 результатов будут для учетной записи 10 (следующий номер учетной записи в лексическом смысле). Итак, вам нужно быть немного умнее в том, как вы обрабатываете свои результаты.
Если бы вы дополнили идентификатор учетной записи начальными 0, вы могли бы сделать что-то вроде этого (здесь также используется псевдокод)
ctx.PartionKey > "TextCache_0000000001"
amp;amp; ctx.PartitionKey < "TextCache_0000000002"
amp;amp; ctx.RowKey > "123465798"
Следует иметь в виду еще кое-что, что запросы к таблицам Azure возвращают свои результаты в PartitionKey
том RowKey
порядке. Таким образом, в вашем случае сообщения без ParentMessageId
будут возвращены перед сообщениями с ParentMessageId
. Если вы никогда не собираетесь запрашивать эту таблицу с помощью ParentMessageId
, я бы перенес это в свойство.
Если TextCache_
это просто строковая константа, она ничего не добавляет, будучи включенной в PartitionKey
, если только это действительно не будет что-то значить для вашего кода, когда оно будет возвращено.
Пока вы выполняете второй запрос, я не думаю, что он выдаст то, что вам нужно. Если вы хотите, чтобы первые десять строк располагались в DateOfMessage
порядке, то это не сработает (см. Мой пункт выше о порядке сортировки). Если вы выполнили этот запрос как есть, и у учетной записи 1 было 11 сообщений, он вернет только первые 10 сообщений, связанных с учетной записью 1, независимо от того, было ли у учетной записи 2 более раннее сообщение.
Хотя попытка минимизировать количество используемых вами транзакций является хорошей практикой, не стоит слишком беспокоиться об этом. Стоимость запуска ваших рабочих / веб-ролей уменьшит ваши транзакционные издержки. 1 000 000 транзакций обойдутся вам в 1 доллар, что меньше, чем стоимость запуска одного небольшого экземпляра в течение 9 часов.
Комментарии:
1. Спасибо knightpfhor, меня больше заботило достижение скорости 500 транзакций в секунду в хранилище таблиц, что привело бы к регулированию. Я не подумал о заполнении идентификатора учетной записи, которое определенно потребуется. Проведем некоторое тестирование
2. Стоит отметить, что ограничение дроссельной заслонки для каждого раздела, а не глобальное (хотя глобальное ограничение составляет несколько тысяч транзакций в секунду
3. Что касается
TextCache_
, я добавил это в качестве идентификатора таблицы. Если у меня есть несколько объектов, как мне их различать?4. Вы имеете в виду, что у вас есть несколько типов объектов, которые вы пытаетесь сохранить в одной таблице?
5. ДА… правильно. Или я должен создавать другую таблицу для этого .. Хммм… Я думаю, что мне следовало бы ввести этот постоянный префикс…