Использование счетчика приращений для генерации уникального ключа в кластере Couchbase
самый распространенный вопрос, который я слышу о Couchbase и других базах данных NoSQL, - это как генерировать уникальные ключи для записей - или более конкретно-как реплицировать функцию автоматического приращения общих баз данных отношений.
решение в Couchbase часто упоминается функция increment, где вы можете вызвать increment на числовом ключе, и он будет генерировать новый уникальный номер в последовательности.
мой вопрос в том, что я не могу получить мою голову вокруг массивного проблема, которую я предвижу, когда дело доходит до репликации.
рассмотрим, что у вас есть кластер из трех узлов Couchbase, и вы храните журнал запросов. Вы хотите ввести этот журнал, чтобы создать запись под названием "requestlog_counter".
теперь скажем, что у нас есть 4 веб-узла, каждый из которых получает 20 запросов в секунду, и каждый из них должен быть записан как "request::{ID})". Это 80 запросов в секунду.
скажем, узлы 1 и 3 имеют крошечную задержку сети, но оба получают один из этих 40 запросов одновременно. Ваш скрипт увеличивает счетчик запросов (скажем, для этого примера он в настоящее время равен 1500) и получает идентификатор. Конечно, теперь возможно, что оба экземпляра Couchbase могут вернуть 1501 на веб-узлы 1 и 3, и оба сервера теперь попытаются сохранить запрос, с которым они имеют дело, как "request:1501".
теперь репликация будет иметь дело с этим, и по существу последний выиграет. Но теперь вы потеряли запись одного запрос.
значит ли это, что на самом деле вам нужен лучший способ ввода жизненно важных данных и что использование автоматических приращений для абсолютных значений и генерации уникальных ключей-это то, чего следует избегать в кластерной среде NoSQL?
или-есть ли что-то, что вы можете сделать как часть вашей процедуры генерации ключей, что делает это 100% надежным.
пожалуйста, также рассмотрите множественную кластерную среду с использованием перекрестной репликации центра обработки данных тоже.
спасибо.
Майк
1 ответов
прежде всего в соответствии с couchbase документация функции increment
и decremant
являются "атомарными" внутри кластера. Поэтому, если вы используете их для создания "автоинкремента", все должно работать нормально.
но если вы хотите заверить, что при сохранении нового элемента в couchbase вы не будете переопределять существующие (например, "оба экземпляра Couchbase могут вернуть 1501"), вы можете использовать операцию хранения с StoreMode.Add
. Так что, если вы звоните в то же время couchbase.store(StoreMode.Add, "request:1501",value)
, один запрос будет готово с успехом, другие потерпят неудачу, и вы можете поймать этот "сбой" и попытаться повторить эту операцию магазина снова (с получением нового autoincremented id для нового ключа)