2012-06-06 142 views
10

我有一個擁有500k用戶的網站(運行在sql server 2008上)。我想現在包括用戶和他們的朋友的活動流。在SQL Server上測試一些東西之後,很明顯RDMS不是這種功能的好選擇。它很慢(即使我對數據進行了嚴重的非規範化處理)。所以在看過其他的NoSQL解決方案後,我發現我可以使用MongoDB。我將根據以下數據結構activitystrea.ms json specifications for activity stream 所以我的問題是:什麼是最好的MongoDB中的活動流模式設計(有很多用戶,你幾乎可以預測它會很沉重我寫了MongoDB - 它有很好的「寫入」性能,我想過3種類型的結構,請告訴我這是否合理,或者我應該使用其他模式模式。與此模式中的所有朋友/追隨者進行的活動:MongoDB數據庫模式設計

 

    { 
    _id:'activ123', 
    actor:{ 
      id:person1 
      }, 
    verb:'follow', 
    object:{ 
      objecttype:'person', 
      id:'person2' 
      }, 
    updatedon:Date(), 
    consumers:[ 
      person3, person4, person5, person6, ... so on 
      ] 

    } 

2 - 第二個設計:Collectio ñ名稱 - activity_stream_fanout

 

    { 
    _id:'activ_fanout_123', 
    personId:person3, 
    activities:[ 
    { 
    _id:'activ123', 
    actor:{ 
      id:person1 
      }, 
    verb:'follow', 
    object:{ 
      objecttype:'person', 
      id:'person2' 
      }, 
    updatedon:Date(), 
    } 

    ],[ 
    //activity feed 2 
    ] 

    } 


3 - 這種方法將存儲在一個集合的活動項目,而在另一個消費者。在活動中,你可能有這樣一個文件:

 

    { _id: "123", 
     actor: { person: "UserABC" }, 
     verb: "follow", 
     object: { person: "someone_else" }, 
     updatedOn: Date(...) 

    } 

,然後跟隨者,我有以下的「通知」文件:

 

    { activityId: "123", consumer: "someguy", updatedOn: Date(...) } 
    { activityId: "123", consumer: "otherguy", updatedOn: Date(...) } 
    { activityId: "123", consumer: "thirdguy", updatedOn: Date(...) } 

你的答案是極大的讚賞。

回答

20

我會用下面的結構去:

  1. 使用一個集合爲happend所有行動,Actions

  2. 使用另一個集合誰跟隨誰,Subscribers

  3. 使用第三個集合Newsfeed用於某個用戶的n ews飼料,物品從Actions集合中散發出來。

Newsfeed集合按工作進程異步處理新Actions進行填充。因此,新聞提要不會實時填充。我不同意吉爾特 - 詹的觀點,即時是重要的;我相信大多數用戶並不在意大多數(不是全部)應用程序(即時,我會選擇完全不同的架構)的延遲。

如果您有非常多的consumers,扇出可能需要一段時間,如此。另一方面,將消費者放入對象中也不會有很大的追隨者數量,並且會創建佔用大量索引空間的過大對象。

最重要的是,扇出的設計是非常更加靈活,並允許相關性打分,過濾等我最近剛寫了一篇博客文章news feed schema design with MongoDB,我解釋一些靈活性的更多細節。

說到靈活性,我會小心有關activitystrea.ms規範。作爲不同提供者之間互操作的規範似乎是有意義的,但只要您不打算從各種應用程序聚合活動,我不會將所有詳細信息存儲在數據庫中。

+0

很棒的建議。實時我並不是指亞秒,我只是意味着實時速度足夠快,以至於從OP中場景2中的多個用戶活動的「批處理」中獲益不大。然後我再次對「扇出」這個詞不太熟悉(OP的第二個選項似乎指的是,你也提到),所以我可能完全不瞭解2的意圖。 ..順便說一句:要閱讀該博客帖子,總是很高興看到關於MongoDB架構設計的架構設計 –

+0

很棒的閱讀,我在您的博客上留下了一條評論,提供您可能想要閱讀的相關問題。謝謝 –

+1

夥計們,非常感謝您的建議。我將@mnemosyn帖子標記爲答案,因爲它確實有道理。我會讀你的博客,看看我的需求。再次感謝日誌中的所有建議。 –

1

我相信你應該看看你的訪問模式:有什麼疑問,你可能對這個數據進行最等

對我來說,必須是最快的用例是能夠推每個'活動消費者'的'牆'的某些活動(以fb爲單位),並在活動進入時立即進行。

從這個觀點來看(我沒有多少考慮過)因爲2.在處理它們之前似乎爲特定用戶批量處理活動?因此,如果不能立即需要更新。而且,對於這個用例,我沒有看到3的優勢。

1上的一些增強?問問自己,是否真的需要爲每個活動定義一系列消費者的靈活性。真的需要在這個細粒度的尺度上指定這個嗎?而不是提到'演員'的'朋友'就足夠了? (從長遠來看,這會有很大的空間,因爲消費者陣列是每個活動的整個消息的大部分,當消費者的數量通常在幾百(?)。範圍內時,取決於您希望如何實現這些活動流的實時通知,可能需要查看Pusher - http://pusher.com/和類似的解決方案。

心連心