首頁>技術>

出處:https://mp.weixin.qq.com/s?__biz=MzI0NTIxNzE1Ng==&mid=2651220676&idx=1&sn=7b68ed889ecfe7fc939f88dc3cadf2c3

Kylin 資料模型

Kylin 的資料模型本質上是將二維表(Hive 表)轉換為 Cube,然後將 Cube 儲存到 HBase 表中,也就是兩次轉換。

第一次轉換,其實就是傳統資料庫的 Cube 化,Cube 由 CuboId 組成,下圖每個節點都被稱為一個 CuboId,CuboId 表示固定列的資料資料集合,比如“ AB” 兩個維度組成的 CuboId 的資料集合等價於以下 SQL 的資料集合:

select A, B, sum(M), sum(N) from table group by A, B

第二次轉換,是將 Cube 中的資料儲存到 HBase 中,轉換的時候 CuboId 和維度資訊序列化到 rowkey,度量列組成列簇。在轉換的時候資料進行了預聚合。下圖展示了 Cube 資料在 HBase 中的儲存方式。

Kylin 索引結構

因為 Kylin 將資料儲存到 HBase 中,所以 kylin 的資料索引就是 HBase 的索引。HBase 的索引是簡化版本的 B+樹,相比於 B+樹,HFile 沒有對資料檔案的更新操作。

HFile 的索引是按照 rowkey 排序的聚簇索引,索引樹一般為二層或者三層,索引節點比 MySQL 的 B+樹大,預設是 64KB。資料查詢的時候透過樹形結構定位到節點,節點內部資料是按照 rowkey 有序的,可以透過二分查詢快速定位到目標。

Kylin 小結:適用於聚合查詢場景;因為資料預聚合,Kylin 可以說是最快的查詢引擎(group-by 查詢這樣的複雜查詢,可能只需要掃描 1 條資料);kylin 查詢效率取決於是否命中 CuboId,查詢波動較大;HBase 索引有點類似 MySQL 中的聯合索引,維度在 rowkey 中的排序和查詢維度組合對查詢效率影響巨大;所以 Kylin 建表需要業務專家參與。

Druid 資料模型

Druid 資料模型比較簡單,它將資料進行預聚合,只不過預聚合的方式與 Kylin 不同,kylin 是 Cube 化,Druid 的預聚合方式是將所有維度進行 Group-by,可以參考下圖:

Druid 索引結構

Druid 索引結構使用自定義的資料結構,整體上它是一種列式儲存結構,每個列獨立一個邏輯檔案(實際上是一個物理檔案,在物理檔案內部標記了每個列的 start 和 offset)。對於維度列設計了索引,它的索引以 Bitmap 為核心。下圖為“city”列的索引結構:

首先將該列所有的唯一值排序,並生成一個字典,然後對於每個唯一值生成一個 Bitmap,Bitmap 的長度為資料集的總行數,每個 bit 代表對應的行的資料是否是該值。Bitmap 的下標位置和行號是一一對應的,所以可以定位到度量列,Bitmap 可以說是反向索引。同時資料結構中保留了字典編碼後的所有列值,其為正向的索引。

那麼查詢如何使用索引呢?以以下查詢為例:

select site, sum(pv) from xx where date=2020-01-01 and city='bj' group by site
city列中二分查詢dictionary並找到’bj’對應的bitmap遍歷city列,對於每一個字典值對應的bitmap與’bj’的bitmap做與操作每個相與後的bitmap即為city='bj’查詢條件下的site的一個group的pv的索引透過索引在pv列中查詢到相應的行,並做agg後續計算

Druid 小結:Druid 適用於聚合查詢場景但是不適合有超高基維度的場景;儲存全維度 group-by 後的資料,相當於只儲存了 KYLIN Cube 的 Base-CuboID;每個維度都有建立索引,所以每個查詢都很快,並且沒有類似 KYLIN 的巨大的查詢效率波動。

ClickHouse 索引結構 (只討論 MergeTree 引擎)

因為 Clickhouse 資料模型就是普通二維表,這裡不做介紹,只討論索引結構。整體上 Clickhouse 的索引也是列式索引結構,每個列一個檔案。Clickhouse 索引的大致思路是:首先選取部分列作為索引列,整個資料檔案的資料按照索引列有序,這點類似 MySQL 的聯合索引;其次將排序後的資料每隔 8192 行選取出一行,記錄其索引值和序號,注意這裡的序號不是行號,序號是從零開始並遞增的,Clickhouse 中序號被稱作 Mark’s number;然後對於每個列(索引列和非索引列),記錄 Mark’s number 與對應行的資料的 offset。

下圖中以一個二維表(date, city, action)為例介紹了整個索引結構,其中(date,city)是索引列。

那麼查詢如何使用索引呢?以以下查詢為例:

select count(distinct action) where date=toDate(2020-01-01) and city=’bj’
二分查詢primary.idx並找到對應的mark’s number集合(即資料block集合)在上一步驟中的 block中,在date和city列中查詢對應的值的行號集合,並做交集,確認行號集合將行號轉換為mark’s number 和 offset in block(注意這裡的offset以行為單位而不是byte)在action列中,根據mark’s number和.mark檔案確認資料block在bin檔案中的offset,然後根據offset in block定位到具體的列值。後續計算

該例項中包含了對於列的正反兩個方向的查詢過程。反向:查詢 date=toDate(2020-01-01) and city=’bj’資料的行號;正向:根據行號查詢 action 列的值。對於反向查詢,只有在查詢條件匹配最左字首的時候,才能剪枝掉大量資料,其它時候並不高效。

Clickhouse 小結:MergeTree Family 作為主要引擎系列,其中包含適合明細資料的場景和適合聚合資料的場景;Clickhouse 的索引有點類似 MySQL 的聯合索引,當查詢字首元組能命中的時候效率最高,可是一旦不能命中,幾乎會掃描整個表,效率波動巨大;所以建表需要業務專家,這一點跟 kylin 類似。

06 小結

Kylin、Druid只適合聚合場景,ClickHouse適合明細和聚合場景聚合場景,查詢效率排序:Kylin > Druid > ClickHouseKylin、ClickHouse建表都需要業務專家參與Kylin、ClickHouse查詢效率都可能產生巨大差異ClickHouse在向量化方面做得的最好,Druid少量運算元支援向量化、Kylin目前還不支援向量化計算。

作者:大資料技術與架構

出處:https://mp.weixin.qq.com/s?__biz=MzI0NTIxNzE1Ng==&mid=2651220676&idx=1&sn=7b68ed889ecfe7fc939f88dc3cadf2c3

9
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 如何優雅的消滅掉react生命週期函式