Базовый распределенный счетчик с использованием сокетов Java

У меня есть некоторые процессы Java (программы Socket), работающие на разных серверах, некоторые в одной сети, а некоторые в разных сетях. Вместе эти процессы поддерживают глобальный счетчик. Клиент может подключиться к любому из этих процессов и выдать команду на increase, decrease или get значение счетчика. В конечном итоге глобальный счетчик должен быть согласованным (может произойти раздел сети, и мы сможем восстановиться после него).

Решение, о котором я думал до сих пор, заключается в подсчете приращений и уменьшений на каждом узле для всех узлов. Когда на узле выдается команда увеличения, он увеличивает свою собственную локальную копию своих счетчиков приращений, а затем широковещательно передает свои счетчики приращения и уменьшения. Узлы, которые получают эту широковещательную рассылку, берут максимальное количество полученных счетчиков и свою локальную копию счетчиков отправителя и сохраняют результат как последний счетчик. Когда команда get выдается на любом узле, она дает разницу сумм всех приращений и уменьшений. Я предполагаю, что это позаботится о случаях, когда широковещательные передачи принимаются не по порядку и других ненадежных случаях. Я не хочу использовать какой-либо слой сохранения.

Есть ли лучший способ реализовать это? Какой протокол я должен использовать для трансляции счетчиков? Будут ли работать сплетни на UDP? Любые библиотеки Java, которые могут помочь?


person azuri    schedule 13.09.2017    source источник
comment
Ваше интуитивно понятное решение называется CRDT, и это хорошо. бумага об этом, если вам нужна дополнительная информация .   -  person Oleg    schedule 14.09.2017


Ответы (2)


Возможно, вы знаете об этом шаблоне проектирования, но он все равно может вдохновлять: https://en.wikipedia.org/wiki/Observer_pattern

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

Что касается библиотек Java, проверьте их, посмотрите, облегчит ли какая-либо из них вашу жизнь:

person D. Wood    schedule 13.09.2017
comment
Если все мои java-процессы являются субъектами и все они являются наблюдателями, и субъект будет уведомлять всякий раз, когда на нем происходит инкремент или декремент (что будет происходить довольно часто), по мере роста числа узлов сеть будет забита из-за чтобы процессы постоянно разговаривали друг с другом. - person azuri; 14.09.2017

Похоже, вам нужен PNCounter из библиотеки распределенных данных Akka. Он использует Gossip для передачи состояния счетчика в сеть. У вас также есть точный контроль над согласованностью чтения и записи. Так, например, вы можете сделать ReadMajority, где «значение будет прочитано и объединено с большинства реплик».

Между прочим, PNCounter работает так, как вы описываете, используя два распределенных счетчика для поддержания приращений и уменьшений.

person David    schedule 23.02.2018