TiDB 2016 回顧與 2017 的一些想法
新年伊始,突然發現 TiDB 又一次被國際友人頂上了 HackerNews 首頁前十,借著這個由頭有友人約稿說想讓我寫一下對於這個資料庫的過去和未來的一些想法和規劃,正好這個周末偷得半日閑,於是趕緊動筆,不過我本人一向懶得總結,同時不太希望做太遠的計劃,所以就想到哪寫到哪了 ?? 。
TiDB 是一個大概開始了兩年的項目,從最早的 3 個人到現在背後目前大約 30 多個活躍開發者,包括周邊的工具和 CI ,可以說是一個凝結了我們大量心血的一個項目。這個項目的開始的起點是很高的,當時的想法是要麼別做,要麼就做到最好,當時(即使到了現在)全球社區內都沒有一個令人滿意的面向 OLTP 的分散式資料庫,所以為什麼不做?首先盡量能徹底的解決 MySQL 的擴展性問題,並發展出一個面向雲時代的分散式關係型資料庫的標準。整個 TiDB 項目群從分散式存儲到 SQL 優化器,除了底層的 RocksDB 外,其他都是以大規模的 Scale-out 為前提重新設計和實現,由於歷史包袱比較小加上早期設計上的一些比較正確的決定,當然最主要也得力於非常強悍的各位 Committers,整個項目以非常驚人的迭代速度演進,2016 年 12 月底,正式發布了 RC1,此時已經達到了相當高的成熟度,也有不少用戶已經將 TiDB 使用在了生產環境,也算是完成了對社區的承諾。回顧過去,最重要的設計決定我之前在我的朋友圈裡也提到過,這裡還是在贅述一下:
* MySQL 文法和網路協議的兼容,這讓我們得以吸收 MySQL 社區大量的測試用例,以保證高速迭代過程中的軟體質量不至於失控,當然這個決定對於用戶的推廣也是很重要的。
* 高度模塊化,這點可能就是和友商 CockroachDB 非常不一樣的,我其實比較反感各種 P2P 模型,從 Codis 的設計與 Redis Cluster 差異就能看出來,去中心化也不一定就只有 P2P,從更宏觀的抽象上來看,總是可以分層的,而且 P2P 模型帶來的複雜度其實非常難以控制,雖然好處也是比較明顯,就是部署的組件少了點,但是呢,比起後續的升級維護成本,犧牲掉的開發迭代速度來說,這個好處基本不值一提,更何況部署的問題有無數種方法可以解決,比如 TiDB 就有一鍵部署的方案。TiDB 的存儲層每層介面抽象非常薄且清晰,不允許出現跨越層次的調用的情況,主要是為了控制複雜度和提高開發者的並發度。
* 編程語言的選擇,Go 和 Rust,事後看來是對於我們這個團隊來說最好的選擇,雖然當時做這個決定也很艱難,回頭看看確實也很大膽,但是我覺得我們還是基本做到了不帶有任何個人感情色彩,一切通過數據和試驗做出的判斷。
* 極端嚴格的 Code Review、自動化測試、CI 流程,這個就不提了,在很多會議上提到過,之前劉奇也發了 3 篇文章說這個事情,翻翻 PingCAP 過去的文章列表就行。
過去就不廢話太多了,今天主要想聊的是未來,前段時間和褚霸聊天提到做資料庫不易,特別對於公有雲來說只要開了口子,無數用戶就能玩出花來,大量的精力需要花在周邊的各種旁路系統。對於創業的團隊來說,做的又是一個關係型資料庫這樣的東西,能做的或者需要做的東西實在太多,如何控制住自己的慾望,專註在最重要的事情上面我認為是最重要的,這個看起來容易,但是做起來難,比如:
* 你的團隊都是一些非常聰明的小朋友(老朋友),對於一個技術問題,總能發散出很多想法和特別聰明的解決辦法,有的確實很驚艷,但是大多數時候,這樣的方案並非最簡潔同時最容易正確實現的,這時候就需要站出來狠狠拍掉,記住 make it right before making it faster,複雜性才是你最大的敵人。
* 你的一個客戶說,實現 xx 功能或者接入 xx 系統,可能這個幾百萬的單就拿下了,你做還是不做?
我自認為,過去的一年多,在禁慾方面 TiDB 做得還是蠻不錯的,相比友商 CockroachDB 好不少,目前 TiDB 已經在 460 個實例規模的集群上高壓力穩定的運行,我們能承諾用戶可以在生產環境安心使用,至少這個是領先友商的,2017 年也要會保持,RC1 的發布標誌著介面和功能的穩定,至少今年技術上的主要目標是進一步的性能優化,更高的兼容性以及更好的用戶部署和使用體驗,新功能開發和大規模的重構應該是不會發生的。
在性能優化上的一些想法,其實分兩個比較大的方面,一個是 SQL 優化器方面,另一個是 KV 層的吞吐。
先說 SQL 優化器方面,其實在分散式 SQL 優化器方面,現在 TiDB 的優化器框架已經完成了幾次大的重構,基於代價的優化器(CBO)框架已經有了,而且因為沒什麼歷史包袱,所以 SMP 方面採用了很多比較新的優化技巧(可以參考 TiDB 的子查詢優化,聚合下推等技巧),就目前線上用戶的 case 來看,已經能解決我們目前見到的大部分問題,而且簡單評估了一下現有的分散式資料庫,優化器這邊 TiDB 在 SQL 上的表現應該是屬於最優秀的集團中。2017 年的目標仍然是提高在 SMP 方面的能力,一方面嘗試下推更多的運算元,一方面嘗試分散式的 CBO,可能更好的解決索引選擇和 join reordering 的問題;另一方面在執行器方面,其實 TiDB 的潛力很大,目前在 OLAP 裡面常用的 vectorized 和 codegen 等技巧,其實在 TiDB 裡面還沒有,這部分如果完成,對於大部分掃描,聚合的性能應該還能有若干倍的提升空間。另一方面,TiDB 在 MPP 方面還比較謹慎,雖然這個是必經之路,但是我覺得第一,目前還沒有見到非 MPP 不可的場景,另外純粹的 OLAP 場景也不是 TiDB 的目標,就像我一再強調的: TiDB 是一個 100% OLTP + 80% OLAP 的 Hybrid 的資料庫,這 20% 的非得 MPP 解決的問題,我們會嘗試接入 Spark SQL,並非簡單的實現一個 connector, 而是在 TiKV 層面上去實現 Spark SQL 的運算元,能讓 Spark *高效*的從 TiKV 按需載入數據和下推運算元。這步完成後,應該能做到:一份存儲,多個可插拔查詢引擎(TiDB / Spark SQL),這部分完成後相信大部分 Hybrid 場景 TiDB 都能高效的解決,而且和 Spark 的對接能夠讓我們更加順利的融入 OLAP 生態,這個應該會在 2017 年做。
另一方面,KV 層的吞吐提升也包含幾個方面:
1. Raft 狀態機本身的優化,這個其實我們和 etcd 這邊一直在合作,比如非同步 log apply 等,目前已經在 2017 年初合併到 TiKV 主幹,這個做完後,TiKV 的 raft store 的吞吐大概能有 30% 左右的提升。
2. 事務模型,其實雖然理論上只有 2PC 一種搞法,而且目前來看 Percolator 的模型也沒啥問題,但是針對不同的 Workload 其實還是有優化的空間,對於高並發底衝突的小事務和衝突率比較高的大事務,其實是有不同的優化策略在保證安全的情況下提升吞吐的,在這方面我有一些新的想法,以後有機會單獨寫一下。
3. RocksDB,選擇 RocksDB 簡直太正確了,RocksDB 5.0 的優化很多都能對 TiKV 的用戶直接受益,但是唯一有點不爽的是 RockDB 的 C API 的更新速度並沒有 C++ 的 API 更新速度快,不過這個問題也不大,TiKV 這邊會加一層 wrapper 來保證能夠使用最新的 C++ API,另外一方面 rust 官方也正在對 C++ library 做更好的兼容。
4. 硬體,這個是 2017 年我們一個很重要的嘗試,我也會投很多精力在這個方面,軟體層面的優化其實是比較有限的而且是有天花板的,可能費很大的精力換來 10% 的提升就很了不起了,但是現在我們正處於一個硬體快速變革的時間點,SSD、NVMe 、PCIe FPGA 已經進入大家的視野之中,可能硬體上的進步會能帶來數量級的性能提升,這個是純軟體很難做到的。最近看了一篇論文提到一個新的名詞:In-Stroage Computing,我隱約覺得專有硬體加速可能也是基礎軟體未來的一個重要的趨勢,雖然分散式系統一定是未來,但是性能這種東西是越高越好,也許原來 10 個節點的業務,現在通過硬體上的改進,結果只需要 3 節點就搞定了,也是一個可觀的進步。今年我們會嘗試將一些資料庫邏輯在 FPGA 上實現,通過 PCIe 介面的板子提供針對資料庫的硬體加速,另外我們也在和 Intel 合作,比如針對 Intel 的一些新型號的 CPU 的旁路 FPGA 晶元看看能否有什麼優化的地方。
就寫那麼多吧。
推薦閱讀:
※有沒有自動生成複雜sql的軟體?
※一個不聰明但勤奮好學能吃苦的女孩紙 適合做DBA嗎?
※如何評價OceanBase近期強大的宣傳攻勢?
※SF 講堂「超越find():使用MongoDB聚合框架探索數據」要開播啦
※學校圖書館購買的資料庫是什麼?