著名的開源分佈式緩存服務 Codis 的做者,PingCAP 聯合創始人& CTO ,資深 infrastructure 工程師的黃東旭,擅長分佈式存儲系統的設計與實現,開源狂熱分子的技術大神級別人物。即便在互聯網如此繁榮的今天,在數據庫這片邊界模糊且不肯定地帶,他還在努力尋找肯定性的實踐方向。git
在數據庫的平行世界裏,黃東旭以不一樣的方式在追隨着本身的心裏。他認爲,一般傳統的關係型數據庫沒法知足海量數據處理和分析時,新一輪的窗口期也隨之需求開啓,可是各種劣勢架構、內存架構、 NoSQL 等方案都不能知足本身理想的解決方案,這些都不夠美,不多可以把分佈式事務與彈性擴展作到完美。github
絕對的理性與感性,在黃東旭的身上看似矛盾,直到 2012 年末,他看到 Google 發佈的兩篇論文,如同棱鏡般,折射出他本身心裏微爍的光彩。這兩篇論文描述了 Google 內部使用的一個海量關係型數據庫 F1/Spanner ,解決了關係型數據庫、彈性擴展以及全球分佈的問題,並在生產中大規模使用。「若是這個能實現,對數據存儲領域來講將是顛覆性的」,黃東旭爲完美方案的出現而興奮, PingCAP 的 TiDB 在此基礎上誕生了。算法
固然,每向前進一步,都須要付出巨大的努力。在啓動 TiDB 項目以前,黃東旭先完成了一個開源分佈式的 Redis 集羣方案 Codis ,這個項目完成之後讓他們以爲雖然緩存的水平擴展問題有了解決方案,可是底層的關係型數據庫(主要是 MySQL 爲主)並無一個優雅的擴展方案。業界除了在業務層分庫分表,或者使用中間件等折衷方案外,並無其餘太多的辦法,有些業務可能能遷移到 NoSQL 之上,例如 HBase 、 C* 等,跟不少的業務無法平滑遷移,幾乎須要重寫所有邏輯。若是採用分庫分表和中間件的方案,擴展以及高可用的方案會帶來大量額外的運維成本,好比沒法使用跨 shard 的 join、子查詢、跨行事務等。數據庫
可是做爲一個基礎軟件工程師的黃東旭他們不但願將這些複雜度轉嫁給業務層,因此就開始從新審視整個數據庫,但願從根本上解決 MySQL 的擴展問題,而不是再造一箇中間件。編程
「若是創造一個全新的東西,使它有一天可以成爲生產力,那種感受真好!」緩存
在 2012 、 2013 年期間,黃東旭他們就開始研究了Google 發表的一系列關於新一代分佈式數據庫 Spanner 和 F1 的論文以及相關的學術界的進展,直到 2015 年,他們以爲基本全部的技術問題和架構都已經思考得差很少了,因而決定出來全職去從新開始完整的實現一個新的數據庫,也就是今天的主角——下一代開源 NewSQL 數據庫 TiDB 。安全
固然了,創造並不意味着開始,它須要面臨的是無限的投入和無限的博弈來適應互聯網的競爭和審視,真正作到讓開發者和企業受益,纔是真正的開始。性能優化
TiDB在總體架構基本是參考 Google Spanner 和 F1 的設計,上分兩層爲 TiDB 和 TiKV 。 TiDB 對應的是 Google F1, 是一層無狀態的 SQL Layer ,兼容絕大多數 MySQL 語法,對外暴露 MySQL 網絡協議,負責解析用戶的 SQL 語句,生成分佈式的 Query Plan,翻譯成底層 Key Value 操做發送給 TiKV , TiKV 是真正的存儲數據的地方,對應的是 Google Spanner ,是一個分佈式 Key Value 數據庫,支持彈性水平擴展,自動的災難恢復和故障轉移(高可用),以及 ACID 跨行事務。值得一提的是 TiKV 並不像 HBase 或者 BigTable 那樣依賴底層的分佈式文件系統,在性能和靈活性上能更好,這個對於在線業務來講是很是重要。網絡
▲ TiDB 總體架構架構
這羣理想很豐沛,這不被骨感現實所惑的人。在 TiDB 研發語言的選擇過程當中,放棄了 Java 而採用 Go 。
TiDB整個項目分爲兩層,TiDB 做爲 SQL 層,採用 Go 語言開發, TiKV 做爲下邊的分佈式存儲引擎,採用 Rust 語言開發。在架構上確實相似 FoundationDB,也是基於兩層的結構。 FoundationDB 的 SQL Layer 採用 Java ,底層是 C++ ,不過在去年,被 Apple 收購了。
在選擇編程語言並無融入太多的我的喜愛偏向, SQL 層選擇 Go 相對 Java 來講:
第一是 他們團隊的背景使用 Go 的開發效率更高,並且性能尚可,尤爲對於高併發程序而言,可使用 goroutine / channel 等工具用更少的代碼寫出正確的程序;
第二是 在標準庫中不少包對網絡程序開發很是友好,這個對於一個分佈式系統來講很是重要;
第三是 在存儲引擎底層對於性能要求很高,Go 畢竟是一個帶有 GC 和 Runtime 的語言,在 TiKV 層能夠選擇的方案並很少,過去基本只有 C 或 C++,不過近兩年隨着 Rust 語言的成熟,又在通過長時間的思考和大量實驗,最終他們團隊選擇了 Rust。
Rust 這門靜態語言的定位是取代 C++,最大的特色是經過不少語法的限制來避免開發者寫出內存泄露和 data race 的程序,將不少問題解決在編譯期,使得運行時不須要花費額外的代價進行 GC 之類的事情,保證高性能。因此,寫出安全的程序,這正是 C++ 程序的很大的一個痛點。
雖然在 C++ 11 中有了不少的改進,可是因爲歷史包袱過重或者第三方包庫開發者的水平良莠不齊。可是重要的緣由不由於別的,正是他們的背後並非一個 C++ 背景很深的團隊,因此最後放棄了 C++ 11 而選擇了 Rust 。
Rust 不只有安全和高性能的特色,同時語法更加現代,開發效率更高,另外擁有很是完善的包管理機制(Cargo),使得在能寫出很是高性能且安全的程序同時,開發效率比起 Go並無降低太多,對於目前來講是一個很是正確的選擇。做爲 Rust 社區內全球最大的開源項目之一,也獲得了 Rust 語言官方團隊的很大支持,黃東旭表示,包括一些他們須要的第三方庫,Rust team 都會放在很高優先級上去開發或者在社區裏推動。另外 Rust 早已發佈 1.0,語法也早已穩定,是一個很是有前途的系統編程語言。
輪番在Google中刷出了存在感後,還一直在沒有盡頭的草原上奔跑,黃東旭認爲只有聚焦,專一,才能擺脫掉使人迷惑的干擾。在不斷的探索後,終於尋找到了實現事務模型的方式。
TiDB 的事務模型經過參考了 Google 的 Percolator。該論文發表於 2010 年,是描述 Google 在 BigTable 上的構建 ACID 跨行事務框架用於保證索引更新的一致性。算法的核心思想是兩階段提交,可是傳統的分佈式兩階段提交的問題是單點的事務管理器無法擴展,會成爲整個系統的瓶頸,Percolator 使用了一個兩級鎖的機制實現了去中心化的事務管理器,使得整個系統的可擴展性大大提高。
▲ Goolge Percolator內部實現
TiDB 將這個模型應用在底層的存儲引擎中,並作了不少工程上的優化,黃東旭舉例說,經過 batch 和 pipeline 等手段大大提高了授時服務的吞吐,使用 Raft + RockDB 來替代原文的 BigTable 性能更好,另外採用樂觀事務機制追求更高的吞吐,不過是從算法層面,是 Percolator 實現。
TiDB 對比 NOSQL
TiDB 對於這些 NoSQL 來講,最大的特色是編程接口是 SQL,SQL對於開發者而言是更加靈活的操做數據庫的方式,且對 MySQL 有着極高的兼容性—原業務的 MySQL切換到 TiDB 幾乎一行代碼都不用修改就能夠完成。TiDB 在支持 SQL 的同時有沒有喪失 HBase 這樣的系統的彈性擴展能力,業務層不須要再去關心數據庫的容量,不用去考慮分庫分表,也不用像過去那樣投入很大的運維力量,擴容只需簡單加機器就好,存儲節點故障對業務透明,並且數據庫自己具備自我修復的能力,保證數據不會丟失。
對於 MongoDB 也是同樣,更重要的是不須要改變用戶已有的習慣和程序,並且爲了定義將來的雲上的數據庫形態,TiDB 設計的目標是單集羣須要能夠 Scale 到 1000 以上物理節點的規模,支持 P 級別容量,萬億以上的行的結構化數據存儲,在這個前提約束下的設計和技術選型和 MongoDB 很不同,在大數據量的狀況下 TiDB 的表現更穩定,擴展更加平滑。
TiDB 的 SQL 優化器是黃東旭他們從頭開始實現的一個面向分佈式存儲設計的查詢優化器,使用了不少學術界很新的查詢優化技術和分佈式計算框架的思想,保證 MySQL 兼容性的前提下比 MySQL 在複雜查詢下表現要好得多。
傳統數據庫的痛點解決
任何企業,若是使用傳統的單機關係型數據庫,在數據量持續增加下,或者對業務的可用性有嚴格要求的狀況下,可能都會面臨單點故障和單點容量限制的問題,這個問題最近幾年在互聯網行業尤爲突出,目前來講除了上面提到的分庫分表和中間件也並無其餘的方案解決,幾乎苦不堪言。
TiDB 基於更先進的 Raft 算法來實現了存儲層的水平擴展基礎上加上了分佈式事務,構建了完整的 SQL 查詢層,在保證不喪失 ACID 事務的前提下,支持 JOIN ,子查詢等複雜查詢,另外對外暴露 MySQL 接口,讓用戶幾乎在無侵入性的前提下,解決大量結構化數據的存儲問題。考慮到傳統行業和互聯網行業的代差大概在 3 年左右,另外這個時間在不斷的縮短,最近隨着 TiDB 趨於穩定,愈來愈多的互聯網在使用 TiDB ,相信將來會成爲擴展數據庫的一個新的主流選擇。
TiDB 的應用場景
應用場景是典型的 OLTP 場景,範圍很大,覆蓋到任何企業。在關係型數據庫上遇到擴展性問題、同時須要強一致事務、須要實現多數據中心強一致和高可用,都是 TiDB 的典型用戶。TiDB 對 MySQL 的支持很完善,基於目前使用着 MySQL 的用戶或企業,但願尋求更優雅的水平擴展方案,都是很是不錯的選擇。
其實目前在統計大多數線上生產環境中使用的用戶基本都是互聯網場景,從 MySQL 過來。TiDB 目前暫時不支持存儲過程和視圖,因此前提條件是已有業務中沒有這類操做。
在項目開始第一天就肯定了 TiDB 最大兼容 MySQL ,黃東旭坦言, MySQL 是一個單機的數據庫,並且查詢優化器是針對單機場景設計,基於這架構上去作一個分佈式數據庫的難度很大。
而此時,他們決定選擇一條更完全的道路,就是重寫整個 SQL Parser 和查詢優化引擎。雖然看上去幾乎是不可能完成的事情,可是實際作下來他們以爲在一個更良好設計和複雜度控制下,反而是一條更輕鬆的路。而選擇徹底的 MySQL 兼容這個事情帶來的好處不只限於對用戶的友好度,更重要的是能從 MySQL 社區吸收大量的測試。這對於一個數據庫產品來講,作出來並不難,如何證實你是對的,這纔是更重要的!黃東旭他們不斷的從 MySQL 社區收集了千萬級的測試用例來保證每一個模塊的正確性,和對 MySQL 行爲的一致性。
TiDB 項目開源的程度
TiDB 項目是100% 開源,致力於作一個具備國際水準的頂級開源項目,從 Github repo 自己其實很難看出來這是一個背後是國人主導的開源項目,全部的提交記錄,全部的協做,Roadmap ,Issue tracking ,中英文文檔,以及代碼審覈都是開源的。
而項目已經迭代到 Beta 4 版本,從線上用戶的反饋,主要的功能已經基本完善穩定。黃東旭表示,接下來重要的工做會是持續的性能優化和繼續提高穩定性,還有在更大容量,更惡劣嚴苛的集羣環境下持續測試。固然周邊工具,部署教程,更多的設計文檔也是在持續的豐富中。
TiDB 的將來
從更長遠的角度,一切東西都會運行在雲端,數據庫也不例外。在海量數據,大規模集羣的前提下,關係型數據庫的設計和理論還有不少東西須要探索,這種集羣規模之下,一切依賴人工的運維都將會失效,由於人是無法 scale ,數據庫須要具備自我修復和自我擴展的能力,也只有這樣,才能更好的利用集羣的計算資源,這也爲何 TiDB 團隊對本身的定位是要作 Cloud-Native 的數據庫,他們在爲將來作不少基礎性的研究和準備,包含對 Kubernetes 和分佈式數據庫的結合上也作了不少探索性的工做。
黃東旭但願 TiDB 定義下一代關係型數據庫,將來開發者可以真正專一本身的業務,不用在關心數據庫有多大,併發可能會有多高,何時須要擴容一下,選哪一個 sharding key 好等這些問題都應該被隱藏在一個很簡單的 SQL interface 之下。
TiDB 有了很是不錯的開頭,他們作到了,在下一代關係型數據庫裏面,每一個人都能感覺到這種技術所帶來生產力的美好!
開源項目地址:https://github.com/pingcap/tidb
PS:黃東旭將在11月26號出席WOT2016大數據技術峯會,屆時在NoSQL實踐技術專場分享《NewSQL in action: Patterns and Tools》內容,敬請關注。
WOT2016大數據技術峯會官網:http://wot.51cto.com/