Kudu的概念术语
不多說,直接上干貨!
Columnar Data Store(列式數(shù)據(jù)存儲)
Kudu 是一個 columnar data store(列式數(shù)據(jù)存儲)。列式數(shù)據(jù)存儲在強類型列中。由于幾個原因,通過適當(dāng)?shù)脑O(shè)計,Kudu 對 analytical(分析)或 warehousing(數(shù)據(jù)倉庫)工作會非常出色。
Read Efficiency(高效讀取)
對于分析查詢,允許讀取單個列或該列的一部分同時忽略其他列,這意味著您可以在磁盤上讀取更少塊來完成查詢。與基于行的存儲相比,即使只返回幾列的值,仍需要讀取整行數(shù)據(jù)。
Data Compression(數(shù)據(jù)壓縮)
由于給定的列只包含一種類型的數(shù)據(jù),基于模式的壓縮比壓縮混合數(shù)據(jù)類型(在基于行的解決方案中使用)時更有效幾個數(shù)量級。結(jié)合從列讀取數(shù)據(jù)的效率,壓縮允許您在從磁盤讀取更少的塊時完成查詢。請參閱 數(shù)據(jù)壓縮。
Table(表)
一張 table 是數(shù)據(jù)存儲在 Kudu 的位置。表具有 schema 和全局有序的 primary key(主鍵)。table 被分成稱為 tablets 的 segments。
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 里面貌似沒有提及,后面只能看代碼了。
Tablet(片)
一個 tablet 是一張 table 連續(xù)的 segment,與其它數(shù)據(jù)存儲引擎或關(guān)系型數(shù)據(jù)庫中的 partition(分區(qū))相似。給定的 tablet 冗余到多個 tablet 服務(wù)器上,并且在任何給定的時間點,其中一個副本被認(rèn)為是 leader tablet。任何副本都可以對讀取進行服務(wù),并且寫入時需要在為 tablet 服務(wù)的一組 tablet server之間達(dá)成一致性。
Master
該 master 保持跟蹤所有的 tablets,tablet servers,Catalog Table 和其它與集群相關(guān)的 metadata。在給定的時間點,只能有一個起作用的 master(也就是 leader)。如果當(dāng)前的 leader 消失,則選舉出一個新的 master,使用 Raft Consensus Algorithm 來進行選舉。master 還協(xié)調(diào)客戶端的 metadata operations(元數(shù)據(jù)操作)。例如,當(dāng)創(chuàng)建新表時,客戶端內(nèi)部將請求發(fā)送給 master。 master 將新表的元數(shù)據(jù)寫入 catalog table,并協(xié)調(diào)在 tablet server 上創(chuàng)建 tablet 的過程。所有 master 的數(shù)據(jù)都存儲在一個 tablet 中,可以復(fù)制到所有其他候選的 master。tablet server 以設(shè)定的間隔向 master 發(fā)出心跳(默認(rèn)值為每秒一次)。
Tablet Server
一個 tablet server 存儲 tablet 和為 tablet 向 client 提供服務(wù)。對于給定的 tablet,一個 tablet server 充當(dāng) leader,其他 tablet server 充當(dāng)該 tablet 的 follower 副本。只有 leader 服務(wù)寫請求,然而 leader 或 followers 為每個服務(wù)提供讀請求。leader 使用 Raft Consensus Algorithm 來進行選舉 。一個 tablet server 可以服務(wù)多個 tablets ,并且一個 tablet 可以被多個 tablet servers 服務(wù)著。
Raft Consensus Algorithm
Kudu 使用 Raft consensus algorithm 作為確保常規(guī) tablet 和 master 數(shù)據(jù)的容錯性和一致性的手段。通過 Raft,tablet 的多個副本選舉出 leader,它負(fù)責(zé)接受以及復(fù)制到 follower 副本的寫入。一旦寫入的數(shù)據(jù)在大多數(shù)副本中持久化后,就會向客戶確認(rèn)。給定的一組 N 副本(通常為 3 或 5 個)能夠接受最多(N - 1)/2 錯誤的副本的寫入。
Catalog Table(目錄表)
catalog table 是 Kudu 的 metadata(元數(shù)據(jù)中)的中心位置。它存儲有關(guān) tables 和 tablets 的信息。該 catalog table(目錄表)可能不會被直接讀取或?qū)懭搿O喾矗荒芡ㄟ^客戶端 API 中公開的元數(shù)據(jù)操作訪問。
catalog table 存儲兩類元數(shù)據(jù):
Tables
table schemas, locations, and states(表結(jié)構(gòu),位置 和狀態(tài))
Tablets
現(xiàn)有 tablet 的列表,每個 tablet 的副本所在哪些 tablet server,tablet 的當(dāng)前狀態(tài)以及開始和結(jié)束的 keys(鍵)。
Logical Replication(邏輯復(fù)制)
Kudu 復(fù)制操作,不是磁盤上的數(shù)據(jù)。這被稱為 logical replication(邏輯復(fù)制),而不是 physical replication(物理復(fù)制)。這有幾個優(yōu)點 :
雖然 insert(插入)和 update(更新)確實通過網(wǎng)絡(luò)傳輸數(shù)據(jù),deletes(刪除)不需要移動任何數(shù)據(jù)。delete(刪除)操作被發(fā)送到每個 tablet server,它在本地執(zhí)行刪除。
物理操作,如 compaction,不需要通過 Kudu 的網(wǎng)絡(luò)傳輸數(shù)據(jù)。這與使用 HDFS 的存儲系統(tǒng)不同,其中 blocks (塊)需要通過網(wǎng)絡(luò)傳輸以滿足所需數(shù)量的副本。
tablet 不需要在同一時間或相同的時間表上執(zhí)行壓縮,或者在物理存儲層上保持同步。這會減少由于壓縮或大量寫入負(fù)載而導(dǎo)致所有 tablet server 同時遇到高延遲的機會。
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ù)了。
分區(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 流程。
將新的節(jié)點加入到 Raft 的 configuration 里面Leader 發(fā)送 StartEmoteBootstrap RPC,新的 follower 開始拉去 snapshot 和之后的 logFollower 接受完所有數(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é)以下幾個事情:
(1)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ù)這個流程。
(2)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)化工作的)。
(3)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,也有一些不同:
因為 Kudu 使用的是 MVCC,所以任何的刪除其實也是插入,所以這個 tree 沒有刪除操作。
不支持任意的 in-place 數(shù)據(jù)變更操作,除非這次操作不會改變 value 的大小。
將 Leaf link 起來,類似 B+-tree,這樣對于 scan 會有明顯的性能提升。
并沒有完全實現(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,加速讀操作。
歡迎大家,加入我的微信公眾號: 大數(shù)據(jù)躺過的坑 人工智能躺過的坑 Java從入門到架構(gòu)師
同時,大家可以關(guān)注我的個人博客:
http://www.cnblogs.com/zlslch/和 http://www.cnblogs.com/lchzls/ http://www.cnblogs.com/sunnyDream/
詳情請見:http://www.cnblogs.com/zlslch/p/7473861.html
人生苦短,我愿分享。本公眾號將秉持活到老學(xué)到老學(xué)習(xí)無休止的交流分享開源精神,匯聚于互聯(lián)網(wǎng)和個人學(xué)習(xí)工作的精華干貨知識,一切來于互聯(lián)網(wǎng),反饋回互聯(lián)網(wǎng)。
目前研究領(lǐng)域:大數(shù)據(jù)、機器學(xué)習(xí)、深度學(xué)習(xí)、人工智能、數(shù)據(jù)挖掘、數(shù)據(jù)分析。 語言涉及:Java、Scala、Python、Shell、Linux等 。同時還涉及平常所使用的手機、電腦和互聯(lián)網(wǎng)上的使用技巧、問題和實用軟件。 只要你一直關(guān)注和呆在群里,每天必須有收獲
對應(yīng)本平臺的討論和答疑QQ群:大數(shù)據(jù)和人工智能躺過的坑(總?cè)海?61156071)
總結(jié)
- 上一篇: 超经典,百度最爱考的安卓Android百
- 下一篇: JSON是什么?