分庫分表後如何部署上線?

分庫分表後如何部署上線?

 

引言mysql

咱們先來說一個段子面試

面試官:「有併發的經驗沒?」sql

應聘者:「有一點。」數據庫

面試官:「那大家爲了處理併發,作了哪些優化?」後端

應聘者:「先後端分離啊,限流啊,分庫分表啊。。」性能優化

面試官:"談談分庫分表吧?"服務器

應聘者:「bala。bala。bala。。」架構

面試官心理活動:這個仁兄講的怎麼這麼像網上的博客抄的,容我再問問。併發

面試官:「大家分庫分表後,如何部署上線的?」oracle

應聘者:「這!!!!!!」

不要驚訝,寫這篇文章前,我特地去網上看了下分庫分表的文章,很神奇的是,都在講怎麼進行分庫分表,卻不說分完之後,怎麼部署上線的。這樣在面試的時候就比較尷尬了。

大家本身摸着良心想一下,若是你真的作過度庫分表,你會不知道如何部署的麼?所以咱們來學習一下如何部署吧。

ps: 我發現一個很神奇的現象。由於不少公司用的技術比較low,那麼一些求職者爲了提升本身的競爭力,就會將一些高大上的技術寫進本身的low項目中。而後呢,他出去面試懼怕碰到從這個公司出來的人,畢竟從這個公司出來的人,必定知道本身之前公司的項目情形。所以爲了圓謊,他就會說:「他們從事的是這個公司的老項目改造工做,用了不少新技術進去!」

那麼,請你好好思考一下,大家的老系統是如何平滑升級爲新系統的!

如何部署

停機部署法

大體思路就是,掛一個公告,半夜停機升級,而後半夜把服務停了,跑數據遷移程序,進行數據遷移。

步驟以下:

(1)出一個公告,好比「今晚00:00~6:00進行停機維護,暫停服務」

(2)寫一個遷移程序,讀 db-old 數據庫,經過中間件寫入新庫 db-new1 和 db-new2 ,具體以下圖所示

分庫分表後如何部署上線?

 

(3)校驗遷移先後一致性,沒問題就切該部分業務到新庫。

順便科普一下,這個中間件。如今流行的分庫分表的中間件有兩種,一種是 proxy 形式的,例如 mycat ,是須要額外部署一臺服務器的。還有一種是 client 形式的,例如噹噹出的 Sharding-JDBC ,就是一個jar包,使用起來十分輕便。我我的偏向 Sharding-JDBC ,這種方式,無需額外部署,無其餘依賴,DBA也無需改變原有的運維方式。

評價:

你們不要以爲這種方法low,我其實一直以爲這種方法可靠性很強。並且我相信各位讀者所在的公司必定不是什麼很牛逼的互聯網公司,若是大家的產品凌晨1點的用戶活躍數還有超過1000的,大家握個爪!畢竟不是全部人都在什麼電商公司的,大部分產品半夜都沒啥流量。因此此方案,並不是沒有可取之處。

可是此方案有一個缺點, 累! 不止身體累,心也累!你想一想看,原本定六點結束,你五點把數據庫遷移好,可是不知怎麼滴,程序切新庫就是有點問題。因而,眼瞅着天就要亮了,趕忙把數據庫切回老庫。第二個晚上繼續這麼幹,簡直是身心俱疲。

ps: 這裏教你們一些技巧啊,若是你真的沒作過度庫分表,又想吹一波,漲一下工資,建議答這個方案。由於這個方案比較low,low到沒什麼東西能夠深挖的,因此答這個方案,比較靠譜。

另外,若是面試官的問題是

大家怎麼進行分庫分表的?

這個問題問的很泛,因此回答這個問題建議本身主動把分表的策略,以及如何部署的方法講出來。由於這麼答,顯得嚴謹一些。

不過,不少面試官爲了賣弄本身的技術,喜歡這麼問

分表有哪些策略啊?大家用哪一種啊?

ok。。這個問題具體指向了分庫分表的某個方向了,你不要主動答如何進行部署的。等面試官問你,你再答。若是面試官沒問,在面試最後一個環節,面試官會讓你問讓幾個問題。你就問

你剛纔恰好有提到分庫分表的相關問題,咱們當時部署的時候,先停機。而後半夜遷移數據,而後次日將流量切到新庫,這種方案太累,不知道貴公司有沒有什麼更好的方案?

那麼這種狀況下,面試官會有兩種回答。第一種,面試官硬着頭皮隨便扯。第二種,面試官真的作過,據實回答。記住,面試官怎麼回答的不重要。重點的是,你這個問題出去,會給面試官一種錯覺:"這個小夥子真的作過度庫分表。"

若是你擔憂進去了,真派你去作分庫分表怎麼辦?OK,不要怕。我賭你試用期碰不到這個活。由於能進行分庫分表,一定對業務很是熟。還在試用期的你,一定對業務不熟,若是領導給你這種活,我只能說他有一顆大心臟。

ok,指點到這裏。面試原本就是一場鬥智鬥勇的過程,扯遠了,回到咱們的主題。

雙寫部署法(一)

這個就是不停機部署法,這裏我須要先引進兩個概念: 歷史數據 和 增量數據 。

假設,咱們是對一張叫作 test_tb 的表進行拆分,由於你要進行雙寫,系統裏頭和 test_tb表有關的業務以前一定會加入一段雙寫代碼,同時往老庫和新庫中寫,而後進行部署,那麼

歷史數據:在該次部署前,數據庫表 test_tb 的有關數據,咱們稱之爲歷史數據。

增量數據:在該次部署後,數據庫表 test_tb 的新產生的數據,咱們稱之爲增量數據。

而後遷移流程以下

(1)先計算你要遷移的那張表的 max(主鍵) 。在遷移過程當中,只遷移 db-old 中 test_tb 表裏,主鍵小等於該 max(主鍵) 的值,也就是所謂的歷史數據。

這裏有特殊狀況,若是你的表用的是uuid,無法求出 max(主鍵) ,那就以建立時間做爲劃分歷史數據和增量數據的依據。若是你的表用的是uuid,又沒有建立時間這個字段,我相信機智的你,必定有辦法區分出歷史數據和增量數據。

(2)在代碼中,與 test_tb 有關的業務,多加一條往消息隊列中發消息的代碼,將操做的sql發送到消息隊列中,至於消息體如何組裝,你們自行考慮。 須要注意的是, 只發寫請求的sql,只發寫請求的sql,只發寫請求的sql。重要的事情說三遍!

緣由有二:

  • (1)只有寫請求的sql對恢復數據纔有用。
  • (2)系統中,絕大部分的業務需求是讀請求,寫請求比較少。

注意了,在這個階段,咱們不消費消息隊列裏的數據。咱們只發寫請求,消息隊列的消息堆積狀況不會太嚴重!

(3)系統上線。另外,寫一段遷移程序,遷移 db-old 中 test_tb 表裏,主鍵小於該 max(主鍵)的數據,也就是所謂的歷史數據。

上面步驟(1)~步驟(3)的過程以下

分庫分表後如何部署上線?

 

等到 db-old 中的歷史數據遷移完畢,則開始遷移增量數據,也就是在消息隊列裏的數據。

(4)將遷移程序下線,寫一段訂閱程序訂閱消息隊列中的數據

(5)訂閱程序將訂閱到到數據,經過中間件寫入新庫

(6)新老庫一致性驗證,去除代碼中的雙寫代碼,將涉及到 test_tb 表的讀寫操做,指向新庫。

上面步驟(4)~步驟(6)的過程以下

分庫分表後如何部署上線?

 

這裏你們可能會有一個問題,在步驟(1)~步驟(3),系統對歷史數據進行操做,會形成不一致的問題麼?

OK,不會。這裏咱們對 delete 操做和 update 操做作分析,由於只有這兩個操做纔會形成歷史數據變更, insert 進去的數據都是屬於增量數據。

(1)對 db-old 的 test_tb 錶的歷史數據發出 delete 操做,數據還未刪除,就被遷移程序給遷走了。此時 delete 操做在消息隊列裏還有記錄,後期訂閱程序訂閱到該 delete 操做,能夠進行刪除。

(2)對 db-old 的 test_tb 錶的歷史數據發出 delete 操做,數據已經刪除,遷移程序遷不走該行數據。此時 delete 操做在消息隊列裏還有記錄,後期訂閱程序訂閱到該 delete 操做,再執行一次 delete ,並不會對一致性有影響。

對 update 的操做相似,不贅述。

雙寫部署法(二)

上面的方法有一個硬傷,注意我有一句話

(2)在代碼中,與test_tb有關的業務,多加一條往消息隊列中發消息的代碼,將操做的sql發送到消息隊列中,至於消息體如何組裝,你們自行考慮。

你們想一下,這麼作,是否是形成了嚴重的代碼入侵。將非業務代碼嵌入業務代碼,這麼作,後期刪代碼的時候特別累。

有沒什麼方法,能夠避免這個問題的?

有的,訂閱 binlog 日誌。關於 binlog 日誌,我儘可能下週寫一篇《研發應該掌握的binlog知識》,這邊我就介紹一下做用

記錄全部數據庫表結構變動(例如CREATE、ALTER TABLE…)以及表數據修改(INSERT、UPDATE、DELETE…)的二進制日誌。binlog不會記錄SELECT和SHOW這類操做,由於這類操做對據自己並無修改。

還記得咱們在 雙寫部署法(一) 裏介紹的,往消息隊列裏發的消息,都是寫操做的消息。而 binlog 日誌記錄的也是寫操做。因此訂閱該日誌,也能知足咱們的需求。

因而步驟以下

(1)打開binlog日誌,系統正常上線就好

(2)仍是寫一個遷移程序,遷移歷史數據。步驟和上面相似,不囉嗦了。

步驟(1)~步驟(2)流程圖以下

分庫分表後如何部署上線?

 

(3)寫一個訂閱程序,訂閱binlog(mysql中有 canal 。至於oracle中,你們就隨緣本身寫吧)。而後將訂閱到到數據經過中間件,寫入新庫。

(4)檢驗一致性,沒問題就切庫。

步驟(3)~步驟(4)流程圖以下

分庫分表後如何部署上線?

 

怎麼驗數據一致性

這裏大概介紹一下吧,這篇的篇幅太長了,你們內心有底就行。

(1)先驗數量是否一致,由於驗數量比較快。

至於驗具體的字段,有兩種方法:

(2.1)有一種方法是,只驗關鍵性的幾個字段是否一致。

(2.2)還有一種是 ,一次取50條(不必定50條,具體本身定,我只是舉例),而後像拼字符串同樣,拼在一塊兒。用md5進行加密,獲得一串數值。新庫同樣如法炮製,也獲得一串數值,比較兩串數值是否一致。若是一致,繼續比較下50條數據。若是發現不一致,用二分法肯定不一致的數據在0-25條,仍是26條-50條。以此類推,找出不一致的數據,進行記錄便可。

ok,囉嗦完畢。

順便在此給你們推薦一個Java架構方面的交流學習羣:698581634,裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化這些成爲架構師必備的知識體系,主要針對Java開發人員提高本身,突破瓶頸,相信你來學習,會有提高和收穫。在這個羣裏會有你須要的內容  朋友們請抓緊時間加入進來吧。

相關文章
相關標籤/搜索