天天看點

AnalyticDB for PostgreSQL 黑科技解析 - 列存儲 Meta Scan 性能加速1. 概述2. 列存 metascan的實作3. TPC-H測試4. 既有執行個體更新 meta scan5. 結論

作者:張曉博

2011年畢業于武漢理工大學,曾任職于人大金倉、北大方正信産研究院、百分點等公司,從事資料庫核心開發工作,現在任職于阿裡雲資料庫事業部,雲化資料倉庫服務 AnalyticDB for PostgreSQL 資料庫核心開發技術專家。

1. 概述

AnalyticDB for PostgreSQL

(原HybridDB for PostgreSQL,以下簡稱 ADB PG)是阿裡雲上的MPP資料倉庫服務,其核心采用PostgreSQL引擎,基于開源資料庫 Greenplum 改造,并在此基礎上優化分析性能,其中列存儲 metascan 就是提升資料庫查詢性能的一個關鍵特性。

ADB PG支援列存儲格式,具有較高的資料壓縮能力,以及查詢性能,但是當針對有較高過濾率的查詢條件時,依然要做整列資料讀取,或者建 B-Tree 索引,但是索引也有其應用的限制:一是索引無壓縮,資料膨脹較嚴重;二是結果集大的時候,索引代價比 tablescan 高,索引失效等問題。為此 ADB PG 開發了meta scan 功能,具有很好的過濾性能,并且占用的存儲空間也基本可以忽略不計。

ADB PG 的meta scan是對列存表的一種加強,通過收集列存表列的max/min,并配合 block offset機制,可以實作類似于索引的過濾功能。meta資訊裡儲存列的每個block的max、min,offset,max/min用于條件過濾,block offset用于跳過不滿足過濾條件的block,以達到最大程度的減少列存讀取的IO和block解壓的CPU消耗,進而實作查詢性能的提升。TPC-H 1TB 測試整體提升 29%,對于有高過濾率條件的查詢裡,可以提升最高5倍性能,比如 TPC-H的 Q06、Q12、Q14、Q15。

2. 列存 metascan的實作

ADB PG的 meta scan 機制類似于開源格式 ORC 或者 PARQUET的元資訊,通過meta 資訊過濾掉不滿足條件的列存 block,來提升性能。

AnalyticDB for PostgreSQL 黑科技解析 - 列存儲 Meta Scan 性能加速1. 概述2. 列存 metascan的實作3. TPC-H測試4. 既有執行個體更新 meta scan5. 結論

如上圖所示,ADB PG的每張列存表的資料分為2部分,一部分是表資料,一部分是meta資料,存儲收集的meta資訊。在scan的時候,先讀取meta資料,根據min、max過濾掉不需要讀取的block,通過block offset直接讀取滿足條件的block,然後把tuple傳回給executor,executor計算後,把結果傳回給用戶端。

ADB PG meta存儲格式如下:

AnalyticDB for PostgreSQL 黑科技解析 - 列存儲 Meta Scan 性能加速1. 概述2. 列存 metascan的實作3. TPC-H測試4. 既有執行個體更新 meta scan5. 結論

meta資訊按行分為兩級meta:row group meta和batch group meta

  • row group meta:

    每張表的meta資訊有多個row group meta組成,每個row group meta的max/min反應了連續的1w行的meta資訊。每個row group meta包含10個row batch meta,如上圖所示,row group的meta為:(min, max) = (1, 4000)。

  • row batch meta:

    每個row batch meta的min/max反應了連續1000個行的meta資訊。與row group meta不同的是row batch meta還會記錄覆寫的第一行所在的block 的block offset。

metascan 在掃描時,會順序讀取row group meta,如果過濾條件滿足目前row group的min/max,則依次周遊每個row batch meta,如果過濾條件滿足row batch meta的min/max,則會根據block offset,直接定位到檔案中的block,否則掃描下一個row batch meta;如果過濾條件不滿足目前的row group,這讀取下一個row group meta,如此循環,直到所有的資料周遊完全。

AnalyticDB for PostgreSQL 黑科技解析 - 列存儲 Meta Scan 性能加速1. 概述2. 列存 metascan的實作3. TPC-H測試4. 既有執行個體更新 meta scan5. 結論

為了簡單并且滿足事務特性,meta資訊我們采用heap表的形式儲存,即meta儲存到輔助表中。在建立一個列存表時,同時建立meta表。這樣通過heap表的mvcc以及事務機制,可以自然的實作meta資訊與表資料資訊的一緻性和原子性。

但是該實作方式有一個問題,按這種方式meta必須覆寫所有的資料,即表上的每一行資料更新,必須更新meta,如果使用者使用單條insert這種方式插入資料,則meta資訊會被頻繁更新,這樣既會降低寫入的性能又會降低查詢是scan meta資訊的性能。為解決這個問題,我們把meta 表分成兩個primary meta 表和secordary meta 表。随着insert/update主表,meta資訊會同步更新到secordary meta表中,當每個row group meta覆寫1w個行時,把meta資訊從secordary meta表移動到primary meta表中,查詢的時候隻查詢primary meta表,這樣就不會因為主表資料的頻繁小量insert/update而導緻primary meta膨脹。但是使用這種meta維護方式,scan就需要對primary meta 沒有覆寫的行做特殊處理,是以meta scan執行邏輯如下:

AnalyticDB for PostgreSQL 黑科技解析 - 列存儲 Meta Scan 性能加速1. 概述2. 列存 metascan的實作3. TPC-H測試4. 既有執行個體更新 meta scan5. 結論

meta資訊的收集是按segfile來劃分的,是以當一個segfile的meta讀取完後,需要把該segfile檔案尾部的tuple順序傳回給executor。對于primary meta表沒有記錄的segfile,scan完primary meta後,同樣的把這些segfile順序掃描一遍。這樣通過meta scan就可以掃描所有的表資料。

目前的metascan支援如下的資料類型和操作符:

  • 支援的類型:

    Int2/int4/int8

    Float4/float8

    Time/timetz/timestamp/timestamptz

    Varchar/text/bpchar

    cash

  • 支援的操作符

    =、<、<=、>、>=

    and 邏輯運算符

sortkey 是AnalyticDB for PostgreSQL的另一個特性,可以讓表按指定的列排序,其用來指定在單分區内資料進行排序。把metascan與sortkey結合使用,可以更有效的提高meta scan執行的性能。如果列的值在資料檔案中分布比較分散,即使過濾性比較好,meta scan的執行性能可能不好,因為列的值分散在太多的block内,導緻隻能跳過極少的block。這種情況就可以在表上建立 sortkey,使得在單分區内資料有序排列,讓表按照過濾字段排序,這樣相同的值都會集中在一起,這些block都是連續的,這樣在執行metascan時,就可以跳過掉大部分block,進而提升掃描的性能。

3. TPC-H測試

TPCH 是一個測試OLAP資料倉庫性能的标準測試集,其主要評價名額是各個查詢的響應時間,即從送出查詢到結果傳回所需時間,我們在ADB PG上針對meta scan特性測試對tpch的加速效果,針對tpch 1TB資料HDD硬碟測試,在其中4個表上建立了sortkey:

table name sort key
customer c_mktsegment
part p_brand
lineitem l_shipdate
orders o_orderdate

tpch 測試結果如下:

query metascan tablescan 性能提升 (%)
q01 19.347 11.199 0.00%
q02 55.696 59.996 7.72%
q03 170.492 206.383 21.05%
q04 108.586 129.101 18.89%
q05 160.95 165.855 3.05%
q06 19.564 53.544 173.69%
q07 646.875 629.539
q08 153.666 156.489
q09 724.835 725.829
q10 217.339 248.316 14.25%
q11 30.574 29.692
q12 44.796 113.121 152.52%
q13 178.811 199.52 11.58%
q14 12.194 72.635 495.66%
q15 39.285 115.22 193.29%
q16 58.443 64.909 11.06%
q17 1446.869 1394.215
q18 1118.851 1110.468
q19 212.091 225.613 6.38%
q20 331.7 365.711 10.25%
q21 1027.04 1015.196
q22 165.681 167.305
Total (GEOMEAN) 163.315 211.372 29.43%

從測試結果看,對于Q03、Q04、Q06、Q10、Q12、Q14、Q15有非常顯著的性能提升,最多提升了5倍左右。對于tpch 整體性能,按Geomean算後,有22%的提升。

對于剩餘的查詢無明顯的性能提升。分析這些查詢的特性,meta scan對于tpch中有強過濾條件的查詢,性能提升較明顯,但對于全表scan或者join則沒有效果。

4. 既有執行個體更新 meta scan

對于阿裡雲 AnalyticDB for PostgreSQL 的現有執行個體,如何使用新的meta scan機制? meta scan在實作的時候做了存儲格式的前向相容,現有執行個體通過小版本更新後,如果要使用新的meta scan特性,則需要重新整理列存表的 meta 資訊,可以使用如下的 UDF 來重新整理某張表的meta資訊:

CREATE OR REPLACE FUNCTION UPGRADE_AOCS_TABLE_META(tname TEXT) RETURNS BOOL AS 
$$

DECLARE
    tcount INT := 0;
BEGIN
    -- CHECK TABLE NAME
    EXECUTE 'SELECT COUNT(1) FROM PG_AOCSMETA WHERE RELID = ''' || tname || '''::REGCLASS' INTO tcount;
    IF tcount IS NOT NULL THEN
        IF tcount > 1 THEN
            RAISE EXCEPTION 'found more than one table of name %', tname;
        ELSEIF tcount = 0 THEN
            RAISE EXCEPTION 'not found target table in pg_aocsmeta, table name:%', tname;
        END IF;
    END IF;

    EXECUTE 'ALTER TABLE ' || tname || ' SET WITH(REORGANIZE=TRUE)';
    RETURN TRUE;
END;

$$
  LANGUAGE PLPGSQL;

select UPGRADE_AOCS_TABLE_META(tname);           

AnalyticDB for PostgreSQL 提供了配置參數rds_enable_column_meta_scan用來啟動和關閉metascan,可以使用如下sql啟動或者關閉目前session的metascan:

-- disable metascan
set rds_enable_column_meta_scan = off;
-- enable metascan
set rds_enable_column_meta_scan = on;
-- show metascan is enable?
show rds_enable_column_meta_scan;           

如果需要執行個體級别的開啟或者關閉metascan,可以提工單聯系我們的技術支援同學修改。

5. 結論

ADB PG 的列存儲 meta scan主要是通過row group 和batch group的max/min 過濾不滿足的block,通過block offset,直接讀取滿足條件的block,這種方式減少掃描是的IO以及block解壓時的CPU消耗,是以在查詢的filter具有一定的過濾性時,meta scan可以有比較明顯的性能提升。

ADB PG 基于開源資料庫PostgreSQL/Greenplum建構,由阿裡雲資料庫 OLAP 資料庫團隊維護演進,近期會将全部功能增強開源,回饋開源社群。