20180705關於mysql binlog的解析方式

來源:互聯網
上載者:User

標籤:資訊   多進程   虛線   流程圖   資料解析   glob   reg   parser   last   

來自:74964366/

關係型資料庫和Hadoop生態的溝通越來越密集,時效要求也越來越高。本篇就來調研下即時抓取MySQL更新資料到HDFS。

本篇僅作為調研報告。

初步調研了canal(Ali)+kafka connect+kafka、maxwell(Zendesk)+kafka和mysql_streamer(Yelp)+kafka。這幾個工具抓取MySQL的方式都是通過掃描binlog,類比MySQL master和slave(Mysql Replication架構–解決了:資料多點備份,提高資料可用性;讀寫分流,提高叢集的並發能力。(並非是負載平衡);讓一些非即時的資料操作,轉移到slaves上進行。)之間的協議來實現即時更新的


先科普下Canal

Canal簡介原理

Canal原理圖


原理相對比較簡單:

 

  1. canal類比mysql slave的互動協議,偽裝自己為mysql slave,向mysql master發送dump協議
  2. mysql master收到dump請求,開始推送(slave拉取,不是master主動push給slaves)binary log給slave(也就是canal)
  3. canal解析binary log對象(原始為byte流)
架構

Canal架構圖

 

組件說明:

  1. server代表一個canal運行執行個體,對應於一個jvm
  2. instance對應於一個資料隊列(1個server對應1..n個instance)

而instance模組又由eventParser(資料來源接入,類比slave協議和master進行互動,協議解析)、eventSink(Parser和Store連接器,進行資料過濾,加工,分發的工作)、eventStore(資料存放區)和metaManager(增量訂閱&消費資訊管理器)組成。

  • EventParser在向mysql發送dump命令之前會先從Log Position中擷取上次解析成功的位置(如果是第一次啟動,則擷取初始指定位置或者當前資料區段binlog位點)。mysql接受到dump命令後,由EventParser從mysql上pull binlog資料進行解析並傳遞給EventSink(傳遞給EventSink模組進行資料存放區,是一個阻塞操作,直到儲存成功),傳送成功之後更新Log Position。流程圖如下:

    EventParser流程圖

     

  • EventSink起到一個類似channel的功能,可以對資料進行過濾、分發/路由(1:n)、歸併(n:1)和加工。EventSink是串連EventParser和EventStore的橋樑。

  • EventStore實現模式是記憶體模式,記憶體結構為環形隊列,由三個指標(Put、Get和Ack)標識資料存放區和讀取的位置。

  • MetaManager是增量訂閱&消費資訊管理器,增量訂閱和消費之間的協議包括get/ack/rollback,分別為:

Message getWithoutAck(int batchSize),允許指定batchSize,一次可以擷取多條,每次返回的對象為Message,包含的內容為:batch id[唯一標識]和entries[具體的資料對象]
void rollback(long batchId),顧命思議,復原上次的get請求,重新擷取資料。基於get擷取的batchId進行提交,避免誤操作
void ack(long batchId),顧命思議,確認已經消費成功,通知server刪除資料。基於get擷取的batchId進行提交,避免誤操作

增量訂閱和消費之間的協議互動如下:

增量訂閱和消費協議

 

canal的get/ack/rollback協議和常規的jms協議有所不同,允許get/ack非同步處理,比如可以連續調用get多次,後續非同步按順序提交ack/rollback,項目中稱之為流式api.

流式api設計的好處:

  • get/ack非同步化,減少因ack帶來的網路延遲和操作成本 (99%的狀態都是處於正常狀態,異常的rollback屬於個別情況,沒必要為個別的case犧牲整個效能)
  • get擷取資料後,業務消費存在瓶頸或者需要多進程/多線程消費時,可以不停的輪詢get資料,不停的往後發送任務,提高並行化. (在實際業務中的一個case:業務資料消費需要跨中美網路,所以一次操作基本在200ms以上,為了減少延遲,所以需要實施並行化)

流式api設計如下:

流式api

 

  • 每次get操作都會在meta中產生一個mark,mark標記會遞增,保證運行過程中mark的唯一性
  • 每次的get操作,都會在上一次的mark操作記錄的cursor繼續往後取,如果mark不存在,則在last ack cursor繼續往後取
  • 進行ack時,需要按照mark的順序進行數序ack,不能跳躍ack. ack會刪除當前的mark標記,並將對應的mark位置更新為last ack cusor
  • 一旦出現異常情況,用戶端可發起rollback情況,重新置位:刪除所有的mark, 清理get請求位置,下次請求會從last ack cursor繼續往後取

這個流式api是不是類似hdfs write在pipeline中傳輸packet的形式,先將packet放入dataQueue,然後向下遊傳輸,此時將packet放入ackQueue等到下遊返回的ack,這也是非同步。

HA機制

canal是支援HA的,其實現機制也是依賴zookeeper來實現的,用到的特性有watcher和EPHEMERAL節點(和session生命週期綁定),與HDFS的HA類似。

canal的ha分為兩部分,canal server和canal client分別有對應的ha實現

  • canal server: 為了減少對mysql dump的請求,不同server上的instance(不同server上的相同instance)要求同一時間只能有一個處於running,其他的處於standby狀態(standby是instance的狀態)。
  • canal client: 為了保證有序性,一份instance同一時間只能由一個canal client進行get/ack/rollback操作,否則用戶端接收無法保證有序。

server ha的架構圖如下:

ha


大致步驟:

 

  1. canal server要啟動某個canal instance時都先向zookeeper進行一次嘗試啟動判斷(實現:建立EPHEMERAL節點,誰建立成功就允許誰啟動)
  2. 建立zookeeper節點成功後,對應的canal server就啟動對應的canal instance,沒有建立成功的canal instance就會處於standby狀態
  3. 一旦zookeeper發現canal server A建立的instance節點消失後,立即通知其他的canal server再次進行步驟1的操作,重新選出一個canal server啟動instance。
  4. canal client每次進行connect時,會首先向zookeeper詢問當前是誰啟動了canal instance,然後和其建立連結,一旦連結不可用,會重新嘗試connect。

Canal Client的方式和canal server方式類似,也是利用zookeeper的搶佔EPHEMERAL節點的方式進行控制.

Canal部署及使用MySQL配置

canal同步資料需要掃描MySQL的binlog日誌,而binlog預設是關閉的,需要開啟,並且為了保證同步資料的一致性,使用的日誌格式為row-based replication(RBR),在my.conf中開啟binlog,

1234
[mysqld]log-bin=mysql-bin #添加這一行就okbinlog-format=ROW #選擇row模式server_id=1 #配置mysql replaction需要定義,不能和canal的slaveId重複

更改my.conf之後,需要重啟MySQL,重啟的方式有很多找到合適自己的就行。

Canal配置

由上面的介紹得知Canal由ServerInstance組成,而Server中又可以包含很多個Instance,一個Instance對應一個資料庫執行個體,則Canal將配置分為兩類,一類是server的配置,名字為canal.properties,另一類是instance的配置,名字為instance.properties,一般會在conf目錄下建立一個instance同名的目錄,將其放入此目錄中。

先介紹canal.properties中的幾個關鍵屬性

參數名字 參數說明 預設值
canal.destinations 當前server上部署的instance列表
canal.conf.dir conf/目錄所在的路徑 ../conf
canal.instance.global.spring.xml 全域的spring配置方式的組件檔案 classpath:spring/file-instance.xml 
(spring目錄相對於canal.conf.dir)
canal.zkServers canal server連結zookeeper叢集的連結資訊
canal.zookeeper.flush.period canal持久化資料到zookeeper上的更新頻率,單位毫秒 1000
canal.file.data.dir canal持久化資料到file上的目錄 ../conf (預設和instance.properties為同一目錄,方便營運和備份)
canal.file.flush.period canal持久化資料到file上的更新頻率,單位毫秒 1000
canal.instance.memory.batch.mode canal記憶體store中資料緩衝模式 
1. ITEMSIZE : 根據buffer.size進行限制,只限制記錄的數量 
2. MEMSIZE : 根據buffer.size * buffer.memunit的大小,限制緩衝記錄的大小
MEMSIZE
canal.instance.memory.buffer.size canal記憶體store中可緩衝buffer記錄數,需要為2的指數 16384
canal.instance.memory.buffer.memunit 記憶體記錄的單位大小,預設1KB,和buffer.size組合決定最終的記憶體使用量大小 1024

下面看下instance.properties,這裡的屬性較少:

參數名字 參數說明 預設值
canal.instance.mysql.slaveId mysql叢集配置中的serverId概念,需要保證和當前mysql叢集中id唯一 1234
canal.instance.master.address mysql主庫連結地址 127.0.0.1:3306
canal.instance.master.journal.name mysql主庫連結時起始的binlog檔案
canal.instance.master.position mysql主庫連結時起始的binlog位移量
canal.instance.master.timestamp mysql主庫連結時起始的binlog的時間戳記
canal.instance.dbUsername mysql資料庫帳號 canal
canal.instance.dbPassword mysql資料庫密碼 canal
canal.instance.defaultDatabaseName mysql連結時預設schema
canal.instance.connectionCharset mysql 資料解析編碼 UTF-8
canal.instance.filter.regex mysql 資料解析關注的表,PerlRegex. 
多個正則之間以逗號(,)分隔,轉義符需要雙斜杠
.*\\..*

除了上面兩個設定檔,conf目錄下還有一個目錄需要強調下,那就是spring目錄,裡面存放的是instance.xml設定檔,目前預設支援的instance.xml有memory-instance.xml、file-instance.xml、default-instance.xml和group-instance.xml。這裡主要維護的增量訂閱和消費的關係資訊(解析位點和消費位點)。

對應的兩個位點組件,目前都有幾種實現:

  • memory (memory-instance.xml中使用)
  • zookeeper
  • mixed
  • file (file-instance.xml中使用,集合了file+memory模式,先寫記憶體,定時重新整理資料到本地file上)
  • period (default-instance.xml中使用,集合了zookeeper+memory模式,先寫記憶體,定時重新整理資料到zookeeper上)

分別介紹下這幾種配置的功能

  • memory-instance.xml:

所有的組件(parser , sink , store)都選擇了記憶體版模式,記錄位點的都選擇了memory模式,重啟後又會回到初始位點進行解析

特點:速度最快,依賴最少(不需要zookeeper)

情境:一般應用在quickstart,或者是出現問題後,進行資料分析的情境,不應該將其應用於生產環境

  • file-instance.xml:

所有的組件(parser , sink , store)都選擇了基於file持久化模式(組件內容持久化的file存在哪裡???),注意,不支援HA機制.

特點:支援單機持久化

情境:生產環境,無HA需求,簡單可用.

  • default-instance.xml:

所有的組件(parser , sink , store)都選擇了持久化模式,目前持久化的方式主要是寫入zookeeper,保證資料集群共用.(所有組件持久化的內容只有位置資訊吧???)

特點:支援HA

情境:生產環境,叢集化部署.

  • group-instance.xml:

主要針對需要進行多庫合并時,可以將多個物理instance合并為一個邏輯instance,提供用戶端訪問。

情境:分庫業務。 比如產品資料拆分了4個庫,每個庫會有一個instance,如果不用group,業務上要消費資料時,需要啟動4個用戶端,分別連結4個instance執行個體。使用group後,可以在canal server上合并為一個邏輯instance,只需要啟動1個用戶端,連結這個邏輯instance即可.

canal example 部署
  • 在需要同步的MySQL資料庫中建立一個使用者,用來replica資料,這裡建立的使用者名稱和密碼都為canal,命令如下:
1234
CREATE USER canal IDENTIFIED BY ‘canal‘;GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO ‘canal‘@‘%‘;-- GRANT ALL PRIVILEGES ON *.* TO ‘canal‘@‘%‘ ;FLUSH PRIVILEGES;
  • Mysql建立canal使用者並為其賦要求的權限之後,需要對Canal的設定檔(canal.properties和instance.properties)進行設定。

canal.properties和instance.properties裡採用預設配置即可(這裡只是運行個範例,生產中可以參考具體的參數屬性進行設定),

  • Canal配置好之後,啟動Canal client(client的作用是將Canal裡的解析的binlog日誌固化到儲存介質中)。

client組件Canal本身是不提供的,需要根據api進行開發,這裡將官方提供的client代碼打包成jar進行消費Canal資訊。

canal HA配置

canal的HA機制是依賴zk來實現的,需要更改canal.properties檔案,修改內容如下:

1234
# zk叢集地址canal.zkServers=10.20.144.51:2181# 選擇記錄方式canal.instance.global.spring.xml = classpath:spring/default-instance.xml

更改兩台canal機器上instance執行個體的配置instance.properties,修改內容如下:

12
canal.instance.mysql.slaveId = 1234 ##另外一台機器改成1235,保證slaveId不重複即可canal.instance.master.address = 10.20.144.15:3306

配置好之後啟動canal進程,在兩台伺服器上執行sh bin/startup.sh

client進行消費時,可以直接指定zookeeper地址和instance name,也可以讓canal client會自動從zookeeper中的running節點,擷取當前服務的工作節點,然後與其建立連結。

maxwell簡介

maxwell即時抓取mysql資料的原理也是基於binlog,和canal相比,maxwell更像是canal server + 即時client。(資料幫浦 + 資料轉換)

maxwell整合了kafka producer,直接從binlog擷取資料更新並寫入kafka,而canal則需要自己開發即時client將canal讀取的binlog內容寫入kafka中。

maxwell特色:

  • 支援bootstrap啟動,同步曆史資料
  • 整合kafka,直接將資料落地到kafka
  • 已將binlog中的DML和DDL進行了模式比對,將其解碼為有schema的json(有利於後期將其重組為nosql支援的語言)
    {“database”:”test”,”table”:”e”,”type”:”update”,”ts”:1488857869,”xid”:8924,”commit”:true,”data”:{“id”:1,”m”:5.556666,”torvalds”:null},”old”:{“m”:5.55}}

缺點:

  • 一個MySQL執行個體需要對應一個maxwell進程
  • bootstrap的方案使用的是select *

maxwell的設定檔只有一個config.properties,在home目錄。其中除了需要配置mysql master的地址、kafka地址還需要配置一個用於存放maxwell相關資訊的mysql地址,maxwell會把讀取binlog關係的資訊,如binlog name、position。

工具對比

以上是Canal的原理及部署,其餘類似maxwell和mysql_streamer對mysql進行即時資料抓取的原理一樣就不再進行一一介紹,這裡只對他們進行下對比:

特色 Canal Maxwell mysql_streamer
語言 Java Java Python
活躍度 活躍 活躍 不活躍
HA 支援 定製 支援
資料落地 定製 落地到kafka 落地到kafka
分區 支援 不支援 不支援
bootstrap 不支援 支援 支援
資料格式 格式自由 json(格式固定) json(格式固定)
文檔 較詳細 較詳細 略粗
隨機讀 支援 支援 支援

以上只是將mysql裡的即時變化資料的binlog以同種形式同步到kafka,但要即時更新到hadoop還需要使用一個即時資料庫來儲存資料,並自定製開發將kafka中資料解析為nosql資料庫可以識別的DML進行即時更新Nosql資料庫,使其與MySQL裡的資料即時同步。

基礎架構

架構圖如下:

基礎架構圖

 

虛線框是可選的方案

方案對比
  1. 方案1使用阿里開源的Canal進行Mysql binlog資料的抽取,另需開發一個資料轉換工具將從binlog中解析出的資料轉換成內建schema的json資料並寫入kafka中。而方案2使用maxwell可直接完成對mysql binlog資料的抽取和轉換成內建schema的json資料寫入到kafka中。
  2. 方案1中不支援表中已存在的曆史資料進行同步,此功能需要開發(如果使用sqoop進行曆史資料同步,不夠靈活,會使結果表與原始表結構相同,有區別於資料交換平台所需的schema)。方案2提供同步曆史資料的解決方案。
  3. 方案1支援HA部署,而方案2不支援HA

方案1和方案2的區別只在於kafka之前,當資料緩衝到kafka之後,需要一個定製的資料路由群組件來將內建schema的資料解析到目標儲存中。
資料路由群組件主要負責將kafka中的資料即時讀出,寫入到目標儲存中。(如將所有日誌資料儲存到HDFS中,也可以將資料落地到所有支援jdbc的資料庫,落地到HBase,Elasticsearch等。)

綜上,
方案1需要開發的功能有:

  • bootstrap功能
  • 即時資料轉換工具
  • 資料路由工具

方案2需要開發的功能有:

  • 資料路由工具
  • HA模組(初期可暫不支援HA,所以開發緊急度不高)

資料路由工具是兩個方案都需要開發的,則我比較偏向於第二種方案,因為在初期試水階段可以短期出成果,可以較快的驗證想法,並在嘗試中能夠較快的發現問題,好及時的調整方案。即使方案2中maxwell最終不能滿足需求,而使用canal的話,我們也可能將即時資料轉換工具的資料輸出模式與maxwell一致,這樣初始投入人力開發的資料路由工具依然可以繼續使用,而不需要重新開發。

把增量的Log作為一切系統的基礎。後續的資料使用方,通過訂閱kafka來消費log。

比如:
大資料的使用方可以將資料儲存到Hive表或者Parquet檔案給Hive或Spark查詢;
提供搜尋服務的使用方可以儲存到Elasticsearch或HBase 中;
提供快取服務的使用方可以將日誌緩衝到Redis或alluxio中;
資料同步的使用方可以將資料儲存到自己的資料庫中;
由於kafka的日誌是可以重複消費的,並且緩衝一段時間,各個使用方可以通過消費kafka的日誌來達到既能保持與資料庫的一致性,也能保證即時性;

{“database”:”test”,”table”:”e”,”type”:”update”,”ts”:1488857869,”xid”:8924,”commit”:true,”data”:{“id”:1,”m”:5.556666,”torvalds”:null},”old”:{“m”:5.55}}

{“database”:”test”,”table”:”e”,”type”:”insert”,”ts”:1488857922,”xid”:8932,”commit”:true,”data”:{“id”:2,”m”:4.2,”torvalds”:null}}

20180705關於mysql binlog的解析方式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.