2015-05-29 80 views
15

目前我使用socket.io沒有RethinkDB這樣的:socket.io VS RethinkDB changefeed

客戶發出事件socket.io,接收事件,發出各種其他客戶端,並保存到數據庫爲了持久。新的客戶端連接將從數據庫獲取現有數據,然後通過socket.io監聽新事件。

如何切換到RethinkDB和更換飼料在這裏幫助我?

我看到與RethinkDB一樣的工作方式是客戶端可以執行POST(插入到RethinkDB中)而不是發送到socket.io,然後socket.io正在觀看RethinkDB換件並向所有客戶端發送時它接收新的數據。

這種方法如何使用RethinkDB和更換飼料比我目前的方法更好?對我來說,他們都覺得他們完成了同樣的事情,但我在RethinkDB方法中看不到任何明顯的優勢,並且因爲我會去db而不是直接從服務器上的socket.io發出它,它會肯定會慢一點。

回答

34

首先,讓我們來澄清socket.io和RethinkDB換刀之間的關係。 Socket.io用於客戶端(瀏覽器)和服務器(Node.js)之間的實時通信。 RethinkDB更新是服務器(Node.js)監聽數據庫更改的方式。客戶端無法直接與RethinkDB通信。

實時應用程序的一個非常典型的架構是讓RethinkDB更改訂閱訂閱數據庫中的更改,然後使用socket.io將這些更改傳遞給客戶端。客戶端通常也會發送可寫入數據庫的消息,具體取決於您的應用程序邏輯。

是的,您可以通過socket.io發送所有消息,然後將所有消息傳遞給所有客戶端,然後將這些消息寫入數據庫以實現持久性。這也是事實,這是更快的,但這種方法有許多缺點。

1.數據庫真理

被發現的最簡單的問題,單一來源如下:

  • 如果您的應用程序不能寫東西到 數據庫會發生什麼?
  • 如果試圖插入數據庫的數據無效或重複,會發生什麼情況?你編寫應用程序邏輯來處理這個問題嗎?
  • 如果Node.js服務器在發出 寫查詢之前發生故障,會發生什麼情況?

這些只是一些簡單的例子,在這些例子中,由於您的體系結構,您將丟失或失去同步數據。只是爲了重申這一點,你將失去數據,因爲你的真相的主要來源是內存。您的Node.js應用程序中的數據與您的數據庫之間也可能有差異。

問題是,數據庫應該始終是您的唯一真理來源,並且您應該只在數據寫入磁盤時才確認數據。我不確定每晚有人能否在晚上睡覺。

2。高級查詢

如果您只是通過socket.io將所有客戶端的所有新消息傳遞給所有客戶端,那麼您現在必須在客戶端中擁有一些非常複雜的邏輯,以便過濾出所有實際上非常重要的數據。考慮到你通過網絡傳遞大量無用的數據,客戶端實際上不會使用它們。

另一種方法是編寫一個訂閱某些渠道(或類似的東西)的發佈/訂閱系統,以過濾出對客戶來說非常重要的數據。

RethinkDB通過提供它自己的查詢語言來解決此問題,您可以附加到更改供稿。例如,如果客戶需要我的users表中年齡在20至30歲之間的所有用戶,他們居住在加利福尼亞州,距舊金山10英里,並且在過去6個月內購買過書籍,可以使用ReQL(RethinkDB的查詢語言)表示,並且可以爲該查詢設置更換進料,以便僅當相關的更改時纔會通知客戶端。這對於Socket.io和Node.js來說很難做到。

3.擴展

即RethinkDB解決的是,它是一個更靈活的解決方案,只是在內存中存儲的一切最後一個問題(通過Socket.io和Node.js的)。由於RethinkDB是從頭開始構建的,因此您可以擁有包含分片和副本的20多個RethinkDB節點的集羣。您編寫的每個RethinkDB查詢都是默認分發的。現在,您可以擁有20多個無狀態的Node.js節點,並且都在監聽更新。因爲數據庫是真相的中心來源,所以這不是問題。

另一種方法是將自己限制在一臺服務器上,擁有一些其他的pub/sub系統(例如建立在像Reddis之類的東西上),只有一個數據庫可以輪詢......可能有更多的例子,但你可以看到我要去哪裏。


我很想聽聽,如果這回答了你的問題,如果我得到你的出發到來。開始時如何構建應用程序有點困難,但它對於大多數實時體系結構來說確實是一個優雅的解決方案。

+1

非常有幫助:) 對於高級查詢,請考慮多房間聊天應用程序,並將消息發送給房間中的客戶。我不能只聆聽1份換貨(所有聊天)並只發送給那個房間的客戶嗎? ('room')()函數()函數(函數(err,row)){r.table('chat')。 + row.new_val.id,row.new_val); // 1 room }); });' ...所以高級查詢與此特定用例無關,因爲它們將涉及觀察一個每個房間更換飼料,這是相當浪費的。我們也不需要在這個客戶端有'非常複雜的邏輯'。 – user3096484

+0

「,所以高級查詢與此特定用例無關,因爲它們涉及每個房間觀看一次換貨,這相當浪費。」換刀實際上很便宜,所以最好設置更具體的不同換刀,而不是設置一個換刀,以便以後處理應用邏輯。 –

+2

「我不能只聆聽1次換貨(所有聊天)並只發送給那個房間的客戶嗎?」是的,你也可以這樣做。如果你只想要一個聊天消息的話,那很好。話雖如此,我會在需要時立即轉而編寫ReQL查詢+更換,而不是將其添加到應用程序層。同樣,更換進度查詢相當便宜,不用擔心要慷慨地開放它們。 –