摘要:編者按是國內(nèi)團(tuán)隊(duì)開發(fā)的一個分布式數(shù)據(jù)庫。國內(nèi)最大的使用者是小米公司,有幾個的,所以經(jīng)過一些修改后可以支持分布式事務(wù),于是能夠解決之前的問題。對于分布式關(guān)系型數(shù)據(jù)庫,站在更上層一點(diǎn)看,比如谷歌的,數(shù)據(jù)庫底層都是層,都在層邏輯下操作。
【編者按】TiDB 是國內(nèi) PingCAP 團(tuán)隊(duì)開發(fā)的一個分布式 SQL 數(shù)據(jù)庫。其靈感來自于 Google 的?F1,TiDB 支持包括傳統(tǒng) RDBMS 和 NoSQL 的特性。在國內(nèi) ITOM 管理平臺 OneAPM 舉辦的技術(shù)公開課中,TiDB 的高級工程師劉奇從 HBase 特性、TiDB 的優(yōu)勢和系統(tǒng)架構(gòu)等方面進(jìn)行了詳細(xì)闡述。以下為演講整理:
HBase 簡介
眾所周知,在 SQL 方面處于頂級的有兩個公司,一個是 Oracle,他們已經(jīng)積累了大量的經(jīng)驗(yàn),另一個是谷歌,谷歌 F1 在2012年發(fā)布了一篇論文,個人認(rèn)為它是全球最優(yōu)秀的 SQL OLTP 數(shù)據(jù)庫。
1978年左右,數(shù)據(jù)庫剛剛發(fā)展時出現(xiàn)了SQL RDBMS。2000年左右,國內(nèi)開始流行互聯(lián)網(wǎng),互聯(lián)網(wǎng)對 Oracle 數(shù)據(jù)庫也產(chǎn)生較大的沖擊?,F(xiàn)在,傳統(tǒng)的數(shù)據(jù)庫大部分是集中在傳統(tǒng)領(lǐng)域,互聯(lián)網(wǎng)方面用得比較多的是 MySQL ,其次 HBase 等 NoSQL 也吸引了大量的用戶。
為什么會出現(xiàn) NoSQL?最開始所有人都用 SQL Database,那時比較高端有 Oracle,開源的還有 MySQL、PostgreSQL??墒请S著業(yè)務(wù)的迅速發(fā)展,數(shù)據(jù)庫成為了瓶頸,于是促使了 NoSQL 的誕生,NoSQL 將 Scale 放在第一位。如果業(yè)務(wù)快速發(fā)展,擴(kuò)容會成為亟待解決的首要問題。這時,大多數(shù)人會選擇放棄事務(wù)一致性。什么是一致性?比如使用微信時,如果我加你為好友,這是一個雙向關(guān)系,對應(yīng)到數(shù)據(jù)庫中至少是兩個操作,第一是在好友列表里把你加進(jìn)來,第二個是你的好友列表里把我加進(jìn)去。如果這兩個列表的數(shù)據(jù)庫放在不同的機(jī)器上,就需要保證一致性。否則可能會出現(xiàn)我是你的好友,但你的好友中卻找不到我的這種情況。但這中間可能會出現(xiàn)多種情況,比如我把你加為好友,然后修改數(shù)據(jù)的時候 Crush 掉了,這個時候傳統(tǒng)方案是會引入一個消息隊(duì)列,有的還需要做一些補(bǔ)償,這些問題在 NoSQL 里處理起來相對麻煩。
國內(nèi)最大的 HBase 使用者是小米公司,有幾個 HBase 的 Committer ,所以經(jīng)過一些修改后可以支持分布式事務(wù),于是能夠解決之前的問題。為什么在面臨諸多選擇時,小米會選擇 HBase 呢?就目前情況來說,主要還是技術(shù)選型和人才儲備上的考慮。 MongoDB 大家應(yīng)該不陌生,但用到一定程度后,總會出現(xiàn)各種問題,甚至有文章呼吁大家放棄 MongoDB 。但所有數(shù)據(jù)庫都不是“十全十美”的,沒有最好,選擇最適合的尤為重要。
很多時候產(chǎn)品都有其特性,在滿足其特性或者規(guī)格的情況下,使用起來可能非常順手,否則十之八九都遇到各種麻煩。比如小米使用 HBase 就非常順手,但其他的公司則不一定。道理很簡單,如果不熟悉其使用場景,也不知道在相應(yīng)場景下配什么參數(shù),所以會出現(xiàn)各種各樣的問題。
事實(shí)上,HBase 有非常好的特性,目前在小米公司可以每秒跑一百萬 OPS ,最近 Pinterest 公布他們的 HBase 每秒可以跑三百萬個 OPS ,這個數(shù)量級可以遠(yuǎn)超很多互聯(lián)網(wǎng)公司。 HBase 在讀寫一致性方面非常出色,有很好的自動 Scale 的能力,通過Block Cache 和 Bloom Filters可以很好的解決查詢問題,是否在磁盤上也可以通過Bloom Filters來判定。
另一方面,Oracle 把一部分邏輯會放在 CPU/硬件里,對應(yīng)的 HBase 也會把一部分邏輯下推到對應(yīng)的 RegionServer 上。對于一個分布系統(tǒng)來說,如果需要查詢一個條件,可以直接把這個簡單調(diào)節(jié)推到對應(yīng)的 RegionServer 上執(zhí)行。再比如求和運(yùn)算,現(xiàn)在有一百億數(shù)據(jù),甚至一千億條數(shù)據(jù),分布在10個節(jié)點(diǎn)上,最快的求和方法是讓所有節(jié)點(diǎn)同時運(yùn)算,將這個條件下推得到所有對應(yīng)數(shù)據(jù)的和,最后收集到10個數(shù)據(jù)的和即可。其實(shí)還可以繼續(xù)往下推,這是比較復(fù)雜的數(shù)據(jù)庫優(yōu)化技術(shù),實(shí)際情況還會更復(fù)雜。這在 HBase 里面依賴 Coprocessor 來實(shí)現(xiàn)。
大家應(yīng)該對 MVCC 比較熟悉,也就是多版本,它的優(yōu)點(diǎn)在于可以多次讀取而不會 block。然后還有一個很好的特性,假設(shè)你用的 Database ,MVCC 在你沒有做 compaction 之前可以回到任何時間的數(shù)據(jù)?,F(xiàn)在云服務(wù)上也可以每隔半小時做一次快照,實(shí)際上如果使用 MVCC 回到任意一秒的話,可以完全不需要快照。
TiDB的優(yōu)勢
下面再介紹一下我們的產(chǎn)品 TiDB,Ti 是元素周期表里的元素。大家如果了解我們團(tuán)隊(duì)的程序員,就知道他們都比較 Geek,取名字要么在希臘神話里選一個神的名字,或者在數(shù)學(xué)里找一個希臘字母, 但是看了一圈,好坑都已經(jīng)被占上了。于是,我們在化學(xué)元素周期表里找了一個金屬作為項(xiàng)目名稱,對于 Database 而言,它必須是高速穩(wěn)定的,剛好鈦金屬有很強(qiáng)的防腐蝕性,所以選擇了鈦(Ti)。
因?yàn)?TiDB 的目標(biāo)是谷歌 F1,所以自然會滿足以上特性。首先是可以滿足分布式一致,也就是說對于應(yīng)用來說,不用關(guān)心后面分成多少個機(jī)器,事務(wù)的一致性是必須保證的,比如我們之前提到的 A 關(guān)注 B,兩個互相加好友或者轉(zhuǎn)帳,可以直接利用一條 SQL 搞定,而無需擔(dān)心中間過程。另外一個特性是兼容 MySQL 協(xié)議,國內(nèi)大概有70% 的互聯(lián)網(wǎng)公司都在使用 MySQL,為了考慮大家的遷移成本,我們會兼容 MySQL 協(xié)議。同時,由于已經(jīng)很多 APP 在 MySQL 上運(yùn)行,為我們提供了充足的測試樣本。 TiDB 的測試有五百多萬個,每次提交一行代碼時,后面大概有6個機(jī)器并行地跑 Test ,五百多萬 Test 所需時間大約是十分鐘。為了照顧各種引擎愛好者,我們還支持了 LevelDB 、RocksDB、LMDB、BoltDB 等。TiDB 主要是采用 Go 語言開發(fā)的,其代碼簡單、易于理解,而且性能非常高。
系統(tǒng)架構(gòu)
任何用 MySQL 協(xié)議寫的程序都可以直接使用 TiDB ,其中間是 MySQL 協(xié)議相關(guān)的內(nèi)容,再往下是 SQL Layer。其次是事務(wù) KV 層,這正是 F1 和 Spanner 構(gòu)造得最為精密的地方。最底層的構(gòu)造是從 KV 開始,在 KV 基礎(chǔ)上架一個分布式的 KV 層用于支持事務(wù),然后再讓 SQL 語句直接映射到 KV 層上。
接下來,向大家介紹 現(xiàn)階段 TiDB 使用的分布式事務(wù)是如何在 HBase 上實(shí)現(xiàn)的,早期版本中,我們參考的是 Google 的 Percolator 的模型。首先假設(shè)有一個 Client,先為其分配一個 Timestamp,在 Google 論文中叫做Time Oracle,用來分配時間戳。分配之后可以做讀寫操作,根據(jù)時間戳進(jìn)行快照讀。最后提交之前要先 Prepare ,Prepare的時候會檢測是否沖突,最后提交時會得到 Commit ,如果整個過程沒有任何沖突就可以提交。
上圖代表了一個實(shí)例,最初帳戶情況是 Bob 有10美金,而 Joe 有5美金。前面的數(shù)字代表其版本,當(dāng)前是第6個版本,指向的是第5個版本,為10美金,Joe 是2美金。
假設(shè)Bob要轉(zhuǎn)4美金給 Joe。第一步,要先轉(zhuǎn)出去4美金,10美金變成6美金,由于被扣掉4美金,然后會標(biāo)注一下自己是主鎖。
Joe當(dāng)前是第7個版本,因?yàn)樗玫搅?美金,所以余額變成了6美金,同時標(biāo)記自己指向另外一個主鎖 Bob。
到第八個版本時,主鎖會指向現(xiàn)在的7,這時可以把主鎖刪掉。如果訪問的時候發(fā)現(xiàn)主鎖被刪除,那么主鎖沖突已不存在,可以進(jìn)行提交。同時,它會把自己的鎖刪掉,中間還有一些其它的清理過程。
整個事務(wù)模型中會有單點(diǎn),從 Time Oracle 分配一個時間戳,單點(diǎn)決定了整個系統(tǒng)的性能。Google 論文里有一個對應(yīng)描述,可以跑到兩百萬每秒。因?yàn)槭聞?wù)開始和結(jié)束的時候都需要取一個 Timestamp ,所以他們最快讀寫事務(wù)的速度是一百萬每秒,他們已經(jīng)在論文中實(shí)現(xiàn)。實(shí)際上,現(xiàn)在有更好的方式可以提高速度,如 HLC 和一些 Time Oracle的改進(jìn)算法。
關(guān)于 Spanner ,我們重點(diǎn)參考對象是谷歌 Spanner 和 F1 。由于 Spanner 高度依賴于時鐘,所以谷歌有一套原子鐘和 GPS 時鐘,GPS 信號可以給出地理位置和時間。為什么需要原子鐘呢?由于 GPS 時鐘特別容易受到干擾,比如天氣惡劣時 GPS 時鐘就不能運(yùn)行,而原子鐘仍然適用。
上圖是谷歌 F1 的一些信息,其中多帶帶標(biāo)記了谷歌 F1 的這篇論文,大家有興趣的話不妨細(xì)讀一番,目前整個 TiDB 所做的都是在實(shí)現(xiàn)這篇論文。假設(shè)有一千億數(shù)據(jù),你現(xiàn)在要給某一列加索引時,在傳統(tǒng)數(shù)據(jù)庫上應(yīng)該如何操作?比如說在分布式環(huán)境下,你用MySQL 給一列添加一個索引,這幾乎很難實(shí)現(xiàn),而且還必須保證 index 的一致性。更多細(xì)節(jié)請參考論文。
TiDB 是如何從 SQL 遷移到 KV 上的呢?由基礎(chǔ)知識可知,傳統(tǒng)的 RDBMS 數(shù)據(jù)庫底下一般是一個 B-Tree。對于分布式關(guān)系型數(shù)據(jù)庫,站在更上層一點(diǎn)看,比如谷歌的F1,數(shù)據(jù)庫底層都是 KV 層,都在 KV 層邏輯下操作。如果有一個 User Table,在 TiDB 里假設(shè)你的Table的結(jié)構(gòu)是由 uid、name和 email 構(gòu)成。在 TiDB 里有一個隱藏列叫做 RowID ,所有的操作包括行鎖都是鎖的 RowID 。假設(shè) RowID 是1, uid 是XX,Name 是 Bob,Email 是 [email protected],這都屬于元信息。即便你的 Column name 很長,但最后在數(shù)據(jù)庫里存儲的是原信息。在 TiDB 中, 每一列都有唯一的UID。
假設(shè) Table 的 ID 是1,uid 的 ID 是2,name 的ID是3,email 的 ID 是4。在數(shù)據(jù)庫中存儲為一個 KV 結(jié)構(gòu),然后對 TableID、RowID 、ColumnID 進(jìn)行重新編碼,直接將這個表的一行切成4個 KV 。這時候如果進(jìn)行 select , Email 等于某一個值的話,于是可以直接取出來相應(yīng)的值,速度非??臁?
兼容 MySQL
TiDB 對 MySQL 協(xié)議有很好的兼容性。有一些比較知名的 MySQL 應(yīng)用和管理工具,比如WordPress、PhpMyAdmin, MySQL Workbench,都可以直接基于 TiDB 運(yùn)行。而且數(shù)據(jù)可以無限擴(kuò)展,不再是單機(jī)數(shù)據(jù)庫。其次,TiDB 還兼容各種 ORM ,比如 XORM 、Beego ORM 等,能夠支持很多 MySQL 的應(yīng)用。每一次代碼更新,這些 ORM Test 會自動運(yùn)行一次,從而保證與 MySQL 的兼容性,雖然還有一些比較細(xì)微的特性暫時沒有支持?,F(xiàn)在已經(jīng)支持異步的 Schema 變更,對于 DDL 操作,不會阻塞線上的業(yè)務(wù)。
關(guān)于社區(qū)
目前 TiDB 完全開源在 Github 上面。開源和開放的概念是兩回事,很多大公司,所謂的開源只是把代碼上傳一下,國內(nèi)比較知名的案例也挺多的,大家知道很多項(xiàng)目都已經(jīng)放棄了維護(hù)。但是我們是打算完全以一個開放的心態(tài)來做整個事情,全部的代碼,全部的討論, Code Review,Bug Tracking,Roadmap 都是開源的,畢竟通用的分布式 OLTP 關(guān)系型數(shù)據(jù)庫是一個非常前沿而且極端重要的領(lǐng)域,未來是云上的 DBaaS 的重要組成部分,但是在這塊目前整個技術(shù)社區(qū),即使全球來看都沒有一個太成熟開源解決方案,TiDB也目前也處于早期,從架構(gòu)上來看,我們將 SQL 層和 KV 層做了很徹底的分離,這也是我們希望更多開發(fā)者能根據(jù)自己的需要更方便的進(jìn)行定制,我們也想得很清楚,依靠某一家公司,或者某幾個人的力量是不夠的,我們 PingCAP 只是將這一把火點(diǎn)起來,將框架搭好,制定好透明和公平的規(guī)則,吸引更多的合作公司和獨(dú)立開發(fā)者,一起將 TiDB 做成中國第一個世界頂級的開源項(xiàng)目,實(shí)現(xiàn)共贏。
好的項(xiàng)目可以由社區(qū)進(jìn)行推動,就比如 HBase,HBase 不屬于任何一個公司,但是社區(qū)一直推動它進(jìn)步。目前我們在 GitHub 狀態(tài)是有 3200+的 Star,有 32個 Contributors,算是開了一個好頭,非常感謝大家,希望大家都能參與進(jìn)來。
本文系國內(nèi) ITOM 行業(yè)領(lǐng)軍企業(yè) OneAPM 工程師整理。OneAPM 致力于幫助企業(yè)用戶提供全棧式的性能管理以及 IT 運(yùn)維管理服務(wù),通過一個探針就能夠完成日志分析、安全防護(hù)、APM 基礎(chǔ)組件監(jiān)控、集成報(bào)警以及大數(shù)據(jù)分析等功能。想閱讀更多技術(shù)文章,請?jiān)L問 OneAPM 官方技術(shù)博客
本文轉(zhuǎn)自 OneAPM 官方博客
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/17525.html
閱讀 3247·2021-11-22 12:07
閱讀 1887·2021-10-12 10:11
閱讀 1051·2019-08-30 15:44
閱讀 2951·2019-08-30 12:45
閱讀 2214·2019-08-29 16:41
閱讀 1645·2019-08-29 16:35
閱讀 2637·2019-08-29 12:57
閱讀 1158·2019-08-26 13:51