数据库数据实时采集--Maxwell

1、Maxwell 简介

  • Maxwell 是一个能实时读取 MySQL 二进制日志文件binlog,并生成 Json格式的消息,作为生产者发送给 Kafka,Kinesis、RabbitMQ、Redis、
    Google Cloud Pub/Sub、文件或其它平台的应用程序。它的常见应用场景有ETL、维护缓存、收集表级别的dml指标、增量到搜索引擎、数据分区迁移、
    切库binlog回滚方案等。

  • Maxwell主要提供了下列功能

      1. 支持SELECT * FROM table的方式进行全量数据初始化。
      1. 支持在主库发生failover后,自动恢复binlog位置,实现断点续传。
      1. 可以对数据进行分区,解决数据倾斜问题,发送到Kafka的数据支持库、表、列等级别的数据分区。
      1. 工作方式是伪装为slave接收binlog events,然后根据schema信息拼装,可以接受ddl、xid、row等event。

2、Mysql Binlog介绍

2.1 Binlog 简介

  • MySQL中一般有以下几种日志

    日志类型写入日志的信息
    错误日志 记录在启动,运行或停止mysqld时遇到的问题
    通用查询日志 记录建立的客户端连接和执行的语句
    二进制日志 binlog 记录更改数据的语句
    中继日志 从服务器 复制 主服务器接收的数据更改
    慢查询日志 记录所有执行时间超过 long_query_time 秒的所有查询或不使用索引的查询
    DDL日志(元数据日志) 元数据操作由DDL语句执行
  • 在默认情况下,系统仅仅打开错误日志,关闭了其他所有日志,以达到尽可能减少IO损耗提高系统性能的目的,但是在一般稍微重要一点的实际应用场景中,都至少需要打开二进制日志,因为这是MySQL很多存储引擎进行增量备份的基础,也是MySQL实现复制的基本条件

  • 接下来主要介绍二进制日志 binlog。

    • MySQL 的二进制日志 binlog 可以说是 MySQL 最重要的日志,它记录了所有的 DDL 和 DML 语句(除了数据查询语句select、show等),以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。binlog 的主要目的是复制和恢复
  • Binlog日志的两个最重要的使用场景

    • MySQL主从复制
      • MySQL Replication在Master端开启binlog,Master把它的二进制日志传递给slaves来达到master-slave数据一致的目的。
    • 数据恢复
      • 通过使用 mysqlbinlog工具来使恢复数据。

2.2 Binlog 的日志格式

  • 记录在二进制日志中的事件的格式取决于二进制记录格式。支持三种格式类型:

    • Statement:基于SQL语句的复制(statement-based replication, SBR)
    • Row:基于行的复制(row-based replication, RBR)
    • Mixed:混合模式复制(mixed-based replication, MBR)
  • Statement

    • 每一条会修改数据的sql都会记录在binlog中。
    • 优点
      • 不需要记录每一行的变化,减少了binlog日志量,节约了IO, 提高了性能。
    • 缺点
      • 在进行数据同步的过程中有可能出现数据不一致。
      • 比如 update tt set create_date=now(),如果用binlog日志进行恢复,由于执行时间不同可能产生的数据就不同。
  • Row

    • 它不记录sql语句上下文相关信息,仅保存哪条记录被修改。
    • 优点
      • 保持数据的绝对一致性。因为不管sql是什么,引用了什么函数,它只记录执行后的效果。
    • 缺点
      • 每行数据的修改都会记录,最明显的就是update语句,导致更新多少条数据就会产生多少事件,占用较大空间。
  • Mixed

    • 从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合。
    • 在Mixed模式下,一般的复制使用Statement模式保存binlog,对于Statement模式无法复制的操作使用Row模式保存binlog, MySQL会根据执行的SQL语句选择日志保存方式(因为statement只有sql,没有数据,无法获取原始的变更日志,所以一般建议为Row模式)。
    • 优点
      • 节省空间,同时兼顾了一定的一致性。
    • 缺点
      • 还有些极个别情况依旧会造成不一致,另外statement和mixed对于需要对binlog的监控的情况都不方便。

3、Mysql 实时数据同步方案对比

  • mysql 数据实时同步可以通过解析mysql的 binlog 的方式来实现,解析binlog可以有多种方式,可以通过canal,或者maxwell等各种方式实现。以下是各种抽取方式的对比介绍。

  • 其中canal由 Java开发,分为服务端和客户端,拥有众多的衍生应用,性能稳定,功能强大;canal 需要自己编写客户端来消费canal解析到的数据。

  • Maxwell相对于canal的优势是使用简单,Maxwell比Canal更加轻量级,它直接将数据变更输出为json字符串,不需要再编写客户端。对于缺乏基础建设,短时间内需要快速迭代的项目和公司比较合适。

  • 另外Maxwell 有一个亮点功能,就是Canal只能抓取最新数据,对已存在的历史数据没有办法处理。而Maxwell有一个bootstrap功能,可以直接引导出完整的历史数据用于初始化,非常好用。

4、开启Mysql的Binlog

  • 1、服务器当中安装mysql(省略)

    • 注意:mysql的版本尽量不要太低,也不要太高,最好使用5.6及以上版本。
  • 2、添加mysql普通用户maxwell

    • 为mysql添加一个普通用户maxwell,因为maxwell这个软件默认用户使用的是maxwell这个用户。

    • 进入mysql客户端,然后执行以下命令,进行授权

      mysql -uroot -p123456
      
    • 执行sql语句

      --校验级别最低,只校验密码长度
      mysql> set global validate_password_policy=LOW;
      mysql> set global validate_password_length=6;
      
      --创建maxwell库(启动时候会自动创建,不需手动创建)和用户
      mysql> CREATE USER 'maxwell'@'%' IDENTIFIED BY '123456';
      mysql> GRANT ALL ON maxwell.* TO 'maxwell'@'%';
      mysql> GRANT SELECT, REPLICATION CLIENT, REPLICATION SLAVE on *.* to 'maxwell'@'%'; 
      --刷新权限
      mysql> flush privileges;
      
  • 3、修改配置文件 /etc/my.cnf

    • 执行命令 sudo vim /etc/my.cnf, 添加或修改以下三行配置

      #binlog日志名称前缀
      log-bin= /var/lib/mysql/mysql-bin
      
      #binlog日志格式
      binlog-format=ROW
      
      #唯一标识,这个值的区间是:1到(2^32)-1
      server_id=1
      
  • 4、重启mysql服务

    • 执行如下命令

      sudo service mysqld restart
      
  • 5、验证binlog是否配置成功

    • 进入mysql客户端,并执行以下命令进行验证

      mysql -uroot -p123456
      mysql> show variables like '%log_bin%';
      

  • 6、查看binlog日志文件生成

    • 进入 /var/lib/mysql 目录,查看binlog日志文件.

 

Maxwell安装部署

 
  • 1、下载对应版本的安装包

  • 2、上传服务器,这里我们选择在hadoop03节点安装Maxwell

  • 3、解压安装包到指定目录

     tar -zxvf maxwell-1.21.1.tar.gz -C /bigdata/install/
    
  • 4、修改Maxwell配置文件

    • 进入到安装目录 /bigdata/install/maxwell-1.21.1 进行如下操作
    cd /bigdata/install/maxwell-1.21.1 
    cp config.properties.example config.properties
    vim config.properties
    
    • 配置文件config.properties 内容如下:
    # choose where to produce data to
    producer=kafka
    # list of kafka brokers
    kafka.bootstrap.servers=hadoop01:9092,hadoop02:9092,hadoop03:9092
    # mysql login info
    host=hadoop03
    port=3306
    user=maxwell
    password=123456
    # kafka topic to write to
    kafka_topic=maxwell
    
    • 注意:一定要保证使用maxwell 用户和 123456 密码能够连接上mysql数据库。

Maxwell实时采集mysql表数据到kafka

 
  • 1、启动kafka集群和zookeeper集群

    • 启动zookeeper集群

      [hadoop@hadoop01 bin]zk.sh start
      
    • 启动kafka集群

      [hadoop@hadoop01 bin]kafka.sh start
      
  • 2、创建topic

    [hadoop@hadoop01 ~]kafka-topics.sh --create --topic maxwell --partitions 3 --replication-factor 2 --zookeeper hadoop01:2181,hadoop02:2181,hadoop03:2181
    
  • 3、启动maxwell服务

    [hadoop@hadoop03 ~]/bigdata/install/maxwell-1.21.1/bin/maxwell
    
  • 4、进入hadoop02的mysql数据库,插入数据并进行测试

    • 向mysql当中创建数据库和数据库表,向表中插入一条数据。
      CREATE DATABASE `test_db`;
      
      USE `test_db`;
      
      /*Table structure for table `user` */
      
      DROP TABLE IF EXISTS `user`;
      
      CREATE TABLE `user` (
        `id` varchar(10) NOT NULL,
        `name` varchar(10) DEFAULT NULL,
        `age` int(11) DEFAULT NULL,
        PRIMARY KEY (`id`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      
      /*Data for the table `user` */
      #插入数据
      insert  into `user`(`id`,`name`,`age`) values  ('1','xiaokai',20);
      #修改数据
      update `user` set age= 30 where id='1';
      #删除数据
      delete from `user` where id='1';
      
  • 5、启动kafka的自带控制台消费者

    • 测试maxwell主题是否有数据进入

      [hadoop@hadoop01 ~]kafka-console-consumer.sh --topic maxwell --bootstrap-server hadoop01:9092,hadoop02:9092,hadoop03:9092 --from-beginning 
      
      SHELL 复制 全屏
    • 观察输出结果

      {"database":"test_db","table":"user","type":"insert","ts":1621244407,"xid":985,"commit":true,"data":{"id":"1","name":"xiaokai","age":20}}
      
      {"database":"test_db","table":"user","type":"update","ts":1621244413,"xid":999,"commit":true,"data":{"id":"1","name":"xiaokai","age":30},"old":{"age":20}}
      
      {"database":"test_db","table":"user","type":"delete","ts":1621244419,"xid":1013,"commit":true,"data":{"id":"1","name":"xiaokai","age":30}}

 

posted @ 2022-05-03 19:31  hanease  阅读(517)  评论(0编辑  收藏  举报