转载

如何设计一个可靠的消息系统

全民K歌的消息包含两种:一种是用户作品相关的消息汇聚,用户所有作品的评论、送礼等,按照时间线纵向给用户聚合起来。一种是横向用户与用户之间的交流信息,提供类似QQ、微信的会话列表和详情查看。本文结合这个功能,分享设计后台时候要注意的三个点: 容量预估、一致性保证、防止雪崩。

一、容量预估

如何设计一个可靠的消息系统

看菜吃饭,量体裁衣,运筹帷幄、决胜千里。方案设计时和服务正式上线前要做预估:

1.吞吐量的预估

1)响应时间(RT)

响应结果所需的时间

2)并发数

系统同时处理的请求数,可以理解为同步单线程情况下的进程数

3)每秒处理的请求量QPS

QPS=并发数/RT

我们要保证峰值QPS<系统处理的QPS,这个数据决定了要多少机器总共多少个进程

2.存储的预估

每个用户最多存多少条数据?每条最大多大?平均多大?平均每用户存储多少条?

3.网络流量的预估

每个请求对应的RPC请求要几次?出流量和入流量多少?和QPS相乘就得到总流量。网卡是有处理能力上限的,这里也决定了机器数。

在方案设计阶段要预估QPS,不同的请求量级对应的方案不通,如果说请求量特别大,那要考虑是否加入异步队列,让请求异步处理。比如私信的发信过程,大的步骤有三个,Step1写发送者的存储,Step2写接受者的存储,Step3通知接受者,可以通过异步队列,让Step2和Step3异步处理,从而降低发信过程的时延。

另一个重要的设计点是存储,不同的存储的读写更新性能不同,对应的单位容量价格也不通,要结合看用户的场景而定。比如基于内存的KV存储成本高,但读写性能都非常好,基于SSD的存储虽然性能低一些,但成本也低,而且组件封装了比较适合的特性。没有最好的组件,只有最合适的组件。具体到消息系统,私信列表我们采用的是KV存储,而作品消息和私信详情我们采用的是基于SSD的列表存储TLIST。

二、一致性保证

如何设计一个可靠的消息系统

为了完成用户的一个请求,后台通常对应多个远程调用,后台如何保证事务的一致性成为了难题。以转账为例,A给B转账,两人原账户各有1000,数据版本号为a1,b1两个步骤为从A扣除100,给B增加100,假如A扣除这步成功了,但给B增加这个步骤超时了呢?给B到底增加了没有?在操作前给这个步骤分配唯一编号 Tid,A(a1)减100 ,然后写日志(Tid, s1,a1, -100,a2)。如果日志写失败了呢?因为数据是有版本号的,重试不会减两次。同理操作B(b1)增加100,然后写日志(Tid, s2,b1, +100,b2)。如果操作B过程超时了,也重试。有了操作日志,可以灵活的选择回滚还是重试,重试的时机是立即还是延后。在消息系统里,每条消息也被分配了唯一ID,确保操作的可追溯可重试。

三、防止雪崩

如何设计一个可靠的消息系统

重试可以提高访问的成功率,那是不是所有调用都适合重试呢?重试提高了对被调服务的访问QPS,如果被调服务处理能力不足,重试就会造成雪崩,请求在队列排队呢,结果访问量又加大了,正常请求、重试请求都在排队,调用端超时后又增加新的重试请求…

问题的根源在于被调用的资源不足,那么解决的方式就是两个,开源节流。开源就是扩容被调用服务,提高吞吐量;节流是被调用服务把请求分成高低不同优先级,预估自己处理能力,优先处理高优先级的,对处理不来的低优先级的及早拒绝掉。

原文  http://mp.weixin.qq.com/s?__biz=MzI1NjEwMTM4OA==&mid=2651231881&idx=1&sn=fca6f6ecca06eacb9284f41597255700&scene=0
正文到此结束
Loading...