Kudu:一個融合低延遲寫入和高性能分析的存儲系統(tǒng)

Kudu 是一個基于 Raft 的分布式存儲系統(tǒng)瘟仿,它致力于融合低延遲寫入和高性能分析這兩種場景桑嘶,并且能很好的嵌入到 Hadoop 生態(tài)系統(tǒng)里面,跟其他系統(tǒng)譬如 Cloudera Impala伯顶,Apache Spark 等對接揽趾。

Kudu 很類似 TiDB。最開始亭姥,TiDB 是為了 OLTP 系統(tǒng)設(shè)計的稼钩,但后來發(fā)現(xiàn)我們 OLAP 的功能也越來越強大,所以就有了融合 OLTP 和 OLAP 的想法达罗,當(dāng)然這條路并不是那么容易坝撑,我們還有很多工作要做。因為 Kudu 的理念跟我們類似粮揉,所以我也很有興趣去研究一下它巡李,這里主要是依據(jù) Kudu 在 2015 發(fā)布的 paper,因為 Kudu 是開源的扶认,并且在不斷的更新侨拦,所以現(xiàn)在代碼里面一些實現(xiàn)可能還跟 paper 不一樣了,但這里僅僅先說一下我對 paper 的理解辐宾,實際的代碼我后續(xù)研究了在詳細(xì)說明狱从。

為什么需要 Kudu膨蛮?

結(jié)構(gòu)化數(shù)據(jù)存儲系統(tǒng)在 Hadoop 生態(tài)系統(tǒng)里面,通常分為兩類:

  • 靜態(tài)數(shù)據(jù)季研,數(shù)據(jù)通常都是使用二進制格式存放到 HDFS 上面敞葛,譬如 Apache Avro,Apache Parquet与涡。但無論是 HDFS 還是相關(guān)的系統(tǒng)惹谐,都是為高吞吐連續(xù)訪問數(shù)據(jù)這些場景設(shè)計的,都沒有很好的支持單獨 record 的更新驼卖,或者是提供好的隨機訪問的能力氨肌。
  • 動態(tài)數(shù)據(jù),數(shù)據(jù)通常都是使用半結(jié)構(gòu)化的方式存儲酌畜,譬如 Apache HBase怎囚,Apache Cassandra。這些系統(tǒng)都能低延遲的讀寫單獨的 record檩奠,但是對于一些像 SQL 分析這樣需要連續(xù)大量讀取數(shù)據(jù)的場景桩了,顯得有點捉緊見拙附帽。

上面的兩種系統(tǒng)埠戳,各有自己的側(cè)重點,一類是低延遲的隨機訪問特定數(shù)據(jù)蕉扮,而另一類就是高吞吐的分析大量數(shù)據(jù)整胃。之前,我們并沒有這樣的系統(tǒng)可以融合上面兩種情況喳钟,所以通常的做法就是使用 pipeline屁使,譬如我們非常熟悉的 Kafka,通常我們會將數(shù)據(jù)快速寫到 HBase 等系統(tǒng)里面奔则,然后通過 pipeline蛮寂,在導(dǎo)出給其它分析系統(tǒng)。雖然我們在一定層面上面易茬,我們其實通過 pipeline 來對整個系統(tǒng)進行了解耦酬蹋,但總歸要維護多套系統(tǒng)。而且數(shù)據(jù)更新之后抽莱,并不能直接實時的進行分析處理范抓,有延遲的開銷。所以在某些層面上面食铐,并不是一個很好的解決方案匕垫。

Kudu 致力于解決上面的問題,它提供了簡單的來處理數(shù)據(jù)的插入虐呻,更新和刪除象泵,同時提供了 table scan 來處理數(shù)據(jù)分析寞秃。通常如果一個系統(tǒng)要融合兩個特性,很有可能就會陷入兩邊都做偶惠,兩邊都沒做好的窘境蜕该,但 Kudu 很好的在融合上面取得了平衡,那么它是如何做到的呢洲鸠?

Keyword

Tables 和 schemas

Kudu 提供了 table 的概念堂淡。用戶可以建立多個 table,每個 table 都有一個預(yù)先定義好的 schema扒腕。Schema 里面定義了這個 table 多個 column绢淀,每個 column 都有名字,類型瘾腰,是否允許 null 等皆的。一些 columns 組成了 primary key。

可以看到蹋盆,Kudu 的數(shù)據(jù)模型非常類似關(guān)系數(shù)據(jù)庫费薄,在使用之前,用戶必須首先建立一個 table栖雾,訪問不存在的 table 或者 column 都會報錯楞抡。用戶可以使用 DDL 語句添加或者刪除 column,但不能刪除包含 primary key 的 column析藕。

但在 Paper 里面說到 Kudu 不支持二級索引以及除了 primary key 之外的唯一索引召廷,這個后續(xù)可以通過更新的代碼來確定下。

其實我這里非常關(guān)注的是 Kudu 的 Online DDL 是如何做的账胧,只是 Paper 里面貌似沒有提及竞慢,后面只能看代碼了。

API

Kudu 提供了 Insert治泥,Update 和 Delete 的 write API筹煮。不支持多行事務(wù) API,這個不知道最新的能支持了沒有居夹,因為僅僅能對單行數(shù)據(jù)操作败潦,還遠(yuǎn)遠(yuǎn)不夠。

Kudu 提供了 Scan read API 讓用戶去讀取數(shù)據(jù)吮播。用戶可以指定一些特定的條件來過濾結(jié)果变屁,譬如用一個常量跟一個 column 里面的值比較,或者一段 primary key 的范圍等條件意狠。

提供 API 的好處在于實現(xiàn)簡單粟关,但對于用戶來說,其實更好的使用方式仍然是 SQL,一些復(fù)雜的查詢最好能通過 SQL 搞定闷板,而不是讓用戶自己去 scan 數(shù)據(jù)澎灸,然后自己組裝。

一致性模型

Kudu 提供兩種一致性模型:snapshot consistency 和 external consistency遮晚。

默認(rèn) Kudu 提供 Snapshot consistency性昭, 它具有更好的讀性能,但可能會有 write skew 問題县遣。而 External consistency 則能夠完全保證整個系統(tǒng)的 linearizability糜颠,也就是當(dāng)寫入一條數(shù)據(jù)之后,后面的任何讀取都一定能讀到最新的數(shù)據(jù)萧求。

為了實現(xiàn) External consistency其兴,Kudu 提供了幾種方法:

  • 在 clients 之間顯示的傳遞時間戳。當(dāng)寫入一條數(shù)據(jù)之后夸政,用戶用要求 client 去拿一個時間戳作為 token元旬,然后通過一個 external channel 的方式傳遞給另一個 client。然后另一個 client 就可以通過這個 token 去讀取數(shù)據(jù)守问,這樣就一定能保證讀取到最新的數(shù)據(jù)了匀归。不過這個方法實在是有點復(fù)雜。
  • 提供類似 Spanner 的 commit-wait 機制耗帕。當(dāng)寫入一條數(shù)據(jù)之后穆端,client 需要等待一段時間來確定寫入成功。Kudu 并沒有采用 Spanner TrueTime 的方案兴垦,而是使用了 HybridTime 的方案徙赢。HybridTime 依賴 NTP字柠,這個可能導(dǎo)致 wait 的時間很長探越,但 Kudu 認(rèn)為未來隨著 read-time clock 的完善,這應(yīng)該不是問題了窑业。

Kudu 是我已知的第二個采用 HybridTime 來解決 External consistency 的產(chǎn)品钦幔,第一個當(dāng)然就是 CockroachDB 了王暗。TiDB 跟他們不一樣婴程,我們采用的是全局授時的方案,這個會簡單很多汽绢,但其實也有跟 PD 交互的網(wǎng)絡(luò)開銷西潘。后續(xù)TiDB 可能使用類似 Spanner 的 GPS + 原子鐘卷玉,現(xiàn)階段相關(guān)硬件的制造方式 Google 并沒有說明,但其實難度不大喷市。因為已經(jīng)有很多硬件廠商主動找我們希望一起合作提供相种,只是比較貴,而現(xiàn)階段我們大多數(shù)客戶并沒有跨全球事務(wù)這種場景品姓。

Kudu 的一致性模型依賴時間戳寝并,這應(yīng)該是現(xiàn)在所有分布式系統(tǒng)通用的做法箫措。Kudu 并沒有給用戶保留時間戳的概念,主要是覺得用戶很可能會困惑衬潦,畢竟不是所有的用戶都能很好的理解 MVCC 這些概念斤蔓。當(dāng)然,對于 read API镀岛,還是允許用戶指定特定的一個時間戳弦牡,這樣就能讀取到歷史數(shù)據(jù)。這個 TiDB 也是類似的做法漂羊,用戶不知道時間戳喇伯,只是我們額外提供了一個設(shè)置 snapshot 的操作,讓用戶指定生成某個時間點的快照拨与,讀取那個時間點的數(shù)據(jù)稻据。這個功能已經(jīng)幫很多公司恢復(fù)了因為錯誤操作寫壞的數(shù)據(jù)了。

架構(gòu)

上面說了一些 Kudu 的 keyword买喧, 現(xiàn)在來說說 Kudu 的整體架構(gòu)捻悯。Kudu 類似 GFS,提供了一個單獨的 Master 服務(wù)淤毛,用來管理整個集群的元信息今缚,同時有多個 Tablet 服務(wù),用來存儲實際的數(shù)據(jù)低淡。

分區(qū)

Kudu 支持對數(shù)據(jù)按照 Range 以及 Hash 的方式進行分區(qū)姓言。 每個大的 table 都可以通過這種方式將數(shù)據(jù)分不到不同的 Tablet 上面。當(dāng)用戶創(chuàng)建一個表的時候蔗蹋,同時也可以指定特定的 partition schema何荚,partition schema 會將 primary key 映射成對應(yīng)的 partition key。每個 Tablet 上面會覆蓋一段或者多段 partition keys 的range猪杭。當(dāng) client 需要操作數(shù)據(jù)的時候餐塘,它可以很方便的就知道這個數(shù)據(jù)在哪一個 Tablet 上面。

一個 partition schema 可以包括 0 或者多個 hash-partitioning 規(guī)則和最多一個 range-partitioning 規(guī)則皂吮。用戶可以根據(jù)自己實際的場景來設(shè)置不同的 partition 規(guī)則戒傻。

譬如有一行數(shù)據(jù)是 (host, metric, time, value),time 是單調(diào)遞增的蜂筹,如果我們將 time 按照 hash 的方式分區(qū)需纳,雖然能保證數(shù)據(jù)分散到不同的 Tablets 上面,但如果我們想查詢某一段時間區(qū)間的數(shù)據(jù)艺挪,就得需要全部掃描所有的 Tablets 了不翩。所以通常對于 time,我們都是采用 range 的分區(qū)方式。但 range 的方式會有 hot range 的問題慌盯,也就是同一個時間會有大量的數(shù)據(jù)寫到一個 range 上面周霉,而這個 hot range 是沒法通過 scale out 來緩解的,所以我們可以將 (host, metric) 按照 hash 分區(qū)亚皂,這樣就在 write 和 read 之間提供了一個平衡俱箱。

通過多個 partition 規(guī)則組合,能很好的應(yīng)對一些場景灭必,但同時這個這對用戶的要求比較高狞谱,他們必須更加了解 Kudu,了解自己的整個系統(tǒng)數(shù)據(jù)會如何的寫入以及查詢〗欤現(xiàn)在 TiDB 還只是單純的支持 range 的分區(qū)方式跟衅,但未來不排除也引入 hash。

Raft

Kudu 使用 Raft 算法來保證分布式環(huán)境下面數(shù)據(jù)一致性播歼,這里就不再詳細(xì)的說明 Raft 算法了伶跷,因為有太多的資料了。

Kudu 的 heartbeat 是 500 毫秒秘狞,election timeout 是 1500 毫秒叭莫,這個時間其實很頻繁,如果 Raft group 到了一定量級烁试,網(wǎng)絡(luò)開銷會比較大雇初。另外,Kudu 稍微做了一些 Raft 的改動:

  • 使用了 exponential back-off 算法來處理 leader re-election 問題减响。
  • 當(dāng)一個新的 leader 跟 follower 進行交互的時候靖诗,Raft 會嘗試先找到這兩個節(jié)點的 log 分叉點,然后 leader 再從這個點去發(fā)送 log支示。Kudu 直接是通過 committedIndex 這個點來發(fā)送刊橘。

對于 membership change,Kudu 采用的是 one-by-one 算法悼院,也就是每次只對一個節(jié)點進行變更伤为。這個算法的好處是不像 joint consensus 那樣復(fù)雜,容易實現(xiàn)据途,但其實還是會有一些在極端情況下面的 corner case 問題。

當(dāng)添加一個新的節(jié)點之后叙甸,Kudu 首先要走一個 remote bootstrap 流程颖医。

  1. 將新的節(jié)點加入到 Raft 的 configuration 里面
  2. Leader 發(fā)送 StartEmoteBootstrap RPC,新的 follower 開始拉去 snapshot 和之后的 log
  3. Follower 接受完所有數(shù)據(jù)并 apply 成功之后裆蒸,開始響應(yīng) Raft RPC

可以看到熔萧,這個流程跟 TiKV 的做法類似,這個其實有一個缺陷的。假設(shè)我們有三個節(jié)點佛致,加入第四個之后贮缕,如果新的節(jié)點還沒 apply 完 snapshot,這時候掛掉了一個節(jié)點俺榆,那么整個集群其實是沒法工作的感昼。

為了解決這個問題,Kudu 引入了 PRR_VOTER 概念罐脊。當(dāng)新的節(jié)點加入的時候定嗓,它是 PRE_VOTE 狀態(tài),這個節(jié)點不會參與到 Raft Vote 里面萍桌,只有當(dāng)這個節(jié)點接受成功 snapshot 之后宵溅,才會變成 VOTER

當(dāng)刪除一個節(jié)點的時候上炎,Leader 直接提交一個新的 configuration恃逻,刪除這個節(jié)點,當(dāng)這個 log 被 committed 之后藕施,這個節(jié)點就把刪除了辛块。被刪除的節(jié)點有可能不知道自己已經(jīng)被刪除了,如果它長時間沒有收到其他的節(jié)點發(fā)過來的消息铅碍,就會問下 Master 自己還在不在润绵,如果不在了,就自己干掉自己胞谈。這個做法跟 TiKV 也是類似的尘盼。

Master

Kudu 的 Master 是整個集群最核心的東西,類似于 TiKV 里面的 PD烦绳。在分布式系統(tǒng)里面卿捎,一些系統(tǒng)采用了無中心化的架構(gòu)設(shè)計方案,但我個人覺得径密,有一個中心化的單點午阵,能更好的用全局視角來控制和調(diào)度整個系統(tǒng),而且實現(xiàn)起來很簡單享扔。

在 Kudu 里面底桂,Master 自己也是一個單一的 Tablet table,只是對用戶不可見惧眠。它保存了整個集群的元信息籽懦,并且為了性能,會將其全部緩存到內(nèi)存上面氛魁。因為對于集群來說暮顺,元信息的量其實并不大厅篓,所以在很長一段時間,Master 都不會有 scale 的風(fēng)險捶码。同時 Master 也是采用 Raft 機制復(fù)制羽氮,來保證單點問題。

這個設(shè)計其實跟 PD 是一樣的惫恼,PD 也將所有的元信息放到內(nèi)存档押。同時,PD 內(nèi)部集成 etcd尤筐,來保證整個系統(tǒng)的可用性汇荐。跟 Kudu Master 不一樣的地方在于,PD 是一個獨立的組件盆繁,而 Kudu 的 Master 其實還是集成在 Kudu 集群里面的掀淘。

Kudu 的 Master 主要負(fù)責(zé)以下幾個事情:

Catalog manager

Master 的 catalog table 會管理所有 table 的一些元信息,譬如當(dāng)前 table schema 的版本油昂,table 的 state(creating革娄,running,deleting 等)冕碟,以及這個 table 在哪些 Tables 上面拦惋。

當(dāng)用戶要創(chuàng)建一個 table 的時候,首先 Master 在 catalog table 上面寫入需要創(chuàng)建 table 的記錄安寺,table 的 state 為 CREATING厕妖。然后異步的去選擇 Tablet servers 去創(chuàng)建相關(guān)的元信息。如果中間 Master 掛掉了挑庶,table 記錄里面的 CREATING state 會表明這個 table 還在創(chuàng)建中言秸,新的 Master leader 會繼續(xù)這個流程。

Cluster coordinator

當(dāng) Tablet server 啟動之后迎捺,會給 Master 注冊举畸,并且持續(xù)的給 Master 進行心跳匯報消后續(xù)的狀態(tài)變化。

雖然 Master 是整個系統(tǒng)的中心凳枝,但它其實是一個觀察者抄沮,它的很多信息都需要依賴 Tablet server 的上報,因為只有 Tablet server 自己知道當(dāng)前自己有哪一些 tablet 在進行 Raft 復(fù)制岖瑰,Raft 的操作是否執(zhí)行成功叛买,當(dāng)前 tablet 的版本等。因為 Tablet 的狀態(tài)變更依賴 Raft锭环,每一次變更其實就在 Raft log 上面有一個對應(yīng)的 index聪全,所以上報給 Master 的消息一定是冪等的,因為 Master 自己會比較 tablet 上報的 log index 跟當(dāng)前自己保存的 index辅辩,如果上報的 log index 是舊的难礼,那么會直接丟棄。

這個設(shè)計的好處在于極大的簡化了整個系統(tǒng)的設(shè)計玫锋,如果要 Master 自己去負(fù)責(zé)管理整個集群的狀態(tài)變更蛾茉,譬如 Master 給一個 tablet 發(fā)送增加副本的命令,然后等待這個操作完成撩鹿,在繼續(xù)處理后面的流程谦炬。整個系統(tǒng)光異常處理,都會變得特別復(fù)雜节沦,譬如我們需要關(guān)注網(wǎng)絡(luò)是不是斷開了键思,超時了到底是成功了還是失敗了,要不要再去 tablet 上面查一下甫贯?

相反吼鳞,如果 Master 只是給 tablet 發(fā)送一個添加副本的命令,然后不管了叫搁,剩下的事情就是一段時間后讓 tablet 自己上報回來赔桌,如果成功了繼續(xù)后面的處理,不成功則嘗試在加一次渴逻。雖然依賴 tablet 的上報會有延遲(通常情況疾党,只要有變動,tablet 會及時的上報通知惨奕,所以這個延遲其實挺小的)雪位,整個架構(gòu)簡單了很多。

其實看到這里的時候梨撞,我覺得非常的熟悉雹洗,因為我們也是采用的這一套架構(gòu)方案。最開始設(shè)計 PD 的時候聋袋,我們還設(shè)想的是 PD 主動去控制 TiKV队伟,也就是我上面說的那套復(fù)雜的發(fā)命令流程。但后來發(fā)現(xiàn)實在是太復(fù)雜了幽勒,于是改成 TiKV 主動上報嗜侮,這樣 PD 其實就是一個無狀態(tài)的服務(wù)了,無狀態(tài)的服務(wù)好處就是如果掛了啥容,新啟動的 PD 能立刻恢復(fù)(當(dāng)然锈颗,實際還是要做一些很多優(yōu)化工作的)。

Tablet directory

因為 Master 知道集群所有的信息咪惠,所以當(dāng) client 需要讀寫數(shù)據(jù)的時候击吱,它一定要先跟 Master 問一下對應(yīng)的數(shù)據(jù)在哪一個 Tablet server 的 tablet 上面,然后才能發(fā)送對應(yīng)的命令遥昧。

如果每次操作都從 Master 獲取信息覆醇,那么 Master 鐵定會成為一個性能瓶頸朵纷,鑒于 tablet 的變更不是特別的頻繁,所以很多時候永脓,client 會緩存訪問的 tablet 信息袍辞,這樣下次再訪問的時候就不用從 Master 再次獲取。

因為 tablet 也可能會變化常摧,譬如 leader 跑到了另一個 server 上面搅吁,或者 tablet 已經(jīng)不在當(dāng)前 server 上面,client 會收到相關(guān)的錯誤落午,這時候谎懦,client 就重新再去 Master 獲取一下最新的路由信息。

這個跟我們的做法仍然是一樣的溃斋,client 緩存最近的路由信息界拦,當(dāng)路由失效的時候,重新去 PD 獲取一下盐类。當(dāng)然寞奸,如果只是單純的 leader 變更,其實返回的錯誤里面通常就會帶上新的 leader 信息在跳,這時候 client 直接刷新緩存枪萄,在直接訪問了。

Tablet storage

Tablet server 是 Kudu 用來存放實際數(shù)據(jù)的服務(wù)猫妙,為了更好的性能瓷翻,Kudu 自己實現(xiàn)了一套 tablet storage,而沒有用現(xiàn)有的開源解決方案割坠。Tablet storage 目標(biāo)主要包括:

  • 快速的按照 Column 掃描數(shù)據(jù)
  • 低延遲的隨機更新
  • 一致的性能

RowSets

Tablets 在 Kudu 里面被切分成更小的單元齐帚,叫做 RowSets。一些 RowSets 只存在于內(nèi)存彼哼,叫做 MemRowSets对妄,而另一些則是使用 disk 和 memory 共享存放,叫做 DiskRowSets敢朱。任何一行數(shù)據(jù)只存在一個 RowSets 里面剪菱。

在任何時候,一個 tablet 僅有一個單獨的 MemRowSet 用來保存最近插入的數(shù)據(jù)拴签。后臺有一個線程會定期的將 這些 MemRowSets 刷到 disk 上面孝常。

當(dāng)一個 MemRowSet 被刷到 disk 之后,一個新的空的 MemRowSet 被創(chuàng)建出來蚓哩。之前的 MemRowSet 在刷到 disk 之后构灸,就變成了 DiskRowSet。當(dāng)刷的同時岸梨,如果有新的寫入喜颁,仍然會寫到這個正在刷的 MemRowSet 上面稠氮,Kudu 有一套機制能夠保證新寫入的數(shù)據(jù)也能一起被刷到 disk 上面。

MemRowSet

MemRowSet 是一個支持并發(fā)洛巢,提供鎖優(yōu)化的 B-tree括袒,主要基于 MassTree次兆,也有一些不同:

  1. 因為 Kudu 使用的是 MVCC稿茉,所以任何的刪除其實也是插入,所以這個 tree 沒有刪除操作芥炭。
  2. 不支持任意的 in-place 數(shù)據(jù)變更操作漓库,除非這次操作不會改變 value 的大小。
  3. 將 Leaf link 起來园蝠,類似 B+-tree渺蒿,這樣對于 scan 會有明顯的性能提升。
  4. 并沒有完全實現(xiàn) trie of trees彪薛,是只是使用了一個單一 tree茂装,因為 Kudu 并沒有太多高頻隨機訪問的場景。

DiskRowSet

當(dāng) MemRowSets 被刷到 disk 之后善延,就變成了 DiskRowSets少态。當(dāng) MemRowSets 被刷到 disk 的時候,Kudu 發(fā)現(xiàn)超過 32 MB 了就滾動一個新的 DiskRowSet易遣。因為 MemRowSet 是順序的彼妻,所以 DiskRowSets 也是順序的,各滾動的 DiskRowSet 里面的 primary keys 都是不相交的豆茫。

一個 DiskRowSet 包含 base data 和 delta data侨歉。Base data 按照 column 組織,也就是通常我們說的列存揩魂。各個 column 會被獨立的寫到 disk 里面一段連續(xù)的 block 上面幽邓,數(shù)據(jù)會被切分成多個 page,使用一個 B-tree 進行高效索引火脉。

除了刷用戶自定義的 column牵舵,Kudu 還默認(rèn)將 primary key index 寫到一個 column,同時使用 Bloom filter 來保證能快速通過找到 primary key忘分。

為了簡單棋枕,當(dāng) column 的數(shù)據(jù)刷到 disk,它就是默認(rèn) immutable 的了妒峦,但在刷的過程中重斑,有可能有更新的數(shù)據(jù),Kudu 將這些數(shù)據(jù)放到一個 delta stores 上面肯骇。Delta stores 可能在內(nèi)存 DeltaMemStores窥浪,或者 disk DeltaFiles祖很。

Delta store 維護的一個 map,key 是 (row_offset, timestamp)漾脂,value 就是 RowChangeList 記錄假颇。Row offset 就是 row 在 RowSet 里面的索引,譬如骨稿,有最小 primary key 的 row 在 RowSet 里面是排在最前面的笨鸡,它的 offset 就是 0。Timestamp 就是通常的 MVCC timestamp坦冠。

當(dāng)需要給 DiskRowSet 更新數(shù)據(jù)的時候形耗,Kudu 首先通過 primary key 找到對應(yīng)的 row。通過 B-tree 索引辙浑,能知道哪一個 page 包含了這個 row激涤,在 page 里面,可以計算 row 在整個 DiskRowSet 的 offset判呕,然后就把這個 offset 插入到 DeltaMemStore 里面倦踢。

當(dāng) DeltaMemStore 超過了一個閥值,一個新的 DeltaMemStore 就會生成侠草,原先的就會被刷到 disk辱挥,變成 immutable DeltaFile。

每個 DiskRowSet 都有一個 Bloom filter梦抢,便于快速的定位一個 key 是否存在于該DiskRowSet 里面般贼。DIskRowSet 還保存了最小和最大的 primary key,這樣外面就能通過 key 落在哪一個 key range 里面奥吩,快速的定位到這個 key 屬于哪一個 DiskRowSet哼蛆。

Compaction

當(dāng)做查詢操作的時候,Kudu 也會從 DeltaStore 上面讀取數(shù)據(jù)霞赫,所以如果 DeltaStore 太多腮介,整個讀性能會急劇下降。為了解決這個問題端衰,Kudu 在后臺會定期的將 delta data 做 compaction叠洗,merge 到 base data 里面。

同時旅东,Kudu 還會定期的將一些 DIskRowSets 做 compaction灭抑,生成新的 DiskRowSets,對 RowSet 做 compaction 能直接去掉 deleted rows抵代,同時也能減少重疊的 DiskRowSets腾节,加速讀操作。

總結(jié)

上面對 Kudu 大概進行了介紹,主要還是參考 Kudu 自己的論文案腺。Kudu 在設(shè)計上面跟 TiKV 非常類似庆冕,所以對于很多設(shè)計,我是特別能理解為啥要這么做的劈榨,譬如 Master 的信息是通過 tablet 上報這種的访递。Kudu 對 Raft 在實現(xiàn)上面做了一些優(yōu)化,以及在數(shù)據(jù) partition 上面也有不錯的做法同辣,這些都是后面能借鑒的拷姿。

對于 Tablet Storage,雖然 Kudu 是自己實現(xiàn)的邑闺,但我發(fā)現(xiàn)跌前,很多方面其實跟 RocksDB 差不了多少,類似 LSM 架構(gòu)陡舅,只是可能這套系統(tǒng)專門為 Kudu 做了定制優(yōu)化,而不像 RocksDB 那樣具有普適性伴挚。對于 storage 來說靶衍,現(xiàn)在我們還是考慮使用 RocksDB。

另外茎芋,Kudu 采用的是列存颅眶,也就是每個列的數(shù)據(jù)單獨聚合存放到一起,而 TiDB 這邊還是主要使用的行存田弥,也就是存儲整行數(shù)據(jù)涛酗。列存對于 OLAP 非常友好,但在寫入的時候壓力可能會比較大偷厦,如果一個 table 有很多 column商叹,寫入性能影響會非常明顯。行存則是對于 OLTP 比較友好只泼,但在讀取的時候會將整行數(shù)據(jù)全讀出來剖笙,在一些分析場景下壓力會有點大。但無論列存還是行存请唱,都是為滿足不同的業(yè)務(wù)場景而服務(wù)的弥咪,TiDB 后續(xù)其實可以考慮的是行列混存,這樣就能適配不同的場景了十绑,只是這個目標(biāo)比較遠(yuǎn)大聚至,希望感興趣的同學(xué)一起加入來實現(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末本橙,一起剝皮案震驚了整個濱河市扳躬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖坦报,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件库说,死亡現(xiàn)場離奇詭異,居然都是意外死亡片择,警方通過查閱死者的電腦和手機潜的,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來字管,“玉大人啰挪,你說我怎么就攤上這事〕笆澹” “怎么了亡呵?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長硫戈。 經(jīng)常有香客問我锰什,道長,這世上最難降的妖魔是什么丁逝? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任汁胆,我火速辦了婚禮,結(jié)果婚禮上霜幼,老公的妹妹穿的比我還像新娘嫩码。我一直安慰自己,他們只是感情好罪既,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布铸题。 她就那樣靜靜地躺著,像睡著了一般琢感。 火紅的嫁衣襯著肌膚如雪丢间。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天猩谊,我揣著相機與錄音千劈,去河邊找鬼。 笑死牌捷,一個胖子當(dāng)著我的面吹牛墙牌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播暗甥,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼喜滨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了撤防?” 一聲冷哼從身側(cè)響起虽风,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后辜膝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體无牵,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年厂抖,在試婚紗的時候發(fā)現(xiàn)自己被綠了茎毁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡忱辅,死狀恐怖七蜘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情墙懂,我是刑警寧澤橡卤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站损搬,受9級特大地震影響碧库,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜场躯,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一谈为、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧踢关,春花似錦、人聲如沸粘茄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柒瓣。三九已至儒搭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芙贫,已是汗流浹背搂鲫。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留磺平,地道東北人魂仍。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像拣挪,于是被迫代替她去往敵國和親擦酌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容