MySQL分佈式數據庫高可用實踐:架構、複製機制、多機房

大家好!我是網易數據運維工程師杜明友,大家可以叫我老杜。首先介紹一下網易雲,是網易集團旗下雲計算和大數據品牌,本文要深入分析的案例是網易雲旗下的即時通訊雲平臺業務,開發者通過集成客戶端SDK和雲端OPEN API,即可快速實現強大的IM功能,作爲PaaS服務模式的網易雲信全面支持Android、iOS、Web、PC等多平臺。還提供了高級通訊功能,包括實時音視頻、互動直播、教學白板、專線電話、短信、專屬雲在內的獨家功能以及更多其他服務。網易雲信滿足包括遊戲、協同辦公、在線醫療、在線客服、在線教育、娛樂、諮詢、生活服務、物流、旅遊、金融等各行業各種產品的即時通訊服務需求。客戶案例有順豐、寶寶樹、挖財網、網易雲音樂、網易雲課堂等等。
分佈式數據庫架構介紹  
作爲時下最火爆的IM雲服務,網易雲無時不刻不在爲百萬商家億級終端用戶提供便捷的即時通信服務。商家產品爆款、用戶活躍交流都在考驗着我們的業務系統。如何保障系統的穩定運行,支撐更大的併發,提供真正的可擴展的IM雲服務一直是我們非常關注的一個問題。

作爲互聯網的一支老牌勁旅,我們在大併發海量互聯網系統構建方面也有着非常深厚的積累與經驗。在數據庫選擇上我們使用了網易私有云中的分佈式數據庫服務(雲DDB)

其架構圖如下

雲DDB主要包括五個組件: NLB、SQL Proxy、DBN、Master、SYSDB

NLB是負載均衡服務,基於LVS打造,負責將應用請求轉發到後端SQL Proxy, 同時定時檢測後端SQL Proxy的可用性,及時將故障機器從集羣中摘除。

SQL Proxy實現了MySQL協議,接收客戶端請求,同時負責將請求路由到具體的後端數據庫節點,並返回數據給客戶端。如果數據請求分佈在多個節點,則可能使用2PC協議進行分佈式事務(保障數據一致性)。

DBN則是底層真正負責數據存取的服務,通常是一個關係型數據庫,目前支持MySQL、Oracle。

Master是管理服務,負責管理集羣,比如新建表、設置數據路由策略、設置客戶端連接池參數、DBN切換、配置變更通知等,操作結果(集羣元數據)將持久化到SYSDB。

SYSDB是一個數據庫,負責存儲分佈式數據庫的元數據信息,包括表、字段、權限、數據路由等信息

DBN與SYSDB使用的是網易私有云RDS,其它組件則部署在使用雲主機上,雲DDB服務的核心組件SQL Proxy以及DBN都是可擴展的,並且高可用的。

DDB處理邏輯簡單來說就是應用請求通過NLB轉發到具體SQL Proxy上,SQL Proxy解析SQL生成執行計劃,下發請求至底層節點,收到DBN數據後做一定的處理返回給客戶端。

高可用分佈式DB服務構建指南  
網易IM雲服務目標是支持彈性擴展、消息必達,那就需要在保證高吞吐、高性能的同時,那就需要數據的高可用性:簡單而言就是數據存儲服務要高可用並且數據不丟失。

因爲關係型數據庫發展幾十年在穩定性方面對比其他數據存儲方案來說存在非常大的優勢,基於此,業務很多對數據一致性的場景都是直接依賴於DB。

比如爲了保證消息準確到達,發送方的消息需要先持久化到DB,再發送到接收方,接收方收到之後更新爲已接收狀態,因此對數據庫是重度依賴。

對關係型數據庫來說高性能高可用跟數據不丟失又往往是魚跟熊掌的關係,要保證數據完全不丟失的話,數據必然是要同時寫入到主庫與從庫纔算完成,此時如果從機異常,數據寫入將失敗,這將導致數據庫服務不可用,相信很少有人能接受。

所以通常在數據一致性與服務可用性上會做一定的妥協,即正常情況下表現爲主從強一致性模式,異常情況下則退化爲異步模式。這在MySQL裏面我們稱之爲Semi sync複製,Oracle 複製(DataGuard) 裏面則爲最大保護模式。

在保證數據服務高性高吞吐的情況下儘量避免數據丟失,我們對網易雲DDB底層DBN做了如下設置:

將sync_binlog與innodb_flush_log_at_trx_commit同時設置爲1,每次數據庫寫操作都會持久化binlog與redo log到磁盤上,保證數據的持久性。

開啓VSR(virtual sync replication),保證主從能實時一致。

開啓Group Commit,以及從庫的並行複製,提升主從性能。

第2點裏的VSR,這個是網易MySQL分支InnoSQL的一個特性,InnoSQL在官方半同步複製(semi sync)基礎上做了部分改進,改善了主庫宕機時主從數據不一致問題,實現機制如圖所示:

簡單來說,MySQL5.5版本中官方semi sync是在binlog與redo都寫完後再將binlog傳輸到從庫,而vsr則是在binlog寫完後與redo log寫之前傳輸binlog,這樣做的好處是可以避免事務日誌提交後主庫宕機恢復後數據幻讀問題。(在官方MySQL5.7中這個問題得到解決,見rpl_semi_sync_master_wait_point參數解釋)

當然這樣做也有缺點,事務需要等待數據傳輸到從庫後再返還,肯定會增加一定的延遲時間,針對這個問題,優化方法就是第三點開啓group commit。開啓後多個事務的binlog一次性提交到磁盤跟傳輸至從庫,這樣可以減少磁盤fsync次數並提升吞吐量。

以下是sync_group (vsr+group commit) 與原生semi sync、 sync(vsr) 、async(不開啓semi sync) 之間性能對比圖,可以看到 vsr + group commit性能與異步複製幾無差別:

同時爲了從庫及時同步數據,我們在從庫上打開並行複製,主庫上事務並行提交從庫上也可以並行恢復,這樣大併發寫入下從庫沒有基本延時。

隨着業務的暴漲,數據量規模及QPS也暴漲幾百倍,經過多次擴容後,爲了提升DDB性能及容量,我們將IM雲底層DBN節點從RDS遷移到物理機,並且使用大量的SSD作爲底層存儲。遷出RDS後DDB底層節點便不再擁有高可用這一特性,爲此我們自己開發了一套DDB底層節點監控與切換工具DDB Monitor,此時DB高可用架構圖變成

DDB Monitor可用於執行日常數據庫擴容切換、故障切換、狀態監控等工作

故障切換模式下會定時(幾秒) 做如下事情:

狀態檢測,包括檢測DBN存活狀態,主從複製關係,binlog位置點,semi狀態等

模擬數據寫入,檢查主庫是否可寫

在判斷MySQL主從何時可以切換方面,與其它開源工具可能有些不同,需要滿足以下情況纔可能觸發故障切換:

DBN主節點無法連接,錯誤號爲2000-3000間指定幾個(避免max connection等服務端反回的錯誤號造成誤判)

DBN主節點指定時間內重試多次仍無法寫入

從庫接收到的binlog已經應用完成或者在若干秒時間內應用完成

上一次數據庫vsr(semi sync)狀態正常或上一次從庫收到的binglog落後主庫若干字節內 (根據業務數據重要程度設置)

如果主庫無法連接,從庫show slave status中Slave_IO_Running狀態需爲NO (從庫與DDB Monitor工具同時監控主庫是否宕機,避免腦裂問題)

從庫Slave_SQL_Running狀態需爲 Yes

其中條件1與條件2 需要滿足至少1者。 4中表示如果對主從一致性要求很高需要滿足上次檢測vsr(semi sync)正常才能切換,而如果可以容忍一定的數據丟失那麼可以設置檢測上次主從同步binlog差值在指定範圍內即可切換。

故障切換後,SQL Proxy收到Master消息會重新建立到正確DBN的連接,主庫宕機情況下基本可以在秒級別完成切換。

當然除了上面這些說的這些部署上保障高可用外之外,加強數據庫設計與監控也是保障數據庫穩定運行非常重要的一環。

數據庫設計方面的措施主要有:

按照數據庫設計規範進行表、SQL設計。表設計儘量精簡,從數據訪問角度設計表結構,在範式與反範式間要做合理的取捨

數據請求儘量精簡快,並減少垮節點訪問,提升數據庫真正的服務時間

高頻查詢需要添加緩存,用戶配置、羣信息配置等少更新高訪問請求走要緩存

對數據一致性要求不高以及數據分析統計類的請求放到從庫查詢

非核心功能、核心但數量少頻次低模塊走RDS,避免相互影響

與應用合作,添加對DB衝擊較大業務場景(比如聊天室)提供限流支持

數據庫監控方面我們主要做了如下以下幾個方面:

DDB各個組件的網絡、系統層面通用性指標監控

SQL Proxy、DDB Master jvmgc信息、連接數、cpu、請求量、響應時間內存使用率日誌等監控

DBN節點(MySQL) Global status、processlist、innodb engine status、slowlog、數據增長率、表分區、文件句柄等監控

數據運維平臺上報表展示基於海量監控數據下通過一定算法得到數據庫容量、運行狀態、重要指標不同時間同比環比,風險點分析提示,風險SQL指示等

一套DDB內通常包含幾百個維度的指標監控及幾十個維度的報警項

多機房高可用實踐  
在過往的運維經歷中,我們遇到過機櫃掉電、機房大面積故障等事情,這種情況的發生會嚴重影響產品可用性。所以對於雲信等重要產品,單機房高可用顯然無法滿足業務追求

多機房是個非常複雜的工程,不僅需要在部署上有多機房部署,在應用層面也需要支持多機房架構,雖然我們在產品發展初期就開始了多機房高可用建設,但到目前我們並沒有完全做到自動化故障切換

這裏介紹下我們做的工作也是拍磚引玉,希望大家提出寶貴意見

我們多機房高可用主要做到的工作

備機房距主機房至少需隔兩百公里距離,機房間必須有專線

服務入口多機房,客戶端請求根據流量配置轉發到不同機房服務器

應用與依賴組件多機房高可用部署(MQ、Hbase、對象存儲服務等),部分組件需要應用雙寫多機房,比如Hbase、對象存儲的寫入等

應用訪問數據服務通過配置管理服務(DISCONF)獲取,數據庫與緩存通過使用功能(MySQL)或複製工具(緩存) 做跨機房數據複製

監控多機房組件的可用性,PE與DBA部署好自動化切換工具

確定基於binlog與應用日誌的重要數據校驗與補償機制

最後數據庫高可用架構圖:

人工切換始終會存在一定的延時,不過我們運維部強大的運維協作工具Stone支持移動端執行服務器命令,可以隨時隨地執行切換操作:

以上就是我此次分享的全部內容,感謝大家的參與,謝謝大家

QA環節

Q1:有什麼好的方案能在保證業務不中斷的情況下實現跨機房大數據庫遷移,在這過程中又如何保證數據的實時性呢?

A1: 數據庫的實時性 可以有專線網絡 + DB複製 來保障, 不終端服務實現跨機房的話 就需要系統相關的所有組件都支持跨機房高可用,並且需要實現自動化切換。補充一點, 跨機房服務部終端,會犧牲一定的數據一致性。我:

Q2:請問你們都有哪些自己研發的模塊開源呢?很想學習下

A2:網易InnoSQL是開源的,另外redis複製遷移工具 redis-migration也是開源的

Q3:關係型數據庫MySQL很流行,但是也有不足,我們最近在考慮有沒有替換的方案。能否將它和其他的對比一下?你們是怎樣做的選擇?

A3:首先我覺得最好是選擇你最熟悉的,能搞定的數據庫。GitLab數據丟失事故 我認爲很大的原因是因爲他們的工程師對postgresql 不是很懂。 另外MySQL發展其實非常快的,5.7 有很多非常好的特性,很多東西都借鑑了Oracle。

Q4:你們有什麼開源的跨機房數據實時同步工具嗎。

A4:我們網易內部有一套自己開發的數據複製工具DTS, 目前還沒有開源, 緩存複製工具有開源 是 redis-migration。git 上大家可以搜一下

Q5:你們的數據訪問高峯是什麼時候呢?還是說一直比較平緩?還有,有沒有大規模遷移數據庫的經歷,可以講一講嗎?

A5:業務肯定有高峯低估的,一般晚上黃金時段是高峯期,凌晨是低谷。數據遷移的話其實做好工具後,數據大小量沒有太大的差別,數據量大的話 需要做限流。

Q6:從技術上選擇MySQL和PG有什麼區別?選擇他們的時候你們是選了最熟悉的還是做了技術選型的調研?

A6:我們選擇了最熟悉並且最適合我們的。PG跟MySQL都非常優秀,性能上也差不多。

Q7:能不能講講上次大規模故障的事情?多長時間內完成恢復?有哪些措施?數據如何備份?

A7: 故障恢復通常需要做好預案, 比如當你無法做到自動化切換的時候,就需要有一套切換的腳本,另外故障切換後通常需要做好一定的限流,不能切完再掛。 數據備份方面:我們一套數據庫備份系統, 數據庫的備份會備份到存儲服務上

Q8:你們的採用分佈式數據庫與單節點數據庫能完全兼容嗎?

A8:大部分都能兼容,少數極端的case不兼容

Q9:你們線上業務單表數據量能去到多少?是如何對這些表進行優化?

A9:一般我們都會分表, 一張大表可能有幾十到幾百張字表,百億級表很多的,比如我們的消息表。 表優化: 1 將歷史數據遷移到離線數據庫 2 精確好字段長度 3 儘量以primary key 或者聯合索引去訪問表

Q10:爲什麼不在sql proxy層使用mycat?最近使用了mycat感覺還不錯

A10:SQL Proxy跟我們DDB各組件是集成在一起的, DDB是2006年開始研發的,比市面上任何一款分庫分表工具都悠久,我們對比過SQL Proxy跟mycat,  各有優缺點。


————————————————
版權聲明:本文爲CSDN博主「高效開發運維」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_37098404/article/details/102704366

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章