2014-05-01 66 views
2

我一直在使用Akka創建一個實時處理系統,該系統接收Twitter流(現在)並使用參與者以各種方式處理所述消息。我一直在閱讀有關,其他人已經用阿卡和這個特殊的博客帖子內置類似的架構吸引了我的眼球:Akka - 拉模式和持久郵箱

http://blog.goconspire.com/post/64901258135/akka-at-conspire-part-5-the-importance-of-pulling

在這裏,他們解釋推動工作的時候(即信息)演員VS出現的不同問題讓演員拉動工作。爲了解釋這篇文章,通過推送消息,沒有內建的方法可以知道哪個工作單元由哪個工作人員接收,也不能被可靠地跟蹤。另外,如果一名員工突然收到大量的消息,其中每條消息都很大,那麼您可能會不知所措,並且機器可能會耗盡內存。或者,如果處理是CPU密集型處理,則可能導致節點由於CPU抖動而無響應。此外,如果jvm崩潰,您將丟失演員在其郵箱中的所有消息。

拉動消息很大程度上消除了這些問題。由於特定的演員必須從協調員處獲得工作,協調員總是知道每個工作人員的工作單位;如果一名工人死亡,協調員知道要重新處理哪個工作單元。消息也不在工作人員的郵箱中(因爲它只是拉動一條消息並在處理另一條消息之前對其進行處理),因此如果參與者崩潰,這些郵箱的丟失不是問題。此外,由於每個員工在完成當前任務後只會請求更多工作,因此不會擔心員工接受或啓動的工作量多於可同時處理的工作量。顯然,這個解決方案也存在問題,例如協調器本身崩潰時會發生什麼,但現在讓我們假設這是一個非問題。更多關於此拉模式也可以在「讓它崩潰」的網站上找到該博客引用:

http://letitcrash.com/post/29044669086/balancing-workload-across-nodes-with-akka-2

這讓我想到了一個可能的替代這樣拉動模式是做推動,但與持久郵箱。我想到的一個例子是實現一個使用RabbitMQ的郵箱(Redis,MongoDB,Kafka等其他數據存儲也可以在這裏工作),然後讓每個路由器(所有這些都將用於相同目的)共享相同的消息隊列(或相同的DB /集合/等...取決於所使用的數據存儲)。換句話說,每個路由器在RabbitMQ中都有自己的隊列作爲郵箱。這樣,如果其中一個路由器出現故障,那些仍然處於運行狀態的用戶可以簡單地繼續從RabbitMQ中檢索,而不用擔心隊列會因爲不再使用典型的內存郵箱而溢出。另外,由於他們的郵箱沒有在內存中實現,如果一個routee崩潰了,它可能丟失的大部分信息只會是它在崩潰之前處理的單個郵件。如果整個路由器出現故障,那麼您可以期待RabbitMQ(或任何正在使用的數據存儲)處理負載增加,直到路由器能夠恢復並再次開始處理消息。

就持久郵箱而言,似乎早在2.0版本中,Akka傾向於更積極地支持這些工具,因爲他們已經實施了一些可以與MongoDB,ZooKeeper等協同工作的工具。但是,似乎無論出於何種原因他們自從最新版本(本文撰寫時的2.3.2)沒有提到它們之後就放棄了這個想法。您仍然可以通過實現MessageQueue接口來實現自己的郵箱,該接口爲您提供諸如enqueue(),dequeue()等方法......因此,使與RabbitMQ,MongoDB,Redis等協同工作的方法似乎不會成爲一個問題。

無論如何,只是想讓你的傢伙和gals的想法。這似乎是一個可行的替代做拉?

回答

1

這個問題在akka-user上也產生了一個相當長的信息。總之,最好是明確地管理工作項目,由(可執行的)參與者處理,可變數量的工作者參與者可以從中獲得新的工作,因爲這允許更好的資源管理和顯式控制處理的內容以及如何處理重試。