Maxwell 底层原理 详解

news2024/11/26 19:32:01

        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 提供了灵活的输出方式和良好的容错机制,适用于实时数据同步和流式数据处理场景。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

字节跳动青训营——入营考核解答(持续更新中~~~)

考核内容&#xff1a; 在指定的题库中自主选择不少于 15 道算法题并完成解题&#xff0c;其中题目难度分配如下&#xff1a; 简单题不少于 10 道中等题不少于 4 道困难题不少于 1 道 解答代码 20. 百分位数&#xff08;中等&#xff09; 代码实现&#xff1a; import jav…

Uiautomator2与weditor配置一直报错咋办

作者在配置这两个的时候绞尽脑汁了&#xff0c;u2的init总是报错并且无法自动在手机上安装atx&#xff0c;weditor可以打开但是只要对元素操作或者任意操作就会让你去重新init&#xff0c;搞得作者焦头烂额&#xff0c;而且网上各种各样的报错信息眼花缭乱&#xff0c;作者几乎…

【深入学习Redis丨第八篇】详解Redis数据持久化机制

前言 Redis支持两种数据持久化方式&#xff1a;RDB方式和AOF方式。前者会根据配置的规则定时将内存中的数据持久化到硬盘上&#xff0c;后者则是在每次执行写命令之后将命令记录下来。两种持久化方式可以单独使用&#xff0c;但是通常会将两者结合使用。 一、持久化 1.1、什么…

基于neo4j知识图谱的菜谱推荐系统

&#x1f374; AI菜谱推荐系统让你“煮”事半功倍&#xff01; &#x1f374; 找不到做饭灵感的时候&#xff0c;是不是总觉得“今天吃啥”这道选择题简直是终极挑战&#xff1f;别急&#xff0c;我们基于Neo4j知识图谱的菜谱推荐系统&#xff0c;正是为了解决你的困扰而设计&a…

linux线程 | 同步与互斥 | 全解析信号量、环形生产消费者模型

前言: 本节内容讲述linux下的线程的信号量&#xff0c; 我们在之前进程间通信那里学习过一部分信号量&#xff0c; 但是那个是systemV版本的信号量&#xff0c;是以进程间通信的视角谈的。 但是本篇内容会以线程的视角谈一谈信号量。 ps&#xff1a;本篇内容建议学习了生产者消…

集合collection和泛型

collection可以直接打印内容&#xff0c;而不是地址&#xff0c;内部已经重写了。 List家族&#xff1a; package com.itheima.d6_collection_update_delete;import java.util.ArrayList; import java.util.Iterator; import java.util.List;/**目标&#xff1a;研究集合遍历并…

解决关于HTML+JS + Servlet 实现前后端请求Session不一致的问题

1、前后端不分离情况 在处理session过程中&#xff0c;如果前后端项目在一个容器中&#xff0c;session是可以被获取的。例如如下项目结构&#xff1a; 结构 后端的代码是基本的设置值、获取值、销毁值的内容&#xff1a; 运行结果 由此可见&#xff0c;在前后统一的项目中&a…

Sign Language Dataset: 聋哑人手语数据集(猫脸码客 第209期)

Sign Language Dataset: 聋哑人手语数据集 摘要&#xff1a;手语是聋哑人群体进行沟通交流的重要工具&#xff0c;通过手势、动作及面部表情的组合表达复杂的思想和情感。随着计算机视觉和人工智能技术的发展&#xff0c;聋哑人手语数据集在促进手语识别、翻译和交互系统开发中…

计算机指令系统,打个结~

计算机指令系统是计算机硬件与软件之间的桥梁&#xff0c;它定义了计算机能够执行的各种操作。一个完善的指令系统不仅影响着计算机的性能&#xff0c;还直接决定了计算机能够完成的任务种类和复杂度。本文将从计算机指令的基本概念出发&#xff0c;探讨指令系统的分类、常见指…

第13篇:无线与移动网络安全

目录 引言 13.1 无线网络的安全威胁 13.2 无线局域网的安全协议 13.3 移动通信中的安全机制 13.4 蓝牙和其他无线技术的安全问题 13.5 无线网络安全的最佳实践 13.6 总结 第13篇&#xff1a;无线与移动网络安全 引言 无线和移动网络的发展为我们的生活带来了极大的便利…

cisco网络安全技术第3章测试及考试

测试 使用本地数据库保护设备访问&#xff08;通过使用 AAA 中央服务器来解决&#xff09;有什么缺点&#xff1f; 试题 1选择一项&#xff1a; 必须在每个设备上本地配置用户帐户&#xff0c;是一种不可扩展的身份验证解决方案。 请参见图示。AAA 状态消息的哪一部分可帮助…

Java程序设计:spring boot(2)

目录 1 Spring MVC 零配置创建与部署 1.1 创建Spring MVC Web⼯程 1.2 pom.xml 添加坐标相关配置 1.3 添加源代码 1.4 添加视图 1.5 SpringMVC 配置类添加 1.6 入口文件代码添加 1.7 部署与测试 2 Spring Boot 概念&特点 2.1 框架概念 2.2 框架特点 2.3 Spring…

微知-如何临时设置服务器风扇转速?(ipmitool raw 0x30 0x30 0x02 0xff 0x40)

服务器风扇可以通过PWM输出来控制转速。 设置方式 设置单次PWM ipmitool raw 0x30 0x30 0x02 0xff 0x40如果要持续设置需要类似while循环持续输出&#xff1a; while true; do ipmitool raw 0x30 0x30 0x02 0xff 0x64; done > /dev/null参数说明&#xff1a; 其他参数&a…

Qt(简介)

1. Qt简介 Qt是一个基于C的图形用户界面&#xff08;GUI&#xff09;框架&#xff0c;可以开发可视化人机交互程序&#xff0c;但是这并不是Qt的全部。Qt除了可以绘制漂亮的界面外&#xff0c;还包含很多其他的功能&#xff1a;多线程、数据库、图像处理、音视频处理、网络通信…

CentOS安装NVIDIA驱动、CUDA以及nvidia-container-toolkit

0.提前准备 0.1.更新yum源&#xff08;以阿里为例&#xff09; 0.1.1 备份当前的yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 0.1.2 下载新的CentOS-Base.repo 到/etc/yum.repos.d/ CentOS 5 wget -O /etc/yum.repos.d/CentOS-Base…

【LeetCode每日一题】——523.连续的子数组和

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 前缀和 二【题目难度】 中等 三【题目编号】 523.连续的子数组和 四【题目描述】 给你一个…

github学生认证(白嫖copilot)-Why are you not on campus?不在校园内

详细申请操作流程可参考如下博文&#xff1a;从0开始的github学生认证并使用copilot教程&#xff08;超详细&#xff01;&#xff09;_copilot学生认证-CSDN博客 在此记录解决“Why are you not on campus?”提示的方法&#xff1a; 当出现这个提示时&#xff0c;说明在选择学…

2024年底蓝奏云最新可用API接口列表 支持优享版 无需手动抓取cookie

Lanzou Pro V1 接口列表 API状态版本路由获取文件与目录✅^1.0.1/v1/getFilesAndDirectories?url{}&page{}获取目录✅^1.0.0/v1/getDirectory?url{}获取文件✅^1.0.1/v1/getFiles?url{}&page{}搜索文件✅^1.0.0/v1/searchFile?url{}&wd{}依Id解析✅^1.0.2/v1/…

从0-1实战演练后台管理系统 (2)从零开始:Pure Admin 环境搭建完全指南,小白也能轻松掌握!

在开始使用Pure Admin之前&#xff0c;我们需要先了解一下Pure Admin是什么? vue-pure-admin (opens new window)是一款开源完全免费且开箱即用的中后台管理系统模版。完全采用 ECMAScript 模块&#xff08;ESM&#xff09;规范来编写和组织代码&#xff0c;使用了最新的 Vue3…

【原创】java+ssm+mysql计算机等级考试网系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…