Автоматический прирост в хранилище таблиц Azure

В настоящее время я разрабатываю приложение для хранения таблиц Azure. В этом приложении у меня есть таблица, в которой будет относительно немного вставок (пара тысяч/день), а первичный ключ этих объектов будет использоваться в другой таблице, которая будет иметь миллиарды строк.

Поэтому я ищу способ использовать автоматически увеличивающееся целое число, а не GUID, в качестве первичного ключа в маленькой таблице (поскольку он будет экономить много памяти и масштабируемость вставок, это не проблема).

Были некоторые дискуссии по этой теме, например. на http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/6b7d1ece-301b-44f1-85ab-eeb274349797.

Однако, поскольку проблемы concurrency могут быть очень трудными для отладки и обнаружения, мне немного неудобно выполнять это самостоятельно. Мой вопрос, поэтому, если есть хорошо протестированное империрование этого?

Ответы

Ответ 1

Я еще не реализовал это, но работаю над этим...

Вы можете засеять очередь с помощью следующих идентификаторов для использования, а затем просто выберите их из очереди, когда они вам понадобятся.

Вам нужно сохранить таблицу, чтобы содержать значение самого большого числа, добавленного в очередь. Если вы знаете, что не будете использовать тонну целых чисел, у вас может быть каждый рабочий так часто просыпаться и убедиться, что в очереди все еще есть целые числа. Вы могли бы также использовать использованную очередь int, которую работник мог проверить, чтобы следить за использованием.

Вы также можете подключить этого работника, чтобы, если очередь была пуста, когда ваш код нуждался в идентификаторе (случайно), он мог перетащить рабочий сон, чтобы создать больше ключей как можно скорее.

Если этот вызов завершился неудачно, вам понадобится способ (скажите работнику, что вы собираетесь делать для них работу (блокировка), затем рабочие работают над получением следующего id и разблокировки)

  • блокировка
  • получить последний ключ, созданный из таблицы
  • приращение и сохранение
  • разблокировать

затем используйте новое значение.

Ответ 2

Для всех, кто найдет его в поиске, есть лучшее решение. Минимальное время блокировки таблицы - 15 секунд - это ужасно. Не используйте его, если вы хотите создать действительно масштабируемое решение. Используйте Etag!

Создайте один объект в таблице для ID (вы даже можете назвать его как идентификатор или что-то еще).

1) Прочтите.

2) Приращение.

3) InsertOrUpdate WITH Etag указан (из прочитанного запроса).

если последняя операция (InsertOrUpdate) будет успешной - у вас будет новый, уникальный, автоинкрементный идентификатор. Если запрос завершится с ошибкой (исключение с HttpStatusCode == 412), это означает, что другой клиент изменил его. Итак, повторите снова 1,2 и 3. Обычное время для Read+InsertOrUpdate меньше 200 мс. Моя тестовая утилита с источником на github.

Ответ 4

Решение, которое я обнаружил, что предотвращает дублирование идентификаторов и позволяет автоинкремент это

  • заблокировать (арендовать) blob и позволить этому действовать как логические ворота.

  • Затем прочитайте значение.

  • Введите приращенное значение

  • Отпустите аренду

  • Используйте значение в своем приложении/таблице

Затем, если во время этого процесса ваша рабочая роль потерпила крах, тогда у вас будет только отсутствующий идентификатор в вашем магазине. ИМХО, что лучше дубликатов.

Вот пример кода и более подробная информация по этому подходу от Стива Маркса

Ответ 5

Если вам действительно нужно избегать указаний, вы считаете, что используете что-то, основанное на дате/времени, а затем используя ключи разделов, чтобы минимизировать риск concurrency.

Ключ раздела может быть по пользователю, году, месяцу, дню, часу и т.д., а ключ строки может быть остальной частью времени datetime в течение достаточно небольшого промежутка времени для управления concurrency.

Конечно, вы должны спросить себя, по цене даты в Лазуре, если избегать Guid действительно стоит всех этих дополнительных усилий (при условии, что Guid будет просто работать).