Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

XING輞發表於2018-12-15

前段時間寫了MySql實時資料變更事件捕獲kafka confluent之debezium,使用的是confluent整套的,接下來這篇將會介紹完整實戰。

首先明確需求,公司訂單資料越來越大,商戶端和E端各種業務需求也越來越多查詢越發複雜,我們想引進elasticsearch來實現查詢和搜尋。那麼問題來了,實時更新的訂單資料如何同步到es中,業務程式碼中insert或者update es中的index這肯定是不可取的,我們選擇使用kafka和debezium結合使用,讀取MySQLbinlog及時寫入es.

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

本文將會實現一套完整的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

複製程式碼

Zookeeper

kafka的啟動依賴於zookeeper,所以這裡先安裝並且啟動zookeeper.

  • download

  • install and start

    首先需要配置conf/zoo.cfg,可以直接複製一份conf/zoo_sample.cfg使用.切換到安裝目錄下bin/zkServer.sh start啟動zookeeper.

Kafka

  • kafka download

  • 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"
}
複製程式碼

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

備註: http://localhost:8083/connectors/order-center-connector/config這個介面不但能更新connector還能建立,如果connector不存在的時候使它就會建立一個connector如果存在就去更新.

debezium提供了諸多配置引數,上圖例子中只是提供了常用的配置,詳細配置參考Debezium Connector for MySQL .

connector建立成功之後,可以通過http://localhost:8083/connectors/檢視已經建立個的connector.

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

同時你還可以通過http://localhost:8083/connectors/order-center-connector/檢視某一個connector的詳細配置資訊.

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

也可以通過http://localhost:8083/connectors/order-center-connector/status檢視當前connector的詳細狀態,如果當前connector出現故障,也會在這裡提示出來.

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

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.

    1. 任意修改orders表的一行資料,然後回到第一步就可以觀察到.

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

看到這樣的結果說明debezium已經開始工作了.

spring boot消費kafka訊息並且寫入elasticsearch中

{
  "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"}}
      
     }
  }
}
複製程式碼

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

此時說明MySQL到connect到kafka再到server再到es整個流程通了,同時可以通過server去查詢esTestController-http://localhost:8080/test/list

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

常見問題

  • Unexpected exception while parsing statement alter table pay_cs_market_balance alter column balance_amt set default 0 at line 1

blog.csdn.net/lzufeng/art…

  • 如果配置無效

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

Debezium結合Kafka Connect實時捕獲MySQL變更事件寫入Elasticsearch實現搜尋流程

解決辦法

建議資料都改成timestamp(攜帶了時區)型別然後再kafka消費的時候使用Date物件接收,轉成Date物件時區就是本地的了,再寫入es就是你想要的了.

相關文章