1、涉及业务:好友动态、个人动态(也涉及个人动态计数)、好友关系(也涉及关注数和粉丝数)
2、涉及操作:新增、查找、删除
1、涉及缓存设计和数据库设计
2、需要考虑峰值写入情况
3、需要考虑读写的性能
4、使用语言无限,可以是自己比较熟悉的语言
1、提供业务接口(部署到测试服务器上)
2、压测数据:包括压测场景及其压测结果数据
3、系统可支撑的量级评估
4、系统再进一步发展的瓶颈点评估
1、思考怎么实现未读数(给出方案,或者进一步实现功能,这部分可以考虑按照小组来做)
2、涉及到视频和图片
1、好友动态
http://127.0.0.1:7788/api/friendstimeline
GET
参数:timebegin、timeend、userid
说明:利用时间段和用户id获取好友动态
2、个人动态
http://127.0.0.1:7788/api/personaltimeline
GET
参数:timebegin、timeend、userid
说明:利用时间段和用户id获取个人动态
POST
参数:action(add/delete)、userid、timestamp、value
说明:发布个人动态需要提供时间,内容,用户id以及关键的操作(增加或删除)
3、好友关系
http://127.0.0.1:7788/api/friendsinfo
GET
参数:userid
说明:返回用户的关注对象和粉丝列表
POST
参数:action(add/delete)、userid、like和fan二选一
说明:更改好友关系需要提供用户id以及关键的操作(增加或删除)和粉丝id或者关注对象的id(两者同时存在,以like为优先)
4、未读数
http://127.0.0.1:7788/api/unreadnum
GET
参数:userid
说明:返回用户好友动态的未读数
Mac
cd $GOPATH/src/feed
go build main.go
sudo ./main -c conf/feed-for-test.toml
Linux
cd $GOPATH/src/feed
./build.sh
cd feed
sudo ./bin/feedserver -c conf/feed-for-test.toml
MC:缓存层(L1+M+S)
Mysql: 存储层(分库分表)
Kafka: 队列
Redis: 存储未读数(对持久化要求不高的对象)
Feed流聚合: 推拉结合,设定阀值X,只向最早(时间有序)的X名粉丝push个人动态(mysql存储),其余由粉丝主动pull,在粉丝取关时会主动删除自己存储的对方的所有timeline(如果有的话)并且遵从一个重要的假设,即基于push方式时,用户在关注某一对象时,不关心对方之前发布的动态
视频、图片:发布动态时,首先获取资源的md5 key,通过存储多媒体资源在云上存储的KEY,或者进一步存储KEY的key,减轻聚合动态时的带宽和资源消耗
CPU:2
Mem:1.5G
Disk:50G
除mysql外均在远程机器上(ping值 1ms以内)
personaltimeline_Post personaltimeline_Get friendsinfo_Post
|_________________________________________________________________________
|30(ms) 600/5000/678(kB) 500/4800/1.43(MB) 800/8700/1.18(MB)
|_________________________________________________________________________
|50 1500/5893/788 1200/5000/1.50 1500/10894/1.42
|_________________________________________________________________________
|100 2000/5680/760 2000/5080/1.50 3500/11400/1.49
|_________________________________________________________________________
|200 5000/5400/733 5000/5100/1.50 5000/10400/1.40
|_________________________________________________________________________
|500
|_________________________________________________________________________
|1000
|_________________________________________________________________________
friendstimeline_Get friendsinfo_Get unreadnum
|_________________________________________________________________________
|30(ms) 200/1778/0.84(MB) 500/4432/0.71(MB) 1000/9591/1.50(MB)
|_________________________________________________________________________
|50 500/2541/1.18 1200/6100/0.95 1500/10307/1.62
|_________________________________________________________________________
|100 1500/3443/1.60 2200/6472/1.00 2500/12485/1.97
|_________________________________________________________________________
|200 3000/3473/1.61 5000/6608/1.02 5000/12819/2.03
|_________________________________________________________________________
|500 5000/3457/1.60
|_________________________________________________________________________
|1000
|_________________________________________________________________________
注:GET请求均命中MC的case下测试
服务器状态:0.33 0.25 0.14
除并发量小于1000的小压力case,其余CPU双核均跑满
mysql性能压测:sysbench
从SLA的角度考虑,针对测试服务器,推荐的量级分别是:
1.获取好友动态:3000r/s左右的请求量;
2.获取个人动态:5000r/s左右的请求量;
3.增删个人动态:5000r/s左右的请求量;
4.获取好友关系:6000r/s左右的请求量;
5.增删好友关系:10000r/s左右的请求量;
6.获取未读数:10000r/s左右的请求量;
压测发现,由于使用的队列处理post请求,瓶颈点在于CPU,可以想到的原因主要是consumer消费以及系统本身的处理逻辑;此外,mysql的性能由于单个消费者消费过慢,并没有充分发挥出来。因此磁盘IO不作为瓶颈点考虑,而将消费者线程作为可优化点考虑。
从性能上考虑,可优化的地方包括增加消费者线程,mysql批量写入等;
从可用性上出发,需要增加写失败重试逻辑;
从用户体验上出发,在变更好友关系时,针对push和pull的方式需要做更多针对上的考虑,本次只是以其中一种类型的用户体验优化考虑,参看聚合策略的重要假设。