# feed **Repository Path**: jackcoder8694/feed ## Basic Information - **Project Name**: feed - **Description**: 高可用feed流系统 - **Primary Language**: Go - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-04-26 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 高可用Feed流动态策略设计和实现 * * * ## 业务说明: **1、涉及业务:好友动态、个人动态(也涉及个人动态计数)、好友关系(也涉及关注数和粉丝数)** **2、涉及操作:新增、查找、删除** * * * ## 设计要点: **1、涉及缓存设计和数据库设计** **2、需要考虑峰值写入情况** **3、需要考虑读写的性能** **4、使用语言无限,可以是自己比较熟悉的语言** * * * ## 最终交付: **1、提供业务接口(部署到测试服务器上)** **2、压测数据:包括压测场景及其压测结果数据** **3、系统可支撑的量级评估** **4、系统再进一步发展的瓶颈点评估** * * * ## 附加题: **1、思考怎么实现未读数(给出方案,或者进一步实现功能,这部分可以考虑按照小组来做)** **2、涉及到视频和图片** * * * ## 业务接口: **1、好友动态**          GET     参数:timebegin、timeend、userid     说明:利用时间段和用户id获取好友动态 **2、个人动态**          GET     参数:timebegin、timeend、userid     说明:利用时间段和用户id获取个人动态     POST     参数:action(add/delete)、userid、timestamp、value     说明:发布个人动态需要提供时间,内容,用户id以及关键的操作(增加或删除) **3、好友关系**          GET     参数:userid     说明:返回用户的关注对象和粉丝列表     POST     参数:action(add/delete)、userid、like和fan二选一     说明:更改好友关系需要提供用户id以及关键的操作(增加或删除)和粉丝id或者关注对象的id(两者同时存在,以like为优先) **4、未读数**          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以内) ### 压测数据(T99,成功率100%,最大并发(<5000),cpu 100%): 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的方式需要做更多针对上的考虑,本次只是以其中一种类型的用户体验优化考虑,参看聚合策略的重要假设。 * * * ## Github