В хранилище данных BigTable, касательно параллелизма, как мне «заблокировать» сущность? - PullRequest
2 голосов
/ 26 ноября 2009

Я не уверен, как справиться с этим в хранилище данных BigTable.

Представьте себе следующий пример (просто для объяснения концепции. Пример не соответствует моей реальной модели данных):

  • У меня есть объект Counter, который отслеживает количество транзакций в моем хранилище данных. Допустим, текущий счетчик равен 100.
  • Теперь два веб-запроса читают это значение одновременно.
  • Оба веб-запроса добавляют новую транзакцию
  • И, наконец, оба обновляют счетчик (до 101).

Значение счетчика теперь неточно. Это должно быть 102.

Есть предложения о том, как справиться с этой ситуацией? Могу ли я «заблокировать» счетчик, чтобы убедиться, что второй веб-запрос даже не прочитал его до завершения первого веб-запроса?

Ответы [ 2 ]

4 голосов
/ 26 ноября 2009

У вас есть несколько вариантов:

  • В зависимости от области действия вашего счетчика и ваших сущностей, сущности Транзакции должны быть дочерними сущностями счетчика. Затем вы можете вставить транзакцию и обновить счетчик транзакции . Имейте в виду, что это ограничивает вашу частоту обновления до 1-5 QPS.
  • Если ваши значения не должны быть точными на 100%, вставьте объект и обновите счетчик (используя транзакцию с одним объектом) отдельно. Вы можете запустить обычный cronjob, чтобы пересчитать количество объектов и исправить счетчик, если из-за ошибок он не синхронизирован.
  • Вы можете создать собственную ограниченную поддержку распределенных транзакций .
1 голос
/ 26 ноября 2009

В дополнение к опциям, которые дает Ник, вы можете рассмотреть возможность использования счетчика.

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

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

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

...