當前位置 博文首頁 > 信息技術智庫:??爆肝新一代大數據存儲寵兒,梳理了2萬字 “超硬

    信息技術智庫:??爆肝新一代大數據存儲寵兒,梳理了2萬字 “超硬

    作者:[db:作者] 時間:2021-09-13 19:00

    🍅 作者:不吃西紅柿

    🍅 簡介:CSDN博客專家🏆、信息技術智庫公號作者?。簡歷模板、職場PPT模板、技術難題交流、面試套路盡管【關注】私聊我。

    🍅 歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正!

    熱門專欄推薦:

    🥇 大數據集錦專欄:大數據-硬核學習資料 & 面試真題集錦?
    🥈?數據倉庫專欄:數倉發展史、建設方法論、實戰經驗、面試真題?
    🥉?Python專欄:Python相關黑科技:爬蟲、算法、小工具?

    (優質好文持續更新中……)?

    目錄

    一、kudu介紹

    二、基礎概念

    三、設計架構

    四、數據存儲結構

    五、表設計

    六、注意事項


    一、kudu介紹

    ????Kudu是Cloudera開源的新型列式存儲系統,是Apache Hadoop生態圈的成員之一(incubating),專門為了對快速變化的數據進行快速的分析,填補了以往Hadoop存儲層的空缺。

    1 功能上的空白

    ????Hadoop生態系統有很多組件,每一個組件有不同的功能。在現實場景中,用戶往往需要同時部署很多Hadoop工具來解決同一個問題,這種架構稱為混合架構 (hybrid architecture)。比如,用戶需要利用Hbase的快速插入、快讀random access的特性來導入數據,HBase也允許用戶對數據進行修改,HBase對于大量小規模查詢也非常迅速。同時,用戶使用HDFS/Parquet + Impala/Hive來對超大的數據集進行查詢分析,對于這類場景, Parquet這種列式存儲文件格式具有極大的優勢。

    ????很多公司都成功地部署了HDFS/Parquet + HBase混合架構,然而這種架構較為復雜,而且在維護上也十分困難。首先,用戶用Flume或Kafka等數據Ingest工具將數據導入HBase,用戶可能在HBase上對數據做一些修改。然后每隔一段時間(每天或每周)將數據從Hbase中導入到Parquet文件,作為一個新的partition放在HDFS上,最后使用Impala等計算引擎進行查詢,生成最終報表。
    ????這樣一條工具鏈繁瑣而復雜,而且還存在很多問題,比如:

    • 如何處理某一過程出現失敗
    • 從HBase將數據導出到文件,多久的頻率比較合適
    • 當生成最終報表時,最近的數據并無法體現在最終查詢結果上
    • 維護集群時,如何保證關鍵任務不失敗
    • Parquet是immutable,因此當HBase中刪改某些歷史數據時,往往需要人工干預進行同步

    ????這時候,用戶就希望能夠有一種優雅的存儲解決方案,來應付不同類型的工作流,并保持高性能的計算能力。Cloudera很早就意識到這個問題,在2012年就開始計劃開發Kudu這個存儲系統,終于在2015年發布并開源出來。Kudu是對HDFS和HBase功能上的補充,能提供快速的分析和實時計算能力,并且充分利用CPU和I/O資源,支持數據原地修改,支持簡單的、可擴展的數據模型

    2. 新的硬件設備

    ????RAM的技術發展非?,它變得越來越便宜,容量也越來越大。Cloudera的客戶數據顯示,他們的客戶所部署的服務器,2012年每個節點僅有32GB RAM,現如今增長到每個節點有128GB或256GB RAM。存儲設備上更新也非?,在很多普通服務器中部署SSD也是屢見不鮮。HBase、HDFS、以及其他的Hadoop工具都在不斷自我完善,從而適應硬件上的升級換代。然而,從根本上,HDFS基于03年GFS,HBase基于05年BigTable,在當時系統瓶頸主要取決于底層磁盤速度。當磁盤速度較慢時,CPU利用率不足的根本原因是磁盤速度導致的瓶頸,當磁盤速度提高了之后,CPU利用率提高,這時候CPU往往成為系統的瓶頸。HBase、HDFS由于年代久遠,已經很難從基本架構上進行修改,而Kudu是基于全新的設計,因此可以更充分地利用RAM、I/O資源,并優化CPU利用率。我們可以理解為,Kudu相比與以往的系統,CPU使用降低了,I/O的使用提高了,RAM的利用更充分了。

    3. 設計初衷

    ????kudu設計的初衷為了解決如下問題:

    • 對數據掃描(scan)和隨機訪問(random access)同時具有高性能,簡化用戶復雜的混合架構
    • 高CPU效率,使用戶購買的先進處理器的的花費得到最大回報
    • 高IO性能,充分利用先進存儲介質
    • 支持數據的原地更新,避免額外的數據處理、數據移動
    • 支持跨數據中心replication

    ????Kudu的很多特性跟HBase很像,它支持索引鍵的查詢和修改。Cloudera曾經想過基于Hbase進行修改,然而結論是對HBase的改動非常大,Kudu的數據模型和磁盤存儲都與Hbase不同。HBase本身成功的適用于大量的其它場景,因此修改HBase很可能吃力不討好。最后Cloudera決定開發一個全新的存儲系統。

    ????Kudu的定位是提供”fast analytics on fast data”,也就是在快速更新的數據上進行快速的查詢。它定位OLAP和少量的OLTP工作流,如果有大量的random accesses,官方建議還是使用HBase最為合適。

    二、基礎概念

    列式數據存儲(Columnar Data Store)

    閱讀效率(Read Efficiency)

    ????對于分析查詢,允許讀取單個列或該列的一部分同時忽略其他列

    數據壓縮(Data Compression)

    ????由于給定的列只包含一種類型的數據,基于模式的壓縮比壓縮混合數據類型(在基于行的解決案中使用)時更有效幾個數量級。結合從列讀取數據的效率,壓縮允許您在從磁盤讀取更少的塊時完成查詢

    Table

    ????table是數據存儲在 Kudu 的位置。表具有schema和全局有序的primary key(主鍵)。table被分成很多段,也就是稱為tablets。

    Tablet

    ????一個tablet是一張table連續的segment,與其它數據存儲引擎或關系型數據庫的partition(分區)相似。給定的tablet冗余到多個tablet服務器上,并且在任何給定的時間點,其中一個副本被認為是leader tablet。任何副本都可以對讀取進行服務,但是寫入時需要在為tablet服務的一組tablet server之間達成一致性。

    Tablet Server

    ????一個tablet server存儲tablet和為tablet向client提供服務。對于給定的tablet,一個tablet server充當 leader,其他tablet server充當該 tablet 的follower副本。只有leader服務寫請求,然而leader或followers為每個服務提供讀請求。leader使用Raft Consensus Algorithm來進行選舉 。一個tablet server可以服務多個tablet,并且一個 tablet 可以被多個tablet servers服務著。

    Master

    ????master保持跟蹤所有的tablets,tablet servers,Catalog Table 和其它與集群相關的metadata。在給定的時間點,只能有一個起作用的master(也就是 leader)。如果當前的 leader 消失,則選舉出一個新的master,使用 Raft Consensus Algorithm來進行選舉。

    ????master還協調客戶端的metadata operations(元數據操作)。例如,當創建新表時,客戶端內部將請求發送給master。 master將新表的元數據寫入catalog table,并協調在tablet server上創建 tablet 的過程。

    ????所有master的數據都存儲在一個 tablet 中,可以復制到所有其他候選的 master。

    ????tablet server以設定的間隔向master發出心跳(默認值為每秒一次)。

    ????master是以文件的形式存儲在磁盤中,所以說,第一次初始化集群。需要設定好

    Raft Consensus Algorithm

    ????Kudu 使用 Raft consensus algorithm 作為確保常規 tablet 和 master 數據的容錯性和一致性的手段。通過 Raft,tablet 的多個副本選舉出 leader,它負責接受以及復制到 follower 副本的寫入。一旦寫入的數據在大多數副本中持久化后,就會向客戶確認。給定的一組 N 副本(通常為 3 或 5 個)能夠接受最多(N - 1)/2 錯誤的副本的寫入。

    Catalog Table

    ????catalog table是Kudu 的 metadata(元數據中)的中心位置。它存儲有關tables和tablets的信息。該catalog table(目錄表)可能不會被直接讀取或寫入。相反,它只能通過客戶端 API中公開的元數據操作訪問。catalog table 存儲兩類元數據。

    • Tables

    ????table schemas, locations, and states(表結構,位置和狀態)

    • Tablets

    ????現有tablet 的列表,每個 tablet 的副本所在哪些tablet server,tablet的當前狀態以及開始和結束的keys(鍵)

    三、設計架構

    ????上圖顯示了一個具有三個 master 和多個tablet server的Kudu集群,每個服務器都支持多個tablet。它說明了如何使用 Raft 共識來允許master和tablet server的leader和follow。此外,tablet server 可以成為某些 tablet 的 leader,也可以是其他 tablet follower。leader以金色顯示,而 follower 則顯示為藍色。

    四、數據存儲結構

    ????一張表會分成若干個tablet,每個tablet包括MetaData元信息及若干個RowSet,RowSet包含一個MemRowSet及若干個DiskRowSet,DiskRowSet中包含一個BloomFile、Ad_hoc Index、BaseData、DeltaMem及若干個RedoFile和UndoFile(UndoFile一般情況下只有一個)。

    • MemRowSet用于新數據insert及已在MemRowSet中的數據的更新,一個MemRowSet寫滿后會將數據刷到磁盤形成若干個DiskRowSet。

    • DiskRowSet用于老數據的mutation,后臺定期對DiskRowSet做compaction,以刪除沒用的數據及合并歷史數據,減少查詢過程中的IO開銷。

      • BloomFile根據一個DiskRowSet中的key生成一個bloom filter,用于快速模糊定位某個key是否在DiskRowSet中存在。

      • Ad_hoc Index是主鍵的索引,用于定位key在DiskRowSet中的具體哪個偏移位置。

      • BaseData是MemRowSet flush下來的數據,按列存儲,按主鍵有序。

      • UndoFile是基于BaseData之前時間的歷史數據,通過在BaseData上apply UndoFile中的記錄,可以獲得歷史數據。

      • RedoFile是基于BaseData之后時間的mutation記錄,通過在BaseData上apply RedoFile中的記錄,可獲得較新的數據。

      • DeltaMem用于DiskRowSet中數據的mutation,先寫到內存中,寫滿后flush到磁盤形成RedoFile。

    1. MemRowSet

    ????MemRowSet的數據組織sss是一顆B+Tree,結構如下:

    ????這顆B+樹實現的比較簡單,因為它沒有update跟delete操作,kudu在MemRowSet中中數據的mutation采用類似append log方式,在base數據上有個mutation指針,所有的后續mutation操作都掛在這個指針上了。

    ????雖然只有插入,但是也會出現節點滿時需要做split,同時可能有讀操作也在同步進行,kudu使用AtomicVersion(原子變量+位移)實現了一個鎖。樹的度跟cpu的CACHELINE_SIZE有關,是為了讓一個節點僅讀取一次cpu cache。

    ????樹的檢索是先找到key所在的LeafNode,然后在LeafNode內部進行二分查找,LeafNode間有指針進行串聯,為了方便scan,掃整個MemRowSet一般通過一個空串的key找到第一個LeafNode,然后依次讀數據。

    2. DiskRowSet

    ????這部分是kudu存儲部分最復雜的東西,分為兩個部分來講,DiskRowSet間的組織,DiskRowSet內數據組織,先看DiskRowSet間怎么組織的。

    2.1 DiskRowSet間組織

    ????一個tablet隨這數據的不斷寫入會包含很多個DiskRowSet,每個DiskRowSet上有min_key、max_key標明key的范圍,如果要查找一個key在哪個DiskRowSet上依次遍歷每個DiskRowSet效率是很低的,這種情況線段樹這種數據結構是很適合做range索引的,將所有的DiskRowSet形成一顆線段樹,結構如下:

    ????其實就是一個二叉平衡樹,每次從所有range(最小的min_key跟最大的max_key)的中間key做split,將range跨域左右子樹的DiskRowSet(即split point落在DiskRowSet的min_key與max_key之間)放到overlap rowsets中去。這顆樹實現的也很簡單,因為它只做查詢用,生成后就不會變動,若遇到MemRowSet flush或DiskRowSet Merge Compaction就直接重新生成一顆新樹。

    ????這個樹主要用于在讀或寫的時候定位某個或若干個key在哪些DiskRowSet的range范圍內,只能通過DiskRowSet的min_key/max_key做一層模糊過濾,是否正在存在需要做進一步檢查。

    2.2 DiskRowSet內數據組織

    ????一個DiskRowSet大體數據組織上面概述中已介紹過,其中DeltaMem跟MemRowSet在內存中的組織方式是一樣的,都是B+Tree,而在磁盤上的存儲都是放在CFile中的,下面我們看看CFile的文件格式:

    ????CFile包含Header、Data、Index、Footer幾塊,其中Data部分起始部分是為空值的條目建立的bitmap,僅針對可為null的column,對于主鍵是沒有這個的,bitmap就是以那些值為null的RowId建立起來的位圖,這樣Data中就不用存這些空值。data部分不同的column類型文件會有不同的編碼方式:

    Column TypeEncodingdefault
    int8,int16,int32plain,bitshuffle,run lengthbitshuffle
    int64,unixtime_microsplain,bitshuffle,run lengthbitshuffle
    float,double,decimalplain,bitshufflebitshuffle
    boolplain,run lengthrun length
    string,binaryplain,prex,dictionarydictionary

    ????對于ad_hoc文件使用的是prefix,delta file使用的是plain,bloomfile使用的是plain。每種BlockBuilder在處理一定量數據后就會append到Data中。

    ????Index有兩種,posidx_index是根據RowId找到在Data中的偏移,validx index是根據key的值找到在Data中的偏移,validx只針對只有一個column為key的情況,這個時候DiskRowSet沒有Ad_hoc索引,使用validex來代替。這兩個index內部實現是一個B-Tree,index不一定是連續的,在達到一定長度后就會刷盤,而內部可以區分是中間節點還是葉子節點及其孩子節點的位置。

    ????Footer是記錄了CFile的元信息,包括posidx_index、validx_index兩棵樹根節點所在位置,數據條目、編碼、壓縮方式等。

    下面看看DiskRowSet數據在磁盤上的分布:

    ????在磁盤上每個DiskRowSet有若干個.metadata及.data文件,metadata文件記錄的是DiskRowSet的元信息,主要包括哪些block及block在data中的位置,上圖為block與DiskRowSet中各部分的映射關系,在寫磁盤是通過container來寫,每個container可以寫很大一塊連續的磁盤空間,用于給某個CFile寫數據,當一個CFile寫完后會將container歸還給BlockManager,這時container就可以用于下個CFile寫數據了,當BlockManager中沒有container可用時會新建一個container給新來的CFile使用。

    ????對于新建block先看看有無container可用,若沒有目前默認是在所有配置中的data_dir中隨機選取一個dir中建一個新的metadata及data文件。先寫data,block落盤后再寫metadata。

    五、表設計

    ????kudu的表具有類似于傳統RDBMS中的表的數據結構。schema設計對于實現Kudu的最佳性能和操作穩定性至關重要。
    業務場景的多變,對于table來說并不存在一種最好的schema設計。

    ????大部分情況下,創建kudu的表需要考慮三個問題:

    • 列的設計(column design)
    • 主鍵設計(primary key design)
    • 分區設計(partitioning design)

    ????比較好的Schema設計應該滿足一下要求:

    1. 數據的分布和存儲的方式滿足:讀取和寫入操作都可以均勻的分散到tablet servers上(受分區影響)
    2. tablet將以均勻,可預測的速度增長,并且tablet server的負載將隨著時間的推移保持穩定(受分區影響最大)
    3. 掃描將讀取完成查詢所需的最少數據量。(這主要受主鍵設計的影響,但分區也通過分區修剪發揮作用)

    1. 列設計

    ????一個kudu表由一列或多列構成,每列都需要指定一個類型。非主鍵的列允許為空。
    kudu支持的類型包括:

    • boolean
    • 8-bit signed integer
    • 16-bit signed integer
    • 32-bit signed integer
    • 64-bit signed integer
    • unixtime_micros (64-bit microseconds since the Unix epoch)unix時間戳
    • single-precision (32-bit) IEEE-754 floating-point number 單精度
    • double-precision (64-bit) IEEE-754 floating-point number 雙精度
    • decimal
    • UTF-8 encoded string (up to 64KB uncompressed)
    • binary (up to 64KB uncompressed)

    ????Kudu利用強類型列和柱狀磁盤存儲格式來提供高效的編碼和序列化。要充分利用這些優勢,應該為列指定一個合適的類型,而不是為了讓表看起來結構化而強行讓數據使用string or binary columns 。
    除了編碼之外,Kudu還允許在每列的基礎上指定壓縮方式。

    ==注意==

    與Hbase不同,kudu沒有提供一個version或者timestamp列來追蹤行數據的變化。如果需要version或者timestamp,schema設計將包含一個明確的version或timestamp列。

    1.1 十進制類型(Decimal Type)

    ????十進制類型是一種數字數據類型,具有固定的比例和精度,適用于財務和其他算術計算,其中float和double的不精確表示和舍入行為使這些類型不切實際。十進制類型對于大于int64的整數和在主鍵中具有小數值的情況也很有用。
    十進制類型是一種參數化類型,它擁有精度(Precision )和縮放(Scale )類型屬性。

    精度(Precision )

    ????表示列可以表示的總位數,無論小數點的位置如何。此值必須介于1和38之間,并且沒有默認值。
    案例:

    精度為4的能表示的最大整數為9999,或用兩位小數表示最高的99.99,還可以表示相應的負值,而不會對精度進行任何更改。例如,-9999到9999的范圍仍然只需要4的精度。

    縮放(Scale )

    ????表示小數的位數。該值必須介于0和精度之間。scale為0會產生整數值,沒有小數部分。如果精度和比例相等,則所有數字都在小數點后面。
    案例:

    精度和小數等于3的小數可以表示介于-0.999和0.999之間的值。

    性能考慮

    ????Kudu將每個值存儲在盡可能少的字節中,具體取決于為十進制列指定的精度。因此,為方便起見,不建議盡可能使用最高精度。
    這樣做可能會對性能、內存和存儲產生負面影響。
    不同精度的數據在內存占用的空間大小:

    • Decimal values with precision of 9 or less are stored in 4 bytes. 9位以下的Decimal值存儲需要4bytes空間
    • Decimal values with precision of 10 through 18 are stored in 8 bytes. 10-18位的Decimal值存儲需要8bytes空間
    • Decimal values with precision greater than 18 are stored in 16 bytes. 大于18為的Decimal值存儲需要16bytes空間

    列的(precision)精度和(scale)縮放不能被修改表的語句更改。

    1.2 列編碼(Column Encoding)

    ????kudu表中的每一列都會使用基于列的類型的編碼。列的類型和編碼的關系如下:

    Column TypeEncodingdefault
    int8,int16,int32plain,bitshuffle,run lengthbitshuffle
    int64,unixtime_microsplain,bitshuffle,run lengthbitshuffle
    float,double,decimalplain,bitshufflebitshuffle
    boolplain,run lengthrun length
    string,binaryplain,prex,dictionarydictionary

    下面對各個編碼方式進行介紹:

    1. Plain Encoding

    ????數據按照其原有的格式進行存儲。比如:int32的值保存為固定大小為32字節的整數(fixed-size 32-bit little-endian integers)

    1. Bitshuffle Encoding

    ????重新排列一個值的塊,先存儲每個值的最高有效位,然后是每個值的第二個最高有效位,依此類推。最后,結果是LZ4壓縮。
    Bitshuffle編碼是具有許多重復值的列的理想選擇,或者當按主鍵排序時會按少量更改的值。bitshuffle 項目對性能和用例有很好的描述。

    1. Run Length Encoding

    ????Runs(連續重復值)壓縮列的值通過存儲值和值的計數。Run Length Encoding對按主鍵排序時具有許多連續重復值的列有效。

    1. Dictionary Encoding

    ????構建唯一值的字典,并將每個列值編碼為字典中的對應索引,字典編碼對于基數較低的列有效。
    如果由于唯一值的數量太大而無法壓縮給定行集的列值,則Kudu將透明地回退到該行集的Plain Encoding。 這在沖洗期間(flush)進行評估

    1. Prefix Encoding

    ????公共前綴以連續列值壓縮。前綴編碼對于共享公共前綴的值或主鍵的第一列可能有效,因為行按片中的主鍵排序。

    1.3 列壓縮(Column Compression)

    ????kudu允許使用LZ4,Snappy,Zlib壓縮編碼器對每列進行壓縮。默認,列是沒有進行壓縮的。如果減少存儲空間比原始掃描性能更重要,請考慮使用壓縮。

    ????每個數據集的壓縮方式都不同,但一般來說LZ4是性能最佳的編解碼器,而zlib會壓縮到最小的數據大小。Bitshuffle編碼的列使用LZ4自動壓縮,因此不建議在此編碼的基礎上應用額外的壓縮。

    2. 主鍵設計

    ????kudu的每一個表都必須聲明一個由一列或多列組成的主鍵。與RDBMS主鍵一樣,Kudu主鍵強制執行唯一性約束。嘗試插入具有與現有行相同的主鍵值的行將返回重復鍵錯誤。

    ????主鍵列不能為空,且不能為boolean,float,或者double類型。表創建的過程中設置之后,主鍵列就不能變更改。

    ????與傳統的RDBMS不一樣,kudu沒有提供自增的主鍵列,在應用寫入數據過程中,必須提供全部主鍵列的值。行刪除和更新操作還必須指定要更改的行的完整主鍵。Kudu本身不支持范圍刪除或更新。插入行后,無法更新列的主鍵值。 但是,可以刪除行并使用更新的值重新插入

    2.1 主鍵索引

    ????與許多傳統型數據庫一樣,kudu的主鍵是分布式的索引。
    存儲在一個tablet里面的所有數據都按照主鍵進行排序。掃描kudu的行數據時候,在主鍵列上使用相等或范圍謂詞來有效地查找行。主鍵索引優化適用于單個tablet上的掃描。全局的優化考慮分區的設計

    2.2 Backfill Inserts的注意事項(這部分文檔理解還存在一些問題)

    ????本節討論時間序列用例的主鍵設計考慮因素,其中主鍵是時間戳,或者主鍵的第一列是時間戳。

    ????每當有數據寫入kudu表中的時候,kudu都會在primary key index storage 中查找primary key ,以檢查primary key 在表中的是否已存在。
    如果存在,就會返回一個duplicate key 的錯誤。

    問題場景如下:

    當前插入數據從數據源到達時候,只有少量的主鍵是hot的。因此,這些“檢查存在”操作中的每一個都非?。 它命中內存中的緩存主鍵存儲,不需要轉到磁盤。
    在從離線數據源加載歷史數據(稱為“backfill inserts”)的情況下,插入的每一行都可能遇到主鍵索引的冷區域,該區域不駐留在內存中并且會導致一個或多個HDD磁盤搜索。

    ????在正常情況下,Kudu每秒支持幾百萬次插入,“backfill inserts”用例可能每秒僅維持幾千次插入。

    ????為了緩解backfill inserts的性能問題,考慮下面的幾條:

    1. 使主鍵更加容易壓縮
      案例:主鍵的第一列是32字節的隨機ID,緩存十億的主鍵則需要最少32gb的內存空間。如果從幾天前開始緩存backfill inserts的主鍵,那么你需要數倍于32gb的內存空間。通過將主鍵更改為更易于壓縮,可以增加主鍵適合緩存的可能性,從而減少隨機磁盤I / O的數量。
    2. 使用SSD進行存儲,因為隨機搜索比旋轉磁盤快幾個數量級。(SSD比普通硬盤快)
    3. 更改主鍵結構,使backfill insets寫入命中連續的主鍵范圍。

    3. 分區設計

    ????分區字段一定是主鍵集合的子集。為了提升性能,kudu的表被劃分為稱為tablet的單元,并分布在多個tablet server中。
    一行數據總是屬于單個tablet。數據分配到tablet的方法是由在創建表的時候指定的分區方式決定的。
    ????選擇分區的策略需要理解數據模型、表的主要工作內容:

    1. 對于大量寫入的工作,設計分區以使得寫入工作分布到多個tablet上,避免單個tablet過載非常重要
    2. 對于大量短掃描(short scans)的工作,如果聯系遠程服務器的開銷占主導地位,那么掃描的所有數據都在一個tablet就會提高性能。(短掃描、聯系遠程服務器的開銷占主導地位不太明白)。

    kudu不提供默認分區策略。

    It is recommended that new tables which are expected to have heavy read and write workloads have at least as many tablets as tablet servers.
    建議預計具有大量讀寫工作負載的新表至少具有與tablet servers一樣多的tablets(如何操作?)

    ????kudu提供了兩種分區方式:范圍分區和散列分區。表可以多級分區,多級分區集合了范圍分區和散列分區,或者多個散列分區

    3.1 范圍分區

    ????范圍分區使用全序的范圍分區鍵對數據行進行分配。(全序是指,集合中的任兩個元素之間都可以比較的關系。比如實數中的任兩個數都可以比較大小,那么“大小”就是實數集的一個全序關系。)
    每個分區都是根據范圍分區鍵分配的連續段。范圍分區鍵必須是主鍵的子集。
    如果表只存在范圍分區,不存在散列分區,則每個分區恰好對應一個tablet。

    ????初始化的分區在表創建時期被指定為一組分區邊界和拆分點。對于每個邊界,都會在表中創建分區對于。每次拆分,都會將分區拆分成兩個分區。如果沒有指定分區邊界,則表將默認一個分區覆蓋整個分區鍵空間。
    范圍分區必須始終不重疊,拆分行必須位于范圍分區內。

    ????kudu允許范圍分區在運行時的動態增加和刪除,而不會影響其他分區的可用性。
    刪除分區會同時把屬于這個分區的全部tablet,屬于這些tablet的所有數據都刪除。這樣會導致隨后對這個分區的寫入失敗。
    新的分區可以在運行時候增加,前提是這個新增加的分區和現存的分區不存在重疊。kudu允許在單個事物更改表的操作中新增或刪除任意數量的范圍分區。

    ????動態的增加和刪除分區對于時間序列的場景特別有用?梢栽黾有碌姆秶謪^以覆蓋即將到來的時間范圍。
    案例:

    一個存儲時間日志的表可以增加月分區在該月開始之前用于存儲該月份的事件日志數據。

    有必要的話,可以根據分區去更加有效的刪除數據

    3.2 散列分區

    ????散列分區是根據hash值把行數據分配到某個buckets里面。如果只是一層hash,則一個bucket對應一個tablet。
    buckets的數量是在創建表的時候指定的。
    散列分區使用的分區列是主鍵列,同范圍分區,可以使用主鍵列的任意子集做分區。
    散列分區是一種高效的策略,當不需要要有序的訪問表的時候。
    散列分區對在tablet之間的隨機寫入非常有效,這樣有助于緩解tablet的熱點問題和數據分布不均勻的問題。

    如何選取散列的列,這樣計算的hash值可以保證數據的均勻分配到bucket里面去?

    3.3 多級分區

    ????kudu允許在一個表中指定多級分區。零個或多個散列分區級別可以和可選的范圍分區級別組合。多級分區與單個分區的區別是增加了約束條件,多級散列分區不能散列相同的列。(存在多級散列分區時候,各個散列分區計算散列值使用的列不能一樣)如果使用正確,多級分區可以保留各個分區類型的好處,同時減少每個分區類型的缺點。多級分區表中的tablet總數是每個級別中分區數的乘積。

    3.4 分區修剪(Partition Pruning)

    ????當可以確定掃描關鍵字可以完全過濾分區時,Kudu掃描將自動跳過掃描整個分區。

    • 要修剪散列分區,掃描必須在每個散列列上包含等式關鍵字。
    • 要修剪范圍分區,掃描必須在范圍分區列上包含相等或范圍關鍵字。
    • 多級分區表上的掃描可以獨立地利用任何級別上的分區修剪。

    3.5 分區案例

    了說明與為表設計分區的策略相關的因素和權衡,這里講介紹一些分區方案。
    建立一個用于存儲計算機標準度量數據的表,表字段如下:

    CREATE TABLE metrics (
        host STRING NOT NULL,
        metric STRING NOT NULL,
        time INT64 NOT NULL,
        value DOUBLE NOT NULL,
        PRIMARY KEY (host, metric, time),
    );
    

    3.5.1 范圍分區案例

    通常對metrics進行范圍分區的方式是使用time進行分區,如下圖:

    • 案例1:沒有邊界,用2015101和20160101分割數據,將數據分成了三塊
    • 案例2:有邊界[(2014-01-01), (2017-01-01)],在2015-01-01 and 2016-01-01處分割

    案例1和案例2都存在熱點問題,數據寫入的時候,都會寫入同一個分區。
    但是案例2比案例1更加靈活,案例1中當寫入數據的實際超過20160101時候,全部數據會寫入同一個分區,會造成分區過大,單個tablet無法存儲。案例2則可以增加分區適應新寫入的數據。

    3.5.2 散列分區案例

    對metrict進行分區的散列分區方法是:根據host和metrict進行分區,如下圖:

    上面的案例中,metrict表按照host,metric散列分區,把數據寫入到四個bucket中。與之前的范圍分區不同,這個分區策略會把數據均勻地寫入到各個tablet里面去。
    掃描指定的host和metric可以充分得用到這種分區方式的優點,減少掃描的tablet數量。散列分布需要關注的一個問題是:當越來越多數據寫入表中的時候,單個tablet的數據量會越來越大,最終tablet的數據會超過單個tablet server的存儲。

    3.5.3 范圍分區和散列分區對比

    StrategyWritesReadsTablet Growth
    range(time)? - all writes go to latest partition? - time-bounded scans can be pruned? - new tablets can be added for future time periods
    hash(host, metric)? - writes are spread evenly among tablets? - scans on specific hosts and metrics can be pruned? - tablets could grow too large

    散列分區能最大化系統的吞吐量,范圍分區則可以現在tablet無限增長的問題

    3.5.4 范圍分區和散列分區組合

    如下圖:

    3.5.4 多級散列分區組合

    如下圖:

    六、注意事項

程序員cxuan的個人主頁:這篇 Java 基礎,我吹不動了 小小張自由―>張有博:軟件工程――編碼、測試、維護 小小張自由―>張有博:淺談面向對象方法學 小小張自由―>張有博:UML――概述(事物、關系、圖) 小小張自由―>張有博:UML――用例圖 小小張自由―>張有博:UML――活動圖和狀態圖 小小張自由―>張有博:UML――交互圖(順序圖與協作圖) 小小張自由―>張有博:UML――實現圖(構件圖與部署圖) 小小張自由―>張有博:C#編程基礎――C#與.NET的關系 小小張自由―>張有博:C#編程基礎――數據類型 小小張自由―>張有博:C#編程基礎――常量與變量 小小張自由―>張有博:C#編程基礎――運算符與表達式 小小張自由―>張有博:C#編程基礎――循環語句 小小張自由―>張有博:C#編程基礎――跳轉語句 小小張自由―>張有博:C#編程基礎――類 小小張自由―>張有博:C#編程基礎――方法 小小張自由―>張有博:初始三層架構(超超超詳細) 小小張自由―>張有博:C#連接數據庫之Connection、Command、D 小小張自由―>張有博:System.ArgumentOutOfRangeException: 小小張自由―>張有博:機房重構之單例模式的應用 小小張自由―>張有博:機房重構之備忘錄模式的應用 小小張自由―>張有博:機房重構之職責鏈模式的應用 小小張自由―>張有博:HTML基礎――標簽 小小張自由―>張有博:div+css的入門知識 小小張自由―>張有博:CSS核心內容:標準流、盒子模型、浮動 小小張自由―>張有博:asp.net生成驗證碼并提交驗證 小小張自由―>張有博:XML基礎 小小張自由―>張有博:各種計算機語言簡短簡介 小小張自由―>張有博:2020年10月自考總結 小小張自由―>張有博:vs2019利用gitee(碼云)協作開發 小小張自由―>張有博:1024程序員節 小小張自由―>張有博:IDEA2020.3詳細安裝教程 小小張自由―>張有博:JavaWeb之Request與Response詳解 小小張自由―>張有博:JavaWeb之Filter和Listener 小小張自由―>張有博:Vue插件報錯:Vue.js is detected on t 小小張自由―>張有博:在項目中使用Spring Cloud Alibaba Sen 小小張自由―>張有博:在項目中使用OpenFeign 小小張自由―>張有博:解決idea打開Vue項目報紅 小小張自由―>張有博:CentOS7詳細安裝教程--圖文介紹超詳細 zhtbs的博客:Springboot 入門培訓 5 Thymeleaf 與 MVC項目搭建 zhtbs的博客:(Framework7 移動webapp) Springboot 入門培訓 7 zhtbs的博客:HTML+CSS+JavaScript 迷宮生成算法 【建議收藏】 zhtbs的博客:(Framework7 移動webapp) Springboot 入門培訓 8 C zhtbs的博客:Springboot 入門培訓 9 Security(一) 登錄驗證 zhtbs的博客:Springboot 入門培訓 4 WEB+JSP MVC項目搭建 zhtbs的博客:Springboot 入門培訓 10 Security(二) 數據庫DB 貓耳山在天邊:《Linux命令行與shell腳本編程大全》(第三版)讀 英雄哪里出來:??13萬字《C語言動漫對話教程(入門篇)》??(建議收 qq1113673178的博客:[學習][筆記] qt5 從入門到入墳:<12>Grap qq1113673178的博客:[學習][筆記] qt5 從入門到入墳:<13>基于 .net平臺的rabbitmq使用封裝demo詳解 C++類的特種函數生成機制詳解 Python調用百度AI實現圖片上表格識別功能 node自定義安裝更改npm全局模塊默認安裝路徑的步驟 帶你用C語言實現strtok和字符串分割函數 靜態網頁和靜態網頁性能比較 網頁標題優化原則和描述優化原則 php 怎么設置cookie記住密碼 php設置時區無效怎么辦 php __autoload 失效怎么辦 有關PHP調試的小技巧,看看吧! 從0開始:教你微信小店怎么開! 成本5元竟然賣50元 微信朋友圈賣面膜真黑啊 HashMap原理及put方法與get方法的調用過程 基于IDEA 的遠程調試 Weblogic的操作過程 UTC時間、GMT時間、本地時間、Unix時間戳的具體使用 如何利用SwiftUI實現可縮放的圖片預覽器 網站怎么利用內容更新雙重境界快速提高網站權重? php顯示繁體亂碼怎么辦 php不能開啟php_curl怎么辦
A级免费视频