第1章 Maxwell簡介
1.1 Maxwell概述
Maxwell 是由美國Zendesk公司開源,用Java編寫的MySQL變更數據抓取軟件。它會實時監控Mysql數據庫的數據變更操作(包括insert、update、delete),並將變更數據以 JSON 格式發送給 Kafka、Kinesi等流數據處理平臺。官網地址:http://maxwells-daemon.io/
1.2 Maxwell輸出數據格式
注: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從庫讀取並回放中繼日誌中的事件,將改變的數據同步到自己的數據庫。
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開始的時間。