資料庫容器化|未來已來

沃趣科技發表於2017-11-06
沃趣科技聯合創始人·熊中哲


導語:“你不是不夠好,你只是過時了”這句話用到 IT 行業特別合適,每隔一段時間都會有新的技術出現, 讓碼農們應接不暇。藉著回顧DBA工作中的幾個時期,跟大家分享我們對下一代資料庫運維架構的理解和目前正在做的工作。

明星 DBA 層出不窮的時期

剛進入阿里時聽過一句話一直記到現在, ”要像瞭解自己的老婆一樣瞭解自己管理的資料庫”, 當年我還沒有結婚, 對這句話的理解並不深刻.

 

這應該是 @馮春培 說的, 當年進阿里的面試考官之一, 大家都服氣的稱他為大師

 

它後面其實隱含了1個背景. 相比現在, 當時的應用迭代較慢, 架構集中, 尤其是資料庫層面.用比較流行的叫法是巨石型”monolithic”應用.

 

在資料庫數量,容量和業務需求都沒有爆發的情況下, 更需要 DBA 做出極致的優化, 更強調對資料庫核心的掌握, 10年前混過 ITPUB 的都知道, 當時的 DBA 都是以寫出極其複雜的 SQL 和掌握 Lock,Pin,Latch 執行機制為榮的.

 

還記得,當年每條 SQL 上線都需要 DBA 審閱, 這也是 DBA show  muscle 的最好機會

 

巨石型應用突出了 DBA 的重要性, 那是一個明星 DBA 層出不窮的時期.

DBA 的轉型期

 

後來有機會去了百度, 作為一名 DBA, 給我的衝擊很大, 總結下來有幾個不同:

● 資料庫以 MySQL 為絕對多數, 並且大多數都是由開發自己運維.

● DBA 團隊剛剛組建, 目標是集中管理集團的所有資料庫.當時整個團隊不到15人, 線上執行的 MySQL 例項1000+.

● 沒有 SQL Review 

 

1000+例項和15個 DBA這時我剛結婚, 雖然時間不長但我馬上意識到 ”要像瞭解自己的老婆一樣瞭解自己管理的資料庫” 恐怕是做不到了.

 

工作的重點不再是學習資料庫核心和SQL Review, 而是轉而將大量的日常運維工作指令碼化,自動化(其實是人肉+半自動). 當時沒有 Puppet / Ansible , 一刀一斧都得自己來. 不得已, 又撿回程式設計的手藝. 這個時候, 我從關注少量庫的效能 (Load, TPS, QPS), 到關注大量庫的可用性, 主要包括 :

● 監控的配置和有效性

● 空間是否足夠

● 備庫恢復是否正常

● 是否有備份, 備份是否有效

● 硬體是否有故障

 

沒有SQL Review 這樣奶媽式的貼身服務, 如何解決效能問題呢? 總結下來就是:

● 將複雜的SQL拆分成多個簡單的 SQL, 將複雜性留給應用

● 提前做好Scale Out架構, 效能不夠就擴節點

 

多說幾句:

● Scale Out : 要支援 Scale Out 架構, 應用需要做些改造.說一個常見問題, MySQL叢集的各個分片如何高效的,不重複的獲取自增序列作為表的 PK 或者 UK 呢? 在 Oracle Rac 裡面, sequence 讓一切變得簡單, DBA 關注的只是如何優化獲取 sequence 的效率. 但是在百度, 我第一次知道原來可以通過zookeeper 來解決這個問題.

● 監控 : 當時 Noah (百度內部的告警平臺) 有個功能, 一旦發現線上執行的伺服器負載低於指定閾值時, 將會給相關人傳送報警, 提示有資源浪費. 這個報警追蹤了資源的使用情況, 有效的防止了資源浪費的問題.

● SQL Review : 從阿里巴巴集團研究員 @張瑞 (兩個面試官中的另外一個)發表的題為《面向未來的資料庫體系架構的思考》可以看到類似的描述

 

我也逐漸意識到對 DBA 的要求發生了變化. 從精細化運維到叢集化運維, 從關注個別庫的效能到關注叢集的可用性, 從依靠個人的能力到藉助監控平臺和大量的運維指令碼.

 

這是一個轉型期, 對 DBA 的要求更綜合, 更全面. 不會當廚子的裁縫做不了好司機.

擁抱虛擬化

2017年, WoquTech 已經成立6年, 巨石型 ”monolithic” 應用依然廣泛存在. 同時, 使用者對於資料庫運維自動化的要求越來越高, 資料庫即服務(DBaaS or RDS)的需求越來越強烈, AWS RDS 有個很精煉的總結:

  

總結一下 :

● 所有的日常運維工作自動化

● 高效能,資料零丟失,安全的需求依然是剛需

● 通過彈性擴充套件追求更高的資源利用率(用我們熟悉的語言就是向運維要效益)

● 不再追求極致的效能

 

如何能滿足這些企業級的功能要求? 這並不容易,要對資料庫,硬體,虛擬化,分散式儲存等技術都要熟悉甚至精通。

 

以此為目標,WoquTech 首先基於虛擬化技術實現了一套私有資料庫服務平臺, 這款產品叫做 QFusion,目前迭代到2.0版本. 同時, 我們也面臨一些棘手的問題 :

● 計算密度難以提高 :

虛擬化自身開銷較大, 導致計算資源的有效利用率不高, 這導致客戶需要更多的硬體

● 儲存開銷較大 :

儲存在硬體(SSD,Optane),網路(25Gb,Infiniband),協議層面(NVMEoF)的發生著翻天覆地的變化, 但是虛擬化技術一直支援的不好, 開銷很大, 雖然可以通過穿透技術(passthrough) 降低開銷, 但是又給平臺管理帶來極大成本.

● 迭代成本 :

還是以 OS 的視角建構系統, 導致業務開發的成本較高.

奔向容器, 未來已來 

面對虛擬化技術在實現 RDS 上的短板, 我們一直在探索,資源利用率更高, 整合效率更高的RDS實現方式.

 

所以我們很早就開始確定了容器化的技術方向. 容器技術和 MySQL 本來就不陌生的, 阿里很早就將 cgroup 應用到 MySQL 生產環境(Google 跟阿里的用法非常類似). Oracle 作為商用資料庫的霸主, 也在 github.com 上推出12C 企業版 Docker image.

  

當然, 在生產環境使用容器並不容易, 我們需要解決兩個問題 :

● 關係型資料庫(Oracle, MySQL)如何高效的執行在容器裡

● 如何管理容器叢集

 

Docker + Oracle 為例.

 

針對第一個問題, 我們進行了很長一段時間的探索和測試. 期望在使用相同 Oracle 版本, 硬體配置, 負載模型的情況下, 以業務的TPS  QPS 為指標,對 Oracle in KVM  Oracle in Docker 進行對比.

 

除錯了很長時間以確保 KVM  Docker 都能發揮了自身的優勢. IBM在2014年發表的文章《An Updated Performance Comparison of Virtual Machines and Linux Containers》給了我們很多啟發

 

資料如下:

 

通過 Oracle  AWR 報告,可以很清晰的看到. 相比KVM, Oracle in Docker 的執行次數提高2.47倍, 同時執行時間減少55.25%. 也就是說基於Docker, 不但可以提升一倍的業務服務質量, 還能夠提高2.47倍的業務吞吐量, 優勢非常明顯.

 

針對問題二, 如何管理大規模的 Docker呢就像虛擬化和 OpenStack 的關係. 我們需要容器化時代的 “OpenStack”, 甚至更多, 以排程策略為例 :

● 更細粒度的資源排程單位, 更彈性的資源申請方式, 以實現更高的部署密度

● 識別不同級別的儲存服務(QoS). 比如, 主庫排程到 PCIe Flash節點, 備庫排程到SATA SSD節點, 備份排程到Hard Disk節點

● 識別業務需要的非親緣性. 比如, 在資源都滿足的前提下, 主庫和備庫不能排程到同一物理節點

 

站在巨人(Google)的肩膀上, 我們找到了答案 : Kubernetes

 

簡單說,Kubernetes是自動化容器編排平臺(https://kubernetes.io/). 其隸屬於 CNCF基金會 (Cloud Native Computing Foundation https://www.cncf.io/), CNCF 背後有強大的 Google 站臺.Kubernetes 一經推出, 被大家接受的速度遠超想象.

Oracle 雲服務整合了基於 Kubenretes 的編排架構

微軟雲服務 Azure 把自己容器編排引擎從 ACS 改成 AKS 

通過整合 Docker  Kubernetes 研發 WoquTech 下一代的 RDS 架構即 QFusion 3.0, 成為我們新的目標.

 

目前 Kubernetes 對持久化應用的支援還剛剛起步, 下圖是基於 Kubernetes 構建的持久化服務 :

  

可以看到, 暫時還沒有 Oracle 和 MySQL 的身影, 基於 Kubernetes 構建關係型資料庫業務的難度也可想而知.

 

 

下面將會展示QFusion 3.0 (全部以 MySQL 為例 ) 幾個功能。

例項高可用

例項高可用必不可少, 需要說明的是這個功能必須包含資料零丟失.下面將演示這個過程.

 

我們模擬了四次故障,例如 kill, 重啟節點之類, 平均下來都可以在35秒內恢復訪問

(消耗時間與 AWS Aurora 和阿里雲 PolarDB 持平)

 

同時模擬應用進行持續的資料更新操作,可以看到資料庫服務在幾次故障切換後始終可以保證更新有序, 做到零資料丟失.

 

讀寫分離叢集 : 讀庫水平擴充套件

大多數應用都是讀多寫少, 讀寫分離叢集的很好的支援了這類業務場景. 當讀能力不足時, 彈性擴充套件是 DBA 經常遇到的問題, 下面將演示讀庫水平擴充套件的過程.

 

通過 YAML 檔案, 以申明的方式一鍵建立讀寫分離叢集

 

無關內容已省略

kind: MysqlCluster

  masterdbspec:

    replicas: "1" -- 主庫數量, 讀寫分離叢集中, 該值只能為1

    role: Master -- 主庫角色

  proxyspec:

    role: RW -- 資料庫中介軟體型別

  slavedbspec:

    replicas: "2"  -- 讀庫數量

    role: Slave -- 讀庫角色

  strategy: MySQLRWCluster  -- 叢集型別

 

通過 sysbench + Proxy 模擬對3個備庫的壓力

 

通過我們的平臺一鍵式新增1個備庫, 可以看到讀壓力較平均的分散到4個備庫中

 

 

分庫分表叢集 : 叢集高可用

這類叢集提供了Scale Out 的能力, 相比讀寫分離叢集功能更加強大, 同時也帶來了運維的複雜性. 下面將演示叢集的一鍵式建立和叢集分片的高可用.

 

通過 YAML 檔案, 以申明的方式一鍵建立分庫分表叢集

 

無關內容已省略

kind: MysqlCluster

  masterdbspec:

    replicas: "8" -- 主庫數量, 指定該叢集的分片數量

    role: Master -- 主庫角色

  proxyspec:

    role: Sharding -- 資料庫中介軟體型別

  strategy: MySQLShardCluster  -- 叢集型別

 

一鍵式建立8分片叢集. 

 

模擬分片0故障, 30秒內該分片恢復完畢, 提供服務.

 

分庫分表叢集 : 滾動升級功能

叢集帶來了強大功能的同時提升了運維工作的複雜度. 比如, 修改資料庫配置, 替換新的資料庫版本, 常見的做法就是DBA 人肉的一個節點一個節點的完成變更工作. 下面將演示全自動滾動升級功能

 

修改叢集所有例項的引數 “innodb_buffer_pool_size”, 滾動升級會 :

● 降序從 c7 到 c0

● 依次進行 : 選定節點, 修改引數檔案, 重啟節點, 待節點恢復服務

● 滾動升級流程會保證即使出現異常, 依然可以”斷點續傳”, 已升級節點不會重複操作

 

5.7.5開始,innodb_buffer_pool_size可以通過 set 命令動態調整,不用重啟資料庫例項


下圖可以看到滾動升級的過程.

通過版本管理的方式實現叢集的滾動升級, 通過叢集資訊,可以看到

status:

  currentReplicas: 8 -- 當前版本分片數量

  currentVersion: clustershard-c-559586746c -- 叢集當前版本

  updateVersion: clustershard-c-559586746c -- 叢集待升級版本


currentVersion等於updateVersion , 滾動升級結束

Docker, Kubernetes, RDS, 未來已來

Every once in a while, a revolutionary product comes along that changes everything. 這是喬幫主在第一代 Iphone 釋出會上說的第二句話.

確實, 未來已經到來.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2146884/,如需轉載,請註明出處,否則將追究法律責任。

相關文章