100W 用户实时通知,如何降低数据库压力?(23/31)

推送集群与业务集群解耦,复杂计算每秒只算一次

即时通讯架构实践第 23 课封面:即时通讯23:100W 用户实时通知,如何降低数据库压力

推送集群与业务集群解耦,复杂计算每秒只算一次

《即时通讯架构核心技术》第 23 篇:100W 用户实时通知,如何降低数据库压力。

读者付费提问:交易所盘口数据的缓存和推送怎么做

继续答星球水友提问:交易数据频繁变化,如何做缓存与推送,如何降低数据库压力?

并没有做过相关的业务,结合自己的架构经验,说说自己的思路和想法,希望对大家有启示。

业务抽象

1. 有很多客户端关注交易,假设百万级别;

2. 数据量不一定很大,上市交易的股票个数,假设万级别;

3. 写的量比较大,每秒钟有很多交易发生,假设每秒百级别;

4. 计算比较复杂,有求和/分组/排序等操作;

潜在技术折衷

客户端与服务端连接如何选型?

客户端与服务端的 TCP 连接示意

首先,交易客户端与服务器建立TCP长连接,而不是每次请求都建立与销毁短连接,能极大提升性能,降低服务器压力。

业务的实时性如何满足?

交易业务,对数据实时性的要求较高,服务端可以通过TCP长连接推送,保证消息的实时性。

由于推送量级巨大,可以独立推送集群,专门实施推送。推送集群独立化之后,增加推送服务器数量,就可以线性提升推送能力。

推送集群与业务集群解耦

如上图所示,假设有100W用户接收实时推送:

1. 搭建专门的推送集群,维护与客户端的tcp长连接,实时推送;

2. 每台推送服务维护10W长连接,10台推送服务即可服务100W用户;

3. 推送集群与业务集群之间,通过MQ解耦,推送集群只单纯的推送消息,无任何业务逻辑计算,推送消息的内容,都是业务集群计算好的;

推送服务最大的瓶颈是,如何将一条消息,最快的推送给与之连接的10W个客户端?

1. 如果消息量不大,例如几秒钟一个消息,可以开多线程,例如100个线程,并发推送;

对应水友提到的,如果量不大,可以成交一笔推送一笔。

2. 如果消息量过大,例如一秒钟几百个消息,可以将消息暂存一秒,批量推送;

对应水友提到的,如果消息量巨大,批量推送是很好的方法。

数据量,写入量,扩展性如何满足?

股票个数较少,数据量不是瓶颈。

数据量不是瓶颈

流水数据写入量,每秒百级别,甚至千级别,数据库写性能也不是瓶颈,理论上一个库可以扛住。

水平拆分:两库各承担 50% 盘口写入

假如每秒写入量达到万级别,可以在数据库层面实施水平切分,将不同股票的流水拆到不同水平切分的库里去,就能线性增加数据库的写入量。

水平拆分后,同一个股票,数据在同一个库里,不同股票,可能在不同的库里,理论上不会有跨库查询的需求。

MQ 缓冲削峰填谷保护数据库

如果每秒写入量达到十万,百万级别,还可以加入MQ缓冲请求,削峰填谷,保护数据库。

无论如何,根据本业务的数据量与写入量,单库应该是没有问题的。

复杂的业务逻辑操作,如何满足?

本业务的写入量不大,但读取量很大,肯定不能每个读取请求都sum/group by/order by,这样数据库肯定扛不住。

水友已经想到了,可以用缓存来降低数据库的压力,但担心”随着时间的推移,这个偏差势必会慢慢放大”。

关于缓存的一致性的放大,可以这么搞:

1. 做一个异步的线程,每秒钟访问一次数据库,将复杂的业务逻辑计算出来,放入高可用缓存;

2. 所有的读请求不再耦合业务逻辑计算,都直接从高可用缓存读结果;

如此一来,复杂业务逻辑的计算,每秒钟只会有一次。

带来的问题是,一秒内可能有很多流水写入数据库,但不会实时的反应到缓存里,用户最差情况下,会读到一秒前的交易数据。

无论如何,这是一个性能与一致性的设计折衷。

上面的所有方案,都是基于在线客户量级巨大,推送消息巨大的前提下,采用推送方案。很多时候,工程师都会妄加猜测,把问题想得很复杂,把方案搞得很复杂。

如果在线用户量很小,用户能够接受的交易时延较长(例如5s),完全可以采用轮询拉取方案:

在线用户量小时的轮询拉取方案

1. 取消整个推送集群与MQ集群;

2. 交易数据,异步线程每1s写入高可用缓存一次;

3. 客户端每5s轮询拉取最新的交易数据,都只从缓存中拉取;

搞定!

反正,肯定不能每个读请求都sum/group by/order by扫库计算,这个是最需要优化的。

总结

1. 长连接比短连接性能好很多倍;

2. 推送量巨大时,推送集群需要与业务集群解耦;

3. 推送量巨大时,并发推送与批量推送是一个常见的优化手段;

4. 写入量巨大时,水平切分能够扩容,MQ缓冲可以保护数据库;

5. 业务复杂,读取量巨大时,加入缓存,定时计算,能够极大降低数据库压力;

高并发推送,架构设计要点,你学废了吗?

检验一下

检索练习 · 推送集群规模
每台推送服务维护 10W 长连接,100W 用户需要多少台推送服务?推送集群和业务集群之间靠什么解耦?

检索练习 · 推给 10W 个客户端
单台推送服务如何把一条消息最快推给与之连接的 10W 个客户端?

检索练习 · 复杂计算降库压
读取量巨大且带 sum/group by/order by,如何降低数据库压力?代价是什么?

检索练习 · 写入量扩展
流水写入从每秒百级涨到万级、再到十万百万级,分别怎么扩?

推送、削峰、缓存都齐了。回到 2016 年,看一套完整平台是怎么搭起来的——第 24 篇,通用实时消息平台架构细节(QCon 2016)。

知其然,知其所以然。思路比结论更重要。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

京ICP备2025137728号-3