高性能队列设计

这是一个困扰我司由来已久的问题,近年来随着我司业务的急遽发展,单表数据量越来越大,这样会导致读写性能急遽下降,自然而然的我们想到了分库分表,不过众所周知分库分表规则比较复杂,而且业务代码可能需要大改(由于数据分布在不同的库表里,业务需要判断到底去哪些表取数,并且取完后需要将数据再聚合在一起返回前端),所以经过横向对比我们采用了阿里开源的分库分表中间件 Cobar,这样的话一来 Cobar 根据我们设定的规则分库分表了,二来原来调用 SQL 的地方只需改成调用 Cobar 即可,Cobar 会自动根据我们写的 SQL 去各个分库分表里查询并将结果返回给我们,我们业务层的代码几乎不需要改动(即对应用是透明的)

如图示:使用 cobar 进行分库分表后,可以看到业务代码几乎不需要改动

所以问题是?

使用 Cobar 确实解决了分库分表和对业务代码侵入性的问题,但由于又引入了一个中间层,导致可用性降低,为了防止 Cobar 不可用等造成的影响,我们需要监控 Cobar 的各项性能指标,如 SQL 执行时间,是否失败,返回行数等,这样方便我们分析 Cobar 的各项指标,这就是我们常说的 SQL 审计(记录数据库发生的各种事件),那怎么样才能高效记录这些事件而又不对执行业务代码的线程造成影响呢?

要记录上报这些审计事件,肯定不能在执行业务代码的线程里执行,因为这些事件属于业务无关的代码,如果在业务线程里执行,一来和业务代码藕合,二来如果这些审计事件传输(记录审计事件总要通过磁盘或网络记录下来)遇到瓶颈会对正常的业务逻辑造成严重影响。我们可以修改一下 cobar 代码,在 cobar 里的执行逻辑中拿到这些事件后,把这些事件先缓存在队列中,让另外的线程从这些队列里慢慢取出(消费),然后再将这些数据上报,这样业务线程可以立即返回执行其他正常的业务逻辑。

2 (1)

注:虚线部分为对 cobar 中间件的改造,业务调用是无感知的 如图示,主要步骤如上图所示

客户端请求后执行 cobar

cobar 执行后将「执行时间」,「是否失败」,「返回行数」等写入队列

写入队列后业务线程立即返回,然后可以执行正常的业务逻辑

后台线程则不断取出 event 通过 UDP 传给另外一个机器,写入 kafka 进行上报

小伙子不错啊,一看这架构图就知道有点东西,但我这里有点疑问,在第二步中,为啥不把 SQL 审计的那些指标直接写入 kafka 呢,如下

kafaka 不是号称写入性能可达几十甚至上百万吗,像上述这样实现架构上实现不是更简单吗

这是个很好的问题,有以下两个原因

我们是对 cobar 工程本身进行修改,然后将其打成 jar 包再集成到应用程序中来的,如果采用上面的设计,那就意味着要在 cobar 工程中引入对 kafka 的依赖,而我们只想对 cobar 作少量的修改,不想依赖太多第三方的库

这也是最重要的,引入 kafka 本身会导致可用性降低,有可能会阻塞业务线程,在 kafka Producer 中,设计了一个消息缓冲池,客户端发送的消息首先会被存储到缓冲池中,同时 Producer 启动后还会启动一个 sender 线程不断地获取缓冲池中的消息将其发送到 Broker 中

如图示,我们在构建 kafka producer 时,会有一个自定义缓冲池大小的参数 buffer.memory,默认大小为 32M,因此缓冲池的大小是有限制,那如果这个缓存池满了怎么办,RecordAccumulator 是 Kafaka 缓冲池的核心类,官方对其注释写得非常清楚

The accumulator uses a bounded amount of memory and append calls will block when that memory is exhausted, unless this behavior is explicitly disabled.

也就是说如果缓存池满 了,消息追加调用将会被阻塞,直到有空闲的内存块,这样的话只要 Kafka 集群负载很高或者网络稍有波动,Sender 线程从缓冲池捞取消息的速度赶不上客户端发送的速度,就会造成客户端(也就是 Cobar 执行线程)发送被阻塞,这样的话可能导致线上几乎所有接口调用雪崩,系统不可用,导致严重的灾难!

而原来的设计看似复杂,但实际上符合软件设计中的分层原则,这样的设计有两个好处,如下图示:

首先 Cobar 执行线程将审计信息丢给队列后

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值