敢啃“硬骨頭”,開源分散式資料庫 TiDB 如何煉成?
如今硬體的價效比越來越高,網路傳輸速度越來越快,資料庫分層的趨勢逐漸顯現,人們已經不再強求用一個解決方案來解決所有的儲存問題,而是通過分層,讓快取與資料庫負責各自擅長的業務場景。
TiDB 作為一款 HTAP 資料庫,在高效能的實現 OLTP 特性基礎之上,也同時提供基於實時交易資料的實時業務分析需求。
什麼是 TiDB 資料庫?
TiDB 是一個數據庫。我們知道市面上有很多類似 SQL/">MySQL、Oracle 的資料庫。 為什麼還需要一個新的資料庫?
相信大家 90% 都使用過 MySQL。但是當 MySQL 的資料量比較大或者說併發開始撐不住的時候,能有什麼選擇?
其實選擇沒多少。一個是完全不用 MySQL,而是用 NoSQL。比如說 HBase 或者 Cassandra 去做資料庫。
但是相應的代價就是失去了 SQL 的複雜查詢的能力,還有整個 MySQL 的 EcoSystem。
NoSQL 可以帶來橫向的水平拓展能力,但是會面臨整個業務程式碼的重寫。這在很多場景下是不太現實的。
所以很多時候還是得用 MySQL,但是 MySQL 在數量方面有各種各樣的限制。所以過去我們能做的事情就是 Sharding,水平分割槽,分庫分表。
但是很多時候雖然你做了水平切分,分庫分表,但是 Scale 還是一個非常大的問題。
另外一點比如說你用了讀寫分離,或者你可能用了 Cassandra 這樣的最終一致性的系統,對於開發者來說這個心智負擔是比較大的。
如果你沒有一個強一致的、持久化的儲存系統,你的業務層的程式碼是很難寫的,特別是對一些金融場景或者說對一致性要求比較高的業務。
另外,我們的資料倉庫、大資料分析的解決方案和資料庫的解決方案中間基本是徹底割裂的。這兩年大家常用的 RabbitMQ 或者 Kafka 這樣的管道系統,就是嘗試在資料庫和資料倉庫之間構建一個橋樑。有沒有辦法能夠把實時的 OLAP 直接就在資料庫層面做?
或者說現在你用了 MySQL 的 Sharding,要去做一個簡單的跨業務的 join 的分析,都得把這個資料通過 ETL 導到 Hadoop 或者 data warehouse 裡面再去做分析。
維護 ETL 的過程是一個比較麻煩的事情。另外一個問題是資料分析師可能不是一個工程師或者說一個技術很強的人,所以在技術選型上會有各種限制。
能不能就直接在資料庫上去做一些 in-place 的查詢呢,這是一個問題。
另外一個就是大的趨勢,大家都在思考資料庫這樣的業務怎麼去跟現有云架構去整合。
舉例來說你不可能直接把一個 MySQL 例項放到一個 Container 裡面,因為如果 Container 掛了,資料就沒了。
怎麼去面向一個雲環境或者一個可以彈性伸縮的容器環境,設計一個可以彈性伸縮的資料庫,這其實是個很大的問題。
還有一個特別大的痛點,就是在做高可用的時候人是會出錯的。
我們現在做資料庫碰到這些問題的原因是什麼呢?
我個人認為關係型資料庫像 MySQL,Oracle 這些本身不是面向分散式去做設計的。另外,即使你勉強做這個分庫分表等操作,本質上來說你只是把 MySQL 再複製了一遍,並不是針對它是一個分散式系統來做儲存和計算的優化。
這就是問題,而這也是為什麼我們會覺得我在做一些跨業務的查詢或者說一些跨物理的這個機器的查詢和寫入會比較麻煩的原因。
但是終於這個情況在發生變化, 因為在 2000 年以後,分散式系統理論開始變為主流。
這有一個歷史發展的背景,就是過去硬體價格昂貴,而且網路環境不好。所以儘可能把計算給放在本地去做。
因為 SSD 的出現,現在磁碟 IO 基本上問題已經不大了,而 Intel 很快會發布持久化記憶體。像這種技術基本上解決了資料庫 IO 層上的問題。
現在在 Google 內部,同一個資料中心內讀取遠端磁碟,跟讀取本地磁碟的吞吐和延遲基本是可以做到一致的。
在這種情況下你可以認為整個資料中心就是一臺計算機,你重新去設計資料庫的時候,它本質上就是一個分散式系統。
第三點就是大家的思維在發生改變,大家不再幻想有一個完美的解決方案去解決掉所有儲存上的問題
易維護
TiDB 這個專案是在三年前開始的。專案就是上面介紹的背景,我過去在豌豆莢一直維護 MySQL 叢集。
後來因為關係型資料庫不易維護,經常想能不能有一個數據庫可以結合 MySQL 和 NoSQL 的優點。
所以這就是最開始的初心,我們要去做一個功能完備的 SQL,百分之百去相容現有的,至少是這些常用的複雜查詢、子查詢業務。
然後同時要以一個 MySQL 的協議和用法去面向客戶,或者使用者。這一點很重要,它可以極大地降低使用者去試你產品的成本。
事務
第二點就是事務,事務是絕對不能少的。我覺得過去這十年 NoSQL 的社群有一個特別大的問題就是追求可擴充套件性,但是放棄了強一致事務的支援,這是不對的。
過去不實現這個功能的理由是這個功能會導致系統延遲,效能下降。但是我覺得以犧牲資料準確性為代價去實現這個功能是不現實的。
這就相當於本來這個事情應該資料庫來做,這些 NoSQL 系統卻強行把這個事情交給業務層做。這會給寫業務帶來一個極大的問題。
另外一個就是擴充套件的易用性,就是能不能做到我這裡用了一個詞叫做 push-button scaling。
我簡單地扔一臺機器進去,不做任何的 resharding,不做任何的修改配置,這個系統自己就擴大了,自己去做 rebalancing,這跟傳統的 Sharding 方案有本質的區別。
高可用
然後 HA 是什麼?HA 就是高可用,這個問題是傳統方案很難解決的。就是一切都是需要人工去做這個資料校驗和流量的切換。
有沒有辦法能做到真正的 HA,這個資料庫能不能自動地自己去運維、自己去修復自己,自己去保證這個系統的可用性。
在這塊我們也做了一些工作,就是我們在底下的整個資料模型完全放棄掉了主從的模型,完全基於 Raft 跟 Paxos 這樣的一種分散式選舉演算法來做。
這個還比較重要,因為如果一個系統你不能保證它的可用性,談再多的效能都是沒有意義的,特別是對於 OLTP 系統來說。
我的這個系統能不能既在上面去支援 ACID 事務,同時又可以利用 Spark 或者 Hadoop 去用整個機群的計算資源和能力,再去做一些複雜的 SQL 查詢的時候能加速。這個其實是可以做到的。
開源
最後一點就是一定是百分之百開源,通用的技術軟體不開源是絕對沒有未來的。
因為現在時代已經變了,過去那種閉門造車,然後招一大堆銷售,挨家敲門說你要不要試一下的搞法是不對的,特別是平臺性質的軟體。
而且開源會更加有利於去做軟體推廣,你的使用者越多,使用者給你的反饋就越多。
這會比自己在內部去做軟體速度快得多。這也是為什麼這個專案才開始三年,我們的客戶就超過了 2000 多家。
TiDB 資料庫的四大“殺手鐗”
現在我來總結一下 TiDB 資料庫有哪些應用場景可以在你自己的業務裡面去使用。
用例 1:MySQL 分片與合併
第一種場景就是 MySQL,比如已有的業務使用了 MySQL Sharding,沒問題。現在 TiDB 因為在業務層實時相容 MySQL 的這個訪問協議。
而且我們做了一個工具 Syncer,它能夠把 TiDB 作為一個 MySQL Master 的 Slave,在業務層前端可以是一個主庫 MySQL,而作為從庫的 TiDB 可以看做一個大的 MySQL。
過去我們有一個說法叫一主多從, 但現在有了 TiDB 以後,可以反過來說多主一從。
你可以把這多個 MySQL 組的不同的表、不同的業務、不同的庫,實時的 Binlog 的資料全都同步、彙總到一個大的分散式的 MySQL 上。
這個分散式 MySQL 就是 TiDB。在這個 MySQL 之上,你可以去用一些比較複雜的 Query,比如 join,groupby 全都可以。所以這個是一種使用者場景。
Syncer 是什麼?我剛才簡單提了下,Syncer 是可以把自己偽裝成一個 MySQL 的 Slave 去做資料的同步的工具。
它本質上是一個 Binlog Listener,會去監聽 MySQL 的 Binlog,然後把它變成資料庫的語句。
用例 2:直接替換 MySQL
另外一個應用場景就非常簡單粗暴,最簡單的情況是業務在快速地增長,但是原來業務就是 MySQL 寫的,也沒考慮什麼分庫分表,架構這樣的事情。
摩拜早期的時候就用 MySQL。後來發現業務開始快速增長,公司在 30 人團隊規模的時候開始使用 TiDB。然後一年之內整個公司人數增長到 800 人,資料從很小的資料集到後來在 TiDB 上有幾十 T 的資料,不需要再去做分庫分表。
所以在業務快速增長的場景下 TiDB 是個很好的選擇。
然後對於 OLTP 的業務來說,TiDB 也是一個很好的選擇。對吞吐來說,TiDB 基本上可以做到線型擴張,機器越多,效能越好。而對於延遲來說,TiDB 也有非常出色的表現。
用例 3:資料倉庫
還有一類使用場景是直接把 TiDB 作為資料倉庫用。 TiDB 在 OLAP 的效能測評方面表現非常出眾。
如果有一些特別複雜的 SQL,TiDB 的 SQL 層還是搞不定,我這邊也做了一個開源的專案,叫 TiSpark 。它其實是一個 Spark 的外掛,能夠讓使用者直接用 Spark SQL 來實時地在 TiKV 上做大資料分析。
第三個應用場景,TiDB 本身是一個儲存跟計算分開的一個專案。它底下 Key-Value 的那一層也可以單獨拿出來用,你可以把它當作一個 Hbase 的替代品, 同時支援跨行的事務。
TiDB 的專案其實是受到了 Google Spanner 這個系統的啟發,是通過 NoSQL 這一層支援 transaction 的。
TiKV 提供了兩層 API,一層是支援跨行事物 transaction 的 API。第二層 API 叫弱 API,主要用來做單行的事務,不提供跨行事務的 ACID 的支援,但是換取的是整個效能和延遲的進一步提升。
所以如果有需要,事務可以用 transaction 的 API,如果需要效能,但是沒有強一致事務的跨行事務的需求,就用弱 API。弱 API 跟 Hbase 的一致性級別是一樣的。
用例 4:作為其他系統的基石
基於通用的 KV 層,我們是可以做到很多我們想做的事情。TiDB 並不只是一個簡單的資料庫專案,它應該是其他的分散式系統的 building block,可以作為其他系統構建的基石。
TiDB 本身對外提供的是 MySQL 的介面,但是社群裡面的小夥伴直接去給 TiKV 層去封裝一個 Redis 的協議層。然後能讓使用者直接用 Redis 的協議去做 TiKV。這樣就變成了可持久化的 Scalable 的 Redis。
然後另外一個 Case,是在今日頭條用的,就是對外提供一個 S3,你想造自己的 S3 沒有問題。但是造 S3 最難的部分是在源資訊管理這塊,並不是它的 data nodes,所以如果你已經有了一個支援跨事務的一個源資訊儲存系統,你可以做到自己去建造 S3。
我知道已經有一些社群的同學構建一整套新的分散式儲存的服務,現在 API 還沒有開源,但我覺得不久的未來會開源。
如何從 MySQL 遷移到 TiDB?
既然 TiDB 這麼好,那現在怎麼把 MySQL 遷移到 TiDB 上呢?因為 TiDB 其實是基於 MySQL 生態的,當然可以用 MySQLDump。
我們自己做了一個數據的匯入匯出工具叫 Lightning。 為什麼要做這個呢?
比如說過去我們如果直接是用 MySQL 的協議,用 MyDumper、Myloader,就是簡單粗暴的匯出匯入。
那 TiDB 想要做什麼事情呢?
因為大家知道 MyDumper Dump 出來的就是 MySQL 一條條的語句。然後在 TiDB 這邊要從 SQL,到它的 parser 到執行計劃、指導事務、到 KV,最後才寫到單機的 RocksDB 上面。
這個過程一遍遍重複執行是一個很慢的過程,如下圖:
我們就想,有沒有辦法能夠直接繞過中間所有的東西,直接利用 MyDumper Dump 出來的這個 SQL 語句直接生成底下的 RocksDB 的資料的格式呢?當然可以。
所以這就是 Lightning 在做的事情。你可以認為這是一個升級版的 MySQLDumper,直接 Dump 出 SQL 語句。
然後我們在 TiDB Lightning 這個專案內部直接去做了這個 Record to KV,就是直接生成底層的 key-value pairs。然後同時在內部去做資料分片,提前分好。
第三個就是直接去繞過中間所有的這些 SQL,直接去生成 RocksDB 的 SSD 檔案,相當於儲存的格式檔案傳送給不同的機器。然後這個機器直接去把檔案 Load 到資料庫裡面就完成了,中間其實是很快的。
部署 TiDB,我們選的技術方案是 Ansible,所有的部署都是可以一鍵完成。然後包括效能調優什麼的完全是開源的。
另外, ofollow,noindex">TiKV 這個專案已經捐給了 CNCF 基金會 , TiDB 與 Kubernetes 整合的專案—— TiDB Operator 也已經開源了 。
當然,如果你說想在本地自己去玩一玩,但是 TiDB 這麼多元件,我能不能用一條命令就能在本地搭建一個完整的 TiDB Cluster 去做測試呢?當然可以。
我們這邊是有 Docker Compose,是兩條路徑,一條是 git clone,然後第二條是啟動。
它會啟動包括 Dashboard,資料的遷移、視覺化,TiDB MySQL 的 Service endpoint、TiSpark 全都會在你的 Docker Container 去建立。
另外這還不夠,我們把一些核心演算法通過數學的方式去形式化地證明它是正確的。這個 TLA+ 的原始碼檔案開源了,大家如果想在自己的分散式系統裡面去用 TLA+ 做數學上的證明,你可以去參考我們寫的文件。所以我覺得測試反而是這個公司最重要的一塊資產。
總結
最後,有幾個大的問題也是這段時間我思考得比較多的,比如說你整個叢集雲化了以後,在資料庫的層面上 Multi—tenancy 該怎麼做?就是如何能去做到更有效的資源隔離和複用?
現在並沒有太好的解決方案,因為整個 IO 的隔離還是比較大的問題。
第二個就是自治,這個資料庫能不能擁有智慧,就是我再不需要人工去做運維。
這個資料庫能夠自己部署,自己維護,自己更新。然後資料出現問題,自己修復;效能出現問題,自己調優。
我們也在嘗試去把一些我們運營時的 Metric 往 Tensorflow 裡面去導,自動地去做調優。這個工作正在做,然後應該 CMU 是一些比較有意思的工作。
還有就是軟硬體的結合,就是說怎麼去利用這些新時代的硬體來提升你的整個資料庫的穩定效能。
原文釋出時間為:2018-10-20
本文作者:黃東旭