標籤:

黃東旭:Cloud-Native 的分散式資料庫架構與實踐

19 日,我司 CTO 黃東旭同學在全球雲計算開源大會上,發表了《Cloud-Native 的分散式資料庫架構與實踐》主題演講,以下為演講實錄~~

大家好,今天我的題目是n Cloud-Native 與分散式資料庫的實踐。先簡單的介紹一下自己,我是 PingCAP 的聯合創始人和 nCTO,過去一直在做基礎軟體領域的工程師,基本上做的所有的東西都是開源。在分享之前我想說一下為什麼現在各行各業或者整個技術軟體社區一直在重複的再造資料庫,現在資料庫到底怎麼了,為什麼這麼百花齊放?

首先隨著業務的多種多樣,還有不管是傳統行業還是互聯網行業,業務的迭代速度越來越互聯網化,使得整個數據量其實是一直在往上走的;

第二就是隨著 IOT 的設備還有包括像手機、移動互聯網蓬勃的發展,終端其實也不再僅僅是傳統的 PC 客戶端的數據的接入;

第三方面隨著現在 AI 或者大數據分析一些模型或者理論上的突破,使得在大數據上進行計算的手段越來越多樣,還有在物理上一些硬體的新的帶有保護的內存,各種各樣新的物理的設備,越來越多的硬體或者物理上的存儲成本持續的降低,使得我們的資料庫需要要面對更多的挑戰。

關聯資料庫理論是上世紀七十年代做出來的東西,現在四十年過去不管是物理的環境還是計算模型都是完全不一樣的階段,還抱著過去這種觀念可能並不是一個面向未來的設計。而且今天我的題目是n Cloud-Native,有一個比較大膽的假設,大家在過去三十年的計算平台基本都是在一台 PC n或者一個伺服器或者一個手機這樣的獨立的計算平台,但是未來我覺得一切的服務都應該是分散式的。因為我覺得摩爾定律已經失效了,所以未來的操作系統會是一個大規模分散式的操作系統,在上面跑的任何的進程,任何的服務都應該是分散式的,在這個假設下怎麼去做設計,雲其實是這個假設最好的載體。怎麼在這個假設上去設計面向雲的技術軟體,其實是最近我一直在思考的一個問題。其實在這個時代包括面向雲的軟體,對業務開發來說盡量還是不要太多的改變過去的開發習慣。你看最近大數據的發展趨勢,從最傳統的關係資料庫到過去十年相比,整個改變了用戶的編程模型,但是改變到底是好的還是不好的,我個人覺得其實並不是太好。最近這兩年大家會看到整個學術圈各種各樣的論文都在回歸,包括n DB 新時代的軟體都會把擴展性和分散式放在第一個要素。

  大家可能聽到主題會有點蒙,叫n Cloud-Native,Cloud-Native 是什麼?其實很早的過去也不是沒有人做過這種分散式系統的嘗試,最早是 IBM n提出面向服務的軟體架構設計,最近熱門的 SOA、Micro Service 把自己的服務拆分成小的服務,到現在谷歌一直對外輸出一個觀點就是 nCloud-Native,就是未來大家的業務看上去的分散式會變成一個更加透明的概念,就是你怎麼讓分散式的複雜性消失在雲的基礎設施後,這是 nCloud-Native 更加關心的事情。

這個圖是n CNCF 的一個基金會,也是谷歌支持的基金會上扒過來的圖。這裡面有一個簡單的定義,就是 SCALE 作為一等公民,面向 nCloud-Native 的業務必須是彈性伸縮的,不僅能伸也得能縮;第二就是在對於這種 Cloud-Native 業務來說是面向 Micro nservice 友好;第三就是部署更加的去人工化。

最近大家可能也看到很多各種各樣容器化的方案,背後代表的意義是什麼?就是整個運維和部署脫離人工,大家可以想像過去十幾二十年來,一直以來運維的手段是什麼樣的。我找了一個運維,去買伺服器,買伺服器裝系統,在上面部署業務。但是現在n Cloud-Native n出現變得非常的自動化,就相當於把人的功能變得更低,這是很有意義的,因為理想中的世界或者未來的世界應該怎麼樣,一個業務可能會有成百上千的物理節點,如果是人工的去做運維和部署是根本不可能做得到的,所以其實構建整個n Cloud-Native 的基礎設施的兩個條件:第一個就是存儲本身的雲化;第二就是運維要和部署的方式必須是雲化的。

我就從這兩個點說一下我們 TiDB 在上面的一些工作和一些我的思考。

存儲本身的雲化有幾個基本條件,大家過去認為是高可用,主要停留在雙活。其實仔細去思考的話,主備的方案是很難保證數據在完全不需要人工的介入情況下數據的一致性可用性的,所以大家會發現最近這幾年出來的分散式存儲系統的可用性的協議跟複製協議基本都會用類似n Raft/Paxos 基於選取的一致性演算法,不會像過去做這種老的複製的方案。

第二就是整個分片的策略,作為分散式系統數據一定是會分片的,數據分片是來做分散式存儲唯一的思路,自動分片一定會取代傳統的人工分片來去支撐業務。比如傳統分片,當你的數據量越來越大,你只能做分庫分表或者用中間件,不管你分庫分表還是中間件都必須制訂自己人工的分辨規則,但是其實在一個真正面向n Cloud 的資料庫設計里,任何一種人的介入的東西都是不對的。

第三,接入層的去狀態化,因為你需要面對n Cloud-Native n做設計,你的接入層就不能帶有狀態,你可以相當於是前端的接入層是一層無狀態的或者連接到任何一個服務的接入的入口,對你來說應該都是一樣的,就是說你不能整個系統因為一個關鍵組件的損壞或者說磁碟壞掉或者機器的宕機,整個系統就不能服務了,整個測試系統應該具有自我癒合和自我維護的能力。

其實我本身是架構師,所以整個我們資料庫的設計都是圍繞這些點來做思考的,就是一個資料庫怎麼能讓他自我的生長,自我的維護,哪怕出現任何的災難性的物理故障(有物理故障是非常正常的,每天在一個比較大的集群的規模下,網路中斷、磁碟損壞甚至是很多很詭異的問題都是很正常的),所以怎麼設計這種資料庫。

我們的項目是n nTiDB,我不知道在座的有沒有聽說過這個項目,它其實是一個開源實現。當你的業務已經用了資料庫,數據量一大就有可能遇到一些問題,一個是單點的可靠性的問題,還有一個數據容量怎麼去彈性伸縮的問題。TiDBn n就能解決這個問題,它本身對外暴露了一個介面,你可以用客戶端去連接,你可以認為你下面面對的是一個彈性動態伸縮完全沒有容量限制,同時還可以在上面支持複雜的子查詢的東西。底層存儲的話,相當於這一層無狀態的會把這個請求發到底層的節點上,這個存儲裡面的數據都是通過協議做高可用和複製的,這個數據在底層會不停的分裂和移動,你可以認為這個資料庫是一個活的資料庫,你任何一個節點的宕機都不會影響整個資料庫對業務層的使用,包括你可以跨數據中心部署,甚至你在跨數據中心的時候,整個數據中心網路被切斷,機房著火,業務層都幾乎完全是透明的,而且這個數據比如副本丟失會自己去修復,自己去管理或者移動數據。

上圖右邊是一個集群的調度模塊,你可以認為它是整個集群的大腦,是一個n 7×24 小時不眠的 DBA,你任何的業務可以接上來。NewSQL n這個詞大家聽的都爛了,但是我還是想提,首先它是一個面向擴展的資料庫,同時它還結合的傳統管理資料庫的強一致事務,必須得是 SSI n隔離級別的,並不是非常弱根本沒法用的隔離級別,而是需要提供最強一致性的隔離級別的資料庫。擴展性其實是通過在 TiKV n層面做完全自動分片,可用性是通過 Raft 為保證,我們整個資料庫沒有主從的概念,每一個節點既可以是主又可以是從,然後整個數據複製通過 Raftn n為保證,對外的是一個強一致性的事務層,其實背後的演算法是用兩階段提交的演算法,比如一個最簡單的例子,我一百個並發過來很快,每個平均十毫秒訪問數據,一百個並發,一百萬個並發,你還能保證每一個請求都是十毫秒返回數據嗎?那我可以簡單的通過添加機器把系統的吞吐加上去,每一個吞吐的響應延遲會更大一些,在論文里提到過,谷歌資料庫寫的每一個平均延遲是n 150 到 100 毫秒,可以做到線性擴展。所以終於有一個資料庫可以 scable。剛才說的是存儲層面的雲化,剛才提到了 nCloud-Native 還有一個重要的點就是部署和運維方式的雲化,我們其實選的這個 Kubernetes n就是用來承載背後資料庫大規模集群上的部署,其實大家都知道這個是什麼東西,這是最出名的開源項目之一,谷歌開源的,大家也知道 nborg,就是他們用了這麼多年的集群調度服務,主要做的事情就是服務的編排、部署、自動化的運維,一台物理機掛掉了,他會很好的讓這個業務不中斷,像集群調度器,它就是整個數據中心的操作系統,但是面臨最大的問題就是所有的業務一旦是有狀態的,那你這個就非常噁心。舉個案例,比如我在跑一個資料庫,如果你這台物理機宕機,按照n Kubernetes n會開一個伺服器在那邊展開,但是這一台老的宕機伺服器數據是存在上面的,你不能只是把進程在新的伺服器那啟起來而數據不帶過去,相當於這種業務是帶狀態的,這在n Kubernetes n過去是一個老大難的問題,其實整個應用層,因為它的特性被分成了四個大的陣營,如果想上可以看一下自己的業務到底屬於哪一個陣營。

第一個就是完全無狀態的業務,比如這是一個簡單的n CRUD 業務層的邏輯,其實是無狀態的應用層。第二種就是單點的帶狀態的 applications,還有任何單機的資料庫其實都有屬於 napplications。第三個就是 Static ndistributed,比如高可用的分散式服務,大家也不會做擴容什麼的,這種是靜態的分散式應用。還有最難的一個問題,就是這種集群型的 napplications,clustered 是沒有辦法很好的調度服務的。這是剛才說的,其實對於 Single npoint,其實是很好解決的,對於靜態的其實也是用 Static distributed 來解決帶狀態的持續化的方案。

剛才我說最難的那個問題,我們整個架構中引入了n Operational,調度一套有狀態服務的方案,其實它思路也很簡單,就是把運維分布人員系統的領域知識給嵌入到了系統中,Knowledge n發布調度任務之前都會相當於被 CoreOS 提供的介面以後再調度業務,這套方案依賴了 HtirdPartyResources n調度,因為這個裡面我的狀態我自己才知道,這個時候你需要通過把你的系統領域知識放到 operator 里。很簡單,就是 Create 用 TiDBn Operator 來實現,還有 Rollingupdate 和 Scale Out 還有 Failover 等。使用 Kubemetes n很重要的原因就是它只用到了很毛的一層 API,內部大量的邏輯是在 Operator 內部,而且像 PV/Statefulset n中並不是一個很好的方案,比如 PV 實現你可以用分散式文件系統或者快存儲作為你持久化的這一層,但是資料庫的業務,我對我底層的 IO n或者硬體有很強的掌控力的,我在我的業務層自己做了三副本和高可用,我其實就不需要在存儲層面上比如我在一個裸盤上跑的性能能比其他上快十倍,這個時候你告訴我不好意思下面只支持n statefulset 那這是不適合跑資料庫的,也就是資料庫集群是跟它的普通的雲盤或者雲存儲的業務是分開的。

  分散式資料庫也不是百分之百所有的業務場景都適合,特別是大規模的分散式資料庫來說,比如自增n ID,雖然我們支持,但是自增 IT n高壓力寫入的時候它的壓力會集中在表的末尾,其實是我不管怎麼調度總會有一塊熱點,當然你可以先分表,最後我們聚合分析也沒有問題,像秒殺或者特別小的表,其實是完全不適合在這種分散式資料庫上做的,比較好的一些實踐業務的讀寫比較平均,數據量比較大,同時還有並發的事務的支持,需要有事務的支持,但並不是衝突特別大的場景,並不是秒殺的場景,同時你又可以需要在上面做比較複雜的分析,比如現在我們的一些線上的用戶特別好玩,過去它的業務全都是跑在n MySQL 上,一主多從,他發現我一個個 MySQL 成為了信息的孤島,他並沒有辦法做聚合地分析,過去傳統的方案就是我把 MySQL n或者數據通過一個 ETL 流程導到數據倉庫里,但是開發者不會用各種琳琅滿目大數據的東西,他只會用 MySQL,一般他做的數據分析都會把 nMySQL 倒騰到一個庫上再做分析,數據量一大堆分析不出來,這個時候他把所有他自己的 MySQL 總庫連到了一個 nTiDB上,過去是一主多從,先多主多從,把所有的從都打通,做 MySQL 的分析,所以我覺得 TiDB n打造了新的模型,可以讀寫高並發的事務,所以未來的資料庫會是一個什麼樣子的,我覺得可能是至少我們覺得沿著這條路走下去應該會有一條新的路,謝謝大家。


推薦閱讀:

怎麼看待upyun這次的「UPYUN 雲存儲免費了!」,實際上必須購買流量才能使用存儲的宣傳?
HTTP 2 的新特性你 get 了嗎?
如何運用雲模型改進模糊控制?以及雲模型在國內的發展現狀?
一切計算都是調度問題
群雄逐鹿 誰會成為雲計算行業第一股?

TAG:云计算 |