爲何要作數據同步?由於數據不少,還要共享或作它用。舉個栗子,你從移動硬盤拷貝一份小小電影到你的Macbook上賞析,也叫數據同步
。但系統不比你的單純,它使用的場景千奇百怪。數據同步,無論愛與不愛,你總會碰見,它會在某個時間等你,不見不散。
哎,不就是A到B麼,一個管道,罩得住。java
在進入正文以前,順便給你們推薦一個Java架構方面的交流學習羣:725633148,裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化這些成爲架構師必備的知識體系。相信對於已經工做和遇到技術瓶頸的同窗,在這個羣裏會有你須要的內容。有須要的同窗請抓緊時間加入進來。git
要在有限的時間裏漂亮的完成工做,有時候你關注的並不必定是問題中心,深挖學習了
binlog
的同步方式,並不會對你的工做進度有任何改善。將它加入到研究列表中,空閒的時間去學習更佳,不必非要把頭悶在水裏憋氣去體驗窒息的味道。好了,問題的中心數據同步,已經由阿里的工程師替你完成了,就叫Canal
,解決的是最經常使用的MySQL
數據庫同步到別處的問題。今天咱們談一下Canal集成,但不談Canal細節實現。周邊建設別人不捨得告訴你,小姐姐和你聊。github
Canal
是將本身假裝成一個MySQL從庫
從其餘真正的MySQL庫
上拉取信息,說白了就是實現了MySQL
的一套協議,數據拿過來以後,想怎麼把玩就怎麼玩嘍。東西是好東西,但github
上的wiki
文檔讓人看的昏昏欲睡,既然是談架構,那咱們就聊一下如何才能讓工程師放心的使用你的Canal
。spring
簡單說下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,也確定不能免俗,咱們要讓它的死輕如鴻毛。架構
小姐姐,提醒,架構要考慮到每個交互場景和極端狀況。準備的越細,覺睡的越香。除了讓挑戰你的無聊者碰一鼻子灰(對,就是那些成天將
高可用
掛在嘴上的貨),也能節省更多時間研究些更有意義的事情。併發
ZooKeeper
那麼健壯,爲何還要模擬其當機呢?由於不排除機房斷電
的可能。爲何咱們首先談到ZK?從圖中能夠看到Zk死亡對系統的影響是巨大的。固然這僅僅是機率而已,最終會推斷出SLA服務質量
,知足需求便可。
固然不排除有某些強迫症的外部因素影響你去作它的高可用。除了分機房,你能夠能夠在代碼中進行集成,好比ZK
死亡,咱們去直連Canal
。你要考慮開發成本和達到的效益是否合適。
有些公司在屁都沒作出來以前,就特別潔癖的關注低機率事件,問題自己倒成了次要的了。這種公司是有問題的,儘可能去說服吧。
因此若是ZK當機問題佔用你的工做量,主要是其餘人的認知問題。
Canal
集羣模式已經經過ZK作了HA,你要作的,就是模擬一遍。包括:
1) 當機一臺,是否有其餘實例頂上來
2) 所有當機,上線一臺後是否能正常運行
3) 長時間下線後,忽然上線是否有其餘問題?
4) 內存問題。canal很是耗內存,能夠配置參數使其不溢出,但會產生阻塞。
Client的當機實際上是無所謂的。但因爲實現的方式千奇百怪,也會產生千奇百怪的事情。本部分主要是使用方式問題,能夠備註在注意事項裏。咱們經過代碼來講明:
1) 代碼有兩層while
循環,若是隻有一層的話,會出問題的(想想問什麼)
2) 代碼有ACK
確認機制,代碼顯示的進行了確認和回滾。但若是你的處理是放在多線程裏,那就有可能漏掉消息
3) 消息有batch
,因此不可避免會出現重複消費的狀況,你的業務支持冪等麼?
1) MySQL從新上線後Canal是否可以正常拉取binlog?
2) 主從切換後,是否須要修改Canal? 怎麼補數據?
要將Canal用起來的話,它自己只能算是一個半成品
。只有給它加上翅膀,它纔可以自由飛翔。
考慮到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。這多是一個適配器,也多是一個spring-starter等。還有一些坑須要進行屏蔽等,好比開源版本的Canal沒有GTID等,呵呵。這個時候適當讀下源碼是很是有必要的。
對於一個重量級的中間產品,此部分的重要度是不言而喻的。數據交互節點,每個都應該是不信任的。仔細CHECK數據交互中的每個節點,找出突發狀況的應急方案。有條件的,須要線上反覆演練,確保系統總體達到高可用。
完成責任劃分和應急處理人員,確保每一條報警信息都能快速響應,將故障影響面下降到最低。此部分涉及流程機制問題,做爲架構師是有責任推動其完成的。
爲了達到快速響應的目的,同時讓產品更加平滑的加入到公司技術棧中,須要將其集成到公司內部系統中。好比定製的監控系統、繼續集成系統等。同時,爲了減小其餘夥伴的學習使用成本,一個淺顯易懂的文檔也是必要的(不是doc哦)。對於使用中容易形成故障的點,也要指出,並非每一個人都和你同樣聰明能幹。
若是對你的系統有信心,最大規模的使用去檢驗其魯棒性是極好的。一些宣傳和支持是必要的,相信到了此階段,有大量的使用案例,不斷的培養用戶,對你係統的懷疑會不攻自破。
架構只是作技術麼?這是狹義上的理解,技術是個敲門磚。廣義上的架構包括技術、流程和人。轉變這個觀念,願你的事業更上一層樓。