1

我有一些Java進程(套接字程序)運行在不同的服務器上,一些在同一個網絡上,一些在不同的網絡上。這些過程一起有保持全球計數器的工作。客戶端可以連接到這些進程中的任何一個,並向increasedecreaseget發出命令的計數器值。全球計數器應該最終一致(網絡分區可能發生,我們可以從中恢復)。使用Java套接字的基本分佈式計數器

到目前爲止,我想到的解決方案是在每個節點上爲所有節點維護一個增量和減量的計數。當一個增量命令在節點上發出時,它會增加其自身的增量計數本地副本,然後廣播其增量和減量計數。接收此廣播的節點將收到的計數的最大值以及發件人計數的本地副本,並將結果存儲爲最新計數。當在任何節點上發出get命令時,它會給出所有增量和減量之和的差值。我認爲這將處理無法接收廣播和其他不可靠性的情況。我不想使用任何持久層。

有沒有更好的方法來實現這個? 我應該使用什麼協議來播放計數?會在UDP上工作嗎?任何可能有幫助的Java庫?

+1

您的直觀解決方案稱爲[CRDT](http://www.cakesolutions.net/teamblogs/how-to-build-a-distributed-counter),它很好。關於它的[論文](https://hal.inria.fr/file/index/docid/555588/filename/techreport.pdf)如果你想了解更多的細節。 – Oleg

回答

0

你可能知道這種設計模式,但它仍可能有所啓發:https://en.wikipedia.org/wiki/Observer_pattern

你可以簡單地讓所有的程序的實例的遵守所有的其他情況下的,那麼他們將所有的通知相互之間如果有任何變化(檢查該鏈接圖)。

至於一個Java庫,檢查這些了,看看其中有沒有讓您的生活更輕鬆:

+0

如果我的所有java進程都是主題,並且它們全都是觀察者,並且每當它發生增量或減量時(通常會發生這種情況),主題將會通知,隨着節點數量的增加,網絡將被阻塞由於過程始終在相互交談。 – azuri

0

聽起來像您需要Akka的分佈式數據庫中的PNCounter。它使用Gossip將計數器的狀態傳達給網絡。您還可以對讀寫一致性進行細緻的控制。因此,例如,您可以執行ReadMajority,其中「將從大多數副本中讀取和合並該值」。

順便說一下,PNCounter的工作原理與您描述的一樣,使用兩個分佈式計數器來保持增量和減量。