我很想听听你对实现社交活动流的最佳方式(Facebook就是最著名的例子)的看法。涉及的问题/挑战有:
不同类型的活动(张贴,评论..)
不同类型的对象(帖子,评论,照片..)
1-n个不同角色的用户(“用户x回复了用户y对用户Z帖子的评论”)
同一活动项的不同视图(“您评论了..”vs。“你的朋友x评论”vs。"用户x评论说.."3个“评论”活动的表示)
. .还有更多,特别是如果你把它提高到一个高度复杂的水平,比如,把几个活动项目合并成一个(“用户x, y和z评论了那张照片”)。
任何关于模式、论文等关于最灵活、有效和强大的方法来实现这样一个系统、数据模型等的想法或建议都将受到欢迎。
尽管大多数问题与平台无关,但我最终有可能在Ruby on Rails上实现这样一个系统
我昨天开始执行一个这样的系统,这就是我要做的…
我创建了一个带有属性Id、ActorId、TypeId、Date、ObjectId和附加细节键/值对哈希表的StreamEvent类。这在数据库中由一个StreamEvent表(Id, actid, TypeId, Date, ObjectId)和一个StreamEventDetails表(StreamEventId, DetailKey, DetailValue)表示。
ActorId、TypeId和ObjectId允许捕获一个Subject-Verb-Object事件(以及稍后查询)。每个操作都可能导致创建多个StreamEvent实例。
然后,我为StreamEvent的每种类型的事件创建了一个子类,例如LoginEvent, PictureCommentEvent。这些子类中的每一个都有更多上下文特定的属性,如PictureId, ThumbNail, CommenText等(事件所需的任何属性),这些属性实际上存储为hashtable/StreamEventDetail表中的键/值对。
当从数据库中提取这些事件时,我使用一个工厂方法(基于TypeId)来创建正确的StreamEvent类。
StreamEvent的每个子类都有一个Render(context As StreamContext)方法,该方法根据传递的StreamContext类将事件输出到屏幕。StreamContext类允许基于视图的上下文设置选项。以Facebook为例,主页上的信息流会列出参与每个行动的每个人的全名(以及他们个人资料的链接),而查看朋友的信息流,你只能看到他们的名字(但其他参与者的全名)。
我还没有实现一个聚合提要(Facebook家),但我想我会创建一个AggregateFeed表,其中有字段UserId, StreamEventId,这是基于某种“嗯,你可能会发现这个有趣的”算法。
任何意见都将非常感激。
如果您愿意使用单独的软件,我建议使用Graphity服务器,它完全解决了活动流的问题(构建在neo4j图形数据库之上)。
算法已经作为一个独立的REST服务器实现,因此您可以托管自己的服务器来交付活动流:http://www.rene-pickhardt.de/graphity-server-for-social-activity-streams-released-gplv3/
在论文和基准测试中,我展示了检索新闻流只依赖于你想要检索的条目的数量,而没有任何冗余,你会从反规范化数据中得到:
http://www.rene-pickhardt.de/graphity-an-efficient-graph-model-for-retrieving-the-top-k-news-feeds-for-users-in-social-networks/
在上面的链接中,您可以找到屏幕视频和这种方法的基准测试(显示graphity能够每秒检索超过10k个流)。
// one entry per actual event
events {
id, timestamp, type, data
}
// one entry per event, per feed containing that event
events_feeds {
event_id, feed_id
}
创建事件时,决定它出现在哪个提要中,并将这些提要添加到events_feeds中。
要获取提要,请从events_feeds中选择,加入事件,按时间戳排序。
然后可以对该查询的结果进行过滤和聚合。
使用此模型,您可以在创建后更改事件属性,而不需要额外的工作。
事件流最大的问题是可见性和性能;您需要将显示的事件限制为只显示该特定用户感兴趣的事件,并且需要保持整理和识别这些事件所需的时间。我建立了一个小型的社交网络;我发现,在小范围内,在数据库中保留“事件”表是可行的,但在中等负载下就会出现性能问题。
对于较大的消息流和用户,最好使用消息传递系统,将事件作为消息发送到单个配置文件。这意味着您不能很容易地订阅人们的事件流,也不能很容易地查看以前的事件,但是当您需要为特定用户呈现流时,您只是呈现了一小组消息。
I believe this was Twitter's original design flaw- I remember reading that they were hitting the database to pull in and filter their events. This had everything to do with architecture and nothing to do with Rails, which (unfortunately) gave birth to the "ruby doesn't scale" meme. I recently saw a presentation where the developer used Amazon's Simple Queue Service as their messaging backend for a twitter-like application that would have far higher scaling capabilities- it may be worth looking into SQS as part of your system, if your loads are high enough.