《微信直播聊天室架构演进.docx》由会员分享,可在线阅读,更多相关《微信直播聊天室架构演进.docx(14页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、微信直播聊天室架构演进聊天室概述随着直播以及类直播场景在微信内的增长业务对临时消息通道的需求日益增长聊天室组件应运而生。聊天室组件是一个基于房间的临时消息信道主要提供消息收发、在线状态统计等功能。1500w在线的挑战视频号直播上线后在产品上提出了直播后台需要有单房间支撑1500w在线的技术才能。接到这个工程的时候自然而然就让人联想到了一个非常有趣的命题能不能做到把13亿人拉个群本文将深化浅出地介绍聊天室组件在演进经过的考虑对这个命题做进一步对探究尝试提出更接近命题答案的方案。聊天室1.0架构聊天室1.0诞生于2017年度主要效劳于微信电竞直播间核心是实现高性能、高实时、高可扩展的消息收发架构。
2、消息框架选型读扩散微信群聊天室介入人数500数万关系链有无成员流动低高离线消息关注不关注微信群消息使用写扩散的机制而聊天室跟微信群有着宏大的差异。且同一时间只能关注一个聊天室决定了聊天室应该使用读扩散的机制。longpolling机制为了让用户需要实时同步到新消息我们采用的是longpolling形式。很多人会疑惑为什么不用websocket原因有3个1.websocket主要考虑推形式而推形式那么有可能丢做到不丢还是有需要拉形式来兜底2.推形式下需要精准维护每个时刻的在线列表难度很大。3.longpolling本质是一个短连客户端实现更简单。无状态cache的设计很明显单纯的读扩散会造成宏大
3、读盘的压力。按照国际惯例这里理所应当地增加了一个cache也就是上面架构图中的recvsvr。普通的cache都是有状态的、可穿透的对经常会出现突发流量的聊天室不是十分友好。而通过异步线程任务恰好可以解决这两个点。实时通知发送消息时在写入列表后向recvsvr集群发送通知异步拉取recvsvr机器收到通知后触发异步线程拉取兜底轮询当recvsvr机器上接收到某个聊天室的恳求时触发该聊天室的轮询保证1s内至少访问一次消息列表防止通知失效导致无法更cache同时做到机器启动时数据的自动恢复。无锁读取通过读写表别离以及原子切换做到消息的无锁读取sect化部署群数量增多时扩sect可以把群分摊到新的s
4、ect上。无状态消息cache的设计不仅极大地进步了系统的性能而且帮助聊天室建立了一个高扩展性消息收发架构。痛点尽管做到了高性能的消息收发1.0版本却并不能实现单房间1500w同时在线的目的。通过对整个架构以及逻辑进一步的分析我们发现4个阻碍我们前进的痛点1大直播间里消息信道不保证所有消息都下发连麦成功信令丧失会使得连麦功能不可用大礼物打赏动画信令丧失会带来客诉2一个房间的在线列表是由recvsvr把最近有收取该房间的消息的user聚合到同一台statsvr得到的有单点瓶颈单机失败会导致局部房间在线数跳变、在线列表以及打赏排行榜不可用等3没有提供历史在线人数统计功能4裸的longpolling
5、机制在消息一直有更新的情况下无法控制恳求量。聊天室2.0架构从上面分析的痛点我们得出了聊天室2.0需要解决的问题1解决丢重要信令问题保证热点访问下功能的可靠性。2解决在线统计的单点瓶颈保证热点访问下在线统计模块的可扩展性。3实现一个高效准确的历史在线统计保证大数据量下统计的高性能以及准确性。4灵敏把控流量进一步提升隔离以及容灾才能保证热点访问下系统的可用性。优先级消息列表丢信令的本质原因recvsvr只保存最近2000条消息大直播间里有些消息客户端还没来的及收就被cache淘汰了。在聊天室1.0版本我们已经证实了写扩散不可行因此这里也不可能通过写扩散解决。另外一个比拟直观的方案是将重要的系统信
6、令写到另外一个列表里面recvsvr同时读取两个消息表。带来的消耗是recvsvr对kv层增加将近一倍的访问量。于是我们考虑有没有更优的方案。回到1.0版本的一个方案细节我们可以看到大局部情况下当新消息到来的时候recvsvr它都是能及时感悟到的因此recvsvr一次拉取到的消息条数并不会很多因此这一步骤上不会丢消息。所以我们是可以把消息表这个操作收归到recvsvr里面的打优先级标记仍然只写一张消息表给重要的信令打上优先级标记节省RPC消耗cache内分表recvsvr拉到消息后分开普通消息列表以及重要消息列表最小化改动优先收取收取时分normalseq以及importantseq先收重要消
7、息表再收取普通消息表。优先下发通过一个简单的优化我们以最小的改造代价提供到了一条可靠的重要消息信道做到了连麦以及大礼物动画的零丧失。分布式在线统计1写分享内存主从互备参考微信设备在线模块我们可以有这个一个方案分sect一个直播间选一个sect按roomid选一台机作为master读写该机器的分享内存master把这个roomid的数据同步到sect内其它机器master挂了的情况可以选其它机器进展读写。优点解决了换机跳变问题。缺点主备同步方案复杂读写master大直播间下仍然有单机热点问题。结论用分布式存储作为数据的中心节点。2写tablekv用tablekv的一个表来存在线列表每行记录用户i
8、d以及活泼时间定期更新用户的心跳时间维护在线。优点解决了换机跳变问题数据做到了分布式。缺点1500w在线10s心跳一次9000w/min穿透写单表有并发以及性能问题离线不会实时从磁盘删数据历史活泼人数远大于当前在线造成数据冗余。逐点击破单key是可以通过拆key来解决的数据冗余可以通过key-val存储做全量交换解决而穿透问题其实可以参考recvsvr的实现方式。因此我们得到一个比拟好的方案拆key读写别离异步聚合落盘。分布统计: (1)每台机负责局部在线统计 (2)每台机内按uin哈希再分多shard打散数据 (3)每个shard对应kv的一个key组合数据让每台机都拉取所有key的数据组合
9、出一个完好的在线列表异步聚合更新心跳只更新内存异步任务清理离线用户并把列表序列化到一个key的val异步拉取由异步任务来执行的拉取以及组合数据原子切换完好的在线列表做双指针利用原子操作无锁切换做到无锁查询。由此我们进步了心跳更新以及在线查询的性能做到了在线统计模块的分布式部署以及可平行扩展。基于hyperloglog的历史在线统计历史在线统计是要曾经看过该直播的用户数uv在产品上的体验就是视频号直播的“xxx人看过。在分布式在线统计的章节我们已经谈到了用tablekv来记录成员列表是不太可行的。另外一个想法是利用bloomfilter做数据压缩以及去重统计额外去维护一个count做累加。那么这
10、里有两点一是bloomfilter以及count之间要考虑一致性问题二是bloomfilter准确率跟压缩率相关较好的准确率还是需要比拟大的数据量。于是我们调研了业界的一些uv统计方案最终找到了redis的hyperloglog它以极小的空间复杂度就能做到64位整形级别的基数估算。1hyperloglog是什么hyperLogLog是一种概率数据构造它使用概率算法来统计集合的近似基数算法的最根源那么是伯努利经过。伯努利经过设一个硬币反面为0正面为1抛一枚硬币直到结果为1为止。假如做n次伯努利实验记录每次伯努利经过需要抛硬币的次数为Ki那么可以估算n2Kmax。hyperloglog对Kmax的
11、计算进展了分桶以及调以及平均值优化使得在准确率比裸的伯努利估算要高将要统计的数据hash成一个64位整形用低14位来寻找桶的位置剩下的高位里寻找第一个1出现的位置作为上述伯努利经过的Ki对桶的值进展更新Rjmax(Rj,Ki);估算时对各个桶的值算调以及平均值DV来替代上述的Kmax。从上述算法的描绘来看hyperloglog无非就是存了m个桶的数值(m10000)本来空间复杂度也不高了。再通过一些位压缩hyperloglog把整个数据构造优化到了最大空间复杂度为12K。2tablekvhyperloglog双管齐下由于hyperloglog产生的毕竟是近似值基数较少的时候误差会更明显所以我们
12、可以用tablekv来补全历史在线数较小时的体验。历史在线数较小时双写tablekvhyperloglog以tablekvselectcount为准历史在线数较大时只写hyperloglog以hyperloglog估算值为准在线统计模块定期把在线列表merge到hyperloglog防止丢数据。最终我们到达的效果是历史在线不超过1w时完全准确超过1w时准确率大于95%。流量隔离vipsect大众都知道大直播间会带来爆发式的恳求量我们不能让大直播间引起的失败影响占大多数的小直播间。另外大直播间影响力大也要去保证它的良好体验那需要用比小直播间更多的机器去支撑。而聊天室对kv层的恳求数跟机器数成正比
13、小直播间在多机器下会造成大量不必要的消耗。对于这种情况我们参考了微信支付应对大商户以及小商户的方法流量隔离在聊天室的里设立vipsect。对可预测的大直播提早加白直接走vipsect其它直播直走普通sect大小直播策略分级大直播在线列表才拆key。固然还有些依赖运营但是通过这种方式我们切走大局部的大直播流量也降低了整个系统对kv层的压力。Q为什么不做自动切vipsect?A是一个futurework目前有了一些初步方案还需要去验证切换经过带来影响进一步细化策略也欢送大众提出珍贵建议。自动柔性下的流量把控在longpolling的机制下直播间一直有消息的话100w的在线每分钟至少会产生6kw/m
14、in的恳求而1500w更是高达9亿/min。logicsvr是cpu密集型的效劳按30w/min的性能来算至少需要3000台。所以这个地方必需要有一些柔性措施把控恳求量寻找一个体验以及本钱的平衡点。而这个措施一定不能通过logicsvr回绝恳求来实现原因是longpolling机制下客户端接收到回包以后是会马上提议一次新恳求的。logicsvr回绝越快恳求量就会越大越容易造成滚雪球。回到longpolling机制我们可以发现正常运行下recvsvr没有新消息时是可以让恳求挂在proxy层hold住等待连接超时或longpollingnotify的。所以我们可以利用这个特性柔性让恳求或回包在pr
15、oxyhold一段时间来降低恳求频率。根据不同的在线数设定收取间隔客户端上下文里增加字段记录上一次成功收取的时间成功收取后的一个时间间隔内恳求hold在proxy层根据不同的在线数丢弃longpollingnotify。根据400w在线的压测效果开启自适应大招时触发810s档位恳求量比没有大招的预期值降低58%有效地控制了大直播间对logicsvr的压力。成果1支撑多个业务稳定运行2压测1500w同时在线参考文献s:/zhuanlan.zhihu/p/77289303s:/jianshu/p/4748af30d194总结与展望我们通过抽象问题、精准分析、合理设计完成了liveroom2.0的迭代从性能、可靠性、可扩展性、容灾等方面到达支撑单房间1500w同时在线甚至更高在线的标准。在将来我们将继续优化比方实现大房间自动从普通sect切换到vipsect比方针对房间内个人的重要消息通道使聊天室的功能以及架构更加强大。正文完毕欢送来撩亦期待您的参加微信团队诚招后台开发请点击下方浏览原文解析以及申请职位。TK教主的职场学习成长心得腾讯技术工程
限制150内