maxwell簡介
maxwell是一個由Java編寫的守護進程,可以實時讀取mysql binlog並將行更新以JSON格式寫入Kafka,Kinesis,RabbitMQ,Google Cloud Pub / Sub或Redis(Pub / Sub或LPUSH)。(以上內容摘自maxwell官網)。可以想象,有了mysql增量數據流,使用場景就很多了,比如:實時同步數據到緩存,同步數據到ElasticSearch,數據遷移等等。與canal(ali)相比,更加輕量
maxwell還提供以下功能:
- 使用
SELECT * FROM table
的方式做全量數據初始化 - 支持主庫發生failover後,自動恢復binlog位置
- 對數據進行分區,解決數據傾斜的問題
- 僞裝成mysql從庫,接收binlog
maxwell官網:http://maxwells-daemon.io/
maxwell源碼:https://github.com/zendesk/maxwell
maxwell使用
mysql配置
需要mysql開啓binlog,而binlog默認是關閉的,需要開啓,並且爲了保證同步數據的一致性,使用的日誌格式爲row-based replication(RBR),新建或修改my.conf
開啓binlog。
$ vim /etc/my.cnf
添加內容
[mysqld]
log-bin=mysql-bin #添加這一行就ok
binlog-format=ROW #選擇row模式
server_id=1 #隨機指定一個不能和其他集羣中機器重名的字符串,如果只有一臺機器,那就可以隨便指定了
重啓mysql, 查詢是否已開啓bin
show variables like '%log_bin%'
配置jdk環境(略)
maxwell 依賴java sdk,所以需要先配置JDK環境。
下載maxwell:https://github.com/zendesk/maxwell/releases/download/v1.17.1/maxwell-1.17.1.tar.gz
解壓後
修改config.properties.example爲config.properties
到目前爲止,前期準備已完成
實戰項目:配置maxwell發送消息到rabbitMQ, 監聽MQ隊列,處理消息
mysql db如下:
修改maxwell的config.properties
# tl;dr config 生產環境配置爲info級別
log_level=DEBUG
producer=rabbitmq
# mysql login info, mysql用戶必須擁有讀取binlog權限和新建庫表的權限
host=127.0.0.1
user=xiehd
password=xiehd2018
output_nulls=true
# options to pass into the jdbc connection, given as opt=val&opt2=val2
#jdbc_options=opt1=100&opt2=hello
jdbc_options=autoReconnet=true
#需要同步的數據庫,表,及不包含的字段
include_dbs=xhd-sso
#include_tables=SYS_USER,SYS_ROLE
#exclude_columns=password
metrics_type=http
metrics_slf4j_interval=60
http_port=8111
http_diagnostic=true # default false
#rabbitmq
rabbitmq_host=192.168.50.184
rabbitmq_port=5672
rabbitmq_user=maxwell
rabbitmq_pass=maxwell@2018
rabbitmq_virtual_host=/
rabbitmq_exchange=maxwell
rabbitmq_exchange_type=topic
rabbitmq_exchange_durable=false
rabbitmq_exchange_autodelete=false
rabbitmq_routing_key_template=%db%.%table%
rabbitmq_message_persistent=false
rabbitmq_declare_exchange=true
啓動maxwell
./bin/maxwell
啓動成功
此時會自動生成maxwell庫,該庫記錄了maxwell同步的狀態,最後一次同步的id等等信息,在主庫失敗或同步異常後,只要maxwell庫存在,下次同步會根據最後一次同步的id。如果沒有生成maxwell庫或報錯,可能config.properties中配置的mysql用戶權限不夠
此時修改mysql中的SYS_ROLE表數據,maxwell控制檯會打印相應的json格式的日誌
rabbitMQ控制檯中會自動創建名稱爲maxwell的exchange(該exchange爲config.properties中配置的)
新建Queue並綁定exchange,並設置routingkey爲%db%.%table%(該routingkey爲config.properties中配置)
修改表SYS_USER中數據,此時修改的數據會被髮送到rabbitMQ
一般情況下,一張表對應一個queue, 也可以多張表共用一個queue, 根據實際吞吐量靈活使用。
MQ消費端
新建一個MaxwellData
public class MaxwellData implements Serializable {
private String type;
private String database;
private String table;
private Map<String, Object> data;
private Map<String, Object> old;
public MaxwellData() {
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public String getDatabase() {
return this.database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getTable() {
return this.table;
}
public void setTable(String table) {
this.table = table;
}
public Map<String, Object> getData() {
return this.data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
public Map<String, Object> getOld() {
return this.old;
}
public void setOld(Map<String, Object> old) {
this.old = old;
}
解析maxwell數據
@RabbitHandler
@RabbitListener(queues = "SYS_USER")
public void process(byte[] data) {
String s = new String(data);
MaxwellData maxwellData = decodeMsg(s);
logger.info("maxwellData:" + maxwellData);
//to do
}
private MaxwellData decodeMsg(String msg) {
if (msg == null) {
return null;
}
return JSON.parseObject(msg, MaxwellData.class);
}
當然也可以同步到Redis, kafka, rocketMQ(rocketmq需要自行實現producer)等