MySQL數(shù)據(jù)遷移工具的設計與實現(xiàn)

一洋侨、背景

MySQL作為最流行的關系型數(shù)據(jù)庫產品之一矾瑰,當數(shù)據(jù)規(guī)模增大遭遇性能瓶頸時,最容易想到的解決方案就是分庫分表。無論是進行水平拆分還是垂直拆分或听,第一步必然需要數(shù)據(jù)遷移與同步探孝。由此可以衍生出一系列數(shù)據(jù)遷移過程中的需求:

1.原本一張表遷移到單庫多表(或多庫多表),這是最基本的需求誉裆;

2.原本單庫多表(或多庫多表)遷移到新的多庫多表(因表設計不合理顿颅、數(shù)據(jù)規(guī)模增大等原因導致需要再次分庫分表)

3.新表與舊表的表結構可能不一致,如:類型表更(自增主鍵id由int改為bigint)足丢、字段數(shù)量不一致(刪減粱腻、增加)、字段名稱變更等

4.字段映射斩跌,如:舊表中的多個字段映射為新表的一個字段绍些,或舊表中的一個字段映射為新表的多個字段

5.增量數(shù)據(jù)的實時同步,以及當涉及表結構轉換時增量部分(binlog)如何方便地實現(xiàn)同樣的轉換

6.如何支持垂直拆分的數(shù)據(jù)遷移

7.MySQL到NewSQL的遷移(如:TiDB耀鸦、CockroachDB)

8.異構數(shù)據(jù)源的實時遷移柬批,如:MySQL到HBase、MongoDB(關于異構數(shù)據(jù)源的實時同步設計不在本文內容范圍袖订,后續(xù)將專題介紹)

9.遷移前后的數(shù)據(jù)一致性校驗

二氮帐、設計

為滿足以上需求,下面將從全量遷移和增量同步兩部分來說明MySQL數(shù)據(jù)遷移同步工具的設計與實現(xiàn)洛姑。

2.1 全量遷移

mysqldump是MySQL官方自帶的數(shù)據(jù)備份工具上沐,也可以用于數(shù)據(jù)遷移,但不足之處是單線程處理楞艾,遷移大表時速度極慢参咙,并且不支持寫入分庫分表。因此開源社區(qū)還開發(fā)了一個多線程的類似工具mydumper硫眯,性能有不少提升蕴侧,但同樣不支持寫入分庫分表,也不支持字段的轉換两入。

接下來介紹下快速分片并行讀取MySQL表數(shù)據(jù)的做法:

1戈盈、 自動查找表的主鍵pk;

2谆刨、 查詢主鍵的最大值及最小值:max(pk),min(pk)归斤;

3痊夭、 對主鍵范圍分片,每個分片跨度1萬(即最多讀取1萬行數(shù)據(jù))脏里,由此即可將整張表的查詢分成多個查詢分片:

第1個分片查詢條件為pk >= min(pk) AND pk < min(pk)+10000

第2個分片查詢條件為pk>= min(pk)+10000 AND pk < min(pk)+20000

第3個分片查詢條件為pk >= min(pk)+20000 AND pk < min(pk)+30000

以此類推她我。

以上分片查詢除了可以并行讀取之外,另外一個優(yōu)勢是失敗可恢復,某個分片查詢失敗并不影響整體查詢的進度番舆,只需失敗重試即可酝碳。當然也可以將所有分片持久化,即使程序異常退出恨狈,重啟后也可以恢復疏哗,避免重新查詢全表數(shù)據(jù)。

2.2 增量同步

增量數(shù)據(jù)的讀取基于MySQL的binlog主從復制禾怠。在全量遷移之前首先獲取當前MySQL的位點信息(FileName返奉、Position),以便全量數(shù)據(jù)遷移完成之后從該位點繼續(xù)重放binlog吗氏。

三芽偏、實現(xiàn)

3.1 全量遷移


基于RxJava的觀察者(或生產者消費者)模式實現(xiàn)鏈式最大化并行處理:多張表并行生成查詢分片(Query Split),然后由Source并行執(zhí)行查詢分片從MySQL中讀取數(shù)據(jù)弦讽,然后統(tǒng)一由Sink Selector根據(jù)分庫分表的sharding字段及規(guī)則計算出每行數(shù)據(jù)所屬的slot(即應該寫入到哪張分表)污尉,當一個slot中的數(shù)據(jù)積累到一個batch size時會生成一個插入分片(Insert Split),最終由Sink并行地批量寫入對應的目標表中往产。

為了避免累積的數(shù)據(jù)過多造成GC壓力被碗,slot超過一定時間后即使沒有累積到一個batch size也會生成Insert Split分發(fā)給Sink執(zhí)行寫入。此外還要考慮另外一個問題:當生產者生產過快導致消費者來不及處理時捂齐,將會導致事件堆積蛮放,嚴重時還會OOM,即所謂的背壓(Backpressure)奠宜。幸好RxJava作為一個成熟的Reactive框架已經(jīng)對背壓處理有很好的支持包颁,這也是為什么要基于RxJava來實現(xiàn)的重要原因之一。

3.2 增量同步


binlog的抽取使用了開源的Java類庫mysql-binlog-connector-java压真,與Canal相比更加輕量娩嚼,源碼清晰易懂,不依賴其他第三方jar包滴肿,也沒有那么多不需要的繁雜功能岳悟。

為了實現(xiàn)對binlog的字段轉換,采用了Apache開源的SQL引擎calcite來實現(xiàn):將binlog的每行數(shù)據(jù)根據(jù)原表的表結構映射為一張內存表泼差,然后由calcite執(zhí)行SQL轉換后輸出結果贵少。(PS:calcite當前已被多個開源項目采用,Hive用calcite優(yōu)化查詢堆缘,F(xiàn)link的Streaming SQL基于calcite實現(xiàn)滔灶,Kylin的查詢引擎也采用calcite)

3.3 數(shù)據(jù)校驗

因MySQL表的checksum與數(shù)據(jù)的行順序無關,當新表與舊表的表結構相同并且數(shù)據(jù)不需要轉換時采用執(zhí)行CHECKSUM TABLE tbl_name查詢語句獲取每張新表和舊表的checksum吼肥,然后分別求和對比最終的checksum是否相同以此校驗數(shù)據(jù)是否一致录平。

當新表與舊表存在字段類型變更麻车、字段數(shù)量不一致、數(shù)據(jù)經(jīng)過轉換等會導致checksum發(fā)生變化時斗这,采用排除有關字段动猬,由遷移工具內部只對剩余字段數(shù)據(jù)進行checksum計算。Checksum算法可以選擇CRC32或Adler32表箭,這兩種算法均采用Java自帶的實現(xiàn)類赁咙,默認情況下使用Adler32因為其具有更快的計算效率。

四燃逻、總結

無論是分庫分表常規(guī)方案的實施序目,還是未來新一代分布式關系型數(shù)據(jù)存儲NewSQL的落地實踐,數(shù)據(jù)的遷移與同步都是必不可少的重要環(huán)節(jié)伯襟。畢竟猿涨,快速、準確姆怪、平滑地完成數(shù)據(jù)遷移叛赚,便已成功了一半。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末稽揭,一起剝皮案震驚了整個濱河市俺附,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溪掀,老刑警劉巖事镣,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異揪胃,居然都是意外死亡璃哟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門喊递,熙熙樓的掌柜王于貴愁眉苦臉地迎上來随闪,“玉大人,你說我怎么就攤上這事骚勘☆戆椋” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵俏讹,是天一觀的道長当宴。 經(jīng)常有香客問我,道長泽疆,這世上最難降的妖魔是什么即供? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮于微,結果婚禮上逗嫡,老公的妹妹穿的比我還像新娘。我一直安慰自己株依,他們只是感情好驱证,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著恋腕,像睡著了一般抹锄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荠藤,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天伙单,我揣著相機與錄音,去河邊找鬼哈肖。 笑死吻育,一個胖子當著我的面吹牛,可吹牛的內容都是我干的淤井。 我是一名探鬼主播布疼,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼币狠!你這毒婦竟也來了游两?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤漩绵,失蹤者是張志新(化名)和其女友劉穎贱案,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體止吐,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡宝踪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了祟印。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肴沫。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蕴忆,靈堂內的尸體忽然破棺而出颤芬,到底是詐尸還是另有隱情,我是刑警寧澤套鹅,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布站蝠,位于F島的核電站,受9級特大地震影響卓鹿,放射性物質發(fā)生泄漏菱魔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一吟孙、第九天 我趴在偏房一處隱蔽的房頂上張望澜倦。 院中可真熱鬧聚蝶,春花似錦、人聲如沸藻治。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桩卵。三九已至验靡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雏节,已是汗流浹背胜嗓。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钩乍,地道東北人辞州。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像件蚕,于是被迫代替她去往敵國和親孙技。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容