2016-01-22 21 views
0

我在嘗試解決規模問題時遇到了一個有趣的困境。與Redis在一起的新聞FeedStore Stratagy

目前我們有一個社交平臺,有一個非常典型的飼料。我們正在使用一個圖形數據庫,並且每次用戶請求一個數據源時,我們都會觸發該數據庫。雖然現在情況良好,但隨着我們用戶羣的增長,它會陷入停頓。進入Redis。

目前我們店的東西這樣的評論,喜歡和這樣在JSON編碼字符串個別Redis的鑰匙郵寄ID和更新他們的時候有更新,添加或刪除。然後在代碼中,我們遍歷帖子的數據庫結果並從Redis存儲區中提取數據。這導致多次調用Redis來構造每個帖子,這比每次觸摸DB要好得多。面臨的挑戰是跟上不斷變化的數據,例如評論員/ liker的頭像,屏幕名稱,已關閉的帳戶,新的喜歡,與每個帖子相關的新評論等。

我試圖決定一個策略來處理這個最有效的方法。由於我們將在每臺機器上安裝大約12吉米的RAM,因此Redis只會使我們走得如此之遠。

討論中的一個概念是爲每個存儲新帖子ID的用戶使用一個信標。因此,當用戶分享一些新內容時,他們所有連接好友的信標都會獲取帖子ID,以便當用戶登錄其供稿時被視爲需要更新的「骯髒」,然後將供稿按ID存儲在按時間戳排序的Redis集中。要檢索Feed數據,我們可以通過ID執行單個查詢,而不是完整的遍歷,速度提高數百倍。這仍然無法解決互動用戶的帳戶信息,他們的喜好以及不斷變化的評論問題,但解決了部分構建Feed問題的問題。

另一個想法是用戶的全部飼料原料(JSON編碼)存儲在MySQL記錄,當用戶請求和信標顯示了一個骯髒的飼料更新它的飛行。否則,它只是一個單一的選擇和JSON解碼來建立飼料。再次,動態組件是混雜。

有沒有人成功地處理過這個挑戰,或者有戰略的工作知識來解決這個問題。

+0

對於你的問題沒有一個完整的答案,但是如果你已經使用過JSON數據,你有沒有看過[MongoDB](https://www.mongodb.org)?我已經使用了它多年,它的副本集和分片非常好地擴展。 Redis仍然是一個更快的單鍵查找時間,但mongo提供了靈活性來存儲整個JSON數據集 - 看起來像比將JSON數據存儲在MySQL記錄中更好的解決方案:) – solocommand

+0

我也喜歡使用如上所述的MongoDB,如果您需要進一步擴展,Riak也可能是另一個使用選項,因爲它具有良好的外出鏈接。 – Daniel

回答

1

您可能需要使用MongoDB的作爲@solocommand形容,但你可能要停止的期望,你的「更新」的需求數據。而是將用戶更改推送到「寫入」隊列中,然後根據需要更新數據庫。然後,您可以從數據庫(mongodb)加載並根據需要使用它,或者更新其他redis記錄。

移動到一個消息系統亞馬遜SQS,IronMQ,或RabbitMQ的,可以幫助你更好的擴展。你也可以使用redis隊列作爲基本的消息總線。

1

目前我們店的東西這樣的評論,喜歡和這樣在JSON編碼字符串個別Redis的鑰匙郵寄ID

使用更有效的串,就像igbinary或msgpack。我建議igbinary(檢查http://kiss-web.blogspot.com/

然後在代碼中,我們可以循環通過職位DB結果,並從Redis的存儲中的數據拉。

請務必使用流水線的最高性能。

這會導致多次調用Redis構造每個帖子,這比每次觸摸DB要好得多。

不要低估DB主鍵的強大功能。嘗試做相同的(不加入,但通過按鍵選擇)與DB:

SELECT * FROM comments WHERE id IN (1,2,3,4,5,6): 

單Redis的調用是比單DB調用快,但相比一個SQL查詢做大量的Redis的電話(甚至流水線)的在主鍵上 - 不是很多。特別是當你給你的DB足夠的內存緩衝區。

您可以通過在Redis中「緩存」DB數據來使用DB和Redis。您可以這樣做:

  1. 每次更新數據時,都會在數據庫中進行更新並從Redis中刪除。
  2. 提取數據時,首先嚐試從Redis獲取它們。如果在Redis中找不到數據,則可以在數據庫中搜索它們並插入到Redis中,以供將來使用,並有一定的過期時間。

這樣你就可以在redis中存儲唯一有用的數據。未使用(舊)數據將只保留在數據庫中。

+0

感謝您的提示。通過流水線和mget調用,我們已經轉向了一種非常類似的方法,以更好地處理更多動態信息的性質。 – SeaFuzz