摘要:我司申礫在上分享了產(chǎn)品進(jìn)化過程中的思考與未來規(guī)劃。第一點(diǎn)是對(duì)整個(gè)聚合框架做了優(yōu)化,就是從一行一行處理的聚合模式,變成了一批一批數(shù)據(jù)處理的聚合模式,另外我們還在哈希聚合算子上做了并行。
我司 Engineering VP 申礫在 TiDB DevCon 2019 上分享了 TiDB 產(chǎn)品進(jìn)化過程中的思考與未來規(guī)劃。本文為演講實(shí)錄上篇,重點(diǎn)回顧了 TiDB 2.1 的特性,并分享了我們對(duì)「如何做一個(gè)好的數(shù)據(jù)庫」的看法。
感謝這么多朋友的到場(chǎng),今天我會(huì)從我們的一些思考的角度來回顧過去一段時(shí)間做了什么事情,以及未來的半年到一年時(shí)間內(nèi)將會(huì)做什么事情,特別是「我們?yōu)槭裁匆鲞@些事情」。
TiDB 這個(gè)產(chǎn)品,我們從 2015 年年中開始做,做到現(xiàn)在,三年半,將近四年了,從最早期的 Beta 版的時(shí)候就開始上線,到后來 RC 版本,最后在 2017 年終于發(fā)了 1.0,開始鋪了一部分用戶,到 2.0 的時(shí)候,用戶數(shù)量就開始漲的非常快。然后我們最近發(fā)了 2.1,在 2.1 之后,我們也和各種用戶去聊,跟他們聊一些使用的體驗(yàn),有什么樣的問題,包括對(duì)我們進(jìn)行吐嘈。我們就在這些實(shí)踐經(jīng)驗(yàn)基礎(chǔ)之上,設(shè)計(jì)了 3.0 的一些特性,以及我們的一些工作的重點(diǎn)?,F(xiàn)在我們正在朝 3.0 這個(gè)版本去演進(jìn),到今天早上已經(jīng)發(fā)了?3.0 Beta 版本。
TiDB 2.1首先我們來講 2.1,2.1 是一個(gè)非常重要的版本,這個(gè)版本我們吸取了很多用戶的使用場(chǎng)景中看到的問題,以及特別多用戶的建議。在這里我跟大家聊一聊它有哪些比較重要的特性。
首先我們兩個(gè)核心組件:存儲(chǔ)引擎和計(jì)算引擎,在這兩方面,我們做了一些非常重要的改進(jìn),當(dāng)然這些改進(jìn)有可能是用戶看不到的?;蛘哒f這些改進(jìn)其實(shí)我們是不希望用戶能看到的,一旦你看到了,注意到這些改進(jìn)的話,說明你的系統(tǒng)遇到這些問題了。
1. Raft 1.1 Learner大家都知道 Raft 會(huì)有 Leader 和 Follower 這兩個(gè)概念,Leader 來負(fù)責(zé)讀寫,F(xiàn)ollower 來作為 Backup,然后隨時(shí)找機(jī)會(huì)成為新的 Leader。如果你想加一個(gè)新的節(jié)點(diǎn),比如說在擴(kuò)容或者故障恢復(fù),新加了一個(gè) Follower 進(jìn)來,這個(gè)時(shí)候 Raft Group 有 4 個(gè)成員, Leader、Follower 都是 Voter,都能夠在寫入數(shù)據(jù)時(shí)候?qū)θ罩具M(jìn)行投票,或者是要在成員變更的時(shí)候投票的。這時(shí)一旦發(fā)生意外情況,比如網(wǎng)絡(luò)變更或者出現(xiàn)網(wǎng)絡(luò)分區(qū),假設(shè) 2 個(gè)被隔離掉的節(jié)點(diǎn)都在一個(gè)物理位置上,就會(huì)導(dǎo)致 4 個(gè) Voter 中 2 個(gè)不可用,那這時(shí)這個(gè) Raft Group 就不可用了。
大家可能覺得這個(gè)場(chǎng)景并不常見,但是如果我們正在做負(fù)載均衡調(diào)度或者擴(kuò)容時(shí),一旦出現(xiàn)這種情況,就很有可能影響業(yè)務(wù)。所以我們加了 Learner 這個(gè)角色,Learner 的功能也是我們貢獻(xiàn)給 etcd 這個(gè)項(xiàng)目的。有了 Learner 之后,我們?cè)跀U(kuò)容時(shí)不會(huì)先去加一個(gè) Follower(也就是一個(gè) Voter),而是增加一個(gè) Learner 的角色,它不是 Voter,所以它只會(huì)同步數(shù)據(jù)不會(huì)投票,所以無論在做數(shù)據(jù)寫入還是成員變更的時(shí)候都不會(huì)算上它。當(dāng)同步完所有數(shù)據(jù)時(shí)(因?yàn)閿?shù)據(jù)量大的時(shí)候同步時(shí)間會(huì)比較長),拿到所有數(shù)據(jù)之后,再把它變成一個(gè) Voter,同時(shí)再把另一個(gè)我們想下線的 Follower 下掉就好了。這樣就能極大的縮短同時(shí)存在 4 個(gè) Voter 的時(shí)間,整個(gè) Raft Group 的可用性就得到了提升。
其實(shí)增加 Learner 功能不只是出于提升 Raft Group 可用性,或者說出于安全角度考慮,實(shí)際上我們也在用 Learner 來做更多的事情。比如,我們可以隨便去加 Learner,然后把 Learner 變成一個(gè)只讀副本,很多很重的分析任務(wù)就可以在 Learner 上去做。TiFlash 這個(gè)項(xiàng)目其實(shí)就是用 Learner 這個(gè)特性來增加只讀副本,同時(shí)保證不會(huì)影響線上寫入的延遲,因?yàn)樗⒉粎⑴c寫入的時(shí)候投票。這樣的好處是第一不影響寫入延遲,第二有 Raft 實(shí)時(shí)同步數(shù)據(jù),第三我們還能在上面快速地做很復(fù)雜的分析,同時(shí)線上 OLTP 業(yè)務(wù)有物理上的隔離。
1.2 PreVote除了 Learner 之外,我們 2.1 中默認(rèn)開啟了 PreVote 這個(gè)功能。
我們考慮一種意外情況,就是在 Raft group 中出現(xiàn)了網(wǎng)絡(luò)隔離,有 1 個(gè)節(jié)點(diǎn)和另外 2 個(gè)節(jié)點(diǎn)隔離掉了,然后它現(xiàn)在發(fā)現(xiàn)「我找不到 Leader 了,Leader 可能已經(jīng)掛掉了」,然后就開始投票,不斷投票,但是因?yàn)樗推渌?jié)點(diǎn)是隔離開的,所以沒有辦法選舉成功。它每次失敗,都會(huì)把自己的 term 加 1,每次失敗加 1,網(wǎng)絡(luò)隔離發(fā)生一段時(shí)間之后,它的 term 就會(huì)很高。當(dāng)網(wǎng)絡(luò)分區(qū)恢復(fù)之后,它的選舉消息就能發(fā)出去了,并且這個(gè)選舉消息里面的 term 是比較高的。根據(jù) Raft 的協(xié)議,當(dāng)遇到一個(gè) term 比較高的時(shí)候,可能就會(huì)同意發(fā)起選舉,當(dāng)前的 Leader 就會(huì)下臺(tái)來參與選舉。但是因?yàn)榘l(fā)生網(wǎng)絡(luò)隔離這段時(shí)間他是沒有辦法同步數(shù)據(jù)的,此時(shí)它的 Raft Log 一定是落后的,所以即使它的 term 很高,也不可能被選成新的 Leader。所以這個(gè)時(shí)候經(jīng)過一次選舉之后,它不會(huì)成為新 Leader,只有另外兩個(gè)有機(jī)會(huì)成為新的 Leader。
大家可以看到,這個(gè)選舉是對(duì)整個(gè) Raft Group 造成了危害:首先它不可能成為新的 Leader,第二它把原有的 Leader 趕下臺(tái)了,并且在這個(gè)選舉過程中是沒有 Leader 的,這時(shí)的 Raft Group 是不能對(duì)外提供服務(wù)的。雖然這個(gè)時(shí)間會(huì)很短,但也可能會(huì)造成比較大的抖動(dòng)。
所以我們有了 PreVote 這個(gè)特性。具體是這樣做的(如圖 3):在進(jìn)行選舉之前,先用 PreVote 這套機(jī)制來進(jìn)行預(yù)選舉,每個(gè)成員把自己的信息,包括 term,Raft Log Index 放進(jìn)去,發(fā)給其它成員,其它成員有這個(gè)信息之后,認(rèn)為「我可以選你為 Leader」,才會(huì)發(fā)起真正的選舉。
有了 PreVote 之后,我們就可以避免這種大規(guī)模的一個(gè)節(jié)點(diǎn)上很多數(shù)據(jù)、很多 Raft Group、很多 Peer 的情況下突然出現(xiàn)網(wǎng)絡(luò)分區(qū),在恢復(fù)之后造成大量的 Region 出現(xiàn)選舉,導(dǎo)致整個(gè)服務(wù)有抖動(dòng)。 因此 PreVote 能極大的提升穩(wěn)定性。
2. Concurrent DDL Operation當(dāng)然除了 Raft 這幾個(gè)改進(jìn)之外,TiDB 2.1 中還有一個(gè)比較大的改進(jìn),就是在 DDL 模塊。這是我們 2.1 中一個(gè)比較顯著的特性。
在 2.1 之前的 DDL 整套機(jī)制是這樣的(如圖 4):用戶將 DDL 提交到任何一個(gè) TiDB Server,發(fā)過來一個(gè) DDL 語句,TiDB Server 經(jīng)過一些初期的檢查之后會(huì)打包成一個(gè) DDL Job,扔到 TiKV 上一個(gè)封裝好的隊(duì)列中,整個(gè)集群只有一個(gè) TiDB Server 會(huì)執(zhí)行 DDL,而且只有一個(gè)線程在做這個(gè)事情。這個(gè)線程會(huì)去隊(duì)列中拿到隊(duì)列頭的一個(gè) Job,拿到之后就開始做,直到這個(gè) Job 做完,即 DDL 操作執(zhí)行完畢后,會(huì)再把這個(gè) Job 扔到歷史隊(duì)列中,并且標(biāo)記已經(jīng)成功,這時(shí) TiDB Sever 能感知到這個(gè) DDL 操作是已經(jīng)結(jié)束了,然后對(duì)外返回。前面的 Job 在執(zhí)行完之前,后面的 DDL 操作是不會(huì)執(zhí)行的,因而會(huì)造成一個(gè)情況: 假設(shè)前面有一個(gè) AddIndex,比如在一個(gè)百億行表上去 AddIndex,這個(gè)時(shí)間是非常長的,后面的 Create Table 是非??斓模@時(shí) Create Table 操作會(huì)被 AddIndex 阻塞,只有等到 AddIndex 執(zhí)行完了,才會(huì)執(zhí)行 Create Table,這個(gè)給有些用戶造成了困擾,所以我們?cè)?TiDB 2.1 中做了改進(jìn)。
在 TiDB 2.1 中 DDL 從執(zhí)行層面分為兩種(如圖 5)。一種是 AddIndex 操作,即回填數(shù)據(jù)(就是把所有的數(shù)據(jù)掃出來,然后再填回去),這個(gè)操作耗時(shí)是非常長的,而且一些用戶是線上場(chǎng)景,并發(fā)度不可能調(diào)得很高,因?yàn)樵诨貙憯?shù)據(jù)的時(shí)候,可能會(huì)對(duì)集群的寫入造成壓力。
另外一種是所有其他 DDL 操作,因?yàn)椴还苁?Create Table 還是加一個(gè) Column 都是非??斓?,只會(huì)修改 metadata 剩下的交給后臺(tái)來做。所以我們將 AddIndex 的操作和其他有 DDL 的操作分成兩個(gè)隊(duì)列,每種 DDL 語句按照分類,進(jìn)到不同隊(duì)列中,在 DDL 的處理節(jié)點(diǎn)上會(huì)啟用多個(gè)線程來分別處理這些隊(duì)列,將比較慢的 AddIndex 的操作交給多帶帶的一個(gè)線程來做,這樣就不會(huì)出現(xiàn)一個(gè) AddIndex 操作阻塞其他所有 Create Table 語句的問題了。
這樣就提升了系統(tǒng)的易用性,當(dāng)然我們下一步還會(huì)做進(jìn)一步的并行, 比如在 AddIndex 時(shí),可以在多個(gè)表上同時(shí) AddIndex,或者一個(gè)表上同時(shí) Add 多個(gè) Index。我們也希望能夠做成真正并行的一個(gè) DDL 操作。
3. Parallel Hash Aggregation除了剛剛提到的穩(wěn)定性和易用性的提升,我們?cè)?TiDB 2.1 中,也對(duì)分析能力做了提升。我們?cè)诰酆系乃阕由献隽藘牲c(diǎn)改進(jìn)。 ?第一點(diǎn)是對(duì)整個(gè)聚合框架做了優(yōu)化,就是從一行一行處理的聚合模式,變成了一批一批數(shù)據(jù)處理的聚合模式,另外我們還在哈希聚合算子上做了并行。
為什么我們要優(yōu)化聚合算子?因?yàn)樵诜治鰣?chǎng)景下,有兩類算子是非常重要的,是 Join 和聚合。Join 算子我們之前已經(jīng)做了并行處理,而 TiDB 2.1 中我們進(jìn)一步對(duì)聚合算子做了并行處理。在哈希聚合中,我們?cè)谝粋€(gè)聚合算子里啟用多個(gè)線程,分兩個(gè)階段進(jìn)行聚合。這樣就能夠極大的提升聚合的速度。
圖 7 是 TiDB 2.1 發(fā)布的時(shí)候,我們做了一個(gè) TPC-H Benchmark。實(shí)際上所有的 Query 都有提升,其中 Q17 和 Q18 提升最大。因?yàn)樵?TiDB 2.0 測(cè)試時(shí),Q17、Q18 還是一個(gè)長尾的 Query,分析之后發(fā)現(xiàn)瓶頸就在于聚合算子的執(zhí)行。整個(gè)機(jī)器的 CPU 并不忙,但就是時(shí)間很長,我們做了 Profile 發(fā)現(xiàn)就是聚合的時(shí)間太長了,所以在 TiDB 2.1 中,對(duì)聚合算子做了并行,并且這個(gè)并行度可以調(diào)節(jié)。
4. Ecosystem ToolsTiDB 2.1 發(fā)布的時(shí)我們還發(fā)布了兩個(gè)工具,分別叫 TiDB-DM 和?TiDB-Lightning。
TiDB-DM 全稱是 TiDB Data Migration,這個(gè)工具主要用來把我們之前的 Loader 和以及 Syncer 做了產(chǎn)品化改造,讓大家更好用,它能夠做分庫分表的合并,能夠只同步一些表中的數(shù)據(jù),并且它還能夠?qū)?shù)據(jù)做一些改寫,因?yàn)榉謳旆直砗喜⒌臅r(shí)候,數(shù)據(jù)合到一個(gè)表中可能會(huì)沖突,這時(shí)我們就需要一種非常方便、可配置的工具來操作,而不是讓用戶手動(dòng)的去調(diào)各種參數(shù)。
TiDB-Lightning 這個(gè)工具是用來做全量的數(shù)據(jù)導(dǎo)入。之前的 Loader 也可以做全量數(shù)據(jù)導(dǎo)入,但是它是走的最標(biāo)準(zhǔn)的那套 SQL 的流程,需要做 SQL 的解析優(yōu)化、 兩階段提交、Raft 復(fù)制等等一系列操作。但是我們覺得這個(gè)過程可以更快。因?yàn)楹芏嘤脩粝脒w移到 TiDB 的數(shù)據(jù)不是幾十 G 或者幾百 G,而是幾 T、幾十 T、上百 T 的數(shù)據(jù),通過傳統(tǒng)導(dǎo)入的方式會(huì)非常慢?,F(xiàn)在 TiDB-Lightning 可以直接將本地從 MySQL 或者其他庫中導(dǎo)出的 SQL 文本,或者是 CSV 格式的文件,直接轉(zhuǎn)成 RocksDB 底層的 SST file ,然后再注入到 TiKV 中,加載進(jìn)去就導(dǎo)入成功了,能夠極大的提升導(dǎo)入速度。當(dāng)然我們還在不斷的優(yōu)化,希望這個(gè)速度能不斷提升,將 1TB 數(shù)據(jù)的導(dǎo)入,壓縮到一兩個(gè)小時(shí)。這兩個(gè)工具,有一部分用戶已經(jīng)用到了(并且已經(jīng)正式開源)。
How to build a good database?我們有相當(dāng)多的用戶正在使用 TiDB,我們?cè)诤芏嗟膱?chǎng)景中見到了各種各樣的 Case,甚至包括機(jī)器壞掉甚至連續(xù)壞掉的情況。見了很多場(chǎng)景之后,我們就在想之后如何去改進(jìn)產(chǎn)品,如何去避免在各種場(chǎng)景中遇到的「坑」,于是我們?cè)诟钊氲厮伎家粋€(gè)問題:如何做一個(gè)好的數(shù)據(jù)庫。因?yàn)樽鲆粋€(gè)產(chǎn)品其實(shí)挺容易的,一個(gè)人兩三個(gè)月也能搞一套數(shù)據(jù)庫,不管是分庫分表,還是類似于在 KV 上做一個(gè) SQL,甚至做一個(gè)分布式數(shù)據(jù)庫,都是可能在一個(gè)季度甚至半年之內(nèi)做出來的。但是要真正做一個(gè)好的數(shù)據(jù)庫,做一個(gè)成熟的數(shù)據(jù)庫,做一個(gè)能在生產(chǎn)系統(tǒng)中大規(guī)模使用,并且能夠讓用戶自己玩起來的數(shù)據(jù)庫,其實(shí)里面有非常多工作要做。
首先數(shù)據(jù)庫最基本的是要「有用」,就是能解決用戶問題。而要解決用戶問題,第一點(diǎn)就是要知道用戶有什么樣的問題,我們就需要跟各類用戶去聊,看用戶的場(chǎng)景,一起來分析,一起來獲得使用場(chǎng)景中真實(shí)存在的問題。所以最近我們有大量的同事,不管是交付的同事還是研發(fā)的同事,都與用戶做了比較深入的訪談,聊聊用戶在使用過程中有什么的問題,有什么樣的需求,用戶也提供各種各樣的建議。我們希望 TiDB 能夠很好的解決用戶場(chǎng)景中存在的問題,甚至是用戶自己暫時(shí)還沒有察覺到的問題,進(jìn)一步的滿足用戶的各種需求。
第二點(diǎn)是「易用性」。就好像一輛車,手動(dòng)擋的大家也能開,但其實(shí)大家現(xiàn)在都想開自動(dòng)擋。我們希望我們的數(shù)據(jù)庫是一輛自動(dòng)擋的車,甚至未來是一輛無人駕駛的車,讓用戶不需要關(guān)心這些事情,只需要專注自己的業(yè)務(wù)就好了。所以我們會(huì)不斷的優(yōu)化現(xiàn)有的解決方案,給用戶更多更好的解決方案,下一步再將這些方案自動(dòng)化,讓用戶用更低的成本使用我們的數(shù)據(jù)庫。
最后一點(diǎn)「穩(wěn)定性」也非常重要,就是讓用戶不會(huì)用著用著擔(dān)驚受怕,比如半夜報(bào)警之類的事情。而且我們希望 TiDB 能在大規(guī)模數(shù)據(jù)集上、在大流量上也能保持穩(wěn)定。
未完待續(xù)...
下篇將于明日推送,重點(diǎn)介紹 TiDB 3.0 Beta 在穩(wěn)定性、易用性和功能性上的提升,以及 TiDB 在 Storage Layer 和 SQL Layer 方面的規(guī)劃。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/17924.html
摘要:本文為我司申礫在上的演講實(shí)錄。雖然這個(gè)線程做的事情已經(jīng)足夠簡(jiǎn)單,但是因?yàn)樯纤械亩紩?huì)通過一個(gè)線程來驅(qū)動(dòng)自己的狀態(tài)機(jī),所以當(dāng)壓力足夠大的時(shí)候就會(huì)成為瓶頸。 本文為我司 Engineering VP 申礫在 TiDB DevCon 2019 上的演講實(shí)錄。在?上篇?中,申礫老師重點(diǎn)回顧了 TiDB 2.1 的特性,并分享了我們對(duì)「如何做好一個(gè)數(shù)據(jù)庫」的看法。本篇將繼續(xù)介紹 TiDB 3.0...
摘要:另外,我們?yōu)榻搪毴藛T和在校學(xué)生提供學(xué)術(shù)優(yōu)惠票價(jià),僅限優(yōu)惠碼注冊(cè),申請(qǐng)材料教職人員校園網(wǎng)站個(gè)人信息頁截圖或教師資格證本人身份證掃描件在校學(xué)生本人有效學(xué)生證本人身份證掃描件請(qǐng)將申請(qǐng)材料發(fā)送到,審核結(jié)果將通過郵件通知。優(yōu)惠碼申請(qǐng)截止時(shí)間月日。 年度最高規(guī)格的 TiDB 技術(shù)大會(huì)海內(nèi)外動(dòng)態(tài)及成果的綜合呈現(xiàn)最新核心技術(shù)解讀多個(gè)成果首次亮相2019 RoadMap 展望14 位海內(nèi)外基礎(chǔ)架構(gòu)領(lǐng)域技...
閱讀 3850·2021-11-11 11:02
閱讀 3562·2021-10-11 10:57
閱讀 3693·2021-09-22 16:00
閱讀 1970·2021-09-02 15:15
閱讀 1405·2019-08-30 15:56
閱讀 1089·2019-08-30 15:54
閱讀 2836·2019-08-30 12:43
閱讀 3620·2019-08-29 16:06