天天看點

容器化MYSQL叢集在Uber系統中的應用

本文講的是<b>容器化MYSQL叢集在Uber系統中的應用</b>【編者的話】Uber使用的Schemaless存儲系統支撐了Uber最重要的服務,如,Mezzanine等。Schemaless 是一個建構在MySQL叢集上,可擴充高可用的資料存儲。但管理Uber資料量龐大的資料庫叢集服務需要應用Docker技術。

當叢集節點數為16個時,叢集管理非常容易,但若叢集規模超過1000,并運作了4000多個資料庫服務,就需要另一種工具了。之前所有的叢集都由 Puppet來管理。大量的臨時腳本,以及人工操作已無法滿足Uber業務擴充的要求。我們開始尋找一個管理規模遞增的MySQL叢集工具,工具必須具備以下基本需求:

在每個節點上運作多個資料庫程序

自動化

整個資料中心通過單一的入口管理和監控所有叢集

解決方案被命名為Schemadock,采用Docker容器運作MySQL,目标是将管理叢集拓撲定義在配置檔案中。叢集拓撲定義了MySQL叢集,例如,一個叢集内應用3個資料庫,其中一個是主,代理應用這些拓撲定義在每個資料庫上,一個集中服務用來維護和監控各執行個體的目标狀态,并及時糾正偏差。

Schemadock 由幾個部件組成,Docker是其中一小部分但卻是最重要的部分。轉型到這種可擴充的方案需要付出相當大的努力,本文将介紹Docker如何幫助系統達成目标:

容器化程序可實作不同版本及配置的MySQL程序運作在同一台主機上,也可以在同一個主機上配置不同小叢集用來實作在更少的主機上運作同樣規模叢集的目的。最終,可實作不依賴Puppet,并且所有主機都可配置成一樣的角色。

對于Docker自身,工程師可在docker上建構微服務。關于Docker已經有大量的工具及知識累積,雖然Docker肯定不是最好的,但目前來講是最佳選擇。

選擇Docker包括全虛拟化、LXC容器、或通過類似Puppet工具來管理運作在主機上的MySQL程序。對我們而言,選擇Docker是因為簡單,因為它很适合現有的架構。但如果沒準備好使用Docker,而隻想使用MySQL,這便是一個巨大的工程:包括完成鏡像建立、釋出、監控、更新Docker、日志收集、網絡設定、等等工作。

這意味着,若要使用大量資源,就隻能選擇Docker。此外,Docker隻是一種技術,而不是一個解決方案。在Uber的方案中詳細規劃了一個以Docker為核心部件的大型系統,用于管理 MySQL資料庫。但并不是所有公司都像Uber一樣廣泛使用Docker,因為一些更簡單的方案例如Puppet 或Ansible可能更适合。

在這些基礎上,Docker鏡像隻用下載下傳、安裝 Percona Server、啟動mysqld,仿佛Docker鏡像已經在那一般。然而,在下載下傳和啟動之間,會出現很多問題:

若mounted卷中沒有資料,則使用引導模式。對于主節點,運作mysql_install_db。并建立預設的使用者和表。對于從節點,從叢集的備份或其他節點初始化資料同步。

一旦容器有了資料,mysqld 就完成啟動了。

若任何資料拷貝失敗,容器都會再次當機。

容器的角色通過環境變量來定義。而這個角色僅負責接收初始化資料,Docker鏡像本身不包含任何建立複制拓撲、狀态檢查等邏輯。由于這些邏輯比MySQL 本身變動更為頻繁。是以需要花大力氣實作分離。

MySQL 資料目錄通過主機的檔案系統實作挂載,意味着Docker沒有任何寫開銷,實際部署時将MySQL 的配置考入了鏡像來固化配置。也就是說,當修改配置時無法生效。若容器因為某種原因當機,不是重新開機容器,而是删除容器,再使用同樣的參數,從最新版本鏡像(若目标變更,則從新鏡像)重新建立一個新容器,并啟動它。

這種做法的好處是:

配置的核心容易被管理。配置融入了Docker鏡像,可實作實時監控;

更新MySQL 是一件簡單的事情,建立一個新的鏡像,按計劃停止老的容器;

若出現任何異常僅需重新開機,而省去了打更新檔的過程,隻需使用新的容器接管便可。

Uber 通過建立鏡像支援微服務架構,此架構從資料中心複制鏡像到本地激活注冊使用。

但在一個節點上運作多個容器也有缺點,因為在每個容器之間沒有合适的隔離I/O的功能,一個容器可能占滿所有I/O帶寬,導緻其他容器故障。Docker 1.10 新增了I/O限額功能,但是目前還沒有應用過。不過我們通過降低主機負載和持續監控資料庫性能來預防此問題。

現在我們有一個可以啟動的Docker主或從節點鏡像,為了啟動這些容器并将它們配置到正确的複制拓撲,每台資料庫節點上需要運作一個代理,用來接收不同節點上的所有資料庫的目标資訊。典型的目标狀态資訊執行個體如下:

這段資訊表明:在節點schemadock01 上需在7335端口上運作一個 Mezzanine 資料庫從節點,并啟動schemadock30:7335的資料庫主節點。這裡的‘all’參數是說該節點上隻運作資料庫,是以需要配置設定所有的記憶體給資料庫使用。

建立目标狀态對另一個請求來說就是一個會話,下一步:主機上運作的代理接收到這個資訊後存儲在本地,并開始處理。

處理方式是一個周期為30秒的無線循環,類似每30秒運作Puppet 一樣。通過以下步驟每隔30秒循環檢查系統實際狀态同目标狀态記錄的資訊是否一緻:

檢查容器是否已經運作。若沒有,則根據配置建立一個并啟動;

檢查容器是否有複制拓撲。若無,則修複:

若從節點轉變為主節點,則檢查轉變角色是否安全,通過檢查老的主節點是否為隻讀狀态,同時所有的GTIDs已都被接收應用。一旦确認,就可以斷開到老主節點的連接配接,并啟動可寫功能;

若要失效主節點,打開節點的隻讀模式;

若未啟動從節點的複制,則啟動複制鍊路。

基于角色檢查MySQL各種 參數(例如:read_only 、 super_read_only、 sync_binlog等),如:主節點可寫,從節點為隻讀模式等等。此外,為了降低從節點的運作負載可關閉日志同步等相關參數。

啟停任何支援的容器功能,例如關閉 pt-heartbeat 心跳檢測和pt-deadlock-logger死鎖檢測。

注意:Uber特别認同這種單程序隻做單用途的容器設計理念,因為不用對已運作的容器進行重新配置,更容易控制或更新。

何時何地隻要發生錯誤,程序隻用報錯或者退出。然後嘗試重新啟動。但架構會確定在各個代理之間盡量減少互動,也就是說叢集不關心執行順序。例如,在建立一個新的叢集時,手工建立需以下步驟:

建立MySQL 主節點并等待生效;

建立第一個從節點并連接配接到主節點;

剩餘的從節點重複以上步驟。

必然會發生一些意外,但我們并不關心嚴格的執行順序,隻要最終狀态達到我們設定的目标就行:

這個資訊将被随機推送到相關代理,并啟動運作。為達到最終目标狀态,會有一些重試操作。通常經過幾次重試後都會最終達到目标狀态,但有一些操作可能需要100多次的重試。例如,從節點最先被啟動,無法連接配接到主節點,然後不得不重新開機。因為主節點啟動并運作需要一段時間,是以從節點需要重新開機很多次。

容器化MYSQL叢集在Uber系統中的應用

大部分主機運作的是帶裝置映射的Docker 1.9.1版本使用LVM實作存儲管理。應用LVM進行裝置映射比使用loopback的運作性能優異得多。裝置映射本身存在很多性能和可靠方面的問題,但是若是選擇使用 AuFS 或OverlayFS 也存在大量問題。目前在社群中關于存儲的選型存在很大的争議。目前為止,OverlayFS 獲得了一定的認可,運作比較穩定,是以我們确定了選擇它,并将Docker的版本更新到1.12.1。

Docker更新的痛點之一是需要重新開機所有的容器。這意味着更新時沒有主節點,更新程序必須可控。希望Docker1.12.1是最後一個要擔心這個問題的版本,1.12 已經有一個選項可以控制重新開機和更新Docker 守護程序時無需重新開機容器。

Docker的每個版本都有一些進步和新特性,同時也會有一些漏洞。1.12.1比以往的版本都要有優勢,但也有以下限制:

docker inspect 在Docker運作幾天後偶爾會hang住;

TCP連接配接終端使用 userland proxy 協定的橋接網絡模式可能會有一些奇怪的現象,用戶端經常會收不到RST 信号,無論如何設定逾時,用戶端均保持opend 狀态;

容器程序偶爾會恢複到初始狀态,Docker便會對程序失去控制;

最常見的案例是:Docker守護程序需要很長時間才能建立一個新的容器。

我們在Uber的叢集存儲上提了大量需求:

一台主機運作多個容器

自動

單點登入

現在,我們已經可以通過簡單的工具和統一的UI界面進行日常維護,而無需登入主機。

容器化MYSQL叢集在Uber系統中的應用

在一台主機上運作多個容器提升主機使用率。在可控模式下進行整體更新。Docker已經為我們的技術架構提升了很多,也支援測試環境下整體叢集的本地化更新,及試運作所有作業系統程序。

從2016年開始Uber實施系統Docker化的遷移,目前已運作了1500多個生産伺服器(僅MySQL ),并運作了2300多個MySQL 資料庫。

雖然應用Docker是技術上的重大成功,也使得Uber架構進步更快。但比Schemadock項目本身意義更大的是,整個出行資料倉庫,幾乎每天百萬次出行記錄已經運作在了Docker上的MySQL 中。另一個角度想,Docker成為使用Uber出行打車的關鍵。

<b>原文釋出時間為:</b>2017-01-26

<b>本文作者:</b>Chilly

<b>本文來自雲栖社群合作夥伴Dockerone.io,了解相關資訊可以關注Dockerone.io。</b>

<b></b>

<b>原文标題:</b><b>容器化MYSQL叢集在Uber系統中的應用</b>