Design patterns 如何在社交网络中实现活动流
我正在开发自己的社交网络,但我还没有在web上找到实现用户行为流的示例。。。例如,如何筛选每个用户的操作?如何存储操作事件?对于动作流和动作本身,我可以使用哪种数据模型和对象模型?我认为关于通知系统如何在大型网站上工作的解释可以在的回答中的堆栈溢出问题中找到。他建议使用消息QUE,并指出了实现该功能的两个开源软件:Design patterns 如何在社交网络中实现活动流,design-patterns,architecture,stream,social-networking,Design Patterns,Architecture,Stream,Social Networking,我正在开发自己的社交网络,但我还没有在web上找到实现用户行为流的示例。。。例如,如何筛选每个用户的操作?如何存储操作事件?对于动作流和动作本身,我可以使用哪种数据模型和对象模型?我认为关于通知系统如何在大型网站上工作的解释可以在的回答中的堆栈溢出问题中找到。他建议使用消息QUE,并指出了实现该功能的两个开源软件: 另请参见问题摘要:对于大约100万活跃用户和1.5亿存储活动,我保持简单: 使用关系数据库存储唯一的活动(每个活动1条记录/“发生的事情”),使记录尽可能紧凑。结构,以便您可以
另请参见问题摘要:对于大约100万活跃用户和1.5亿存储活动,我保持简单:
- 使用关系数据库存储唯一的活动(每个活动1条记录/“发生的事情”),使记录尽可能紧凑。结构,以便您可以通过活动ID或使用一组具有时间限制的好友ID快速获取一批活动
- 每当创建活动记录时,将活动ID发布到Redis,并将ID添加到“活动流”列表中,以供每个作为朋友/订阅者的用户查看该活动李>
我使用一个普通的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)
id
subject_id
object_id
type
verb
data
time
feed_name
activity_id
activity\u type
告诉我活动的类型,source\u id
告诉我活动相关的记录。因此,如果活动类型的意思是“added favorite”,那么我知道source_id指的是favorite记录的id
parent\u id
/parent\u type
对我的应用程序很有用-它们告诉我活动与什么相关。如果喜欢某本书,那么parent\u id/parent\u type会告诉我该活动与具有给定主键(id)的书(type)相关
我在(user\u id,time)
上建立索引,并查询(…friends…)中的user\u id和time>某些截止点的活动。放弃id并选择不同的聚集索引可能是个好主意——我还没有尝试过
非常基本的东西,但它是有效的,它很简单,并且随着你需求的变化很容易使用。此外,如果您不使用MySQL,您可能可以在索引方面做得更好
为了更快地访问最近的活动,我一直在尝试。Redis将其所有数据存储在内存中,因此您不能将所有活动都放在内存中,但您可以为站点上大多数常见的屏幕存储足够的数据。每个用户最近的100个或类似的值。在混合使用Redis的情况下,其工作原理可能如下:
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)
id
subject_id
object_id
type
verb
data
time
feed_name
activity_id
- 创建您的MySQL活动记录
- 对于创建活动的用户的每个朋友,将ID推送到他们在Redis中的活动列表上李>
- 将每个列表修剪到最后X个项目
Redis速度很快,并且提供了一种跨一个连接传递命令的方法——因此将一个活动推送到1000个好友需要几毫秒的时间
有关我所说内容的更详细解释,请参阅Redis的Twitter示例:
2011年2月更新目前我有5000万个活动,我没有改变任何事情。做类似的事情的一个好处是,它使用紧凑的小行。我正计划做一些改变,这将涉及更多的活动和对这些活动的更多查询,我肯定会使用Redis来保持速度。我在其他领域使用Redis,它对某些类型的问题非常有效
2014年7月更新我们每月有约70万活跃用户。在过去几年中,我一直在使用Redis(如项目符号列表中所述)为每个用户存储最后1000个活动ID。系统中通常有大约1亿条活动记录,它们仍然存储在MySQL中,并且仍然是相同的布局。这些记录让我们可以用更少的Redis内存,它们可以作为活动数据的记录,如果用户需要回溯到更远的时间来查找某些内容,我们可以使用它们
这不是一个聪明或特别有趣的解决方案,但它为我提供了很好的服务。这是我使用mysql实现的活动流。
有三个类:Activity、ActivityFeed、Subscriber
Activity表示一个Activity条目,其表如下所示:
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)
id
subject_id
object_id
type
verb
data
time
feed_name
activity_id
Subject\u id
是执行动作的对象的id,object\u id
是接收动作的对象的id<代码>类型
和动词
描述动作本身(例如,如果用户向文章添加注释,它们将分别为“注释”和“创建”),数据包含附加数据以避免连接(例如,它可以包含主题名和姓氏、文章标题和url、注释正文等)
每个活动都属于一个或多个ActivityFeeds,它们由如下表关联:
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)
id
subject_id
object_id
type
verb
data
time
feed_name
activity_id
在我的应用程序中,每个用户有一个提要,每个项目(通常是博客文章)有一个提要,但它们可以是您想要的任何内容
订阅者通常是站点的用户,但也可以是对象模型中的任何对象(例如,一篇文章可以订阅其创建者的feed_操作)
每个订阅服务器都属于一个或多个ActivityFeeds,并且与上面一样,它们通过此类链接表进行关联:
feed_name
subscriber_id
reason
此处的原因
字段解释了订阅者订阅订阅源的原因。例如,如果用户将博客文章添加到书签中,则原因是“书签”。这有助于我以后的过滤操作