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

时间:2009-09-18 11:28:46

标签: design-patterns architecture stream social-networking

我正在开发自己的社交网络,我还没有在网上找到用户操作流的实现示例...例如,如何过滤每个用户的操作?如何存储动作事件?我可以将哪种数据模型和对象模型用于操作流和自己的操作?

7 个答案:

答案 0 :(得分:227)

摘要:对于大约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内存,它们可以作为活动数据的记录,如果用户需要及时回溯以寻找内容,我们就会使用它们。

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

答案 1 :(得分:21)

这是我使用mysql实现的活动流。 有三个类:Activity,ActivityFeed,Subscriber。

Activity表示一个活动条目,其表格如下所示:

id
subject_id
object_id
type
verb
data
time

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

每个Activity都属于一个或多个ActivityFeeds,它们通过如下表格相关:

feed_name
activity_id

在我的应用程序中,我为每个用户提供了一个提要,每个项目有一个提要(通常是博客文章),但它们可以是您想要的任何内容。

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

每个订阅者都属于一个或多个ActivityFeeds,并且,如上所述,它们通过此类链接表相关:

feed_name
subscriber_id
reason

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

要检索订阅者的活动,我会对这三个表进行简单连接。加入很快,因为我选择的活动很少,这要归功于现在看起来像WHERE的条件 - time > some hours。由于Activity表中的数据字段,我避免了其他连接。

reason字段的进一步说明。例如,如果我想要向用户过滤电子邮件通知的操作,并且用户将博客文章加入书签(因此他订阅了带有'bookmark'原因的帖子,)我不希望用户收到关于该项目的操作的电子邮件通知,如果他评论帖子(因此它订阅了帖子提要的原因'评论')我希望当其他用户在同一帖子上添加评论时会通知他。 reason字段帮助我进行歧视(我通过ActivityFilter类实现)以及用户的通知首选项。

答案 2 :(得分:14)

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

http://activitystrea.ms/

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

例如:Max发布了一条指向Adam墙的链接。

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

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

答案 3 :(得分:12)

我认为关于通知系统如何在大型网站上运行的解释可以在how does social networking websites compute friends updates?的答案中的堆栈溢出问题Jeremy Wall中找到。他建议使用 Message Qeue ,他指出了两个实现它的开源软件:

  1. RabbitMQ
  2. Apache QPid
  3. 另见问题What’s the best manner of implementing a social activity stream?

答案 4 :(得分: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

答案 5 :(得分:0)

您可以查看通过API使用的第三方服务,而不是自己滚动。我创建了一个名为Collabinate(http://www.collabinate.com),它具有图形数据库后端和一些相当复杂的算法,以高度并发,高性能的方式处理大量数据。虽然它没有Facebook或Twitter所具有的广泛功能,但它足以满足您需要在应用程序中构建活动流,社交订阅源或微博功能的大多数用例。

答案 6 :(得分:0)

Dearlink 社交网络平台的一个最佳实践是在每个帖子中都包含一个视觉效果。即使您的帖子是文本帖子,也可以添加图形或照片以增加参与度。视频也是很好的补充。您还可以通过以感叹号结束帖子来提高参与度。正面情绪对 Dearlink 帖子效果很好。同样,向您的听众提问以吸引更多读者参与,例如评论。话题标签 在 Dearlink 社交网络平台上使用话题标签是将您的帖子与更大范围的讨论联系起来的好方法。如果您明智地选择主题标签,它也可能会得到更多关注。也就是说,Dearlink 上的主题标签并不大,因此将自己限制为一两个。您可以创建自己的品牌相关主题标签并使用它们。例如,带有自己标签的营销活动非常适合参与。 https://www.dearlink.live https://m.dearlink.live