论坛首页 Java企业应用论坛

请做架构的朋友一起讨论下SNS中好友动态功能建模的设计

浏览 66749 次
该帖已经被评为良好帖
作者 正文
   发表时间:2008-03-31  
以前朋友做社区的时候我们讨论过一个方案,分享一下

先说一下背景,由于当时的情况是数据库必须采用sqlserver2k(政治原因),而团队中对sqlserver2k优化都没有什么信心,但是WEB层的架构都是团队定的,所以尽量把业务实现和性能解决方案的重心偏移DB,避免SQL,这是出发点

所有的好友状态和最新行为都是通过物理文件来保存的,实时的操作是memcache来保存。

通过apache或者Light HTTPd 建立 resource服务器,每次用户执行操作后会重写/userid/his/xxx.js,这样用户的好友登陆后首先加载好友列表,然后在页面中分别加载好友相应的js来实现最近操作记录。同时还有类似javaeye的"我在看帖子"这种实时状态,是通过memcache来实现的。


这个方案提供了很好的扩展性,可以通过优化linux来实现非常好的性能,但是,安全性是个问题,最辛酸的是,辛辛苦苦做完,项目被毙了……

0 请登录后投票
   发表时间:2008-03-31  
很简单的一个结构
id 自增id
userid  用户id
content   内容,根据动态的信息拼装成的一个字段
type    分类(例如:blog,music,friend,video),用整型表示
createtime  创建时间
这样,即使是需要关联的话,表也会很少

对于数据的操作,我用的是最直接的办法:
调用dao操作。没有考虑异步,拦截等问题
0 请登录后投票
   发表时间:2008-03-31  
查询才是个大问题,如果你有几百万个用户,每个用户又有几百个好友的情况,更可怕的是有个拥有几百万好友的超级user,就像myspace里的tom
0 请登录后投票
   发表时间:2008-03-31  
说到底就是用户的日志,我比较认同lllyq的设计,通过一条查询语句就可以搞定
user_id
operation_raw_data
operation_type
operation_time
0 请登录后投票
   发表时间:2008-03-31  
我也认为用日志的方式解决比较好,简单且速度不错

如果担心日志表的数据量会太大,可以定时删除过时的日志,或者转移到日志备份表里
0 请登录后投票
   发表时间:2008-03-31  
lllyq 写道
光这些还不够,怎么表示加了多个好友,多个照片,发布话题(跟其他不一样,还要显示段落)

其实只需要四个字段就够,获取数据时真正关心的是ID, 时间,显示需要关心的是数据和样式
user_id
operation_raw_data
operation_type
operation_time

根据operation_type从cache中获取operation_render_template



这两天在搞服务器,没上论坛.一上来发现竟然有这么多热心朋友参与讨论.我下面这个设计有些地方我没说清楚.
其实稍改一下,它也支持多个好友与多个照片的.
呵呵,你这个设计比我这个更简接.我没考虑去cache中去读template.我的意图是用freemarker按每种类型定义一个
macro.这样在页面显示的时候通过读这个Dynamic_Type然后分别调用对应类型的macro.我采用几个冗余字段来保存名字.消息说明(也可以是文章摘要).截图(其实主要是用来保存用户上传的图片)
最重要的这些冗余字段我放的都是一个JSON串在里面.这个JSON串就可以用来保存多个对应信息.

 

如果仔细看那张类似需求图,我们还可以看出.如图片名字.人名.或者分类名字都是可点击的链接.所以我觉得用JSON串保存比较合适


面的Friend_Dynamic的userId对应的好友表(User_Friend)中的FriendUserId
这样要查询用户的好友动态就只需要关联三张表.一张是UserInfo一张是UserFriend然后就是这张FriendDynamic就可以了.性能上如果担心数据太多.做一个quartz定时一天或者一周去清除过期的记录这样就能保持这个表的记录不至于太多
.不过不可避免的是如果建立索引.有太多的insert操作.会有影响.索引字段选择也很为难.
索引:create_time user_Id Dynamic_Type
Dynamic_ID //主键
user_id ;//用户编号
Dynamic_Name ;//动态消息名称
Dynamic_Desc ;//动态消息说明
Dynamic_Thumb ;//动态消息截图
Dynamic_Type ;//消息类型 blog/comment/music/video
Create_time Date;
由于还没实战这部分开发.还只是在考虑中.也存些不成熟的地方.

 

0 请登录后投票
   发表时间:2008-04-01  
ithero 写道
lllyq 写道
光这些还不够,怎么表示加了多个好友,多个照片,发布话题(跟其他不一样,还要显示段落)

其实只需要四个字段就够,获取数据时真正关心的是ID, 时间,显示需要关心的是数据和样式
user_id
operation_raw_data
operation_type
operation_time

根据operation_type从cache中获取operation_render_template



这两天在搞服务器,没上论坛.一上来发现竟然有这么多热心朋友参与讨论.我下面这个设计有些地方我没说清楚.
其实稍改一下,它也支持多个好友与多个照片的.
呵呵,你这个设计比我这个更简接.我没考虑去cache中去读template.我的意图是用freemarker按每种类型定义一个
macro.这样在页面显示的时候通过读这个Dynamic_Type然后分别调用对应类型的macro.我采用几个冗余字段来保存名字.消息说明(也可以是文章摘要).截图(其实主要是用来保存用户上传的图片)
最重要的这些冗余字段我放的都是一个JSON串在里面.这个JSON串就可以用来保存多个对应信息.

 

如果仔细看那张类似需求图,我们还可以看出.如图片名字.人名.或者分类名字都是可点击的链接.所以我觉得用JSON串保存比较合适


面的Friend_Dynamic的userId对应的好友表(User_Friend)中的FriendUserId
这样要查询用户的好友动态就只需要关联三张表.一张是UserInfo一张是UserFriend然后就是这张FriendDynamic就可以了.性能上如果担心数据太多.做一个quartz定时一天或者一周去清除过期的记录这样就能保持这个表的记录不至于太多
.不过不可避免的是如果建立索引.有太多的insert操作.会有影响.索引字段选择也很为难.
索引:create_time user_Id Dynamic_Type
Dynamic_ID //主键
user_id ;//用户编号
Dynamic_Name ;//动态消息名称
Dynamic_Desc ;//动态消息说明
Dynamic_Thumb ;//动态消息截图
Dynamic_Type ;//消息类型 blog/comment/music/video
Create_time Date;
由于还没实战这部分开发.还只是在考虑中.也存些不成熟的地方.

 


动态的内容拼装成一串有html代码的字符串,可以吗?这样里面的内容就是可以点击的。
0 请登录后投票
   发表时间:2008-04-01  
保证性能的前提下,我感觉,必须要有一套稳定的消息系统,有延迟没关系,但是要求可靠。

消息消费系统订阅消息,处理消息,然后分发到每个用户的事件表里。这样,用户登录时,就可以看到好友的状态的。

当然,这类网站有个根本性的东西要解决,那就是,用户profiler及关系的缓存。
有他,消息消费起来才更快。全走数据库的话,这个消息传递的延迟会更长!
0 请登录后投票
   发表时间:2008-04-01  
性能排序:
1.消息分发,最差,对于用户每个操作会产生大量io,不适合用户量多的情况。
2.用户操作日志使用单一表,较差,因为数据量多,每次查询后排序将会浪费大量时间。
3.对每个用户都建立一个操作日志表,较好,缺点是建立的表太多,但是查询速度相对快。
4.自行实现每个用户的操作日志表,直接使用链表,头指针使用定长顺序表或者hash表,查询的同时可以按时间合并链表,计算可控,速度最快。
0 请登录后投票
   发表时间:2008-04-01  
赫赫,这个话题有意思,我想应该是:

1.DBM(QDBM,NDBM,BDB等)存储用户的ID以及Memcached信息

key--->ID
value--->memcahcedID(location)

2.通过Memcached获取用户相关信息
相关信息包含:
     1.用户个人信息,状态
     2.好友信息
     3.行为状态

key--->id
value--->user(info,friend,action)


关于如何获取用户的相关信息,robbin已经提到了,通过用户的crud获取相关变化信息。


基于memcached的get/set是足够快的。对数据库压力方面的好处就不用提了。

至于使用什么语言,php,java,c,ruby,python等都可以,memcached都有相关语言的接口。



如果你的系统比较小或用户比较小。

第一步可以省略。

第二步memcached可以使用mysql或hsqldb进行替换。


0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics