前段時間寫了MySql實時資料變更事件捕獲kafka confluent之debezium,使用的是confluent整套的,接下來這篇將會介紹完整實戰。
首先明確需求,公司訂單資料越來越大,商戶端和E端各種業務需求也越來越多查詢越發複雜,我們想引進elasticsearch來實現查詢和搜尋。那麼問題來了,實時更新的訂單資料如何同步到es中,業務程式碼中insert或者update es中的index這肯定是不可取的,我們選擇使用kafka和debezium結合使用,讀取MySQLbinlog及時寫入es.
本文將會實現一套完整的Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch並實現查詢的流程.
安裝
MySQL
MySQL的安裝比較簡單,同時需要MySQL開啟binlog,為了簡單我這裡使用docker啟動一個MySQL並且裡面已建立有資料。
- docker安裝
docker run -it --rm --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=debezium -e MYSQL_USER=mysqluser -e MYSQL_PASSWORD=mysqlpw debezium/example-mysql:0.8
複製程式碼
-
local安裝 如果本地沒有docker環境或者MySQL環境可以參考mysql 5.7 主從同步配置(windows)和MySQL 5.7.18 資料庫主從(Master/Slave)同步安裝與配置詳解配置。
這裡給出同上docker的資料庫和表結構,點選msyql table inventory ddl下載。
Zookeeper
kafka的啟動依賴於zookeeper,所以這裡先安裝並且啟動zookeeper.
-
首先需要配置
conf/zoo.cfg
,可以直接複製一份conf/zoo_sample.cfg
使用.切換到安裝目錄下bin/zkServer.sh start
啟動zookeeper.
Kafka
-
MySQL Connector plugin archive download
下載好了的kafka檔案目錄裡面其實預設已經包含了幾個connect,這裡我們需要使用的是
debezium
這個外掛,所以需要把下載後的debezium安裝到connect中,安裝方法也比較簡單,把解壓後的MySQL Connector plugin archive
裡面的內容全部copy到kafka安裝目錄libs
目錄下即可. -
啟動kafka Quickstart
在安裝目錄下執行
bin/kafka-server-start.sh config/server.properties
-
啟動kafka connect Running Kafka Connect
在安裝目錄下執行
./bin/connect-distributed.sh config/connect-distributed.properties
Elasticsearch
- download
- 啟動,安裝目錄下
bin/elasticsearch
配置connect
截止目前已經有了本地的MySQL
,kafka
,kafka connect
,elasticearch
,接下來配置kafka connect,通過配置好connect能夠讓debezium讀取到binlog把MySQL的資料change事件寫入到kafka的topic中.
kafka connect為我們提供了restful的訪問方式,詳細文件檢視Kafka Connect REST Interface.
新增一個connect
put http://localhost:8083/connectors/order-center-connector/config
{
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"tasks.max": "1",
"database.hostname": "localhost",
"database.port": "3306",
"database.user": "root",
"database.password": "debezium",
"database.server.id": "1",
"database.server.name": "trade_order_0",
"database.whitelist": "inventory",
"include.schema.changes": "false",
"snapshot.mode": "schema_only",
"snapshot.locking.mode": "none",
"database.history.kafka.bootstrap.servers": "localhost:9092",
"database.history.kafka.topic": "dbhistory.tradeOrder1",
"decimal.handling.mode": "string",
"database.history.store.only.monitored.tables.ddl":"true",
"database.history.skip.unparseable.ddl":"true"
}
複製程式碼
備註: http://localhost:8083/connectors/order-center-connector/config
這個介面不但能更新connector還能建立,如果connector不存在的時候使它就會建立一個connector如果存在就去更新.
debezium提供了諸多配置引數,上圖例子中只是提供了常用的配置,詳細配置參考Debezium Connector for MySQL .
connector建立成功之後,可以通過http://localhost:8083/connectors/檢視已經建立個的connector.
同時你還可以通過http://localhost:8083/connectors/order-center-connector/檢視某一個connector的詳細配置資訊.
也可以通過http://localhost:8083/connectors/order-center-connector/status檢視當前connector的詳細狀態,如果當前connector出現故障,也會在這裡提示出來.
connector建立成功後,接下來應該測試debezium是否開始工作了,MySQL發生insert或者update 的時候有沒有寫入kafka.
[注意事項]
筆者在配置connector的過程中也遇到過了好多問題,一些比較重要的東西也記錄下來了,如果你在使用過程中出現問題可以檢視文末常見問題
裡面是否有同樣的問題.
debezium kafka topic消費
在上面的debezium配置中可以看到引數database.server.name
,database.whitelist
,debezium connector會處理MySQL的binlog後對應資料庫不同的表將訊息傳送到不通的topic上,其中這些topic的構成方式為:[database.server.name].[資料庫名稱].[表名稱],記下來按步驟操作.
* 1. 在kafka的安裝目錄下使用bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic trade_order_0.inventory.orders
消費trade_order_0.inventory.orders
這個topic.
-
- 任意修改orders表的一行資料,然後回到第一步就可以觀察到.
看到這樣的結果說明debezium已經開始工作了.
spring boot消費kafka訊息並且寫入elasticsearch中
-
Demo程式碼已經在github.com/m65536/prac…全部實現.下載後配合上面安裝好了的環境可以直接啟動執行(當前版本使用的6.5,如果需要使用2.X,es客戶端配置略有不同).
-
使用建立index之前可以建立index template,使用簡單並且方便靈活.
-
建立template
{
"template": "trade-order-sales",
"order": 0,
"mappings": {
"_default_": {
"_source": {
"enabled": true
}
},
"type": {
"properties":{"orderNumber":{"type":"text"},"quantity":{"type":"text"},"productId":{"type":"text"},"purchaser":{"type":"date"},"orderDate":{"type":"text"},"purchaserName":{"type":"text"},"createDate":{"type":"date"}}
}
}
}
複製程式碼
-
啟動專案測試
啟動SpringBootElasticsearchApplication後,更改orders表任意資料,此時我們看到日誌,再去觀察es,如圖.
此時說明MySQL到connect到kafka再到server再到es整個流程通了,同時可以通過server去查詢esTestController-http://localhost:8080/test/list
常見問題
- Unexpected exception while parsing statement alter table pay_cs_market_balance alter column balance_amt set default 0 at line 1
- 如果配置無效
1 檢查表白名單 2 檢查database.server.id是否重複 3 檢查其他配置重複是否
- 如何分詞(version 2.X)
zhuanlan.zhihu.com/p/29183128 esuc.dev.rs.com:9200/_analyze?pr… &text=SO5046240000014238
- 消費者亂碼
保持寫入消費使用的同一個序列化方式.
- 資料庫
date
,datetime
,timestamp
之類的欄位,消費者收到少了8個小時或者多了8個小時
這個問題主要是由於時區的問題,建議閱讀官網文件Temporal values without time zone
解決辦法
建議資料都改成timestamp
(攜帶了時區)型別然後再kafka消費的時候使用Date物件接收,轉成Date物件時區就是本地的了,再寫入es就是你想要的了.