由 Canal 組件分析集成中間件架構的一般過程

來源:日新科技報 2018-08-11 00:30:50

由Canal組件分析集成中間件架構的一般過程

數據同步背景

為什麽要做數據同步?因為數據很多,還要共享或做它用。舉個栗子,你從移動硬盤拷貝一份小小電影到你的Macbook上賞析,也叫數據同步。但係統不比你的單純,它使用的場景千奇百怪。數據同步,不管愛與不愛,你總會遇見,它會在某個時間等你,不見不散。

哎,不就是A到B麽,一個管道,罩得住。

在進入正文之前,順便給大家推薦一個Java架構方麵的交流學習群:725633148,裏麵會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高並發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體係。相信對於已經工作和遇到技術瓶頸的同學,在這個群裏會有你需要的內容。有需要的同學請抓緊時間加入進來。

Canal簡介

要在有限的時間裏漂亮的完成工作,有時候你關注的並不一定是問題中心,深挖學習了binlog的同步方式,並不會對你的工作進度有任何改善。將它加入到研究列表中,空閑的時間去學習更佳,沒必要非要把頭悶在水裏憋氣去體驗窒息的味道。好了,問題的中心數據同步,已經由阿裏的工程師替你完成了,就叫Canal,解決的是最常用的MySQL數據庫同步到別處的問題。今天我們談一下Canal集成,但不談Canal細節實現。周邊建設別人不舍得告訴你,小姐姐和你聊。

Canal是將自己偽裝成一個MySQL從庫從其他真正的MySQL庫上拉取信息,說白了就是實現了MySQL的一套協議,數據拿過來之後,想怎麽把玩就怎麽玩嘍。東西是好東西,但github上的wiki文檔讓人看的昏昏欲睡,既然是談架構,那我們就聊一下如何才能讓工程師放心的使用你的Canal。

數據格式

簡單說下Canal的數據格式,根據github的官方文檔就能夠簡單的RUN起來。Canal能夠同步大多數DCL、DML、DDL,我們通常也就關心INSERT、UPDATE、DELETE引起的變化。那Canal解釋的數據是什麽樣子呢,我們可以用一張圖來說明。

可以看到UPDATE同時包括變更前和變更後的值,需要的信息就都有了。有了這些數據,上天入地,無所不能。

一個通用的架構模式就是隻考慮輸入和輸出。使用者大多數並不關心你的係統是怎麽實現的,大家都很忙,而且並不一定都有興趣。他隻需要你告訴他最終的使用方式和輸出格式即可。

整體高可用

那麽開發使用中有哪些元素需要參與呢?我們同樣上一張圖(僅考慮集群主從模式,單機和M/M不談)。

很Easy是不是?ZK控製著HA,同時記錄消費的消費進度,怎麽看都和Kafka之流一個套路。但這裏有幾點要說明:

1) 為了保證binlog正常拉取,Canal服務器同時隻有一台工作,其他都是影子 lol

2) 為了保證消費能正常進行,Client端同時隻有一台能夠工作,其他都是影子 lol

3) binlog推薦使用ROW模式,但有可能一個update語句擠爆你的內存、打碎你的蛋蛋

4) Canal本身沒有持久化能力,非常耗內存

我們接下來按照順序模擬它們的死亡。考慮下麵一張圖。

紅色的區塊都是可能死亡的點,ZK會死(當然它堅挺的很),MySQL會死,至於Canal,也肯定不能免俗,我們要讓它的死輕如鴻毛。

小姐姐,提醒,架構要考慮到每一個交互場景和極端情況。準備的越細,覺睡的越香。除了讓挑戰你的無聊者碰一鼻子灰(對,就是那些整天將高可用掛在嘴上的貨),也能節省更多時間研究些更有意義的事情。

ZK當機

ZooKeeper那麽健壯,為什麽還要模擬其當機呢?因為不排除機房斷電的可能。為什麽我們首先談到ZK?從圖中可以看到Zk死亡對係統的影響是巨大的。當然這僅僅是概率而已,最終會推斷出SLA服務質量,滿足需求即可。

當然不排除有某些強迫症的外部因素影響你去做它的高可用。除了分機房,你可以可以在代碼中進行集成,比如ZK死亡,我們去直連Canal。你要考慮開發成本和達到的效益是否合適。

有些公司在屁都沒做出來之前,就特別潔癖的關注低概率事件,問題本身倒成了次要的了。這種公司是有問題的,盡量去說服吧。

所以如果ZK當機問題占用你的工作量,主要是其他人的認知問題。

Canal當機

Canal集群模式已經通過ZK做了HA,你要做的,就是模擬一遍。包括:

1) 當機一台,是否有其他實例頂上來

2) 全部當機,上線一台後是否能正常運行

3) 長時間下線後,突然上線是否有其他問題?

4) 內存問題。canal非常耗內存,可以配置參數使其不溢出,但會產生阻塞。

Client當機

Client的當機其實是無所謂的。但由於實現的方式千奇百怪,也會產生千奇百怪的事情。本部分主要是使用方式問題,可以備注在注意事項裏。我們通過代碼來說明:

1) 代碼有兩層while循環,如果隻有一層的話,會出問題的(想一想問什麽)

2) 代碼有ACK確認機製,代碼顯示的進行了確認和回滾。但如果你的處理是放在多線程裏,那就有可能漏掉消息

3) 消息有batch,所以不可避免會出現重複消費的情況,你的業務支持冪等麽?

MySQL當機

1) MySQL重新上線後Canal是否能夠正常拉取binlog?

2) 主從切換後,是否需要修改Canal? 怎麽補數據?

外圍擴展

要將Canal用起來的話,它本身隻能算是一個半成品。隻有給它加上翅膀,它才能夠自由飛翔。

MQ

考慮到Canal的堆積能力並不強。堆積數據到10W+時,速度會變慢,並會出現假死現象。另外一個場景,就是canal突然上線,這時候已經延後binlog很多了,重新連接後會一次性獲取所有數據,卡到死為止~。

對於第一個場景,一個MQ介入是非常有必要的。Kafka等消息隊列的堆積能力已經家喻戶曉,我們要做的就是將Canal的數據進行一次轉發。以後的客戶端,打交道的就隻有MQ了。MQ介入後,有以下好處:

1) 獲得非常好的堆積能力,可以延後消費

2) 能夠方便的得到積壓數據,進行監控報警

3) 不比引入Canal客戶端,客戶端開發隻與MQ打交道即可

4) MQ支持順序消息,對於無時序數據而言,非順序消息能增加處理能力

監控報警

每個節點都會出問題,所以每個節點都需要監控。監控係統也是每個公司的工具鏈,你可能需要寫一些zabbix或者telegraf腳本進行數據收集(監控係統我們後續文章介紹)。

進程監控

監控各組件是否存活,java程序發生內存溢出死亡的概率還是很大的。如果想要進程死亡後自動重啟,可以考慮采用supervisor組件。

BTW:如果你找不到進程的死亡原因,執行dmesg命令,大概率會看到死亡原因。

業務監控

1) MySQL binlog位置監控(show master status;)。

2) Canal到MQ的Sink消費位點監控。

3) 業務消費端對於MQ的消費延遲監控(delay)。

自動部署

一個好的持續集成工具能夠大量減少上線時間和故障響應時間。此部分與各公司的工具鏈有關。比如可以使用ansible等命令行工具,也可以使用jenkins等。

這部分的工作量還是比較大的,尤其是當組件增多。有幾個容易忽略的點需要考慮:

1) MySQL主從切換時,Canal的配置是否需要變動

2) 當單MySQL實例庫表過多時,Canal是否需要分開部署,維護其拓撲結構

3) 各組件啟動順序問題,是否代碼做了兼容能夠支持

4) 數據同步需求是否線性增長,對應Topic的粒度支持

迭代思路

一個使用了第三方組件的數據同步中間件產品的建設過程,大體是分為以下6個階段的。很多人還停留在搭起來就OK的階段。除了搭建驗證讀源碼或者是自己造輪子,還有很多額外的事情要做,這才是架構師應該關注的事情。

基礎搭建使用

可以根據文檔完成一個quickstart,並能初步應用到業務中。此時的服務基本上是裸跑,有比較多的風險。

API封裝易用

根據自己的使用場景剔除或者增加部分功能,根據自己公司的編碼和代碼風格,編寫定製易用的API。這可能是一個適配器,也可能是一個spring-starter等。還有一些坑需要進行屏蔽等,比如開源版本的Canal沒有GTID等,嗬嗬。這個時候適當讀下源碼是非常有必要的。

整體高可用和應急方案

對於一個重量級的中間產品,此部分的重要度是不言而喻的。數據交互節點,每一個都應該是不信任的。仔細CHECK數據交互中的每一個節點,找出突發情況的應急方案。有條件的,需要線上反複演練,確保係統整體達到高可用。

報警運維機製

完成責任劃分和應急處理人員,確保每一條報警信息都能快速響應,將故障影響麵降低到最低。此部分涉及流程機製問題,作為架構師是有責任推進其完成的。

內部文檔與係統集成

為了達到快速響應的目的,同時讓產品更加平滑的加入到公司技術棧中,需要將其集成到公司內部係統中。比如定製的監控係統、繼續集成係統等。同時,為了減少其他夥伴的學習使用成本,一個淺顯易懂的文檔也是必要的(不是doc哦)。對於使用中容易造成故障的點,也要指出,並不是每個人都和你一樣聰明能幹。

宣傳應用檢驗階段

如果對你的係統有信心,最大規模的使用去檢驗其魯棒性是極好的。一些宣傳和支持是必要的,相信到了此階段,有大量的使用案例,不斷的培養用戶,對你係統的懷疑會不攻自破。

總結

架構隻是做技術麽?這是狹義上的理解,技術是個敲門磚。廣義上的架構包括技術、流程和人。轉變這個觀念,願你的事業更上一層樓。

點擊查看原文

相關鏈接