數據庫流轉工具—Maxwell

第1章 Maxwell簡介

1.1 Maxwell概述

Maxwell 是由美國Zendesk公司開源,用Java編寫的MySQL變更數據抓取軟件。它會實時監控Mysql數據庫的數據變更操作(包括insert、update、delete),並將變更數據以 JSON 格式發送給 Kafka、Kinesi等流數據處理平臺。官網地址:http://maxwells-daemon.io/

1.2 Maxwell輸出數據格式

img

注:Maxwell輸出的json字段說明:

字段 解釋
database 變更數據所屬的數據庫
table 表更數據所屬的表
type 數據變更類型
ts 數據變更發生的時間
xid 事務id
commit 事務提交標誌,可用於重新組裝事務
data 對於insert類型,表示插入的數據;對於update類型,標識修改之後的數據;對於delete類型,表示刪除的數據
old 對於update類型,表示修改之前的數據,只包含變更字段

第2章 Maxwell原理

Maxwell的工作原理是實時讀取MySQL數據庫的二進制日誌(Binlog),從中獲取變更數據,再將變更數據以JSON格式發送至Kafka等流處理平臺。

2.1MySQL二進制日誌

二進制日誌(Binlog)是MySQL服務端非常重要的一種日誌,它會保存MySQL數據庫的所有數據變更記錄。Binlog的主要作用包括主從複製和數據恢復。Maxwell的工作原理和主從複製密切相關。

2.2 MySQL主從複製

MySQL的主從複製,就是用來建立一個和主數據庫完全一樣的數據庫環境,這個數據庫稱爲從數據庫。

1)主從複製的應用場景如下:

(1)做數據庫的熱備:主數據庫服務器故障後,可切換到從數據庫繼續工作。

(2)讀寫分離:主數據庫只負責業務數據的寫入操作,而多個從數據庫只負責業務數據的查詢工作,在讀多寫少場景下,可以提高數據庫工作效率。

2)主從複製的工作原理如下:

(1)Master主庫將數據變更記錄,寫到二進制日誌(binary log)中

(2)Slave從庫向mysql master發送dump協議,將master主庫的binary log events拷貝到它的中繼日誌(relay log)

(3)Slave從庫讀取並回放中繼日誌中的事件,將改變的數據同步到自己的數據庫。

img

2.3 Maxwell原理

很簡單,就是將自己僞裝成slave,並遵循MySQL主從複製的協議,從master同步數據。

第3章 Maxwell部署

3.1 安裝Maxwell

1)下載安裝包

(1)地址:https://github.com/zendesk/maxwell/releases/download/v1.29.2/maxwell-1.29.2.tar.gz

注:Maxwell-1.30.0及以上版本不再支持JDK1.8。

(2)將安裝包上傳到hadoop102節點的/opt/software目錄

2)將安裝包解壓至/opt/module

[atguigu@hadoop102 maxwell]$ tar -zxvf maxwell-1.29.2.tar.gz -C /opt/module/

3)修改名稱

[atguigu@hadoop102 module]$ mv maxwell-1.29.2/ maxwell

3.2 配置MySQL

3.2.1 啓用MySQL Binlog

MySQL服務器的Binlog默認是未開啓的,如需進行同步,需要先進行開啓。

1)修改MySQL配置文件/etc/my.cnf

[atguigu@hadoop102 ~]$ sudo vim /etc/my.cnf

2)增加如下配置

[mysqld]

#數據庫id
server-id = 1

#啓動binlog,該參數的值會作爲binlog的文件名
log-bin=mysql-bin

#binlog類型,maxwell要求爲row類型
binlog_format=row

#啓用binlog的數據庫,需根據實際情況作出修改
binlog-do-db=gmall

注:MySQL Binlog模式

Statement-based:基於語句,Binlog會記錄所有寫操作的SQL語句,包括insert、update、delete等。

  • 優點: 節省空間

  • 缺點: 有可能造成數據不一致,例如insert語句中包含now()函數。

Row-based:基於行,Binlog會記錄每次寫操作後被操作行記錄的變化。

  • 優點:保持數據的絕對一致性。

  • 缺點:佔用較大空間。

mixed:混合模式,默認是Statement-based,如果SQL語句可能導致數據不一致,就自動切換到Row-based。

Maxwell要求Binlog採用Row-based模式。

3)重啓MySQL服務

[atguigu@hadoop102 ~]$ sudo systemctl restart mysqld

3.2.2 創建Maxwell所需數據庫和用戶

Maxwell需要在MySQL中存儲其運行過程中的所需的一些數據,包括binlog同步的斷點位置(Maxwell支持斷點續傳)等等,故需要在MySQL爲Maxwell創建數據庫及用戶。

1)創建數據庫

msyql> CREATE DATABASE maxwell;

2)調整MySQL數據庫密碼級別

mysql> set global validate_password_policy=0;
mysql> set global validate_password_length=4;

3)創建Maxwell用戶並賦予其必要權限

mysql> CREATE USER 'maxwell'@'%' IDENTIFIED BY 'maxwell';
mysql> GRANT ALL ON maxwell.* TO 'maxwell'@'%';
mysql> GRANT SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'maxwell'@'%';

3.3 配置Maxwell

1)修改Maxwell配置文件名稱

[atguigu@hadoop102 maxwell]$ cd /opt/module/maxwell
[atguigu@hadoop102 maxwell]$ cp config.properties.example config.properties

2)修改Maxwell配置文件

[atguigu@hadoop102 maxwell]$ vim config.properties

#Maxwell數據發送目的地,可選配置有stdout|file|kafka|kinesis|pubsub|sqs|rabbitmq|redis
producer=kafka

#目標Kafka集羣地址
kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092

#目標Kafka topic,可靜態配置,例如:maxwell,也可動態配置,例如:%{database}_%{table}
kafka_topic=maxwell

#MySQL相關配置
host=hadoop102
user=maxwell
password=maxwell
jdbc_options=useSSL=false&serverTimezone=Asia/Shanghai

第4章 Maxwell使用

4.1 啓動Kafka集羣

若Maxwell發送數據的目的地爲Kafka集羣,則需要先確保Kafka集羣爲啓動狀態。

4.2 Maxwell啓停

1)啓動Maxwell

[atguigu@hadoop102 ~]$ /opt/module/maxwell/bin/maxwell --config /opt/module/maxwell/config.properties --daemon

2)停止Maxwell

[atguigu@hadoop102 ~]$ ps -ef | grep maxwell | grep -v grep | grep maxwell | awk '{print $2}' | xargs kill -9

3)Maxwell啓停腳本

(1)創建並編輯Maxwell啓停腳本

[atguigu@hadoop102 bin]$ vim mxw.sh

(2)腳本內容如下

#!/bin/bash
MAXWELL_HOME=/opt/module/maxwell

status_maxwell(){
  result=`ps -ef | grep com.zendesk.maxwell.Maxwell | grep -v grep | wc -l`
  return $result
}

start_maxwell(){
  status_maxwell
  if [[ $? -lt 1 ]]; then
    echo "啓動Maxwell"
    $MAXWELL_HOME/bin/maxwell --config $MAXWELL_HOME/config.properties --daemon
  else
    echo "Maxwell正在運行"
  fi
}

stop_maxwell(){
  status_maxwell
  if [[ $? -gt 0 ]]; then
    echo "停止Maxwell"
    ps -ef | grep com.zendesk.maxwell.Maxwell | grep -v grep | awk '{print $2}' | xargs kill -9
  else
    echo "Maxwell未在運行"
  fi
}

case $1 in
  start )
    start_maxwell
  ;;
  stop )
    stop_maxwell
  ;;
  restart )
    stop_maxwell
    start_maxwell
  ;;
esac

4.3 增量數據同步

1)啓動Kafka消費者

[atguigu@hadoop102 kafka]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic maxwell

2)模擬生成數據

[atguigu@hadoop102 db_log]$ java -jar gmall2020-mock-db-2021-01-22.jar

3)觀察Kafka消費者

{"database":"gmall","table":"comment_info","type":"insert","ts":1634023510,"xid":1653373,"xoffset":11998,"data":{"id":1447825655672463369,"user_id":289,"nick_name":null,"head_img":null,"sku_id":11,"spu_id":3,"order_id":18440,"appraise":"1204","comment_txt":"評論內容:12897688728191593794966121429786132276125164551411","create_time":"2020-06-16 15:25:09","operate_time":null}}

{"database":"gmall","table":"comment_info","type":"insert","ts":1634023510,"xid":1653373,"xoffset":11999,"data":{"id":1447825655672463370,"user_id":774,"nick_name":null,"head_img":null,"sku_id":25,"spu_id":8,"order_id":18441,"appraise":"1204","comment_txt":"評論內容:67552221621263422568447438734865327666683661982185","create_time":"2020-06-16 15:25:09","operate_time":null}}

4.4 歷史數據全量同步

上一節,我們已經實現了使用Maxwell實時增量同步MySQL變更數據的功能。但有時只有增量數據是不夠的,我們可能需要使用到MySQL數據庫中從歷史至今的一個完整的數據集。這就需要我們在進行增量同步之前,先進行一次歷史數據的全量同步。這樣就能保證得到一個完整的數據集。

4.4.1 Maxwell-bootstrap

Maxwell提供了bootstrap功能來進行歷史數據的全量同步,命令如下:

[atguigu@hadoop102 maxwell]$ /opt/module/maxwell/bin/maxwell-bootstrap --database gmall --table user_info --config /opt/module/maxwell/config.properties

4.4.2 boostrap數據格式

採用bootstrap方式同步的輸出數據格式如下:

{
  "database": "fooDB",
  "table": "barTable",
  "type": "bootstrap-start",
  "ts": 1450557744,
  "data": {}
}
{
  "database": "fooDB",
  "table": "barTable",
  "type": "bootstrap-insert",
  "ts": 1450557744,
  "data": {
    "txt": "hello"
  }
}
{
  "database": "fooDB",
  "table": "barTable",
  "type": "bootstrap-insert",
  "ts": 1450557744,
  "data": {
    "txt": "bootstrap!"
  }
}
{
  "database": "fooDB",
  "table": "barTable",
  "type": "bootstrap-complete",
  "ts": 1450557744,
  "data": {}
}

注意事項:

1)第一條type爲bootstrap-start和最後一條type爲bootstrap-complete的數據,是bootstrap開始和結束的標誌,不包含數據,中間的type爲bootstrap-insert的數據才包含數據。

2)一次bootstrap輸出的所有記錄的ts都相同,爲bootstrap開始的時間。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章