《重学Java高并发》Disruptor使用实战

  • EventHandler

事件处理器在获取一个可处理的事件后调用EventHandler的onEvent方法,这也是用户自定处理程序的入口,即编写用户业务代码的扩展点

  • ExceptionHandler

异常处理策略。

2、disruptor在canal中的运用


首先以笔者在工作中遇到一个经典使用场景来和大家观摩一下disruptor的基本使用。

在互联网行业中有一种经典的读写分离架构:数据异构,以物流下单为示例,通常关系型数据库只负责订单的创建业务,而关于订单查询、订单轨迹查询等查询类业务,通常会去查询es,依此来降低数据库压力,但接踵而来的问题是如何将数据库的数据准实时同步到Es呢?canal闪亮登场,其核心理念就是订阅并解析binlog,其基本的流程如下:

在这里插入图片描述

在示例中解析binlog的目的是提取数据的变化,即DML语句(插入、更新、删除),将这些数据变更在目标端进行重放,为了提高性能,采用disruptor框架提高性能,该如何实现呢?

  • 将解析动作分解为两步,第一步判断事件是否是dml事件,即是否需要解析。

  • 解析dml

为什么要这样拆分呢?一是将粒度降低,解耦,灵活提供不一样的并发度。

接下来我们看一下canal中是如何使用disruptor来解决该问题的。

2.1 创建EventFactory

首先需要创建一个EventFactory,用于填充RingBuffer中的对象,避免过多垃圾回收。

在这里插入图片描述

2.2 创建RingBuffer

根据bingo dump协议,mysql的解析线程创建一个,故该场景下的事件发送者只有一个,创建一个单生产者的RingBuffer,其代码如下:

在这里插入图片描述

2.3 创建相关的业务Handler

在该场景中需要定义两个handler,由于是具体的业务逻辑,这里不做详细介绍,简单截图说明如下:

在这里插入图片描述

2.4 创建栅栏(顺序性保证)

由于binlog解析场景有一个特殊的场景:并发解析但不能破坏顺序性语义。

在这里插入图片描述

2.5创建事件处理器

在这里插入图片描述

在解析事件类型、元数据时采用了BatchEventProcessor,但使用了批处理机制;而在解析dml具体数据时采用了WorkProcessor,支持多线程并发解析。

值得注意的是dml解析器必须依赖元数据解析器,故这里需要引入栈栏,具体是利用RingBuffer的addGatingSequences方法依次将自身处理器的sequences加入到RingBuffer中。

2.6 生产者端代码模板

生长者这边主要是将数据写入到RingBuffer中,从而让下游消费。

在这里插入图片描述

上述代码的特点:

  • 使用 do while 循环,持续放入。

  • 首先调用 RingBuffer的tryNext,尝试获取一个可写的序号,如果获取不到,则重试。

  • 获取一个可写序号号,将值进行填充,然后调用publish方法进行发布,让消费端可感知。

如果序列器一次可以返回一批序号,则可以在一个批次处理,即降低了获取序号的次数。


本文就介绍到这里了,经过上述的讲述,大家对disruptor无锁化的实现原理应该有了一个比较全面而清晰的理解,也欢迎大家关注我的公众号,加我微信dingwpmz,共同探讨交流。

总结

大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。

麻烦帮忙转发一下这篇文章+关注我

就这一次!拼多多内部架构师培训Kafka源码笔记(现已绝版)

统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。

麻烦帮忙转发一下这篇文章+关注我

[外链图片转存中…(img-cmcmlyEQ-1716305673224)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值