|
講師: 劉奇(goroutine) 個人簡介: PingCAP創(chuàng)始人兼CEO。分布式系統(tǒng)專家,擅長分布式數(shù)據(jù)庫,分布式緩存。目前從事NewSQL方向的創(chuàng)業(yè),通過開源方式重建google內(nèi)部的F1和spanner。目前項目已經(jīng)開源,https://github.com/pingcap/tidb 正文內(nèi)容: 大家好, 我是開源項目 分布式 NewSQL 數(shù)據(jù)庫 TiDB 和 分布式緩存 Codis 的 創(chuàng)始人 劉奇, 之前在京東, 豌豆莢做 infrastructure 相關(guān)的事情, 現(xiàn)在在創(chuàng)業(yè) (PingCAP), 方向是分布式數(shù)據(jù)庫. 最近如果有朋友關(guān)注開源社區(qū)或者HackerNews 的話,可能會發(fā)現(xiàn)一個叫 TiDB 的數(shù)據(jù)庫項目吸引了一些眼球(https://github.com/pingcap/tidb ) 。 這是我們開源的第一個東西,短短幾天得到了過千Star,特別感謝大家的支持和鼓勵。 今天主要介紹一下 NewSQL 與 TiDB 的設計實現(xiàn), 未來的一些 Roadmap 以及 一些做開源項目的心得。 大家可能經(jīng)常用數(shù)據(jù)庫,但是很少寫一個數(shù)據(jù)庫(實在是有點 hardcore),今天我就從一個開發(fā)者的角度,來看看如何寫一個分布式數(shù)據(jù)庫,因為這個話題實在太大,我試著講一下,講的不好請各位海涵 :D 數(shù)據(jù)庫系統(tǒng)架構(gòu)如何分層 某種程度上看來,數(shù)據(jù)庫作為整個系統(tǒng)的核心,這句話其實并不夸張,數(shù)據(jù)庫的選型關(guān)系到上層業(yè)務代碼實現(xiàn)的方方面面,現(xiàn)在比較流行的架構(gòu)方案是上層業(yè)務邏輯微服務化,并且結(jié)合分布式緩存,這套框架已經(jīng)基本能做到上層業(yè)務的彈性擴展,但是最底層的數(shù)據(jù)存儲還是很難去中心化(除非整個技術(shù)棧中去除關(guān)系型數(shù)據(jù)庫(RDBMS), 全部采用 NoSQL)。所以,經(jīng)常是 RDBMS 成為整個系統(tǒng)的瓶頸。 在長期的斗爭中,大家總結(jié)出了很多方式來擴展最底層的關(guān)系型數(shù)據(jù)庫: 1. 主從,一主多從,雙寫,通過隊列暫存請求... 這些方案其實并沒有解決問題,寫入仍然是單點,而且對于 DBA 的挑戰(zhàn)比較大,今天我們暫時就不討論了。 2. 通過中間件 Sharding,常見的開源方案有: Cobar, TDDL, Vitess, Kingshard, MyCat 等,這些方案的思路是攔截 SQL 的請求通過 sharding key 和一定規(guī)則,將請求轉(zhuǎn)發(fā)/廣播到不同的 MySQL 實例上,從而實現(xiàn)水平擴展的效果,這個方案基本解決了單點寫入的問題,對于業(yè)務來說整體的吞吐也上來了,看上去不錯,這個方案是大多數(shù)業(yè)務遇到性能瓶頸的解決方案,但是缺點也是有的: 1)大多中間件都沒有解決動態(tài)擴容的問題,多采用了靜態(tài)的路由策略,擴容一般還處于人工 x2 的狀態(tài),對 DBA 要求比較高。 2)從一定程度上來說都放棄了事務,這是由于一條語句有可能會涉及到多個數(shù)據(jù)庫實例,實現(xiàn)分布式 事務是一個比較難的事情,我們后面會詳細的介紹。 3)對業(yè)務不透明,需要指定 sharding key, 心智負擔較大 特別是第二點,由于放棄事務,對于上層業(yè)務的程序的寫法帶來很多的影響,有一些中間件支持部分的事務,但是需要使用者保證參與事務的行都會落在一臺實例上(例如 sharding key 選為 userid 按照同一個 user_id 下的多行進行事務操作,)對于一些簡單的業(yè)務來說還比較好,但是一旦對于一致性的要求比較高的業(yè)務,就會給開發(fā)者帶來了比較大的心智負擔,比如通過隊列繞開(http://blog./89140/ )等技巧。 因為上述原因,有些業(yè)務就拋棄了 RDBMS,直接上 NoSQL,常見的選型方案是:HBase,MongoDB, Cassandra 等,簡單介紹一下: HBase 來自 Google 的 Big Table 的論文,底層存儲依賴 HDFS 來實現(xiàn)擴展性,通過對 Key 進行 Range 化、列式存儲(多 Region )的管理,使整個集群達到比較高的隨機讀寫性能(吞吐),比較適用于海量小 Key/Value 讀寫業(yè)務,強一致性,支持多版本,支持 Table 和半結(jié)構(gòu)化的數(shù)據(jù)存儲。但是缺點是并不支持復雜查詢,同時并沒有支持跨行事務。我認為 HBase 是一個 CP 的系統(tǒng)。沒有官方的 SQL 支持,有一些第三方的公司做了 SQL on HBase (比如 Phoenix)但是大多都用于 OLAP 領(lǐng)域,面向 OLTP 的不多。 Cassandra 來自 Dynamo 的模型,比較大的特點是,C* 可以根據(jù)業(yè)務的需求進行決定它是 CP 還是 AP(最終一致性),C* 采用的 WRN 模型,當 W + R > N 的時候是 CP 系統(tǒng),W+R <= N 時是 AP 系統(tǒng),但是擁有最終一致性,其中 W 代表寫入幾個節(jié)點算成功,R 表示讀幾個節(jié)點算成功,N 是可寫入多少節(jié)點。C* 2.0+ 支持了 CAS 算是支持了單行事務。C* 的讀寫性能略優(yōu)于 HBase(http://www./nosql-performance-benchmarks/)但是我認為吧,在分布式系統(tǒng)中的單機 benchmark 其實意義不大,因為系統(tǒng)都是可以水平擴展的,能滿足需求即可。 MongoDB Cluster 網(wǎng)上吐槽的非常多,個人不太熟悉,就不評論了。 以上 NoSQL 的問題是,接口表達力相比 SQL 而言差了很多,對于很多現(xiàn)有業(yè)務來說,從 RDBMS 重構(gòu)至 NoSQL 基本無異于重寫。所以問題就來了,我們能不能既享受 NoSQL 帶來的擴展能力,同時又不丟失像單機一樣的事務能力,并且還能使用 SQL? 在仔細思考過這個問題后,其實并非不可能,而且實際上,有很多公司都已經(jīng)嘗試過造出了這類稱為 NewSQL 的產(chǎn)品,比如 Google 的 Spanner 和 F1 (http://research.google.com/pubs/pub41344.html ),被 Apple 收購的 FoundationDB, 近年出現(xiàn)的 CockroachDB,TiDB 等,都是主打提供 SQL 及分布式事務的數(shù)據(jù)庫產(chǎn)品。 這類數(shù)據(jù)庫的模型都比較統(tǒng)一:即在下層提供一個支持事務的分布式 KV 層,上層構(gòu)造 SQL Layer,將 SQL 語句翻譯成 KV 的事務操作,進而實現(xiàn)在分布式存儲上的帶事務的 SQL 的支持。實際上單機數(shù)據(jù)庫的模型也在往這個方向上靠,比如 sqlite4, MySQL。 我們接下來從上到下,以 TiDB 為例看看如何實現(xiàn)一個分布式數(shù)據(jù)庫,先上架構(gòu)圖 由于篇幅原因,以下主要說說 SQL Layer 和 KV。 1. SQL Layer 寫一個 SQL Layer 第一步考慮的是 Lexer 和 Parser ,做詞法和語法解析,生成語法樹。值得一提的是,整個 TiDB是用純 Go 開發(fā)的,在 Go 的世界里,官方是推薦使用 yacc 來進行語言應用的開發(fā),Go 官方也提供了 yacc 的工具。至于 yacc 的語法在這里就不提了,我們使用了一個開源的 Parser 生成器, cznic/goyacc 和 cznic/ebnf2y (打個廣告: http://github.com/cznic 這個歪國朋友做了很多 go 來開發(fā)語言應用的工具,同時還是一個 go 的嵌入式數(shù)據(jù)庫 ql 的作者,目前也在給 TiDB 貢獻 Parser 部分的代碼) 。 其中 ebnf2y 是一個 EBNF to Yacc 的轉(zhuǎn)換工具,可以通過 EBNF(主要是 EBNF 比較好寫 :D ) 生成一個 Go 版本的 yacc 文件。然后用這個 yacc 文件通過 goyacc 生成 Paser 的 Go 代碼。詞法分析器是通過 cznic/golex 工具生成的。詳細的例子可以參考 TiDB 根目錄下的 parser 文件夾和 Makefile,有完整的實現(xiàn)。 TiDB 是支持大部分常用的 MySQL 語法的(CRUD, JOIN,GROUP BY...)Anyway 雖然比較苦逼,這步算是基本完成了,現(xiàn)在 TiDB 應該擁有 Go 的項目中最完整的 MySQL yacc/lex 文法實現(xiàn),可以生成語法樹。而且相對獨立,如果有朋友對類 SQL 的語法感興趣,想實現(xiàn)一個小數(shù)據(jù)庫的話,可以參考一下 :) 運行時通過 Parser 編譯 SQL 語句拿到 AST(抽象語法樹)后,下一步是生成查詢計劃,會根據(jù)不同的語句類型,生成執(zhí)行計劃 Plan。值得注意的是,Plan 并不是的一個孤立的東西,多個 Plan 其實是可以疊加執(zhí)行的。形成一個 Plan Tree。 例如一個最簡單的例子: SELECT * FROM t WHERE id > 0; 通過 Parser 會生成一個 SelectStmt 對象,它的 Plan 是 :第一步會從AST 結(jié)構(gòu)的 From 成員中生成一個 TableDefaultPlan(t)(默認掃全表,從頭到尾)。然后從 Where 子句中構(gòu)造出 Plan 的時候會將上一步生成的 TableDefaultPlan 作為參數(shù)傳入, 然后根據(jù) Where 的表達式來決定到底是不是轉(zhuǎn)換成 IndexPlan(使用索引掃表)或者是直接生成一個 FilterDefaultPlan(在上一個 Plan 的執(zhí)行過程中上疊加一個 Filter 操作)。簡單來說,Plan 就是根據(jù)語句的語法元素來決定應該如何對數(shù)據(jù)集進行掃描,生成結(jié)果集的一系列方法。 在傳統(tǒng)的數(shù)據(jù)庫中,生成好 Plan Tree 以后,會進行執(zhí)行計劃的優(yōu)化,有很多查詢優(yōu)化的理論就不一一細說了,目前 TiDB 并沒有太多的查詢優(yōu)化(但是最基本的索引識別還是有的),目前的理論多是針對單機的數(shù)據(jù)庫的查詢優(yōu)化,但是在分布式系統(tǒng)中如何進行優(yōu)化,是一個有待探討的課題,我們未來也會在這方面進行一些嘗試。 這里就不細說了,這個話題展開能寫一本書。。。實際上我們也確實準備寫本書,而且 REPO 也建立了,見 https://github.com/ngaut/builddatabase 到這一步為止還是停留在比較正統(tǒng)的 SQL Layer 的實現(xiàn)階段,下面我們介紹事務 KV 引擎,這部分是實現(xiàn)整個系統(tǒng)的核心。 2. 分布式事務 當你有一個支持跨行事務的 kv 層時,在上層構(gòu)建 SQL 引擎就會方便很多。但是就像上文提到的目前的 NoSQL 很少有能支持這個的,但是也不是沒法搞,而且基本上就只有一種辦法,2PC(二階段提交),或者性能更差的 3PC, 很多算法都是在 2PC 上進行的優(yōu)化。 簡單提一下 2PC,在事務開始的時候,協(xié)調(diào)者第一階段會將要修改的內(nèi)容發(fā)給各個事務的參與者,參與者將事務內(nèi)容寫入本地 WAL 后回復OK給協(xié)調(diào)者,當協(xié)調(diào)者收到所有的參與者回復后,協(xié)調(diào)者再次向所有參與者發(fā)送 Commit(或者 Abort) 指令,并在事務狀態(tài)表里標記該事務為成功(失?。?。 在 2PC 中我們還是可以看到幾個不太協(xié)調(diào)的東西,一個協(xié)調(diào)者的選取,另一個是事務狀態(tài)表的一致性如何保證,還有就是如何實現(xiàn)事務的隔離性。 先說協(xié)調(diào)者的問題,在傳統(tǒng)的 2PC 中,為了實現(xiàn)分布式事務的一致性(先提交的事務的結(jié)果,需要被后發(fā)起的事務看到),當有多個協(xié)調(diào)者的時候,如何實現(xiàn)事務的時序呢?單協(xié)調(diào)者肯定不能忍受,在這點上 Google 有很多嘗試,比如在 Percolator 中采用中心授時服務器(不會是單點,應該是一個 Paxos Group),在 Spanner 中使用高度同步的原子鐘,就是為了解決標記事務的先后。 事務狀態(tài)表,這個是用來查詢已成功事務的,在第二階段的 Commit 過程中,理論上協(xié)調(diào)者是不需要收到所有參與者的返回的,因為收到第一階段所有參與者的成功返回后(寫入 WAL),就可以標記事務成功,如果第二階段有人掛了,當它恢復的時候,第一步會去事務狀態(tài)表中詢問這個事務是否已經(jīng)被標記成功,如果成功的話,就寫入本地庫,如果不成功的話,就丟棄 WAL。這個狀態(tài)表修改是不需要跨行事務的,所以使用傳統(tǒng)的做法,sharding 或者按照 range 存儲即可,但是考慮到這個表的讀請求可能會比較大(因為新開始事務需要知道當前最新的事務號,以支持 MVCC),可以通過 Paxos 做多副本。 接下來說到事務的隔離性,在我們的系統(tǒng)中,提供 SI 和 SI+ 樂觀鎖 兩個級別,對應到 MySQL 里面SI+ 樂觀鎖 可以理解為 select for update 語句,但行為略有不同。所以,我們需要實現(xiàn) MVCC,上一段中我們已經(jīng)知道每個事務都會對應一個事務編號,而且這個事務編號是全局有序的。 當我開始新事務 y 的時候,我需要得知我當前的最新已提交事務號 x,然后在我的 y 事務中看到的整個數(shù)據(jù)庫的視圖都是這個事務 x 完成后的狀態(tài)(即使在 y 開始后,有其他的事務 x' 提交,y 是看不到 x' 的內(nèi)容的)。 實現(xiàn)這一點并不困難,底層存儲引擎支持的話,比如 LevelDB 內(nèi)部就已經(jīng)實現(xiàn)了(參考 Snapshot 實現(xiàn)),LMDB 也是一個在 MVCC-BTree 的實現(xiàn)。TiDB 的可插拔的存儲引擎設計可以很方便的實現(xiàn)。比較 tricky 的是沖突的解決策略,在實際的場景中,比如剛才 y 事務開始后,x' 修改了 y 事務中修改的某個行 r,因為有 SI 此時 y 事務是不知道 r 已經(jīng)被修改擁有更新的版本號,此時比較合理的做法是讓 y 事務回滾,然后重試,在 TiDB 中也是這么做的。 TiDB 做了接口的嚴格分層,將 KV 存儲的接口和 SQL Layer 分離得比較徹底,目前本地的存儲引擎 (LevelDB, RocksDB, LMDB, BoltDB) 都已經(jīng)支持,分布式引擎目前第一階段打算采用了 HBase + Coprocessor 來實現(xiàn),分布式事務模型采用 Google 的 Percolator 模型,近期將會開源。 下面我們從TIDB的代碼層面看看一些更細節(jié)的實現(xiàn)。 首先是執(zhí)行方法:
明顯可以看到代碼分為編譯和執(zhí)行兩個步驟,相信很多同學再一次想起大學的編譯原理課程了吧 :) 我們再來看看編譯過程,也可以看到明確的兩個步驟,詞法分析和語法分析
看看最后生成的語法樹長什么樣子:
接下來我們以查詢?yōu)槔賮砜聪?,select語句構(gòu)造邏輯大概是這樣的:
有興趣的同學可以看下具體的代碼,這里我們就先不介紹了,我們繼續(xù):) SQL層如何映射到KV層 最終所有的操作都會映射到 KV 層,我們來看一個簡單的例子,假設有一個 user 表:
如果支持 select uid, name, email from user; 最終會變成哪些 KV 操作呢? 在 TiDB 里面,所有的表都有一個唯一的ID, 所有的列也都有唯一的ID,假設 user 表的 ID 為1, uid 的 ID 為2,name的 ID 為3, email的 ID 為 4。那么最后存儲在 KV 層的大概是這樣的: 整個key的邏輯結(jié)構(gòu): TableID : RowID : ColumnID 一個具體的例子 Key Value 1 : 1 : 1 nil 1 : 1 : 2 xx 1 : 1 : 3 bob 1 : 1 : 4 bob@email.com 第一個1是表的 ID, 第二個是RowID, 第三個是列的 ID,冒號表示分隔符 上面的SQL語句最終會被映射成指令: uid := kv.Get( “ 1 : 1 : 2 ” ) name := kv.Get( “ 1 : 1 : 3 " ) email := kv.Get( “ 1 : 1 : 4 " ) 其它語句類似,會被翻譯成相應的 Put 和 Delete 操作,詳細的請參考 TiDB 源碼。 下面我們聊聊 TiDB 的索引實現(xiàn) 還是以上面的表為例,在name上面建立唯一索引,最后存儲的索引KV大概是這樣的(idx表示index): Key Value 1 : Idx : 3 : bob 1 這里的Value就是實際上的RowID 這樣如果遇到語句 select email from user where name = ‘bob’; 的時候就會自動通過索引來找到 RowID,然后通過 RowID 做一次 kv.Get 操作就能拿到。 類似的,非唯一索引可以通過添加一個RowID的后綴到 key 后面,假設系統(tǒng)里面有兩個 bob, 那么實際存儲格式大概是這樣的: Key Value 1 : Idx : 3 : bob : 1 1 1 : Idx : 3 : bob : 2 2 實際的代碼做了適當?shù)膬?yōu)化,這里只是為了便于理解。 聊到這里,是不是大家對如何實現(xiàn)多引擎支持都比較好奇呢?我們繼續(xù)看看這個:) 默認 TiDB 單機模式使用 Goleveldb 和 BoltDB 作為存儲引擎和測試引擎,因為這兩個都是純go實現(xiàn),沒有依賴,但性能都不好 :( 我們來看看 Transaction的接口,從這個接口也能看出對底層存儲引擎的要求
由于需要 seek,所以底層的存儲引擎的 KV 必須是有序的,能夠 scan。對于一個事務內(nèi)的所有寫操作都是先 buffer 住,最后 commit 時才提交,所以對單機的 KV 引擎來講,支持 Batch 寫入的原子操作即可,即使不支持也可以通過 lock 的方式來搞定。同時由于合理的抽象, TiDB 能夠輕松支持多個存儲引擎。TiDB 自然也可以作為一個很好的 bench 工具, 大家可以用來bench 各種存儲引擎了 :) 為了便于大家理解,或者想給TiDB添加新的引擎支持,我們寫了 lmdb 的引擎的例子,只用了大約200行代碼,見 https://github.com/pingcap/tidb-lmdb 開源的心得 下面想和大家聊一下怎么做開源,算是這幾個月來的小小的感悟吧。 關(guān)于如何做開源,在中國鮮有認真做開源項目的商業(yè)公司,這和整個浮躁的大環(huán)境是分不開的,很多國內(nèi)的開源項目基本就只是 Push 代碼到 Github 上而已,有的甚至就再也不更新了。我個人認為優(yōu)秀的開源項目是社區(qū)和商業(yè)公司支持缺一不可的,特別是基礎(chǔ)軟件領(lǐng)域。 TiDB 的目標是做一個全球性的開源項目,所以我們非??桃獾娜I造社區(qū)的氛圍,比如我們選擇一個比較早期的版本的時間點開源,早期一些比較容易修改和上手的 Bug 會可以留下來,吸引社區(qū)的愛好者來修改。Github 已經(jīng)搭建了一個非常好的代碼協(xié)作平臺,我們不管是公司內(nèi)部的私有項目還是外部的開源項目,都是完全通過 Github 協(xié)作的(有機會我可以講講我們 PingCAP 的工作流) btw,提交的 patch 被合并到主干后,我們都會給這個 contributor 郵寄一件我們的 t-shirt :) 另外提交 PR 也需要相應的標準和格式,TiDB 的標準見 https://github.com/pingcap/tidb/blob/master/docs/CONTRIBUTING.md 對于TiDB而言,通過 https://github.com/pingcap/tidb/issues/158 參與項目是最好的切入點,由于MySQL有大量 builtin 的函數(shù),目前TiDB只實現(xiàn)了一部分。 比較值得注意的是,文檔,README 和 Issues 及討論必須需要英文書寫,否則很難吸引外國的社區(qū)貢獻,這個也是大多數(shù)國內(nèi)開源項目通病。 TiDB 的計劃是: 1. 繼續(xù)完善 SQL 層,更完整的兼容 MySQL 語法。 2. 實現(xiàn)異步 Schema 變更,在分布式系統(tǒng)中,DDL 是不容許阻塞的,這個算法比較巧妙,可以參考 Google 的一篇論文(http://research.google.com/pubs/pub41376.html) 3. 繼續(xù)開發(fā) HBase 的引擎,第一個可以在生產(chǎn)環(huán)境中使用的版本應該是搭載 HBase 引擎的 4. 更長期的計劃是去掉 HBase,構(gòu)建自己的 Kv 層,畢竟 HBase 并不是為 SQL 優(yōu)化的 Kv,而且在依賴太重,我個人不太喜歡 Hadoop,非常難容器化。 5. 多租戶 6. 容器化 由于時間關(guān)系,我們今天的分享就先到這里了,感謝大家的支持:) 以后有機會,我們再聊聊下面的東西: HBase的分布式事務實現(xiàn),以及TiDB如何讓HBase擁有SQL能力 MySQL協(xié)議支持,更重要的哲學問題是為什么選擇支持MySQL協(xié)議 如何在KV的引擎上實現(xiàn)行鎖 隔離級別的選擇,select for update語句的特殊處理 如何用HLC實現(xiàn)去中心化的事務管理 在線異步動態(tài)schema變更 Q&A 1 事務狀態(tài)表如何解決單點問題 多副本,比如通過Paxos或者Raft等一致性協(xié)議 2. TiDB和MySQL的區(qū)別是什么?能不能編譯到一起Go應用里面 可以把 TiDB 理解成一個無比強大的分布式 MySQL, MySQL 自身主要是單機的。 可以和Go應用編譯到一起:) 3. TiDB目前的roadmap是什么?什么時候可以應用于產(chǎn)品中,后期API會不會改變很多? TiDB 的計劃是: 1. 繼續(xù)完善 SQL 層,更完整的兼容 MySQL 語法。 2. 實現(xiàn)異步 Schema 變更,在分布式系統(tǒng)中,DDL 是不容許阻塞的,這個算法比較巧妙,可以參考 Google 的一篇論文(http://research.google.com/pubs/pub41376.html) 3. 繼續(xù)開發(fā) HBase 的引擎,第一個可以在生產(chǎn)環(huán)境中使用的版本應該是搭載 HBase 引擎的 4. 更長期的計劃是去掉 HBase,構(gòu)建自己的 Kv 層,畢竟 HBase 并不是為 SQL 優(yōu)化的 Kv,而且在依賴太重,我個人不太喜歡 Hadoop,非常難容器化。 5. 多租戶 6. 容器化 我們目前主要兼容 MySQL 協(xié)議,所以接口比較穩(wěn)定,直接使用 MySQL 客戶端就可以,現(xiàn)在我們已經(jīng)支持了各種ORM,比如Beego, Xorm等等。 4 分布式事務目前是否只支持hbase 是的,暫時是的 5. Why choose golang to build a database? Golang的開發(fā)和運行效率都很理想,Go語言官方有很好的規(guī)范,統(tǒng)一的風格和標準,我們都很喜歡它:) 6. 請問事務更新沖突為什么不采用行級鎖?其他被回滾的事務如果在被發(fā)現(xiàn)沖突前已經(jīng)結(jié)束怎么處理? TiDB 采用了行鎖,上面也提到,由于時間關(guān)系,沒有來得及詳細講,后面的問題沒看明白,請詳細描述下:) 7.分布式kv如何做到任意擴展? Sharding, split, merge 8. 如采用raft之類做事務狀態(tài)表,對吞吐量有多大影響? 事務狀態(tài)表也可以分配一個key,讓狀態(tài)合理散落到整個分布式系統(tǒng)里面,不存在性能瓶頸 9. 是否對比過如mysql ndb cluster,相對這類實現(xiàn)有哪些優(yōu)缺點? MySQL上面的cluster由于局限于MySQL本身,在分布式上面受到的約束很多,類似PG的xc,好多年都很難有突破性的進展,這方面其它的分布式數(shù)據(jù)庫基本都選擇了一開始就朝著分布式去做設計,優(yōu)缺點見上面的 roadmap, 里面很多東西基于MySQL的方案都很難搞定 10. "事務狀態(tài)表,這個是用來查詢已成功事務的,在第二階段的 Commit 過程中,理論上協(xié)調(diào)者是不需要收到所有參與者的返回的,因為收到第一階段所有參與者的成功返回后(寫入 WAL),就可以標記事務成功,如果第二階段有人掛了,當它恢復的時候,第一步會去事務狀態(tài)表中詢問這個事務是否已經(jīng)被標記成功,如果成功的話,就寫入本地庫,如果不成功的話,就丟棄 WAL。"——這個能否再說明一下,既然第二階段有人掛了,為什么去查詢第一階段為成功以后,還是繼續(xù)寫入本地? 由于多副本存在,而且前面已經(jīng)有了wal,所以其它副本會接替掛了的,繼續(xù)apply wal就行 11. 抽象語法樹這塊是不是類似web中的路由樹的構(gòu)建? 這個有點像,又不太像,抽象語法樹一般用于編譯領(lǐng)域比較多 12. NuoDB對比F1 TiDB 如何? NuoDB不太清楚,也沒怎么見到用戶使用,TiDB 基本上是朝著F1作為目標去的,F(xiàn)1是Google出品目前全球最好的分布式OLTP數(shù)據(jù)庫 |
|
|
來自: dazheng > 《數(shù)據(jù)庫》