Система состоит из десятков одноранговых серверов (ни один из них не является лидером / мастером). Чтобы создать объект, сервис должен получить следующий последовательный номер на основе некоторого группового ключа: для каждого группового ключа существуют разные последовательности.
Допустим, чтобы создать экземпляр объекта A, сервис должен получить последовательность с групповым ключом. A, в то время как для создания объекта B, сервис должен получить порядковый номер с групповым ключом B.
Запрещается получение одного и того же номера дваждыПропущенные числа допускаются.
В настоящее время я реализовал решение с помощью СУБД, имеющей запись для каждого из ключей группы и обновляющей его текущее значение последовательности в транзакции: UPDATE SEQUENCES SET SEQ_ID=SEQ_ID + 1 WHERE KEY = ?
Однако этот подход позволяет только получить200-300 запросов в секунду из-за блокировки и синхронизации.
Другой подход, который я рассматриваю, заключается в наличии локального буфера последовательностей на каждом узле. Когда буфер пуст, служба запрашивает у БД следующую партию идентификаторов и сохраняет их локально: UPDATE SEQUENCES SET SEQ_ID=SEQ_ID + 1000 WHERE KEY = ?
, если размер пакета равен 1000. Это может помочь снизить конкуренцию. Однако, если узел выходит из строя, он теряет все эти полученные порядковые номера, что, если случается часто, может привести к переполнению максимального значения последовательности (например, max int).
Я не знаю заранее, какпотребуется много порядковых номеров. Я не хочу вводить дополнительные зависимости между серверами, чтобы один из них генерировал порядковые номера и служил другим.
- Каковы общие способы решения подобных проблем?
- Какие другие подходы, основанные на RDBMS, могут быть рассмотрены?
- Какие другие подходы, не основанные на RDBMS, могут быть рассмотрены?
- Какие еще проблемы могут возникнуть с локальным буферным решением?