Maxwell 底层原理 详解

        Maxwell 是一个 MySQL 数据库的增量数据捕获(CDC, Change Data Capture)工具,它通过读取 MySQL 的 binlog(Binary Log)来捕获数据变化,并将这些变化实时地发送到如 Kafka、Kinesis、RabbitMQ 或其他输出端。Maxwell 允许用户捕捉到 INSERT、UPDATE、DELETE 等操作的记录,并将其以 JSON 格式发送到下游系统,用于数据同步、分析、实时监控等应用场景。

        要详细解释 Maxwell 的底层原理及源代码,我们需要从 MySQL binlog 的工作机制、Maxwell 如何解析 binlog、内部架构的各个核心组件、事件处理机制等多方面进行深入解析。

1. MySQL binlog 工作原理

        MySQL 的 binlog 是记录数据库事务性和非事务性数据变化的二进制日志文件,所有的 INSERT、UPDATE、DELETE 以及对表结构的更改操作(如 ALTER TABLE)都会写入 binlog 中。这使得 binlog 成为数据库增量数据捕获的重要来源。

binlog 具有两种格式:

  • ROW 格式:记录每一行的数据变化,捕捉到行级别的增删改操作。
  • STATEMENT 格式:记录 SQL 语句本身的执行。
  • MIXED 格式:结合了 ROW 和 STATEMENT 两种格式。

➢ 三种格式的区别:

◼ statement

语句级,binlog 会记录每次一执行写操作的语句。相对 row 模式节省空间,但是可能产生不一致性,比如update test set create_date=now();如果用 binlog 日志进行恢复,由于执行时间不同可能产生的数据就不同。优点:  节省空间   缺点:  有可能造成数据不一致。

◼ row

行级,  binlog 会记录每次操作后每行记录的变化。优点:保持数据的绝对一致性。因为不管 sql 是什么,引用了什么函数,他只记录执行后的效果。缺点:占用较大空间。

◼ mixed

混合级别,statement  的升级版,一定程度上解决了 statement 模式因为一些情况而造成的数据不一致问题。默认还是 statement,在某些情况下,譬如:当函数中包含  UUID()  时;包含  AUTO_INCREMENT  字段的表被更新时;执行  INSERT DELAYED  语句时;用  UDF  时;会按照  ROW 的方式进行处理  优点:节省空间,同时兼顾了一定的一致性。缺点:还有些极个别情况依旧会造成不一致,另外 statement 和 mixed 对于需要对binlog 监控的情况都不方便。

        Maxwell 依赖的是 ROW 格式,因为 ROW 格式可以直接获取到数据变化的细节,如具体哪一行数据发生了修改,这对于实时的数据同步和分析非常关键。

2. Maxwell 架构与工作流程

Maxwell 的架构可以概括为以下几个部分:

  1. Binlog Position 监控:Maxwell 会从 MySQL 的 binlog 文件中读取增量变化事件,且会记录当前读取到的 binlog 文件的位置(position),以保证在 Maxwell 重启后能够继续从上次的位置读取。
  2. Binlog 解析:Maxwell 通过解析 MySQL 的 binlog 文件来获取数据的变化详情(包括表名、列值、操作类型等)。
  3. 事件处理器(Event Processor):解析后的 binlog 数据会通过 Maxwell 的事件处理器进行处理,并转换为 JSON 格式。
  4. 输出适配器(Producer Adapter):Maxwell 支持将处理后的数据发送到多个目标输出(如 Kafka、Kinesis 等)。
2.1 核心组件

Maxwell 的底层工作机制由以下几个核心组件协同实现:

  1. BinlogConnectorReplicator

    • 负责与 MySQL 进行通信并获取 binlog 数据。
    • 使用 MySQL Binary Log Client Library 实现 binlog 的读取和消费。Maxwell 通过 BinlogConnectorReplicator 连接 MySQL,获取实时的 binlog 数据。
  2. BinlogParser

    • 负责将二进制格式的 binlog 转换为可理解的事件对象。
    • 它解析 ROW 格式的 binlog 并将其转换为 Maxwell 可以处理的内部事件对象(如 Insert、Update、Delete 事件)。
  3. MaxwellContext

    • 管理 Maxwell 的运行状态,包括当前的 binlog position、错误处理、断点续传等。
    • MaxwellContext 还负责维护 Maxwell 的元数据(如表结构缓存、上次处理的 binlog 位置等),以保证数据的一致性和容错性。
  4. MaxwellReplicator

    MaxwellReplicator 是系统的核心执行器,它从 BinlogConnectorReplicator 获取 binlog 数据,并通过 BinlogParser 解析这些数据,生成 RowMap 对象(用于描述数据变化)。
  5. RowMap

    RowMap 是 Maxwell 对数据变更的内部抽象,它将 binlog 中的行变化转化为键值对的形式,包含了表名、数据库名、操作类型(insert、update、delete)以及具体的行数据。
  6. Producer

    • Producer 是事件发布器,它负责将处理过的事件推送到外部系统(如 Kafka、Kinesis、文件等)。
    • Producer 将 RowMap 转换为 JSON 格式并将其发送至指定的输出端。
2.2 事件流处理流程

Maxwell 的数据流处理可以分为以下几个步骤:

  1. 读取 binlog:Maxwell 通过 BinlogConnectorReplicator 从 MySQL binlog 中读取最新的事件。
  2. 解析 binlogBinlogParser 将 binlog 的二进制数据解析为内部事件对象(如 InsertUpdateDelete 事件)。
  3. 生成事件对象:解析后的 binlog 事件会被封装为 RowMap 对象,RowMap 中包含了数据库名、表名、操作类型、变更的数据行内容。
  4. 事件发布:通过 Producer,Maxwell 将 RowMap 转换为 JSON 格式,并发送到外部系统,如 Kafka、Kinesis 等。

    格式数据举例


    json 字段的说明:

    字段

    解释

    database

    变更数据所属的数据库

    table

    表更数据所属的表

    type

    数据变更类型

    ts

    数据变更发生的时间

    xid

    事务id

    commit

    事务提交标志,可用于重新组装事务

    data

    对于insert类型,表示插入的数据;对于update类型,标识修改之后的数据;对于delete类型,表示删除的数据

    old

    对于update类型,表示修改之前的数据,只包含变更字段

3. 源代码分析

为了更详细地解释 Maxwell 的工作原理,接下来分析其核心类的部分源代码。

3.1 BinlogConnectorReplicator(binlog 读取器)

        BinlogConnectorReplicator 是 Maxwell 通过 binlog client 读取 MySQL binlog 数据的核心组件。它负责通过 MySQL Replication 协议从 MySQL 实例拉取 binlog 事件。

public class BinlogConnectorReplicator extends AbstractReplicator {
    private BinaryLogClient client;
    private MaxwellFilter filter;

    public BinlogConnectorReplicator(MaxwellContext context, Position startPosition) throws Exception {
        super(context);
        this.client = new BinaryLogClient(
            context.getConfig().mysqlHost,
            context.getConfig().mysqlPort,
            context.getConfig().mysqlUser,
            context.getConfig().mysqlPassword
        );
        // 设置监听器处理 binlog 事件
        client.registerEventListener(this::handleEvent);
    }

    public void start() throws IOException {
        // 启动客户端开始从 binlog 中获取数据
        client.connect();
    }

    private void handleEvent(Event event) {
        // 处理 binlog 事件
        // 将 event 转换为 Maxwell 的 RowMap 对象
    }
}

在上面的代码中:

  • BinaryLogClient 是用来与 MySQL binlog 进行通信的核心类,它会与 MySQL 建立连接并监听 binlog 的变化。
  • handleEvent 方法会被 MySQL binlog 的事件触发,当 binlog 中有新事件时,该方法会被调用,将事件处理并转换为 Maxwell 的内部对象。
3.2 BinlogParser(binlog 解析器)

        BinlogParser 负责将从 binlog 中获取的二进制事件解析为 Maxwell 可以理解的对象。对于每个 binlog 事件,都会转换为相应的 RowMap 对象。

public class BinlogParser {
    public RowMap parse(Event event) {
        EventType type = event.getHeader().getEventType();

        // 根据 binlog 事件类型处理不同的操作
        switch (type) {
            case WRITE_ROWS:
                return handleInsertEvent(event);
            case UPDATE_ROWS:
                return handleUpdateEvent(event);
            case DELETE_ROWS:
                return handleDeleteEvent(event);
            default:
                return null;
        }
    }

    private RowMap handleInsertEvent(Event event) {
        // 解析 insert 事件,将其封装为 RowMap
    }

    private RowMap handleUpdateEvent(Event event) {
        // 解析 update 事件,将其封装为 RowMap
    }

    private RowMap handleDeleteEvent(Event event) {
        // 解析 delete 事件,将其封装为 RowMap
    }
}

在 BinlogParser 中:

  • parse 方法会根据事件类型(如 WRITE_ROWSUPDATE_ROWSDELETE_ROWS)调用对应的处理方法,将事件转换为 RowMap
  • RowMap 是用于描述数据变化的核心对象,包含了具体的数据变化信息。
3.3 RowMap(事件描述对象)

        RowMap 是 Maxwell 中的核心数据结构,负责存储解析后的 binlog 数据。它包含了数据库名、表名、操作类型(如 insert、update、delete)以及具体的列值数据。

public class RowMap {
    private String database;
    private String table;
    private String type; // insert, update, delete
    private Map<String, Object> data;

    public RowMap(String database, String table, String type) {
        this.database = database;
        this.table = table;
        this.type = type;
        this.data = new HashMap<>();
    }

    public void putData(String column, Object value) {
        data.put(column, value);
    }

    public String toJSON() {
        // 将 RowMap 转换为 JSON 字符串
    }
}

在 RowMap 中:

  • database 和 table 表示数据变更的数据库和表。
  • type 表示操作类型(INSERT、UPDATE、DELETE)。
  • data 是存储行变化数据的键值对映射(列名 -> 值)。
3.4 Producer(事件发布器)

        Producer 负责将处理好的事件(即 RowMap)发送到外部系统,如 Kafka 或 Kinesis。Maxwell 提供了多种 Producer 实现,用户可以选择适合自己需求的 Producer。

public class KafkaProducer extends AbstractProducer {
    private org.apache.kafka.clients.producer.KafkaProducer<String, String> kafkaProducer;

    public KafkaProducer(MaxwellContext context) {
        Properties props = new Properties();
        props.put("bootstrap.servers", context.getConfig().kafkaBootstrapServers);
        this.kafkaProducer = new org.apache.kafka.clients.producer.KafkaProducer<>(props);
    }

    @Override
    public void push(RowMap r) {
        String topic = getKafkaTopic(r);
        String key = r.getPrimaryKey();
        String value = r.toJSON();

        kafkaProducer.send(new ProducerRecord<>(topic, key, value));
    }
}

在 KafkaProducer 中:

  • push 方法将 RowMap 对象转换为 JSON 格式,并发送到指定的 Kafka topic。

4. Maxwell 高级特性

  1. Schema 变更捕获:Maxwell 也能够捕捉 MySQL 表结构的变化(如 ALTER TABLE),它维护了一份 schema 的缓存,以便解析 binlog 事件时能够正确映射列与值。

  2. 断点续传:Maxwell 记录并维护 binlog 的位置,当服务重启或崩溃时,能够从上次停止的位置继续读取,不会丢失任何数据。

  3. 过滤:Maxwell 支持基于数据库和表的过滤,用户可以通过配置文件或命令行参数来指定需要捕获或忽略的数据库和表。

  4. 事务处理:Maxwell 通过 binlog 的事务边界来确保事件的顺序性和一致性,保证在输出端(如 Kafka)消费时,数据的顺序与数据库中的顺序一致。

总结

        Maxwell 是一个轻量级的 MySQL binlog 解析工具,它通过 BinlogConnectorReplicator 连接 MySQL 并获取 binlog 数据,利用 BinlogParser 解析这些二进制日志,将其转化为易于处理的 RowMap 对象,并通过 Producer 发送到外部系统。Maxwell 提供了灵活的输出方式和良好的容错机制,适用于实时数据同步和流式数据处理场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/894109.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

信息搜集 --前端js打点

前端js打点 什么是js渗透测试 在Javascript中也存在变量和函数&#xff0c;当存在可控变量及函数调用即可参数漏洞JS开发的WEB应用和PHP&#xff0c;JAVA,NET等区别在于即没有源代码&#xff0c;也可以通过浏览器的查看源代码获取真实的点。获取URL&#xff0c;获取Js敏感信息&…

永磁同步电机控制算法--非线性自抗扰NLADRC转速环控制器(1)

一、原理介绍 ADRC由跟踪微分器(TD)、扩张状态观测器(ESO)和非线性状态误差反馈控制律(NLSEF)三部分组成。 其中SMC-LSEF表达式为: e3v1-z1u0ζsign(s)-ks-ce3u(u0-z2)/b 二、仿真验证 在MATLAB/simulink里面验证所提算法&#xff0c;采用和实验中一致的控制周期1e-4&#…

Navigation2 算法流程

转自 https://zhuanlan.zhihu.com/p/405670882 此文仅作学习笔记 启动流程 在仿真环境中启动导航包的示例程序&#xff0c;执行nav2_bringup/bringup/launch/tb3_simulation_launch.py文件。ROS2的launch文件支持采用python语言来编写以支持更加复杂的功能&#xff0c;本文件…

性能测试工具JMeter

本次使用的博客系统的url&#xff1a; http://8.137.19.140:9090/blog_edit.html 1. JMeter介绍 环境要求&#xff1a;要求java&#xff0c;jdk版本大于8&#xff1b; Apache JMeter 是 Apache 组织基于 Java 开发的压⼒测试⼯具&#xff0c;⽤于对软件做性能测试&#xff1b…

请问:ESModule 与 CommonJS 的异同点是什么?

前言 本篇文章不会介绍模块的详细用法&#xff0c;因为核心是重新认识和理解模块的本质内容是什么&#xff0c;直奔主题&#xff0c;下面先给出最后结论&#xff0c;接下来在逐个进行分析。 ECMAScript Module 和 CommonJS 的相同点&#xff1a; 都拥有自己的缓存机制&#…

分布式链路追踪原理:

我的后端学习大纲 SpringCloud学习大纲 假定三个微服务调用的链路如下图所示&#xff1a;Service 1 调用 Service 2&#xff0c;Service 2 调用 Service 3 和 Service 4 1、完整的调用链路&#xff1a; 1.1.原理分析&#xff1a; 1.那么一条链路追踪会在每个服务调用的时候加…

在PC端使用微信浏览器的调试功能

首先&#xff0c;此功能只限自己开发网页&#xff0c;其次&#xff0c;这是为了帮助使用了微信的相关JS SDK功能&#xff0c;比如微信登录&#xff0c;在不方便使用电脑上的浏览器时使用的的。 方法&#xff1a; 在网页中插入 <script src"https://unpkg.com/vconso…

Java根据word 模板,生成自定义内容的word 文件

Java根据word 模板&#xff0c;生成自定义内容的word 文件 背景1 使用技术2 实现方法依赖啊 3 问题4 背景 主要是项目中需要定制化一个word&#xff0c;也就是有一部分是固定的&#xff0c;就是有一个底子&#xff0c;框架&#xff0c;里面的内容是需要填充的。然后填充的内容…

WPF常见容器全方位介绍

Windows Presentation Foundation (WPF) 是微软的一种用于构建Windows桌面应用程序的UI框架。WPF的布局系统基于容器&#xff0c;帮助开发者以灵活、响应的方式组织用户界面 (UI) 元素。本篇文章将详细介绍WPF中几种常见的容器&#xff0c;包括Grid、StackPanel、WrapPanel、Do…

基于51单片机的proteus数字时钟仿真设计

注意&#xff1a;本项目是本人大学时期的课设项目&#xff0c;不得在未经本人允许下进行转载或商用 数字钟设计 项目背景与意义 在信息化时代&#xff0c;时间管理成为了我们日常生活中不可或缺的一部分。数字钟作为一种常见的时间显示设备&#xff0c;因其精确、直观、易读等…

如何捕捉行情爆发的前兆

在金融市场的激烈角逐中&#xff0c;每一次行情的爆发都是投资者获取丰厚回报的关键时刻。然而&#xff0c;如何识别并把握这些时刻&#xff0c;却是一门需要深厚金融专业知识和敏锐洞察力的艺术。今天&#xff0c;我们就来深入探讨行情爆发的初期信号&#xff0c;揭示那些能够…

Jlink 直接读取单片机数据

1. 驱动版本 因人而异&#xff0c;这里我使用的是 “J-Flash V6.96” 本人驱动链接&#xff1a;夸克网盘 提取码&#xff1a;rgzk 2. 打开软件 3. 创建jlink工程 4. 选择芯片 此处本人使用芯片 “STM32F103VCT6” 5. 连接单片机 连接成功反馈 6. 读取单片机内部数据 …

【2024|FTransUNet|论文解读1】融合视界:解密FTransUNet在遥感语义分割中的创新突破

【2024|FTransUNet|论文解读1】融合视界&#xff1a;解密FTransUNet在遥感语义分割中的创新突破 【2024|FTransUNet|论文解读1】融合视界&#xff1a;解密FTransUNet在遥感语义分割中的创新突破 文章目录 【2024|FTransUNet|论文解读1】融合视界&#xff1a;解密FTransUNet在遥…

web 0基础第四节 多媒体标签

图片标签 主要是讲解 在html 中 怎么将图片放入其中 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <…

Django模型优化

1、创建一个Django项目 可参考之前的带你快速体验Django web应用 我使用的是mysql数据库。按照上述教程完成准备工作。 2、创建一个app并完成注册 demo主要来完成创建用户、修改用户、查询用户、删除用户的操作。 python manage.py startapp test0023、app的目录 新建templ…

【Spring AI】Java实现类似langchain的第三方函数调用_原理与详细示例

Spring AI 介绍 &#xff1a;简化Java AI开发的统一接口解决方案 在过去&#xff0c;使用Java开发AI应用时面临的主要困境是没有统一且标准的封装库&#xff0c;导致开发者需要针对不同的AI服务提供商分别学习和对接各自的API&#xff0c;这增加了开发难度与迁移成本。而Sprin…

【文献综述】扩散模型在文本生成中的进展

【文献综述】扩散模型在文本生成中的进展 Diffusion models in text generation: a survey 摘要&#xff1a; 扩散模型是一种基于数学的模型&#xff0c;最初应用于图像生成。最近&#xff0c;他们对自然语言生成&#xff08;NLG&#xff09;产生了广泛的兴趣&#xff0c;这是…

一起搭WPF架构之livechart的MVVM使用介绍

一起搭WPF架构之livechart使用介绍 前言ModelViewModelView界面设计界面后端 效果总结 前言 简单的架构搭建已经快接近尾声了&#xff0c;考虑设计使用图表的形式将SQLite数据库中的数据展示出来。前期已经介绍了livechart的安装&#xff0c;今天就详细介绍一下livechart的使用…

03 设计模式-创造型模式-单例模式

单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建…

HarmonyOS开发(State模型)

一、State模型概述 FA&#xff08;Feature Ability&#xff09;模型&#xff1a;从API 7开始支持的模型&#xff0c;已经不再主推。 Stage模型&#xff1a;从API 9开始新增的模型&#xff0c;是目前主推且会长期演进的模型。在该模型中&#xff0c;由于提供了AbilityStage、Wi…