摘要: 講師介紹 潘威 網易資深系統運維工程師 現任職于網易,負責網易對象存儲服務nos的運維相關工作; 曾負責過易信、網易視訊雲、網易部落格、lofter等産品資料庫,擁有豐富的大型資料庫架構設計與運維實踐經驗。
講師介紹

潘威
網易資深系統運維工程師
現任職于網易,負責網易對象存儲服務nos的運維相關工作;
曾負責過易信、網易視訊雲、網易部落格、lofter等産品資料庫,擁有豐富的大型資料庫架構設計與運維實踐經驗。
主題簡介:
1、常見的mysql高可用架構
2、分布式資料庫高可用實踐
3、基于keepalive的mysql高可用改造
大家好,我是來自杭州研究院的潘威,今天主要給大家分享下mysql高可用方面的一些具體的經典解決方案,以及我們網易杭州研究院、網易雲 在mysql高可用方面的一些架構和運維上的探索與實踐。希望今天的分享能給大家帶來收獲。
今天分享主要包括三方面内容:一是常見的mysql高可用架構;二是分布式資料庫高可用實踐;三是基于keepalive的mysql高可用改造。第一部分會介紹業界一些經典的mysql高可用解決方案,第二部分和第三部分分别介紹網易在分布式資料庫和單節點mysql上的高可用運維實踐。
一、常見的mysql高可用架構
mysql高可用主要涉及兩個方面,一是用戶端如何切換,如何自動failover,二是多個mysql節點之間如何做資料同步。業界mysql高可用的解決方案有很多,總結起來有幾類:從用戶端自動切換的角度來看主要有兩類:一類是基于ha同步軟體的mysql高可用,使用者通過vip通路資料庫,然後第三方元件監控mysql的狀态,控制vip的漂移。還有一類是基于api調用的mysql高可用,把mysql主從狀态維護在用戶端,應用程式可以通過api調用控制主從切換,進行資料同步。
mysql多節點的資料同步方案也有多種,最常用的是基于binlog的資料同步,其次還有基于共享存儲的資料同步,以及第三方自己實作的資料同步協定(如galera)。
1、基于ha同步軟體實作的高可用方案
如圖所示,基于ha同步軟體的mysql高可用主要是通過vip作為對外的通路入口,正常情況下vip綁定在master上,當master出現故障後,可以将vip切換漂移到slave上。進而實作了一個故障failover的過程。這種基于vip的高可用方案,最常用的資料同步方式是使用mysql原生的binlog複制方式,當然,在成本允許的情況下,也可以選擇利用san之類的共享存儲解決方案。我們這邊重點介紹的還是binlog複制或者其他軟體層次的資料同步方式。
基于ha同步軟體的高可用方式的主要特點包括:
結構簡單、容易管理;
不支援多寫、standby屬于備機;
不保證資料一緻性;
入侵性小,對使用者透明。
2、mha(master high availabitliy)
下面,我們來介紹幾種典型的mysql ha同步軟體。在業界應用最為廣泛,技術最為成熟的ha同步軟體之一是mha。mha全稱是master high availability,是一種一主多從的資料庫高可用解決方案。他的特點是在保障高可用自切換的前提下,最大限度的保障主從資料的一緻性。
我們先來看下mha的架構圖:
一次完整mha故障切換流程如下:
儲存故障的master節點的binlog日志;
manager查找最新更新的slave節點;
應用差異的relay log日志到其他的slave;
在slave節點上應用從master儲存的binlog日志;
提升一個slave為新的master;
使其他的slave連接配接新的master進行複制。
3、mmm(master-master replication manager for mysql)
除了mha以外,還有一個老牌的mysql自動切換套件mmm。
與mha相比,mmm是基于主主複制的故障切換。也就是不支援從多個slave中選擇最新的一個,而是隻能切換到特定的主主複制從節點。
4、基于api調用的mysql高可用
剛才介紹的兩種mysql高可用解決方案,主要都是基于vip切換的,優點是對應用程式沒有入侵,但是缺點是不夠靈活,而且系統的可靠性取決于ha軟體本身的可靠性。如vip通知産生問題,或者keepalive程序自己挂了,都可能導緻切換出現問題。除了這種解決方案,還有一種是在用戶端實作的mysql高可用 - 基于api調用的mysql高可用。也就是jdbc或者其他資料庫驅動可以自主選擇mysql節點。這種實作方案可能使用的不是特别廣泛,但是也有它自身的應用場景,它有如下特點:
架構較重,運維相對複雜
使用靈活,有一定開發成本
支援資料分片、分庫分表、讀寫分離等進階特性
ha-jdbc 就是一種典型的基于api調用的mysql高可用方案,它可以在應用程式中配置多個mysql位址,由ha-jdbc實作選主/屏蔽故障節點以及多個應用程式之間的連接配接狀态通知。ha-jdbc可以實作如下功能:
基本的failover
讀寫分離
節點狀态通知
負載均衡
資料同步(先寫主,然後同時寫多個從節點,如果主寫失敗,則重新選主,如果從寫失敗,屏蔽從) 弱一緻性。
剛才介紹的多是在用戶端角度看到的mysql高可用切換技術,下面再介紹幾種mysql資料同步的高可用解決方案,mysql最經典的資料同步方案就是利用binlog進行資料同步,這種資料同步的優勢是架構簡單、易于管理,對主服務的性能影響相對較小。缺點是不能保障主從完全一緻,而且隻支援單寫。下面介紹幾種能保證主從完全一緻,并且支援多節點寫的方案。
5、galera mysql的高可用及特點
galera架構如圖所示:
用戶端通過galera load balancer通路資料庫,送出的每個事務都會通過wsrep api 在所有伺服器中執行,要不所有伺服器都執行成功,要不就所有都復原,保證所有服務的資料一緻性,而且所有伺服器同步實時更新。
wsrep api是一系列應用回調和複制調用庫,來實作事務資料庫同步寫集(writeset)複制以及應用。其主要思想是在不出現沖突的背景下事務正常執行并持續到commit為止;當用戶端發起commit指令時(此時仍然沒有發生真正的commit),所有本事務内對資料庫的改動與改動資料行的主鍵都會被放入一個寫入集(writeset)中,該寫入集随後會被複制到其他節點執行,在每個節點上使用主鍵進行沖突檢測判斷該寫入集是否可以被應用,如果出現主鍵沖突,則其中一個事務會被復原。
缺點及限制:由于同一個事務需要在叢集的多台機器上執行,是以網絡傳輸及并發執行會導緻性能上有一定的消耗。所有機器上都存儲着相同的資料,全備援。若一台機器既作為主伺服器,又作為備份伺服器,出現樂觀鎖導緻rollback的機率會增大,編寫程式時要小心。不支援的sql:lock / unlock tables / get_lock(), release_lock()…不支援xa transaction。目前基于galera cluster的實作方案有三種:galera cluster for mysql、percona xtradb cluster、mariadb galera cluster。
6、mysql group replication
mysql group replication是16年 mysql 5.7官方推出的多節點資料同步解決方案,它也支援多節點寫和強一緻性。在架構上它與galera相似,但是多節點事務一緻性送出是基于paxos來實作的,性能更高。可以預見mysql group replication,這類基于強一緻性協定的mysql資料同步方案,是mysql高可用的下一個研究熱點,目前騰訊、阿裡均有類似的方案推出。
mysql group replication中的replication-group就是一組節點,每個節點都可以獨立執行事務,讀寫事務會在group内的其它節點進行協調之後再commit。是以,當一個事務準備送出時,會自動在group内進行原子性的廣播,告知其他節點變更了什麼内容/執行了什麼事務。基于paxos協定使得事務在每一個節點上都保持着同樣順序執行,這意味着每一個節點都以同樣的順序,接收到了同樣的事務日志,是以每一個節點以同樣的順序重演了這些事務日志,最終整個group保持了完全一緻的狀态。
mysql group replication僅支援innodb表,并且每張表一定要有一個主鍵,用于做沖突檢測;必須打開gtid特性,二進制日志格式必須設定為row。這是使用mgr的一些限制。
二、mysql高可用在網易的實踐
1、分布式資料庫高可用實踐
首先是分布式資料庫方面的。由于oltp的業務特性和業務量大的特點,分布式資料庫在網易有廣泛的應用,下面我們簡單介紹下網易的分布式資料庫架構以及重點介紹下其高可用解決方案。
ddb的組織架構如上圖所示,dbn(mysql)負責實際的資料存儲與讀寫提供。管理伺服器負責資料庫表、使用者權限、資料分布路由的維護以及dbn狀态的監控與管理。除此之外ddb最核心的子產品是被稱之為dbi的資料庫驅動,它是一個類jdbc驅動,一方面可以與管理伺服器互動,擷取分布式資料庫的表結構與分布路由;另一方面可以解析使用者發過來的sql語句,轉換成适用于分布式場景的sql直接發送給dbn節點,并且将dbn傳回的結果進行聚合或者排序并最終傳回給應用程式。正是由于dbn這一系列的改寫與聚合動作,才能使得應用程式可以像通路一個簡單的關系型資料庫那樣去通路ddb這樣一個分布式資料庫。
管理伺服器的高可用主要是基于分離持久化資訊到sysdb中實作的,也就是管理伺服器本身是一個無狀态的服務,可以部署多個,短暫的故障也不會影響dbi到dbn節點的正常資料讀取。而sysdb本身是個mysql節點,它的高可用可以用經典的mysql高可用方案解決。
dbn的高可用也可以使用mysql原生的高可用方式,比如基于vip的高可用。但是使用分布式資料庫做高可用的優勢就是有一個管理伺服器的角色維護資料路由,是以隻要可以根據目前的節點的狀态更新資料路由就可以做到一個自動的failover的過程。具體到ddb這個場景,我們引入了一個ddbswitch高可用切換工具,這個工具可以監控dbn狀态,維護dbn主從關系。當主dbn存在異常時,ddbswitch工具會檢測到節點異常,并且觸發管理伺服器更新dbn清單,管理伺服器會通知所有用戶端的dbi更新本地的dbn清單,切換緩存中的路由,進而完成了一次完整的切換。除了最基本的故障切換,ddbswitch還可以通過逐漸放開dbn連接配接池的方式控制新切入節點的流量,防止新上線的節點由于之前堆積的請求而瞬間被壓垮。
目前網易杭州這邊的項目,絕大多數的分布式資料庫都是使用的ddb,是以有比較多的線上實踐,事實也證明ddb這套高可用架構是穩定可靠的。目前像網易雲的項目,比如視訊雲、雲信後端依賴的資料庫都是ddb,可以做到資料庫相關子產品故障異常在30s内自動恢複。在減少人工運維成本的前提下,提高系統整體可靠性。
除了分布式資料庫,網易也有少量的單節點mysql。出于成本和易用性的考慮,我們沒有選擇mha方案,而是配合keepalive使用自定義的腳步進行故障自切換與盡可能的保障可靠性。首先keepalive本身是一個多程序的程式,可靠性和成熟度很高,不止可以做無狀态的nginx的高可用代理,還能通過配合第三方的腳本來做類似mysql這種有狀态服務的高可用。
2、基于keepalive的mysql高可用改造
網易的這套keepalive的mysql高可用方案采用的也是經典的mysql主主複制的架構,然後配合自研的切換腳本進行自定義故障判定以及升主的一緻性檢查功能。一次完整的故障切換包含如下幾個步驟:首先利用master上的keepalive定時調用故障檢查check腳本,發現異常後進行3次重試,重試後mysql依然無法正常服務則觸發切換。切換不是采用keepalive傳統的降低權值的方式進行的,而是直接stop keepalive來觸發slave搶占vip,更新為主。更新為主後slave keepalive會調用升主檢查腳本,判定relay log應用完成後才放開寫,關閉read only正式提供服務。
這套keepalive高可用解決方案有如下幾個特點:
具備一緻性檢驗功能(檢查relay log是否應用完),配合杭研改進的semisync 功能,可以保障資料的強一緻;
具備防網絡抖動功能,不會再網絡不穩定的情況下頻繁切換;
原主恢複後不自動更新為master功能(mysql複制延遲);
自定義故障判定規則,貼近業務的高可用;
簡單易用,友善管理,可以人工介入。
keepalived 使用注意事項
現象:
keepalived主從切換後,網關/交換機上的arp表沒有立刻更新vip對應備用 lvs 的mac,或者arp包被交換機drop掉,導緻備機無法被通路。
解決:
arping -i eth1 -c 5 -s vip gateway
garp_master_refresh 選項 (release 1.2.10)
keepalived 不搶占的實作
keepalived自帶nopreempt參數實作不搶占功能,但當新主服務再挂掉後由于原主帶nopreempt參數,即使原主優先級高仍無法完成切換。故現在通過自定義腳本實作類似功能(sudo /etc/init.d/keepalived stop),備機節點腳本隻有當自身 mysql可用且主機mysql不可用時才觸發切換。
keepalive這套方案在網易内部主要用在一些負載比較小,但是對穩定性和可靠性要求比較高的資料庫,比如openresty等雲計算服務的中繼資料庫,易信朋友圈資料庫,也已經線上上穩定運作了3,4年的時間,可以做到秒級别的切換。
今天我們主要介紹了mysql高可用幾種常見的解決方案,以及網易在這方面的一些應用實踐,由于時間關系,可能有些技術細節隻是粗略的帶過,感興趣的同學歡迎留言交流。
原文釋出時間為:2017-05-08
本文來自雲栖社群合作夥伴dbaplus