如何在社交网络中实施活动流


140

我正在开发自己的社交网络,但在Web上的实现示例中却找不到用户操作流…例如,如何为每个用户过滤操作?如何存储动作事件?可以将哪些数据模型和对象模型用于操作流及其自身的操作?


9
祝你好运,这是我们大家都想知道的永无止境的问题,facebook如何实现这一目标,答案非常复杂,我们可能永远不知道最有效的方法。如果找到了一种好的方法,请将其发布在此处供其他人查看,顺便说一句,关于这种方法的讨论已经很多次了,所以只需搜索,您就会发现一些提示
JasonDavis,2009年

1
Stream Framework是使用最广泛的解决方案:github.com/tschellenbach/Stream-Framework另请参阅以下软件包清单:djangopackages.com/grids/g/activities
Thierry

1
在个性化方面,它基于分析和机器学习,另请参阅getstream.io/personalization
Thierry

Answers:


241

摘要:对于大约100万活跃用户和1.5亿存储的活动,我将其简单化:

  • 使用关系数据库存储唯一活动(每个活动1条记录/“发生的事情”)。使记录尽可能紧凑。进行结构设计,以便您可以按活动ID或使用具有时间限制的一组朋友ID来快速抓取一批活动。
  • 每当创建活动记录时,就将活动ID发布到Redis,并将ID添加到每个应该看到该活动的朋友/订户的用户的“活动流”列表中。

查询Redis以获取任何用户的活动流,然后根据需要从数据库中获取相关数据。如果用户需要回到过去浏览时间(如果您甚至提供此功能),则可以按时间查询数据库。


我使用一个普通的旧MySQL表来处理大约1500万个活动。

看起来像这样:

id             
user_id       (int)
activity_type (tinyint)
source_id     (int)  
parent_id     (int)
parent_type   (tinyint)
time          (datetime but a smaller type like int would be better) 

activity_type告诉我活动的类型,source_id告诉我活动相关的记录。因此,如果活动类型表示“已添加收藏夹”,那么我知道source_id引用收藏夹记录的ID。

parent_id/ parent_type是我的应用程序非常有用-他们告诉我是什么活动有关。如果喜欢一本书,则parent_id / parent_type会告诉我该活动与具有给定主键(id)的书籍(类型)相关

我索引(user_id, time)并查询是的活动user_id IN (...friends...) AND time > some-cutoff-point。放弃id并选择其他聚簇索引可能是一个好主意-我还没有尝试过。

很基本的东西,但是它很有效,很简单,并且随着需求的变化也很容易使用。另外,如果您不使用MySQL,则可以在索引方面做得更好。


为了更快地访问最新活动,我一直在尝试Redis。Redis将所有数据存储在内存中,因此您无法将所有活动都存储在其中,但是您可以为站点上大多数常用的屏幕存储足够的空间。每个用户的最近100个或类似内容。混合使用Redis时,它可能像这样工作:

  • 创建您的MySQL活动记录
  • 对于创建活动的用户的每个朋友,将ID推送到他们在Redis中的活动列表中。
  • 将每个列表修剪到最后X个项目

Redis速度很快,并且提供了一种通过一个连接流水线命令的方法-因此将活动推送给1000个朋友需要花费毫秒的时间。

有关我在说什么的更详细说明,请参阅Redis的Twitter示例:http : //redis.io/topics/twitter-clone

2011年2月更新我目前有5000万活跃活动,但我没有做任何更改。做类似的事情的一件好事是它使用紧凑的小行。我正在计划进行一些更改,这些更改将涉及更多的活动和对这些活动的更多查询,并且我肯定会使用Redis来保持速度。我在其他领域使用Redis,它对于某些类型的问题确实非常有效。

2014年7月更新我们每月有大约70万活跃用户。在过去的几年中,我一直在使用Redis(如项目符号列表中所述)存储每个用户的最后1000个活动ID。系统中通常有大约1亿个活动记录,它们仍然存储在MySQL中,并且布局相同。这些记录使我们可以用更少的Redis内存来逃脱它们,它们充当活动数据的记录,如果用户需要及时返回页面以查找某些内容,则可以使用它们。

这不是一个聪明或特别有趣的解决方案,但它对我很有帮助。


2
+1为Redis。v2使用虚拟内存,因此应该有可能完全依赖Redis
stagas 2010年

16
如果活动有多个来源(添加,评论,喜欢等),您如何将这个表与实际活动结合在一起?您是否使用多个左联接(每个联接用于一个活动表)?
2011年

1
@casey回响@JohnS的问题-您如何JOIN在各种activity_type表上执行?这些会增加性能吗?
罗伯·索伯斯

1
有谁能回答有关“ JOIN”的JohnS问题。任何人都可以在可能解释链接的地方发布链接吗?我必须做类似的事情,这对我会非常有帮助。
Waseem

3
没有加入。每个唯一查询一个, activity_type以获取您需要的其他数据。
2015年

21

这是我使用mysql实现的活动流。共有三类:活动,ActivityFeed,订户。

活动代表活动条目,其表如下所示:

id
subject_id
object_id
type
verb
data
time

Subject_id是执行操作object_id的对象的ID,即接收操作的对象的ID。typeverb描述操作本身(例如,如果用户在文章中添加评论,则分别为“评论”和“创建”),数据包含其他数据以避免连接(例如,可以包含主题名称)和姓氏,文章标题和网址,评论正文等)。

每个活动都属于一个或多个ActivityFeed,它们之间的关系如下表所示:

feed_name
activity_id

在我的应用程序中,我为每个用户提供一个提要,为每个项目提供一个提要(通常是博客文章),但是它们可以随心所欲。

订阅者通常是您网站的用户,但也可以是您对象模型中的任何对象(例如,文章可以订阅其创建者的feed_action)。

每个订户都属于一个或多个ActivityFeed,并且如上所述,它们由这种链接表关联:

feed_name
subscriber_id
reason

reason此处的字段说明了订阅者为何订阅源。例如,如果用户为博客帖子添加了书签,则原因是“书签”。这有助于我稍后过滤用于通知用户的操作。

为了检索订户的活动,我对三个表进行了简单的连接。加入的速度很快,因为由于现在的WHERE状况- 我很少选择活动time > some hours。由于活动表中的数据字段,我避免了其他联接。

reason现场进一步解释。例如,如果我要过滤发送给用户的电子邮件通知的操作,并且该用户将该博客帖子添加为书签(因此他以“书签”为原因订阅该帖子供稿),那么我不希望该用户收到电子邮件通知有关该项目的操作,而如果他评论该帖子(因此它以“评论”的原因订阅了该帖子供稿),我希望他在其他用户向同一帖子添加评论时得到通知。原因字段可帮助我进行这种区分(我通过ActivityFilter类实现了它)以及用户的通知首选项。


Nicolo martini我想添加关于活动的回复评论并在活动下方显示,您的结构怎么可能?我应该添加另一个表还是使用相同的表(如果相同),那么您有什么建议?
Basit

该实施的效果如何?在大桌子上有测试吗?
Joshua F. Rountree 2012年

16

一群知名人士正在开发一种当前的活动流格式。

http://activitystrea.ms/

基本上,每个活动都有一个演员(执行该活动的演员),一个动词(该活动的动作),一个对象(演员在其上执行活动的对象)和一个目标。

例如:麦克斯(Max)发布了到亚当(Adam)的墙的链接。

在撰写本文时,他们的JSON规范已达到1.0版,其中显示了您可以应用的活动模式。

它们的格式已被BBC,Gnip,Google Buzz Gowalla,IBM,MySpace,Opera,Socialcast,Superfeedr,TypePad,Windows Live,YIID等采用。


嗨@sntran我知道这是几年前的帖子,但是我对活动流有更多疑问。有什么办法可以帮助您?
hiswendy

当然。你的问题是什么?
子TRAN-阮

我的问题实际上发布在这里!链接。我认为我对活动流有基本的了解,但是我真的不太确定如何实现它(即我应该使用angular还是node.js?)然后,从那里开始,我实际上如何使用传入API JSON?这些都是基本问题,但我在网上找不到任何答案。如果您能提供帮助,我将不胜感激。谢谢!
hiswendy


1

您绝对需要高性能和分布式消息队列。但这还不止于此,您必须决定将什么存储为持久性数据以及将什么存储为瞬态数据等。

无论如何,如果您追求高性能和可扩展的系统,对我的朋友来说,这确实是一项艰巨的任务。但是,当然,一些慷慨的工程师已经分享了他们的经验。LinkedIn最近将其消息队列系统Kafka开源。在此之前,Facebook已经向开源社区提供了Scribe。Kafka是用Scala编写的,起初它需要一些时间才能运行,但是我已经测试了几个虚拟服务器。真的很快。

http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/

http://incubator.apache.org/kafka/index.html


0

您可以使用API​​来使用第三方服务,而不必自己动手做。我创建了一个名为Collabinate(http://www.collabinate.com)的网站,该网站具有图形数据库后端和一些相当复杂的算法,可以以高并发,高性能的方式处理大量数据。尽管它没有Facebook或Twitter那样的功能广度,但对于大多数需要在应用程序中构建活动流,社交源或微博功能的用例而言,它已经足够了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.