雲計算架構下 Cloud TiDB的技術奧秘「上」

近日,國內領先的中立雲計算服務商UCloud與國內開源分散式NewSQL資料庫TiDB團隊PingCAP正式達成合作,雙方聯手在UCloud全球數據中心推出了新一代TiDB的雲端版本——Cloud TiDB。

作為一款定位於Cloud-native的資料庫,截至目前TiDB在雲整合上已取得了階段性進展。Cloud TiDB產品在UCloud平台正式開啟公測,TiDB彈性伸縮特性在Cloud 提供的基礎設施支持下得到了淋漓盡致的展現。

在感受雲資料庫魅力的同時,讓我們來探索一下TiDB與Cloud背後的技術秘密。

TiDB與傳統單機關係型資料庫的區別

首先,從TiDB的架構說起。TiDB作為一款開源的分散式資料庫產品,具有多副本強一致性,能夠根據業務需求非常方便的進行彈性伸縮,並且擴縮容期間對上層業務無感知。

TiDB的主體架構包含三個模塊,對應Github上PingCAP組織下的三個開源項目(TiDB / TiKV / PD):

● TiDB主要是負責SQL的解析器和優化器,它相當於計算執行層,同時也負責客戶端接入和交互;

● TiKV是一套分散式的Key-Value存儲引擎,它承擔整個資料庫的存儲層,數據水平擴展和多副本高可用特性都在這一層實現;

● PD相當於分散式資料庫的大腦,一方面負責收集和維護數據在各個TiKV節點的分布情況,另一方面PD承擔調度器的角色,根據數據分布狀況以及各個存儲節點的負載來採取合適的調度策略,維持整個系統的平衡與穩定。

上述三個模塊中的每個角色都是一個多節點組成的集群,所以最終TiDB的架構如下圖所示:

由此可見,分散式系統本身的複雜性不僅導致手工部署和運維成本較高,而且容易出錯。傳統的自動化部署運維工具(如:Puppet/Chef/SaltStack/Ansible等),由於缺乏狀態管理,在節點出現問題時不能及時自動完成故障轉移,需要運維人員人工干預,有些則需要寫大量DSL甚至與Shell腳本一起混合使用,可移植性較差,維護成本比較高。

在雲時代,容器成為應用分發部署的基本單位,谷歌基於內部使用數十年的容器編排系統Borg經驗,推出的開源容器編排系統Kubernetes就成為當前容器編排技術的主流。

TiDB 與Kubernetes的深度整合

作為Cloud Native Database,TiDB選擇擁抱容器技術,並與Kubernetes進行深度整合,使其可以非常方便地基於Kubernetes完成資料庫自動化管理。甚至可以說Kubernetes項目是為Cloud而生,利用雲平台IaaS層提供的API可以很方便地與雲進行整合。這樣只要讓TiDB與Kubernetes結合得更好,進而就能實現其與各個雲平台的整合,使TiDB在雲上的快速部署和高效運維成為現實。

1.Kubernetes簡介

Kubernetes最早是作為一個純粹的容器編排系統而誕生,用戶部署好Kubernetes集群之後,直接使用其內置的各種功能部署應用服務。由於這個PaaS平台使用起來非常便利,吸引了很多用戶,不同用戶也提出了各種不同需求,有些特性需求Kubernetes可直接在其核心代碼里實現,但有些特性並不適合合併到主幹分支。

為了滿足這類需求,Kubernetes開放出一些API供用戶自己擴展,實現自身需求。當前Kubernetes已經升級到v1.8版本,內部API變得越來越開放,使其更像是一個跑在雲上的操作系統。用戶可以把它當作一套雲的SDK或Framework來使用,而且可以很方便地開發組件來擴展滿足自身業務需求,對有狀態服務的支持就是一個代表性實例。

在最早期,Kubernetes項目只支持無狀態服務(Stateless Service) 來管理,無狀態服務通過ReplicationController定義多個副本,由Kubernetes調度器來決定在不同節點上啟動多個Pod,實現負載均衡和故障轉移。對於無狀態服務,多個副本對應的Pod是等價的,所以當節點出現故障時,在新節點上啟動一個Pod與失效的Pod是等價的,不會涉及狀態遷移問題,因而管理非常簡單。

2.有狀態服務Stateful Service

不過,對於有狀態服務(Stateful Service),由於需要將數據持久化到磁碟,使得不同Pod之間不能再認為成等價,也就不能再像無狀態服務那樣隨意地進行調度遷移。Kubernetes v1.3版本提出PetSet的概念,用來管理有狀態服務並在v1.5版本中將其更名為StatefulSet。

StatefulSet明確定義了一組Pod中的每個身份,啟動和升級都按特定順序來操作。另外,使用持久化卷存儲(PersistentVolume)來作為存儲數據的載體,當節點失效Pod需要遷移時,對應的PV通過umount/mount方式跟著一起遷移到新節點,或者直接使用分散式文件系統作PV底層存儲,使Pod在遷移後仍然能訪問到之前的數據。

同時,Pod在發生遷移時,其網路身份(例如IP地址)是會發生變化的,很多分散式系統不能接受這種情況,所以StatefulSet在遷移Pod時可以通過綁定域名的方式來保證Pod在集群中網路身份不發生變化。

然而,現實中一些分散式系統更為複雜,StatefulSet也顯得捉襟見肘。舉例來說,某些分散式系統的節點在加入集群或下線時,還需要做些額外的註冊和清理操作,或者在滾動升級時,要考量版本兼容性等問題。

基於上述原因,CoreOS公司提出了Operator概念,並實現了etcd-operator和prometheus-operator來管理Etcd和Prometheus這樣複雜的分散式系統。用戶可以開發自己的Operator,在Kubernetes之上實現自定義的Controller,將有狀態服務領域中特定的運維知識編碼進去,從而實現對特定分散式系統的管理。同時,Operator本身也是跑在Kubernetes中的一個Pod(deployment),對Kubernetes系統並無侵入性。

3.TiDB多組件支持

針對TiDB這種複雜的分散式服務,我們開發了tidb-operator等一系列組件,來管理TiDB集群實例在Kubernetes平台上的創建、銷毀、擴縮容、滾動升級和故障轉移等運維操作。同時,在上層封裝了一個tidb-cloud-manager組件,提供RESTful介面,實現了與雲平台的控制台打通功能。這就完成了一個DBaaS(資料庫即服務)架構的基本形態。

由於TiDB對磁碟I/O有比較高的要求,通過PV掛載網路盤,會有明顯的性能損耗。另外,TiKV本身維護了數據多副本,這點和分散式文件系統的多副本是有重複的,所以要給Pod上掛載本地磁碟,並且在Kubernetes上把Local PV管理起來,作為一種特定資源來維護。

Kubernetes官方長期以來一直沒有提供Local PV支持,本地存儲只支持hostPath和 emptyDir兩種方式。其中,hostPath的生命周期是脫離Kubernetes管理的,使用 hostPath的Pod銷毀後,裡面的數據是不會被自動清理,下次再掛載Pod就會造成臟數據。而emptyDir更像是一個臨時磁碟,在Pod重建時會被清理重置,不能成為持久化PV來使用。

為此,我們開發了一個tidb-volume-manager組件,用於管理Kubernetes集群中每台物理主機上的本地磁碟,並且將其暴露成一種特殊的PV資源。結合Operator在部署TiDB節點時會參考Local PV資源的情況,來選擇特定節點進行部署,分配一個空的Local PV和Pod綁定。而當Pod銷毀時,會根據具體情況決定是否結束Local PV的生命周期,釋放掉的Local PV在經歷一個GC周期後,被tidb-volume-manager回收,清理其盤上數據等待再次被分配使用。

Cloud TiDB 總體架構圖

將這些組件整合起來,就形成了上圖描述的Cloud TiDB總體架構。在Kubenetes管理的集群上,通過tidb-operator等組件針對性的調配和使用集群資源,從而實現TiDB集群實例的生命周期管理。通過這種方式實現TiDB分散式資料庫和雲平台的整合。

我們將在下一篇中詳細介紹針對Cloud TiDB的關鍵特性和實現細節。


推薦閱讀:

文件系統和資料庫是由於什麼原因才選擇 B 樹或 B+ 樹建立索引的?
Android 開發中為什麼很少使用 JSON 存儲數據?
適合初學者學習資料庫的書有哪些較好的?
PostgreSQL 與 MySQL 相比,優勢何在?
TiDB Best Practice

TAG:云计算 | TiDB | 数据库 |