支持MySQL協議的分布式數據庫

RandallWing 8年前發布 | 22K 次閱讀 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就非常順手,但其他的公司則不一定。道理很簡單,如果不熟悉其使用場景,也不知道在相應場景下配什么參數,所以會出現各種各樣的問題。

事實上,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的目標是谷歌F1,所以自然會滿足以上特性。首先是可以滿足分布式一致,也就是說對于應用來說,不用關心后面分成多少個機器,事務的一致性是必須保證的,比如我們之前提到的A關注B,兩個互相加好友或者轉帳,可以直接利用一條SQL搞定,而無需擔心中間過程。另外一個特性是兼容MySQL協議,國內大概有70% 的互聯網公司都在使用MySQL,為了考慮大家的遷移成本,我們會兼容MySQL協議。同時,由于已經很多APP在MySQL上運行,為我們提供了充足的測試樣本。TiDB的測試有五百多萬個,每次提交一行代碼時,后面大概有6個機器并行地跑Test,五百多萬Test所需時間大約是十分鐘。為了照顧各種引擎愛好者,我們還支持了LevelDB 、RocksDB、LMDB、BoltDB等。TiDB主要是采用 Go 語言開發的,其代碼簡單、易于理解,而且性能非常高。

系統架構

任何用MySQL協議寫的程序都可以直接使用TiDB,其中間是MySQL協議相關的內容,再往下是SQL Layer。其次是事務KV層,這正是F1和Spanner構造得最為精密的地方。最底層的構造是從KV開始,在KV基礎上架一個分布式的KV層用于支持事務,然后再讓SQL語句直接映射到KV層上。

接下來,向大家介紹 現階段 TiDB 使用的分布式事務是如何在HBase上實現的,早期版本中,我們參考的是 Google 的 Percolator 的模型。首先假設有一個Client,先為其分配一個 Timestamp,在Google論文中叫做Time Oracle,用來分配時間戳。分配之后可以做讀寫操作,根據時間戳進行快照讀。最后提交之前要先Prepare,Prepare的時候會檢測是否沖突,最后提交時會得到Commit,如果整個過程沒有任何沖突就可以提交。

上圖代表了一個實例,最初帳戶情況是Bob有10美金,而Joe有5美金。前面的數字代表其版本,當前是第6個版本,指向的是第5個版本,為10美金,Joe是2美金。

假設Bob要轉4美金給Joe。第一步,要先轉出去4美金,10美金變成6美金,由于被扣掉4美金,然后會標注一下自己是主鎖。

Joe當前是第7個版本,因為他得到了4美金,所以余額變成了6美金,同時標記自己指向另外一個主鎖Bob。

到第八個版本時,主鎖會指向現在的7,這時可以把主鎖刪掉。如果訪問的時候發現主鎖被刪除,那么主鎖沖突已不存在,可以進行提交。同時,它會把自己的鎖刪掉,中間還有一些其它的清理過程。

整個事務模型中會有單點,從Time Oracle分配一個時間戳,單點決定了整個系統的性能。Google論文里有一個對應描述,可以跑到兩百萬每秒。因為事務開始和結束的時候都需要取一個Timestamp,所以他們最快讀寫事務的速度是一百萬每秒,他們已經在論文中實現。實際上,現在有更好的方式可以提高速度,如HLC和一些Time Oracle的改進算法。

關于Spanner,我們重點參考對象是谷歌Spanner和F1。由于Spanner高度依賴于時鐘,所以谷歌有一套原子鐘和GPS時鐘,GPS信號可以給出地理位置和時間。為什么需要原子鐘呢?由于GPS時鐘特別容易受到干擾,比如天氣惡劣時GPS時鐘就不能運行,而原子鐘仍然適用。

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

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,算是開了一個好頭,非常感謝大家,希望大家都能參與進來。

來自: http://www.uml.org.cn/sjjm/2016012210.asp

 本文由用戶 RandallWing 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!