天天看點

開源分布式資料庫 TiDB

如今硬體的成本效益越來越高,網絡傳輸速度越來越快,資料庫分層的趨勢逐漸顯現,人們已經不再強求用一個解決方案來解決所有的存儲問題,而是通過分層,讓緩存與資料庫負責各自擅長的業務場景。

TiDB 作為一款 HTAP 資料庫,在高性能的實作 OLTP 特性基礎之上,也同時提供基于實時交易資料的實時業務分析需求。

什麼是 TiDB 資料庫?

TiDB 是一個資料庫。我們知道市面上有很多類似 MySQL、Oracle 的資料庫。為什麼還需要一個新的資料庫?

相信大家 90% 都使用過 MySQL。但是當 MySQL 的資料量比較大或者說并發開始撐不住的時候,能有什麼選擇?

其實選擇沒多少。一個是完全不用 MySQL,而是用 NoSQL。比如說 HBase 或者 Cassandra 去做資料庫。

但是相應的代價就是失去了 SQL 的複雜查詢的能力,還有整個 MySQL 的 EcoSystem。

NoSQL 可以帶來橫向的水準拓展能力,但是會面臨整個業務代碼的重寫。這在很多場景下是不太現實的。

是以很多時候還是得用 MySQL,但是 MySQL 在數量方面有各種各樣的限制。是以過去我們能做的事情就是 Sharding,水準分區,分庫分表。

開源分布式資料庫 TiDB

但是很多時候雖然你做了水準切分,分庫分表,但是 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 分片與合并

開源分布式資料庫 TiDB

第一種場景就是 MySQL,比如已有的業務使用了 MySQL Sharding,沒問題。現在 TiDB 因為在業務層實時相容 MySQL 的這個通路協定。

而且我們做了一個工具 Syncer,它能夠把 TiDB 作為一個 MySQL Master 的 Slave,在業務層前端可以是一個主庫 MySQL,而作為從庫的 TiDB 可以看做一個大的 MySQL。

過去我們有一個說法叫一主多從, 但現在有了 TiDB 以後,可以反過來說多主一從。

你可以把這多個 MySQL 組的不同的表、不同的業務、不同的庫,實時的 Binlog 的資料全都同步、彙總到一個大的分布式的 MySQL 上。

這個分布式 MySQL 就是 TiDB。在這個 MySQL 之上,你可以去用一些比較複雜的 Query,比如 join,groupby 全都可以。是以這個是一種使用者場景。

開源分布式資料庫 TiDB

Syncer 是什麼?我剛才簡單提了下,Syncer 是可以把自己僞裝成一個 MySQL 的 Slave 去做資料的同步的工具。

它本質上是一個 Binlog Listener,會去監聽 MySQL 的 Binlog,然後把它變成資料庫的語句。

用例 2:直接替換 MySQL

開源分布式資料庫 TiDB

另外一個應用場景就非常簡單粗暴,最簡單的情況是業務在快速地增長,但是原來業務就是 MySQL 寫的,也沒考慮什麼分庫分表,架構這樣的事情。

摩拜早期的時候就用 MySQL。後來發現業務開始快速增長,公司在 30 人團隊規模的時候開始使用 TiDB。然後一年之内整個公司人數增長到 800 人,資料從很小的資料集到後來在 TiDB 上有幾十 T 的資料,不需要再去做分庫分表。

是以在業務快速增長的場景下 TiDB 是個很好的選擇。

然後對于 OLTP 的業務來說,TiDB 也是一個很好的選擇。對吞吐來說,TiDB 基本上可以做到線型擴張,機器越多,性能越好。而對于延遲來說,TiDB 也有非常出色的表現。

用例 3:資料倉庫

開源分布式資料庫 TiDB

還有一類使用場景是直接把 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:作為其他系統的基石

開源分布式資料庫 TiDB

基于通用的 KV 層,我們是可以做到很多我們想做的事情。TiDB 并不隻是一個簡單的資料庫項目,它應該是其他的分布式系統的 building block,可以作為其他系統建構的基石。

TiDB 本身對外提供的是 MySQL 的接口,但是社群裡面的小夥伴直接去給 TiKV 層去封裝一個 Redis 的協定層。然後能讓使用者直接用 Redis 的協定去做 TiKV。這樣就變成了可持久化的 Scalable 的 Redis。

開源分布式資料庫 TiDB

然後另外一個 Case,是在今日頭條用的,就是對外提供一個 S3,你想造自己的 S3 沒有問題。但是造 S3 最難的部分是在源資訊管理這塊,并不是它的 data nodes,是以如果你已經有了一個支援跨事務的一個源資訊存儲系統,你可以做到自己去建造 S3。

我知道已經有一些社群的同學建構一整套新的分布式存儲的服務,現在 API 還沒有開源,但我覺得不久的未來會開源。

如何從 MySQL 遷移到 TiDB?

既然 TiDB 這麼好,那現在怎麼把 MySQL 遷移到 TiDB 上呢?因為 TiDB 其實是基于 MySQL 生态的,當然可以用 MySQLDump。

開源分布式資料庫 TiDB

我們自己做了一個資料的導入導出工具叫 Lightning。為什麼要做這個呢?

開源分布式資料庫 TiDB

比如說過去我們如果直接是用 MySQL 的協定,用 MyDumper、Myloader,就是簡單粗暴的導出導入。

那 TiDB 想要做什麼事情呢?

因為大家知道 MyDumper Dump 出來的就是 MySQL 一條條的語句。然後在 TiDB 這邊要從 SQL,到它的 parser 到執行計劃、指導事務、到 KV,最後才寫到單機的 RocksDB 上面。

這個過程一遍遍重複執行是一個很慢的過程,如下圖:

開源分布式資料庫 TiDB

我們就想,有沒有辦法能夠直接繞過中間所有的東西,直接利用 MyDumper Dump 出來的這個 SQL 語句直接生成底下的 RocksDB 的資料的格式呢?當然可以。

開源分布式資料庫 TiDB

是以這就是 Lightning 在做的事情。你可以認為這是一個更新版的 MySQLDumper,直接 Dump 出 SQL 語句。

然後我們在 TiDB Lightning 這個項目内部直接去做了這個 Record to KV,就是直接生成底層的 key-value pairs。然後同時在内部去做資料分片,提前分好。

第三個就是直接去繞過中間所有的這些 SQL,直接去生成 RocksDB 的 SSD 檔案,相當于存儲的格式檔案發送給不同的機器。然後這個機器直接去把檔案 Load 到資料庫裡面就完成了,中間其實是很快的。

部署 TiDB,我們選的技術方案是 Ansible,所有的部署都是可以一鍵完成。然後包括性能調優什麼的完全是開源的。

另外,TiKV 這個項目已經捐給了 CNCF 基金會, TiDB 與 Kubernetes 整合的項目—— TiDB Operator 也已經開源了。

當然,如果你說想在本地自己去玩一玩,但是 TiDB 這麼多元件,我能不能用一條指令就能在本地搭建一個完整的 TiDB Cluster 去做測試呢?當然可以。

我們這邊是有 Docker Compose,是兩條路徑,一條是 git clone,然後第二條是啟動。

它會啟動包括 Dashboard,資料的遷移、可視化,TiDB MySQL 的 Service endpoint、TiSpark 全都會在你的 Docker Container 去建立。

另外這還不夠,我們把一些核心算法通過數學的方式去形式化地證明它是正确的。這個 TLA+ 的源碼檔案開源了,大家如果想在自己的分布式系統裡面去用 TLA+ 做數學上的證明,你可以去參考我們寫的文檔。是以我覺得測試反而是這個公司最重要的一塊資産。

總結

開源分布式資料庫 TiDB

最後,有幾個大的問題也是這段時間我思考得比較多的,比如說你整個叢集雲化了以後,在資料庫的層面上 Multi—tenancy 該怎麼做?就是如何能去做到更有效的資源隔離和複用?

現在并沒有太好的解決方案,因為整個 IO 的隔離還是比較大的問題。

第二個就是自治,這個資料庫能不能擁有智能,就是我再不需要人工去做運維。

這個資料庫能夠自己部署,自己維護,自己更新。然後資料出現問題,自己修複;性能出現問題,自己調優。

我們也在嘗試去把一些我們營運時的 Metric 往 Tensorflow 裡面去導,自動地去做調優。這個工作正在做,然後應該 CMU 是一些比較有意思的工作。

還有就是軟硬體的結合,就是說怎麼去利用這些新時代的硬體來提升你的整個資料庫的穩定性能。