日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

canal原理的一些学习-1(canal的一些原理性介绍)

發(fā)布時(shí)間:2024/2/28 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 canal原理的一些学习-1(canal的一些原理性介绍) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

    • 1. cannal 是什么,能做什么用
      • 1.1 mysql的binlog
      • 1.2 mysql 的主從復(fù)制過程
      • 1.3 canal能夠同步數(shù)據(jù)的原理
    • 2. quick start
    • 3. canal 的設(shè)計(jì)
      • 3.1 canal的設(shè)計(jì)理念
      • 3.2 canal的組件有哪些
      • 3.3 instance 包含的組件
      • 3.4 各個(gè)組件目前支持的類型
    • 4. canal的工作過程
      • 4.1 啟動(dòng)時(shí)去MySQL 進(jìn)行dump操作的binlog 位置確定
      • 4.2 數(shù)據(jù)在dump回來之后進(jìn)行的歸集(sink)和存儲(chǔ)(store)
      • 4.3 binlog的消費(fèi)者
    • 5. canal的目錄結(jié)構(gòu)(不包含lib目錄)

1. cannal 是什么,能做什么用

canal 的歷史
??早期,阿里巴巴B2B公司因?yàn)榇嬖诤贾莺兔绹?guó)雙機(jī)房部署,存在跨機(jī)房同步的業(yè)務(wù)需求。不過早期的數(shù)據(jù)庫(kù)同步業(yè)務(wù),主要是基于trigger的方式獲取增量變更,不過從2010年開始,阿里系公司開始逐步的嘗試基于數(shù)據(jù)庫(kù)的日志解析,獲取增量變更進(jìn)行同步,由此衍生出了增量訂閱&消費(fèi)的業(yè)務(wù)。
??基于數(shù)據(jù)庫(kù)增量日志解析,提供增量數(shù)據(jù)訂閱&消費(fèi),目前主要支持了mysql。

1.1 mysql的binlog

??它記錄了所有的DDL和DML(除了數(shù)據(jù)查詢語句)語句,以事件形式記錄,還包含語句所執(zhí)行的消耗的時(shí)間。主要用來備份和數(shù)據(jù)同步。

binlog 有三種模式:STATEMENT、ROW、MIXED

1.STATEMENT 記錄的是執(zhí)行的sql語句
2.ROW 記錄的是真實(shí)的行數(shù)據(jù)記錄
3.MIXED 記錄的是1+2,優(yōu)先按照1的模式記錄

舉例來說,下面的sql
update user set age=20

對(duì)應(yīng)STATEMENT模式只有一條記錄,對(duì)應(yīng)ROW模式則有可能有成千上萬條記錄(取決數(shù)據(jù)庫(kù)中的記錄數(shù))。

1.2 mysql 的主從復(fù)制過程

  • Slave 上面的IO線程連接上 Master,并請(qǐng)求從指定日志文件的指定位置(或者從最開始的日志)之后的日志內(nèi)容;
  • Master 接收到來自 Slave 的 IO 線程的請(qǐng)求后,通過負(fù)責(zé)復(fù)制的 IO 線程根據(jù)請(qǐng)求信息讀取指定日志指定位置之后的日志信息,返回給 Slave 端的 IO 線程。返回信息中除了日志所包含的信息之外,還包括本次返回的信息在 Master 端的 Binary Log 文件的名稱以及在 Binary Log 中的位置;
  • Slave 的 IO 線程接收到信息后,將接收到的日志內(nèi)容依次寫入到 Slave 端的Relay Log文件(mysql-relay-bin.xxxxxx)的最末端,并將讀取到的Master端的bin-log的文件名和位置記錄到master- info文件中,以便在下一次讀取的時(shí)候能夠清楚的高速M(fèi)aster“我需要從某個(gè)bin-log的哪個(gè)位置開始往后的日志內(nèi)容,請(qǐng)發(fā)給我”
  • Slave 的 SQL 線程檢測(cè)到 Relay Log 中新增加了內(nèi)容后,會(huì)馬上解析該 Log 文件中的內(nèi)容成為在 Master 端真實(shí)執(zhí)行時(shí)候的那些可執(zhí)行的 Query 語句,并在自身執(zhí)行這些 Query。這樣,實(shí)際上就是在 Master 端和 Slave 端執(zhí)行了同樣的 Query,所以兩端的數(shù)據(jù)是完全一樣的。
    當(dāng)然這個(gè)過程本質(zhì)上還是存在一定的延遲的。
    mysql的binlog文件長(zhǎng)這個(gè)樣子。
  • mysql-bin.003831 mysql-bin.003840 mysql-bin.003849 mysql-bin.003858

    1.3 canal能夠同步數(shù)據(jù)的原理

    理解了mysql的主從同步的機(jī)制再來看canal就比較清晰了,canal主要是聽過偽裝成mysql從server來向主server拉取數(shù)據(jù)。

  • canal模擬mysql slave的交互協(xié)議,偽裝自己為mysql slave,向mysql master發(fā)送dump協(xié)議
  • mysql master收到dump請(qǐng)求,開始推送binary log給slave(也就是canal)
  • canal解析binary log對(duì)象(原始為byte流)
  • 2. quick start

    直接引用 阿里的就不錯(cuò),這里是一個(gè)阿里的單機(jī)版配置。
    https://github.com/alibaba/canal/wiki/QuickStart
    主要的點(diǎn)就是:

  • 數(shù)據(jù)庫(kù)配置,需要記錄bin_log 需要使用row模式,需要?jiǎng)?chuàng)建用戶給canal使用
  • canal配置相應(yīng)的主庫(kù)地址,server_id在mysql的集群中不能重復(fù),過濾哪些表使用的正則。
  • 這個(gè)是一個(gè)單機(jī)的canal的搭建,并不是HA的模式。
  • 3. canal 的設(shè)計(jì)

    3.1 canal的設(shè)計(jì)理念

    canal的組件化設(shè)計(jì)非常好,有點(diǎn)類似于tomcat的設(shè)計(jì)。使用組合設(shè)計(jì),依賴倒置,面向接口的設(shè)計(jì)。

    3.2 canal的組件有哪些

  • canal server 這個(gè)代表了我們部署的一個(gè)canal 應(yīng)用
  • canal instance 這個(gè)代表了一個(gè)canal server中的多個(gè) mysql instance ,從這一點(diǎn)說明一個(gè)canal server可以搜集多個(gè)庫(kù)的數(shù)據(jù),在canal中叫 destionation。
  • ??每個(gè)canal instance 有多個(gè)組件構(gòu)成。在conf/spring/default-instance.xml中配置了這些組件。他其實(shí)是使用了spring的容器來進(jìn)行這些組件管理的。

    3.3 instance 包含的組件

    這里是一個(gè)cannalInstance工作所包含的大組件。截取自 conf/spring/default-instance.xml

    <bean id="instance" class="com.alibaba.otter.canal.instance.spring.CanalInstanceWithSpring"><property name="destination" value="${canal.instance.destination}" /><property name="eventParser"><ref local="eventParser" /></property><property name="eventSink"><ref local="eventSink" /></property><property name="eventStore"><ref local="eventStore" /></property><property name="metaManager"><ref local="metaManager" /></property><property name="alarmHandler"><ref local="alarmHandler" /></property></bean>
  • eventParser 最基本的組件,類似于mysql從庫(kù)的dump線程,負(fù)責(zé)從master中獲取bin_log
  • eventSink 數(shù)據(jù)的歸集,使用設(shè)置的filter對(duì)bin log進(jìn)行過濾,工作的過程如下。
  • eventStore 用來存儲(chǔ)filter過濾后的數(shù)據(jù),canal目前的數(shù)據(jù)只在這里存儲(chǔ),工作流程如下。
  • metaManager 用來存儲(chǔ)一些原數(shù)據(jù),比如消費(fèi)到的游標(biāo),當(dāng)前活動(dòng)的server等信息
  • alarmHandler 報(bào)警,這個(gè)一般情況下就是錯(cuò)誤日志,理論上應(yīng)該是可以定制成郵件等形式,但是目前不支持
  • 3.4 各個(gè)組件目前支持的類型

    canal采用了spring bean container的方式來組裝一個(gè)canal instance ,目的是為了能夠更加靈活。

  • eventParser 目前只有三種
    1.1. MysqlEventParser 用于解析mysql的日志
    1.2. GroupEventParser 多個(gè)eventParser的集合,理論上是對(duì)應(yīng)了分表的情況,可以通過這個(gè)合并到一起
    1.3. RdsLocalBinlogEventParser 基于rds的binlog 的復(fù)制
  • eventSink 目前只有EntryEventSink 就是基于mysql的binlog數(shù)據(jù)對(duì)象的處理操作
  • eventStore 目前只有一種 MemoryEventStoreWithBuffer,內(nèi)部使用了一個(gè)ringbuffer 也就是說canal解析的數(shù)據(jù)都是存在內(nèi)存中的,并沒有到zookeeper當(dāng)中。
  • metaManager 這個(gè)比較多,其實(shí)根據(jù)元數(shù)據(jù)存放的位置可以分為三大類,memory,file,zookeeper
  • ??canal通過這些組件的選取可以達(dá)到不同使用場(chǎng)景的效果,比如單機(jī)的話,一般使用file來存儲(chǔ)metadata就行了,HA的話一般使用zookeeper來存儲(chǔ)metadata。

    4. canal的工作過程

    4.1 啟動(dòng)時(shí)去MySQL 進(jìn)行dump操作的binlog 位置確定

    ??工作的過程。在啟動(dòng)一個(gè)canal instance 的時(shí)候,首先啟動(dòng)一個(gè)eventParser 線程來進(jìn)行數(shù)據(jù)的dump 當(dāng)他去master拉取binlog的時(shí)候需要binlog的位置,這個(gè)位置的確定是按照如下的順序來確定的(這個(gè)地方講述的是HA模式哈)。

  • 在啟動(dòng)的時(shí)候判斷是否使用zookeeper,如果是zookeeper,看能否拿到 cursor (也就是binlog的信息),如果能夠拿到,把這個(gè)信息存到內(nèi)存中(MemoryLogPositionManager),然后拿這個(gè)信息去mysql中dump binlog
  • 通過1拿不到的話(一般是zookeeper當(dāng)中每一,比如第一次搭建的時(shí)候,或者因?yàn)槟承┰騴k中的數(shù)據(jù)被刪除了),就去配置文件配置當(dāng)中的去拿,把這個(gè)信息存到內(nèi)存中(MemoryLogPositionManager),然后拿這個(gè)信息去mysql中dump binlog
  • 通過2依然沒有拿到的話,就去mysql 中執(zhí)行一個(gè)sql show master status 這個(gè)語句會(huì)顯示當(dāng)前mysql binlog最后位置的信息,也就是剛寫入的binlog所在的位置信息。把這個(gè)信息存到內(nèi)存中(MemoryLogPositionManager),然后拿這個(gè)信息去mysql中dump binlog。
  • ??后面的eventParser的操作就會(huì)以內(nèi)存中(MemoryLogPositionManager)存儲(chǔ)的binlog位置去master進(jìn)行dump操作了。
    mysql的show master status 操作

    mysql> mysql> show master status\G *************************** 1. row *************************** File: mysql-bin.000028 Position: 635762367 Binlog_Do_DB:Binlog_Ignore_DB: Executed_Gtid_Set: 18db0532-6a08-11e8-a13e-52540042a113:1-2784514, 318556ef-4e47-11e6-81b6-52540097a9a8:1-30002, ac5a3780-63ad-11e8-a9ac-52540042a113:1-5, be44d87c-4f25-11e6-a0a8-525400de9ffd:1-156349782 1 row in set (0.00 sec)

    4.2 數(shù)據(jù)在dump回來之后進(jìn)行的歸集(sink)和存儲(chǔ)(store)

    sink操作是可以支撐將多個(gè)eventParser的數(shù)據(jù)進(jìn)行過濾filter

    filter使用的是instance.properties中配置的filter,當(dāng)然這個(gè)filter也可以由canal的client端在進(jìn)行subscribe的時(shí)候進(jìn)行設(shè)置。如果在client端進(jìn)行了設(shè)置,那么服務(wù)端配置文件instance.properties的配置都會(huì)失效

    sink 之后將過濾后的數(shù)據(jù)存儲(chǔ)到eventStore當(dāng)中去。
    ??目前eventStore的實(shí)現(xiàn)只有一個(gè)MemoryEventStoreWithBuffer,也就是基于內(nèi)存的ringbuffer,使用這個(gè)store有一個(gè)特點(diǎn),這個(gè)ringbuffer是基于內(nèi)存的,大小是有限制的(bufferSize = 16 * 1024 也就是16M),所以,當(dāng)canal的客戶端消費(fèi)比較慢的時(shí)候,ringbuffer中存滿了就會(huì)阻塞sink操作,那么正讀取mysql binlog的eventParser線程也會(huì)受阻。
    ??這種設(shè)計(jì)其實(shí)也是有道理的。 因?yàn)閏anal的操作是pull 模型,不是producer push的模型,所以他沒必要存儲(chǔ)太多數(shù)據(jù),這樣就可以避免了數(shù)據(jù)存儲(chǔ)和持久化管理的一些問題。使數(shù)據(jù)管理的復(fù)雜度大大降低。

    ??上面這些整個(gè)是canal的parser 線程的工作流程,主要對(duì)應(yīng)的就是將數(shù)據(jù)從mysql搞下來,做一些基本的歸集和過濾,然后存儲(chǔ)到內(nèi)存中。

    4.3 binlog的消費(fèi)者

    ??canal從mysql訂閱了binlog以后主要還是想要給消費(fèi)者使用。那么binlog是在什么時(shí)候被消費(fèi)呢。這就是另一條主線了。就像咱們做一個(gè)toC的系統(tǒng),管理系統(tǒng)是必須的,用戶使用的app或者web又是一套,eventParser 線程就像是管理系統(tǒng),往里面錄入基礎(chǔ)數(shù)據(jù)。canal的client就像是app端一樣,是這些數(shù)據(jù)的消費(fèi)方。
    ??binlog的主要消費(fèi)者就是canal的client端。使用的協(xié)議是基于tcp的google.protobuf,當(dāng)然tcp的模式是io多路復(fù)用,也就是nio。當(dāng)我們的client發(fā)起請(qǐng)求之后,canal的server端就會(huì)從eventStore中將數(shù)據(jù)傳輸給客戶端。根據(jù)客戶端的ack機(jī)制,將binlog的元數(shù)據(jù)信息定期同步到zookeeper當(dāng)中。

    差不多主要的操作就是這些吧。

    5. canal的目錄結(jié)構(gòu)(不包含lib目錄)

    配置父目錄:
    在下面可以看到,

    canal ├── bin ├── canal.pid ├── startup.bat ├── startup.sh └── stop.sh └── conf├── canal.properties├── gamer ---目錄├── ww_social ---目錄├── wother ---目錄├── nihao ---目錄├── liveim ---目錄├── logback.xml├── spring ---目錄├── ym ---目錄└── xrm_ppp ---目錄

    這里是全部展開的目錄

    canal ├── bin │ ├── canal.pid │ ├── startup.bat │ ├── startup.sh │ └── stop.sh └── conf├── canal.properties├── game_center│ └── instance.properties├── ww_social│ ├── h2.mv.db│ ├── h2.trace.db│ └── instance.properties├── wwother│ ├── h2.mv.db│ └── instance.properties├── nihao│ ├── h2.mv.db│ ├── h2.trace.db│ └── instance.properties├── movie│ ├── h2.mv.db│ └── instance.properties├── logback.xml├── spring│ ├── default-instance.xml│ ├── file-instance.xml│ ├── group-instance.xml│ ├── local-instance.xml│ ├── memory-instance.xml│ └── tsdb│ ├── h2-tsdb.xml│ ├── mysql-tsdb.xml│ ├── sql│ └── sql-map└── ym└── instance.properties

    總結(jié)

    以上是生活随笔為你收集整理的canal原理的一些学习-1(canal的一些原理性介绍)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。