歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~mysql
本文由騰訊雲數據庫 TencentDB發表於雲+社區專欄sql
王甲坤,騰訊高級工程師、騰訊雲關係型數據庫MySQL負責人,擁有多年客戶端、數據庫研發經驗。在IOS客戶端、MySQL、PostgreSQL、SQL Server等產品有豐富的研發和產品策劃經驗。數據庫
下面開始咱們今天的主要內容,今天主要是經過什麼、爲何、怎麼作,這條思路跟你們呈現MySQL的高可用。緩存
首先介紹一下什麼是高可用?在我看來就是業務在高質量的狀況下,對用戶提供服務的可運行的總時長。其實咱們從事MySQL相關的工做,你們對9這個數字比較敏感,你們選擇雲廠商雲產品的時候,首先會看它的數據庫有幾個9。目前騰訊雲MySQL能夠作到99.95,整年在25分鐘的樣子。服務器
據我瞭解,高可用最高是能作到3個9,1個6,作到4個9很困難,作到5個9就是極限了。網絡
爲何咱們要作高可用?由於咱們不可控的因素太多了,好比說,挖挖機,我記得基本上每隔一年都會出現這種相似的事件,讓我記憶猶新的是2015年杭州蕭山的某個主幹網被刮斷,致使阿里的部分服務不可用。另外,還有相似的一些停電,或者一些天災等等。值得一提是,運維人員的一些操做失誤案例,rm整個目錄或者drop表,民間有說法叫從刪庫到跑路。不可控制的因素不少,你的數據、用戶是你的,若是不可控的話,你的業務上不去。多線程
通常來講,有兩個指標會被看成衡量的標準,第一是RPO,第二是RTO。RPO從故障開始到業務恢復所丟失的數據量,RTO就是從故障開始到業務恢復所耗費的時長,二者都是越短越好。架構
咱們怎麼作呢?通常來講業界有三種方式,左邊是基於單機存儲方式,這種方式在遊戲場景比較多,你們上層是用單獨的計算機節點,下層用三副本保證數據的可靠性。在計算節點發生故障之後能夠快速遷移到另外一個計算節點,固然咱們騰訊雲的MySQL已經推出了這種模式,相對來講很是廉價,是基礎版,你們在官網均可以購買到這種模式。第二種是基於共享存儲方式,也叫share disk模式,這種比較典型的是oracle的RAC架構。底層基於共享存儲的方式,上層採用多個計算節點,某個計算節點故障可當即從ip列表中提出,不影響用戶訪問。第三種就是基於數據複製模式,也就share nothing模式,經過數據傳輸、複製協議達到兩臺主機數據一致性,也是本次講解的重點。另外,除了存儲節點的高可用,其整個鏈路也須要高可用,好比,我們的IDC機房,交換機,以及主機服務器等。併發
下面咱們介紹下基礎設施的高可用。你們常常聽到幾個術語,第一是同城雙活,第二是兩地三中心,兩地三中心對於金融相關的場景是個強需求,其實說白了就是說咱們在同城兩個節點相差十千米以外有兩個數據中心,在100千米異地之外有另個災備中心,保證了機房的高可用。另外包括網絡、主機,其實架構上是這樣的,至少說你的交換機網絡都有備份,一個倒了之後,另外一個須要替換上去。oracle
下面進入咱們的重點,基於數據複製的高可用,首先介紹一下備份,備份確實是很是重要的,並且備份是一個實在沒辦法最後的一個保障,因此說建議你們無論是在雲上用的業務,仍是本身的IDC儘可能作好備份。
MySQL備份基本上是這兩種:邏輯備份、物理備份。邏輯備份一般使用官方的MySQLDump與第三方工具MyDumper,MyDumper優點在於多線程備份,速率快。物理備份使用Percona的xtrabackup,能夠不落盤,經過基於流式併發與壓縮,生產出成功率較高、速率較快而且暫用存儲空間較低的備份。最後一種就是快照,咱們騰訊雲的基礎版的備份就是經過快照生成的。
那基於數據複製方式,通常是主從兩個節點,數據怎麼保證一致性呢?實際上是經過複製協議進行數據傳輸,經過Switch切換保證故障之後服務可以儘快恢復。右邊的圖基本和騰訊雲MySQL差很少的架構,咱們採用了一主一從的方式,從節點只負責故障的轉移,當主節點掛了之後,經過自動故障探測與自動切換,從而作到業務儘快恢復。另外針對讀寫分離,騰訊雲MySQL現能夠支持一主掛5個只讀節點。
下面介紹一下複製,在介紹複製以前有必要介紹一個重要的概念:binlog,binlog是二進制文件,主要記錄用戶對數據庫更新的sql信息,binlog是什麼樣子呢?它是在磁盤上是這個樣子,使用show binlog events後它是這樣的,裏面會記錄一些元信息,好比位點、事件等等,咱們經過MySQL官方解析工具mysqlbinlog解析後是這樣的,裏面sql語句是使用base64編碼的,解碼後是這樣的,能夠看到這裏是條插入語句。那何時寫binlog呢?你們來看這個圖,咱們知道事務提交有兩個階段:prepare與commit,請問是哪一個階段寫binlog呢?binlog實際上是在prepare後commit前寫入的,同時寫事務過程當中,會產生redolog與undolog,那這二者有什麼區別呢?咱們知道MySQL是多引擎的關係型數據庫,binlog是MySQL Server層的日誌,而redolog是MySQL引擎InnoDB層的日誌;另一個不一樣是二者寫入時機不一樣,redolog是prepare階段每執行sql語句就寫redo了,而binlog是在prepare完commit前寫的。那MySQL在主從架構下怎麼保證數據一致性呢?衆所衆知,MySQL爲了保證性能,數據是先寫內存後落盤的。當你數據庫運行的時候,發生了宕機,機器再次恢復的時候多是部分數據落盤了,部分未落盤。這時,mysql是找到binlog最新同步的位點或GTID,來肯定redolog或者undolog中哪些實例須要回滾,哪些事務須要重作。另外,在寫日誌的時候,好比redolog或binlog,MySQL爲保證高性能,也是先寫內存後落盤的,因此日誌的落盤策略也會影響數據的一致性。爲保證數據的一致性,建議你們將涉及日誌的參數配置爲「雙1」,也就是如圖上所示。
下面咱們來看看複製整個流程,其實很簡單,Master經過dump線程將binlog落盤,在Slave上會有兩個線程,分別是IO線程和SQL線程。IO線程接受來自Master的binlog並落地造成Relaylog,SQL線程並行讀取relaylog中的sql信息,執行回放動做。通常來講, 複製分三種:異步複製、半同步、強同步。這三者的區別在於什麼時候將sql執行的結果反饋給客戶端。異步複製,Master無論Slave,Master執行sql完畢後當即返回給客戶端,這種方式性能最好,可是存在數據不一致的可能;強同步呢,Master徹底關心Slave,等待Slave將relaylog回放後才返回給客戶端,這種方式可以保證數據強一致,可是其性能有必定損耗;半同步則是Master部分關心Slave,認爲只要binlog傳輸到Slave側,落爲relaylog後,便可以返回給客戶端了。半同步是一種兼顧的實現,一方面保證數據一致性,另外一方面兼顧了數據庫的性能。
在複製過程當中,咱們常常遇到延遲問題,你們看圖中所示,複製經歷三個階段:Dump線程落盤binlog、IO線程落盤relaylog、以及SQL線程回放,請問三個步驟裏面哪一個步驟是一個瓶頸?是SQL線程,是由於SQL線程在回放日誌過程當中是串行執行sql的,而Master對外是並行提供服務的。因此這裏瓶頸是SQL線程。你們可用經過開啓並行複製來解決延遲問題,MySQL5.6基於庫級別並行複製;MySQL 5.7基於邏輯時鐘並行複製,也就是表級別的並行;而MySQL8.0則是行級別的並行複製,粒度更細,複製效率更高。
剛纔是說在協議級別進行復制,其實還有一種方式是塊級別的數據複製,其不關心上層是什麼,只須要保證在磁盤層面數據複製便可。固然這種方式的話,應用的比較少。說完複製後,我們來講一下切換,其實MySQL官方以前並無提供故障自動發現與轉移的能力,基本上靠第三方工具來實現。
第一種是Keepalived,Master和Slave相互探測對方,時刻詢問對方存活狀態。當出現網絡抖動或者網絡出現問題的時候,可能會出現腦裂問題,變成了兩主,數據就寫錯亂了。第二種就是MMM的方式, M1M2互爲主備,再加上一個Slave節點作冗餘。從圖上看,雖然是雙主,但該模式下同一時間點下只能有一個節點能夠寫,當發現這個主寫節點出現故障,會將vip切換到另外一個主上比。總體看,這種方式比較老,問題比較多。第三種是MHA,其應用普遍,這種方式是由複製組與管理節點組成,每一個複製組裏是由至少三個數據節點組成,數據節點上部署監控agent,定時上報到管理節點,當主節點出現問題時,由管理節點裁決是否切換到從節點。騰訊雲是本身實現了一套故障檢測,結構如右邊的圖,由高可用保證的Monitor節點來進行故障檢測與切換。另外,目前咱們還在作MySQL高可用的重構,屆時可以作到故障檢測恢復30秒鐘之內,大大提升了高可用。
下面咱們來講下集羣的高可用架構,比較有名的就是PXC、MGC、MGR,PXC和MGC是結構比較相似,MGR是官方提供的,具備故障轉移的高可用架構。大致的層級是這樣的,MGR以插件的形式存在的,MGR主要是把複製協議進行改造,由於MGR支持多活,因此這裏另外一個重點是衝突檢測,若多個節點同時寫同一主鍵時,依照哪一個爲準呢?MGR是採用基於Paxos協議實現的衝突檢測。下面,咱們大體看下結構,MGR是支持多個節點寫,即多活,支持某個節點掛了後自動剔除,恢復後自動加入集羣。這張圖是介紹一下MGR數據流邏輯,圖上有三個節點構成最小MGR集羣。假設DB1有一次寫提交,在Prepare階段,MGR插件會生成一個叫WriteSet的集合,並將其廣播給其餘節點。這個WriteSet集合包含這次提交的binlog和更新的惟一鍵,此惟一鍵由db名、表名和主鍵組成。這裏能夠看出MGR有個限制,表中必需要有主鍵,要不沒法進行衝突檢測。咱們再說回來當節點收到這一信息時,會進行比對,每一個節點都有一個緩存,保存當前同步狀況,即惟一鍵對應的GTID SET。經過比對後將結果返回給DB1,只要多於半數的節點返回說OK,能夠提交,那DB1接下來就會執行binlog的落盤操做,而後返回OK到客戶端。其餘節點則執行寫Relaylog的動做,接下來進行回放的動做。若多數節點返回衝突,DB1則執行回滾操做,其餘節點會drop掉複製過來的binlog。
其實PXC和MGC思路是差很少,應該說是MGR借鑑的,由於PXC和MGC是比較早就出來的,這裏大同小異,主節點將WriteSet寫集合廣播出去,廣播完後進行驗證與裁決。
最後咱們說一下NewSQL高可用架構,首先對AWS表示致敬,孵化出很是優秀的NewSQL產品-Aurora。那Aurora是怎麼產生出來的呢?這與AWS數據庫架構有關。咱們來看看這個圖,AWS數據庫是架構在虛擬機與雲盤上的,咱們都知道MySQL的log比較多,因此不少IO是經過耗時較高的網絡來完成的,所以AWS這種架構網絡IO是它的瓶頸,性能也跑不上去。在此基礎上,咱們來認識下Aurora。
Aurora是計算與存儲分離的架構,典型的share disk 的結構。底層存儲採用6副本,部署在三個不一樣的AZ上,能夠保證一個AZ掛了,或者至多兩個AZ的一個副本丟失的狀況下數據不丟失,業務能夠正常對外服務。Aurora的理念是「日誌即數據庫」,其把MySQL存儲層進行了完全的改造,摒棄了不少LOG,只留下了Redolog,具有將redolog轉換到Innodb page的能力。經過這種方式,Aurora宣稱其減小至少85%比例的IO。另外其把備份和回檔下沉到存儲節點,使得備份恢復更快並獲得保障。Aurora總體感受相對比較接地氣,成本相對比較低。
另外一個就是阿里雲的Polar,理念和AWS不一樣,阿里雲以爲將來網絡不是問題,將來網絡能夠接近總線的質量,因此是架構在RDMA網絡的機房裏,日誌方面大動做較少,保證後續MySQL社區新特性可快速迭代近來。Polardb也是share disk的架構,其存儲節點是通ParallelRaft協議保證數據的完備性。可見這也是個偉大的架構,可是相對來講成本比較高一些。
咱們騰訊雲本身的NewSQL在研發中,只是目前尚未正式上線,咱們的名字叫CynosDB,相比來講咱們的理念是兼顧二者,將來在高網絡新硬件的基礎實施下,會發揮更大的性能,更穩健的服務和更高的可用性。請你們拭目以待。
本次個人分享就到此爲止。更多數據庫前沿技術可關注 咱們公衆號:騰訊雲數據庫CDB
Q & A
Q:我想問一下在騰訊遊戲的高併發行業裏面,咱們主要採用哪一種架構?
A:騰訊內部有不少自研項目,但基本上咱們是基於數據複製的方式。內部有phxsql等分佈式集羣架構。
Q:如何在高併發狀況下,保證總庫的定延時呢?
A:能夠開啓並行複製,業務作分庫分表,分散到多個實例上。
Q:好比說像遊戲類的,在遊戲高峯期的話會有不少人同時在線,這種狀況下怎麼在後臺看數據呢?
A:能夠對比較熱的數據進行分層,前一層能夠經過KV方式緩存,好比Redis,來提升熱數據的讀取,後一層使用MySQL,按期將數據同步落盤。
Q:這種狀況下怎麼保證數據庫是一致的呢?
A:寫數據能夠不通過KV緩存,直接寫MySQL數據庫,讀取時,緩存內沒有數據,須要從DB中撈取出來。另外,KV緩存也有落地能力,非關鍵數據也能夠不使用MySQL落地。
此文已由做者受權騰訊雲+社區發佈,更多原文請點擊
搜索關注公衆號「雲加社區」,第一時間獲取技術乾貨,關注後回覆1024 送你一份技術課程大禮包!
海量技術實踐經驗,盡在雲加社區!