TiDB:支持 MySQL 協議的分佈式數據庫解決方案

【編者按】TiDB 是國內 PingCAP 團隊開發的一個分佈式 SQL 數據庫。其靈感來自於 Google 的 F1,TiDB 支持包括傳統 RDBMS 和 NoSQL 的特性。在國內 ITOM 管理平臺 OneAPM 舉辦的技術公開課中,TiDB 的高級工程師劉奇從 HBase 特性、TiDB 的優點和系統架構等方面進行了詳細闡述。如下爲演講整理:程序員

HBase 簡介算法

衆所周知,在 SQL 方面處於頂級的有兩個公司,一個是 Oracle,他們已經積累了大量的經驗,另外一個是谷歌,谷歌 F1 在2012年發佈了一篇論文,我的認爲它是全球最優秀的 SQL OLTP 數據庫。數據庫

1978年左右,數據庫剛剛發展時出現了SQL RDBMS。2000年左右,國內開始流行互聯網,互聯網對 Oracle 數據庫也產生較大的衝擊。如今,傳統的數據庫大部分是集中在傳統領域,互聯網方面用得比較多的是 MySQL ,其次 HBase 等 NoSQL 也吸引了大量的用戶。安全

爲何會出現 NoSQL?最開始全部人都用 SQL Database,那時比較高端有 Oracle,開源的還有 MySQL、PostgreSQL。但是隨着業務的迅速發展,數據庫成爲了瓶頸,因而促使了 NoSQL 的誕生,NoSQL 將 Scale 放在第一位。若是業務快速發展,擴容會成爲亟待解決的首要問題。這時,大多數人會選擇放棄事務一致性。什麼是一致性?好比使用微信時,若是我加你爲好友,這是一個雙向關係,對應到數據庫中至少是兩個操做,第一是在好友列表裏把你加進來,第二個是你的好友列表裏把我加進去。若是這兩個列表的數據庫放在不一樣的機器上,就須要保證一致性。不然可能會出現我是你的好友,但你的好友中卻找不到個人這種狀況。但這中間可能會出現多種狀況,好比我把你加爲好友,而後修改數據的時候 Crush 掉了,這個時候傳統方案是會引入一個消息隊列,有的還須要作一些補償,這些問題在 NoSQL 裏處理起來相對麻煩。微信

國內最大的 HBase 使用者是小米公司,有幾個 HBase 的 Committer ,因此通過一些修改後能夠支持分佈式事務,因而可以解決以前的問題。爲何在面臨諸多選擇時,小米會選擇 HBase 呢?就目前狀況來講,主要仍是技術選型和人才儲備上的考慮。 MongoDB 你們應該不陌生,但用到必定程度後,總會出現各類問題,甚至有文章呼籲你們放棄 MongoDB 。但全部數據庫都不是「十全十美」的,沒有最好,選擇最適合的尤其重要。架構

不少時候產品都有其特性,在知足其特性或者規格的狀況下,使用起來可能很是順手,不然十之八九都遇到各類麻煩。好比小米使用 HBase 就很是順手,但其餘的公司則不必定。道理很簡單,若是不熟悉其使用場景,也不知道在相應場景下配什麼參數,因此會出現各類各樣的問題。框架

TiDB:支持 MySQL 協議的分佈式數據庫解決方案
事實上,HBase 有很是好的特性,目前在小米公司能夠每秒跑一百萬 OPS ,最近 Pinterest 公佈他們的 HBase 每秒能夠跑三百萬個 OPS ,這個數量級能夠遠超不少互聯網公司。 HBase 在讀寫一致性方面很是出色,有很好的自動 Scale 的能力,經過Block Cache 和 Bloom Filters能夠很好的解決查詢問題,是否在磁盤上也能夠經過Bloom Filters來斷定。運維

另外一方面,Oracle 把一部分邏輯會放在 CPU/硬件裏,對應的 HBase 也會把一部分邏輯下推到對應的 RegionServer 上。對於一個分佈系統來講,若是須要查詢一個條件,能夠直接把這個簡單調節推到對應的 RegionServer 上執行。再好比求和運算,如今有一百億數據,甚至一千億條數據,分佈在10個節點上,最快的求和方法是讓全部節點同時運算,將這個條件下推獲得全部對應數據的和,最後收集到10個數據的和便可。其實還能夠繼續往下推,這是比較複雜的數據庫優化技術,實際狀況還會更復雜。這在 HBase 裏面依賴 Coprocessor 來實現。異步

你們應該對 MVCC 比較熟悉,也就是多版本,它的優勢在於能夠屢次讀取而不會 block。而後還有一個很好的特性,假設你用的 Database ,MVCC 在你沒有作 compaction 以前能夠回到任什麼時候間的數據。如今雲服務上也能夠每隔半小時作一次快照,實際上若是使用 MVCC 回到任意一秒的話,能夠徹底不須要快照。分佈式

TiDB的優點

下面再介紹一下咱們的產品 TiDB,Ti 是元素週期表裏的元素。你們若是瞭解咱們團隊的程序員,就知道他們都比較 Geek,取名字要麼在希臘神話裏選一個神的名字,或者在數學裏找一個希臘字母, 可是看了一圈,好坑都已經被占上了。因而,咱們在化學元素週期表裏找了一個金屬做爲項目名稱,對於 Database 而言,它必須是高速穩定的,恰好鈦金屬有很強的防腐蝕性,因此選擇了鈦(Ti)。

TiDB:支持 MySQL 協議的分佈式數據庫解決方案

由於 TiDB 的目標是谷歌 F1,因此天然會知足以上特性。首先是能夠知足分佈式一致,也就是說對於應用來講,不用關心後面分紅多少個機器,事務的一致性是必須保證的,好比咱們以前提到的 A 關注 B,兩個互相加好友或者轉賬,能夠直接利用一條 SQL 搞定,而無需擔憂中間過程。另一個特性是兼容 MySQL 協議,國內大概有70% 的互聯網公司都在使用 MySQL,爲了考慮你們的遷移成本,咱們會兼容 MySQL 協議。同時,因爲已經不少 APP 在 MySQL 上運行,爲咱們提供了充足的測試樣本。 TiDB 的測試有五百多萬個,每次提交一行代碼時,後面大概有6個機器並行地跑 Test ,五百多萬 Test 所需時間大約是十分鐘。爲了照顧各類引擎愛好者,咱們還支持了 LevelDB 、RocksDB、LMDB、BoltDB 等。TiDB 主要是採用 Go 語言開發的,其代碼簡單、易於理解,並且性能很是高。

系統架構
TiDB:支持 MySQL 協議的分佈式數據庫解決方案

任何用 MySQL 協議寫的程序均可以直接使用 TiDB ,其中間是 MySQL 協議相關的內容,再往下是 SQL Layer。其次是事務 KV 層,這正是 F1 和 Spanner 構造得最爲精密的地方。最底層的構造是從 KV 開始,在 KV 基礎上架一個分佈式的 KV 層用於支持事務,而後再讓 SQL 語句直接映射到 KV 層上。
TiDB:支持 MySQL 協議的分佈式數據庫解決方案

接下來,向你們介紹 現階段 TiDB 使用的分佈式事務是如何在 HBase 上實現的,早期版本中,咱們參考的是 Google 的 Percolator 的模型。首先假設有一個 Client,先爲其分配一個 Timestamp,在 Google 論文中叫作Time Oracle,用來分配時間戳。分配以後能夠作讀寫操做,根據時間戳進行快照讀。最後提交以前要先 Prepare ,Prepare的時候會檢測是否衝突,最後提交時會獲得 Commit ,若是整個過程沒有任何衝突就能夠提交。
TiDB:支持 MySQL 協議的分佈式數據庫解決方案
上圖表明瞭一個實例,最初賬戶狀況是 Bob 有10美金,而 Joe 有5美金。前面的數字表明其版本,當前是第6個版本,指向的是第5個版本,爲10美金,Joe 是2美金。
TiDB:支持 MySQL 協議的分佈式數據庫解決方案

假設Bob要轉4美金給 Joe。第一步,要先轉出去4美金,10美金變成6美金,因爲被扣掉4美金,而後會標註一下本身是主鎖。

TiDB:支持 MySQL 協議的分佈式數據庫解決方案
Joe當前是第7個版本,由於他獲得了4美金,因此餘額變成了6美金,同時標記本身指向另一個主鎖 Bob。
TiDB:支持 MySQL 協議的分佈式數據庫解決方案

到第八個版本時,主鎖會指向如今的7,這時能夠把主鎖刪掉。若是訪問的時候發現主鎖被刪除,那麼主鎖衝突已不存在,能夠進行提交。同時,它會把本身的鎖刪掉,中間還有一些其它的清理過程。

整個事務模型中會有單點,從 Time Oracle 分配一個時間戳,單點決定了整個系統的性能。Google 論文裏有一個對應描述,能夠跑到兩百萬每秒。由於事務開始和結束的時候都須要取一個 Timestamp ,因此他們最快讀寫事務的速度是一百萬每秒,他們已經在論文中實現。實際上,如今有更好的方式能夠提升速度,如 HLC 和一些 Time Oracle的改進算法。
TiDB:支持 MySQL 協議的分佈式數據庫解決方案
關於 Spanner ,咱們重點參考對象是谷歌 Spanner 和 F1 。因爲 Spanner 高度依賴於時鐘,因此谷歌有一套原子鐘和 GPS 時鐘,GPS 信號能夠給出地理位置和時間。爲何須要原子鐘呢?因爲 GPS 時鐘特別容易受到干擾,好比天氣惡劣時 GPS 時鐘就不能運行,而原子鐘仍然適用。
TiDB:支持 MySQL 協議的分佈式數據庫解決方案
TiDB:支持 MySQL 協議的分佈式數據庫解決方案

上圖是谷歌 F1 的一些信息,其中單獨標記了谷歌 F1 的這篇論文,你們有興趣的話不妨細讀一番,目前整個 TiDB 所作的都是在實現這篇論文。假設有一千億數據,你如今要給某一列加索引時,在傳統數據庫上應該如何操做?好比說在分佈式環境下,你用MySQL 給一列添加一個索引,這幾乎很難實現,並且還必須保證 index 的一致性。更多細節請參考論文。
TiDB:支持 MySQL 協議的分佈式數據庫解決方案

TiDB 是如何從 SQL 遷移到 KV 上的呢?由基礎知識可知,傳統的 RDBMS 數據庫底下通常是一個 B-Tree。對於分佈式關係型數據庫,站在更上層一點看,好比谷歌的F1,數據庫底層都是 KV 層,都在 KV 層邏輯下操做。若是有一個 User Table,在 TiDB 裏假設你的Table的結構是由 uid、name和 email 構成。在 TiDB 裏有一個隱藏列叫作 RowID ,全部的操做包括行鎖都是鎖的 RowID 。假設 RowID 是1, uid 是XX,Name 是 Bob,Email 是 bob@Email.com,這都屬於元信息。即使你的 Column name 很長,但最後在數據庫裏存儲的是原信息。在 TiDB 中, 每一列都有惟一的UID。

假設 Table 的 ID 是1,uid 的 ID 是2,name 的ID是3,email 的 ID 是4。在數據庫中存儲爲一個 KV 結構,而後對 TableID、RowID 、ColumnID 進行從新編碼,直接將這個表的一行切成4個 KV 。這時候若是進行 select , Email 等於某一個值的話,因而能夠直接取出來相應的值,速度很是快。

兼容 MySQL

TiDB 對 MySQL 協議有很好的兼容性。有一些比較知名的 MySQL 應用和管理工具,好比WordPress、PhpMyAdmin, MySQL Workbench,均可以直接基於 TiDB 運行。並且數據能夠無限擴展,再也不是單機數據庫。其次,TiDB 還兼容各類 ORM ,好比 XORM 、Beego ORM 等,可以支持不少 MySQL 的應用。每一次代碼更新,這些 ORM Test 會自動運行一次,從而保證與 MySQL 的兼容性,雖然還有一些比較細微的特性暫時沒有支持。如今已經支持異步的 Schema 變動,對於 DDL 操做,不會阻塞線上的業務。

關於社區

目前 TiDB 徹底開源在 Github 上面。開源和開放的概念是兩回事,不少大公司,所謂的開源只是把代碼上傳一下,國內比較知名的案例也挺多的,你們知道不少項目都已經放棄了維護。可是咱們是打算徹底以一個開放的心態來作整個事情,所有的代碼,所有的討論, Code Review,Bug Tracking,Roadmap 都是開源的,畢竟通用的分佈式 OLTP 關係型數據庫是一個很是前沿並且極端重要的領域,將來是雲上的 DBaaS 的重要組成部分,可是在這塊目前整個技術社區,即便全球來看都沒有一個太成熟開源解決方案,TiDB也目前也處於早期,從架構上來看,咱們將 SQL 層和 KV 層作了很完全的分離,這也是咱們但願更多開發者能根據本身的須要更方便的進行定製,咱們也想得很清楚,依靠某一家公司,或者某幾我的的力量是不夠的,咱們 PingCAP 只是將這一把火點起來,將框架搭好,制定好透明和公平的規則,吸引更多的合做公司和獨立開發者,一塊兒將 TiDB 作成中國第一個世界頂級的開源項目,實現雙贏。

好的項目能夠由社區進行推進,就好比 HBase,HBase 不屬於任何一個公司,可是社區一直推進它進步。目前咱們在 GitHub 狀態是有 3200+的 Star,有 32個 Contributors,算是開了一個好頭,很是感謝你們,但願你們都能參與進來。

本文系國內 ITOM 行業領軍企業 OneAPM 工程師整理。OneAPM 致力於幫助企業用戶提供全棧式的性能管理以及 IT 運維管理服務,經過一個探針就可以完成日誌分析、安全防禦、APM 基礎組件監控、集成報警以及大數據分析等功能。想閱讀更多技術文章,請訪問 OneAPM 官方技術博客
本文轉自 OneAPM 官方博客

相關文章
相關標籤/搜索