用户系统设计
Senario:日活100M
读:100M X 100 / 86400 ~ 100k,peak = 300k,每天大概看100次,这个包括你打开page就会读一下你的好友和自己的资料什么的。
写:100M X 0.1 / 86400 ~ 100, peak = 300,修改自己资料,注册,之类的
是一个读多写少的系统------这时必须想到cache优化读
Service:
一个AuthService负责登录注册
一个UserService负责用户信息存储于查询
一个FriendshipService负责好友关系存储/查询
Storage:
AuthService,如何记录用户登录信息。需要一个session table:
session_key | string(全局唯一)建索引 |
user_id | foreign key(指向User table) |
expire_at | timestamp (什么时候过期) |
多机器登录功能实现:session Table里存两条。iphone登录的session_id,user1,存一条;然后web登录的session_id,user1,再存一条。
FriendshipService:
这个得分双向好友还是单向好友关系。也分sql和noSql。如果用sql,要考虑存一份还是存两份,例如A->B,B->A。建议存两份,然后在一个column建立索引。花点时间,写两份,读起来快。存一份的话每次要两条而且要建两个索引。
这个会有consistency的问题,解决方法可以是一周以后统计一下,把数据补全,eventually consistency
from | foreign(用户) |
to | foreign(被关注的人) |
如果存nosql的话要存两份,因为要支持查询“A关注了谁?”和“谁关注了A?” 把A作为key,value就是list of follower,另一个也是A作为key,value是list of following。如果是双向好友关系的话,一个表就ok了,因为follower==following。
另外如果我们有新需求“要查最近一天关注的好友”,这样就得用casandra这种有rowkey,columnkey和value的了,因为要支持range query(加时间戳index)。同样,如果要快速查到好友,和最近一天的好友,我们可以存两份。(nosql表好简单粗暴,要快就多存几分)
存一份的时候,为什么要把小的放左边呢?这个对"查询A用户的所有好友”没有优化,优化的是,“查询A与B是不是好友”这样你就只用查小的那个就ok了。
存一份的优化可以是,挡一个cache,用cache优化,可以在cache里,正向存一个记录,反向存一个记录。
Scale:
vertical sharding vs horizontal sharding
single point of failure:replica,重要的事情写3份,还可以增加读的copy
Last updated