1. 程式人生 > >網易資深運維工程師潘威:MySQL高可用在網易的最佳應用與實踐

網易資深運維工程師潘威:MySQL高可用在網易的最佳應用與實踐

講師介紹:潘威

網易資深系統運維工程師

  • 現任職於網易,負責網易物件儲存服務NOS的運維相關工作;
  • 曾負責過易信、網易視訊雲、網易部落格、LOFTER等產品資料庫,擁有豐富的大型資料庫架構設計與運維實踐經驗。

主題簡介:

1、常見的MySQL高可用架構

2、分散式資料庫高可用實踐

3、基於keepalive的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

一次完整MHA故障切換流程如下:

  1. 儲存故障的master節點的binlog日誌;
  2. Manager查詢最新更新的slave節點;
  3. 應用差異的relay log日誌到其他的slave;
  4. 在slave節點上應用從master儲存的binlog日誌;
  5. 提升一個slave為新的master;
  6. 使其他的slave連線新的master進行復制。

3、MMM(Master-Master Replication Manager for MySQL)

除了MHA以外,還有一個老牌的MySQL自動切換套件MMM。

MySQL

與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可以實現如下功能:

  1. 基本的failover
  2. 讀寫分離
  3. 節點狀態通知
  4. 負載均衡

資料同步(先寫主,然後同時寫多個從節點,如果主寫失敗,則重新選主,如果從寫失敗,遮蔽從) 弱一致性。

剛才介紹的多是在客戶端角度看到的MySQL高可用切換技術,下面再介紹幾種MySQL資料同步的高可用解決方案,MySQL最經典的資料同步方案就是利用binlog進行資料同步,這種資料同步的優勢是架構簡單、易於管理,對主服務的效能影響相對較小。缺點是不能保障主從完全一致,而且只支援單寫。下面介紹幾種能保證主從完全一致,並且支援多節點寫的方案。

5、Galera MySQL的高可用及特點

Galera架構如圖所示:

Galera MySQL

客戶端通過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

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

網易的這套keepalive的MySQL高可用方案採用的也是經典的MySQL主主複製的架構,然後配合自研的切換指令碼進行自定義故障判定以及升主的一致性檢查功能。一次完整的故障切換包含如下幾個步驟:首先利用Master上的keepalive定時呼叫故障檢查check指令碼,發現異常後進行3次重試,重試後MySQL依然無法正常服務則觸發切換。切換不是採用keepalive傳統的降低權值的方式進行的,而是直接stop keepalive來觸發slave搶佔VIP,升級為主。升級為主後slave keepalive會呼叫升主檢查指令碼,判定relay log應用完成後才放開寫,關閉read only正式提供服務。

這套keepalive高可用解決方案有如下幾個特點:

  1. 具備一致性檢驗功能(檢查relay log是否應用完),配合杭研改進的semisync 功能,可以保障資料的強一致;
  2. 具備防網路抖動功能,不會再網路不穩定的情況下頻繁切換;
  3. 原主恢復後不自動升級為master功能(MySQL複製延遲);
  4. 自定義故障判定規則,貼近業務的高可用;
  5. 簡單易用,方便管理,可以人工介入。
  • 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年的時間,可以做到秒級別的切換。