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

全民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,如果被调服务处理能力不足,重试就会造成雪崩,请求在队列排队呢,结果访问量又加大了,正常请求、重试请求都在排队,调用端超时后又增加新的重试请求… 问题的根源在于被调用的资源不足,那么解决的方式就是两个,开源节流。开源就是扩容被调用服务,提高吞吐量;节流是被调用服务把请求分成高低不同优先级,预估自己处理能力,优先处理高优先级的,对处理不来的低优先级的及早拒绝掉。

原文发布于微信公众号 - QQ音乐技术团队(gh_287053a877e6)

原文发表时间:2016-06-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯技术工程官方号的专栏

高并发性能调试经验分享(上)

4月份的时候看到一道面试题,据说是腾讯校招面试官提的:在多线程和高并发环境下,如果有一个平均运行一百万次才出现一次的bug,你如何调试这个bug?遗憾的是知乎很...

1.1K3
来自专栏Linuxer的专栏

谢宝友: 深入理解 Linux RCU 之从硬件说起

想要制造出质量可靠的桥梁,就必须真正懂得力学原理。对于想要理解RCU的软件工程师来说,也需要具备一定的硬件基础。

1K0
来自专栏IT派

Python库大全,建议收藏留用!

学Python,想必大家都是从爬虫开始的吧。毕竟网上类似的资源很丰富,开源项目也非常多。

2272
来自专栏FreeBuf

Flexera FlexNet Publisher中基于栈的缓冲区溢出漏洞分析

近日,安全人员在Flexera FlexNet Publisher(License Manager)中发现了一个基于栈的缓冲区溢出漏洞(CVE编号:CVE-20...

2157
来自专栏Linyb极客之路

低延迟系统的最佳实践

低延迟意味着更快的响应时间,更快的性能,以下最佳实践大部分来自于Quora等问题提炼:

1502
来自专栏微信公众号:Java团长

你的项目应该如何正确分层?

说起应用分层,大部分人都会认为这个不是很简单嘛 就controller,service, mapper三层。看起来简单,很多人其实并没有把他们职责划分开,在很多...

3503
来自专栏北京马哥教育

Python库大全,建议收藏留用!

3503
来自专栏BIT泽清

贷款应用被拒如何应对?怎么上架(含隐藏开关)的马甲包

      突然间的2.1大礼包成了一个重灾区,苹果加大了中国区的审核力度。但其实归根结底,会触犯到这个大礼包的App很大部分或者说几乎都是和这个关键词挂钩的 ...

45510
来自专栏烂笔头

Django 1.10中文文档-第一个应用Part5-测试

目录[-] 本教程上接教程Part4。 前面已经建立一个网页投票应用,现在将为它创建一些自动化测试。 自动化测试简介 什么是自动化测试 测试是检查你的代码是...

3796
来自专栏王清培的专栏

.NET应用架构设计—服务端开发多线程使用小结(多线程使用常识)

有一段时间没有更新博客了,最近半年都在着写书《.NET框架设计—大型企业级框架设计艺术》,很高兴这本书将于今年的10月份由图灵出版社出版,有关本书的具体介绍等书...

2025

扫码关注云+社区

领取腾讯云代金券