12

我有一个拥有 50 万用户的网站(在 sql server 2008 上运行)。我现在想包括用户及其朋友的活动流。在 SQL Server 上测试了一些东西之后,很明显 RDMS 不是这种功能的好选择。它很慢(即使我对数据进行了严重的非规范化)。因此,在查看了其他 NoSQL 解决方案之后,我认为我可以使用 MongoDB 来解决这个问题。我将遵循基于activitystrea.ms json 规范的活动流数据结构 所以我的问题是:MongoDB 中活动流的最佳模式设计是什么(有这么多用户,您几乎可以预测它的写入量会很大,因此我选择了 MongoDB——它具有出色的“写入”性能。我考虑了 3 种类型的结构,请告诉我这是否有意义或者我应该使用其他模式模式。

1 - 以这种模式将每个活动与所有朋友/关注者一起存储:

 

    {
     _id:'activ123',
     演员:{
            编号:person1
            },
    动词:'跟随',
    目的:{
            对象类型:'人',
            id:'person2'
            },
    更新:日期(),
    消费者:[
            person3, person4, person5, person6, ... 等等
            ]

    }

2 - 第二个设计:集合名称-activity_stream_fanout

    {
    _id:'activ_fanout_123',
    人名:person3,
    活动:[
    {
     _id:'activ123',
     演员:{
            编号:person1
            },
    动词:'跟随',
    目的:{
            对象类型:'人',
            id:'person2'
            },
    更新:日期(),
    }

    ],[
    //活动提要2
    ]

    }


3 - 这种方法是将活动项目存储在一个集合中,将消费者存储在另一个集合中。在活动中,您可能有这样的文档:

    { _id:“123”,
      演员:{人:“UserABC”},
      动词:“跟随”,
      对象:{人:“someone_else”},
      更新日期:日期(...)

    }

然后,对于追随者,我将拥有以下“通知”文件:

    { activityId:“123”,消费者:“someguy”,updatedOn:日期(...)}
    {activityId:“123”,消费者:“otherguy”,updatedOn:日期(...)}
    {activityId:“123”,消费者:“thirdguy”,updatedOn:日期(...)}

非常感谢您的回答。

4

2 回答 2

20

我会采用以下结构:

  1. 对发生的所有操作使用一个集合,Actions

  2. 为谁关注谁使用另一个集合,Subscribers

  3. 使用第三个集合,Newsfeed对于某个用户的新闻提要,从Actions集合中扇出项目。

Newsfeed集合将由异步处理 new 的工作进程填充Actions。因此,新闻提要不会实时填充。我不同意 Geert-Jan 的观点,即实时性很重要。我相信大多数用户都不关心大多数(不是全部)应用程序中的一分钟延迟(对于实时,我会选择完全不同的架构)。

如果您有大量的consumers,则扇出可能需要一段时间,确实如此。另一方面,将消费者直接放入对象中也不适用于非常大的追随者数量,并且会创建占用大量索引空间的过大对象。

然而,最重要的是,扇出设计更加灵活,并且允许相关性评分、过滤等。我最近刚刚写了一篇关于使用 MongoDB 进行新闻提要模式设计的博客文章,其中我更详细地解释了其中的一些灵活性。

说到灵活性,我会小心那个 activitystrea.ms 规范。作为不同提供商之间互操作的规范似乎是有意义的,但只要您不打算聚合来自各种应用程序的活动,我就不会将所有详细信息存储在我的数据库中。

于 2012-06-07T10:52:03.490 回答
1

我相信你应该看看你的访问模式:你可能对这些数据执行最多的查询,等等。

对我来说,需要最快的用例是能够将某个活动推送到每个“活动消费者”的“墙上”(以 fb 而言),并在活动进入时立即执行。

从这个角度来看(我没有考虑太多)我会选择 1,因为 2. 似乎在处理某个用户之前为某个用户批处理活动?因此,如果失败,则“立即”需要更新。此外,对于这个用例,我没有看到 3. 超过 1 的优势。

对 1 的一些增强?问问自己,您是否真的需要为每个活动定义一组消费者的灵活性。真的有必要在这个细粒度的范围内指定这个吗?相反,提及“演员”的“朋友”还不够吗?(从长远来看,这将有很多空间,因为当消费者通常在数百个(?)范围内时,我看到消费者数组是每个活动的整个消息的大部分。

在一些相关的注释上:根据您可能希望如何为这些活动流实现实时通知,可能值得查看 Pusher - http://pusher.com/和类似的解决方案。

hth

于 2012-06-06T22:14:33.500 回答