2010-05-29 124 views
14

我開始一個項目,我認爲它將特別適合MongoDB,因爲它提供的速度和可擴展性。MongoDB架構設計 - 實時聊天

我目前感興趣的模塊是實時聊天。如果我是做到這一點在傳統的RDBMS我拆分它伸到:

  • 信道(信道擁有衆多用戶)
  • 用戶(A用戶具有一個信道,但許多消息)
  • 消息(一條消息有一個用戶)

這個用例的目的,我想假設通常會有5個通道一次處於活動狀態,每個通道每秒處理最多5條消息。

需要快速

具體查詢:

  • 獲取新郵件
  • 發佈消息通道
  • 驗證(基於書籤,時間戳也許,或者遞增計數器?)用戶可以在頻道中發帖

請記住,MongoDB的文檔限制是4MB,您將如何設計架構?你的樣子是什麼?有什麼值得我留意的嗎?

回答

3

我用我的Redis,NGINX &我的聊天項目的PHP-FPM。不是超級優雅,但它有訣竅。這個難題有幾個部分。

  1. 有一個非常簡單的PHP腳本,它接收客戶端命令並將它們放入一個大型LIST中。它還檢查所有房間LIST和用戶私人LIST以查看是否有消息必須傳遞。這是通過用jQuery &編寫的客戶端進行輪詢,每隔幾秒完成一次。

  2. 有一個命令行PHP腳本,在無限循環中運行服務器端,每秒20次,它檢查此列表並處理這些命令。該腳本處理腳本內存中的哪些空間和權限,此信息不存儲在Redis中。

  3. 對於每個房間,Redis都有一個列表&作爲專用隊列操作的每個用戶的列表。它也有用戶所在的每個房間的多個計數器。如果用戶計數器小於房間中的總消息,則它獲得差異並將其發送給用戶。

我還沒有能夠強調測試這個解決方案,但至少從我的基本基準測試來看,它可能每秒處理數千條消息。還有機會將其移植到Node.js之類的內容中以提高性能。 Redis也正在成熟,並且有一些有趣的功能,如發佈/訂閱命令,這可能是有趣的,可能會刪除服務器端的輪詢。我研究了基於Comet的解決方案,但其中很多都很複雜,記錄不完整,或者需要我學習全新的語言(例如Jetty-> Java,APE-> C)等等。通過代理有時可能是Comet的一個問題。所以這就是爲什麼我堅持投票。

我想你可以用MongoDB做類似的事情。每個房間收集一個集合,每個用戶集合&然後是一個維護計數器的集合。你仍然需要編寫一個後端守護進程或腳本來處理這些消息傳遞的位置。你也可以使用MongoDB的「受限集合」,這使得排序爲&的文檔也可以自動清除舊郵件,但是在維護正確的計數器方面可能會很複雜。

3

爲什麼在郵件系統中使用mongo?無論有多快的靜態存儲(並且mongo速度非常快),無論是mongo還是db,爲了模擬消息隊列,您將不得不使用某種輪詢,這種輪詢不是很有效。當然,你沒有做任何非常激烈的事情,但爲什麼不只是使用正確的工具來完成正確的工作呢?使用消息系統,如RabbitActiveMQ

如果你必須使用mongo(也許你只是想玩它,這個項目是一個很好的機會嗎?)我想你會有一個用戶集合(其中每個用戶對象都有一個列表用戶偵聽的隊列)。對於消息,您可以爲每個隊列設置一個集合,但是您必須對您感興趣的每個隊列進行輪詢以獲取消息。更好的辦法是將一個集合作爲一個隊列,因爲mongo很容易在單個集合中執行「in」查詢,因此可以很容易地執行諸如「在隊列中獲得所有比X更新的消息在列表[a,b,c]中的.name。「。

您也可以考慮將您的收藏集設置爲mongo加蓋集合,這意味着您在設置集合時告訴mongo您的收藏集只應該包含X個字節或X個項目。添加額外的項目具有先進先出行爲,這對於消息隊列來說非常理想。但是,這又不是一個真正的消息系統。

+1

我不會建議那裏的MQ解決方案真的比那些NoSQL解決方案好得多。許多MQ技術看起來很複雜和過度設計,再加上性能並不總是那麼好,穩定性和可移植性也可能被犧牲掉。請參閱:http://bhavin.directi.com/rabbitmq-vs-apache-activemq-vs-apache-qpid/ – Klinky 2010-05-30 00:08:06

+1

那裏有不錯的MQ解決方案,我只是發現它們沒有太多功能,ZeroMQ和Kestrel都適合他們的目的。另一方面,ActiveMQ是可怕的。 – Michael 2010-05-30 03:48:21

+0

@Klinky我敢打賭,幾乎任何特定的MQ解決方案(尤其是ActiveMQ)都會比消息傳遞(EDA)問題更好地處理,而不是基於非特定類型的NoSQL的定製解決方案(您是指面向文檔的數據庫或密鑰因爲MQ解決方案是針對這個問題而設計的,FTN ActiveMQ使用它自己優化的高性能數據存儲來實現隊列持久性。 – 2010-06-03 07:09:22

1

1)ape-project.org

2)http://code.google.com/p/redis/

3)你通過這一切之後 - 你可以啞數據到MongoDB的日誌記錄和存儲的數據一致(用戶,通道) well