全部產品
Search
文件中心

PolarDB:GanosBase全空間資料多態(冷熱)階層式存放區能力解析與最佳實務

更新時間:Mar 18, 2025

GanosBasePolarDB PostgreSQL版聯合打造了全空間資料多態(冷熱)階層式存放區能力。多態(冷熱)階層式存放區將Object Storage Service直接作為一種更為經濟的資料庫儲存介質,能夠與Block Storage聯合使用。該方案支援將整庫、單表甚至表內的某一欄位儲存在不同介質上,同時確保增刪改查操作的全部透明性,並通過多級緩衝機制保障效能的最小衰減。多態(冷熱)階層式存放區是一種兼顧成本、效能與易用性的全空間資料管理方案,能夠顯著降低業務開發的複雜度及雲資源使用成本。

關於多態(冷熱)階層式存放區

業務背景

隨著物理世界數字化的快速發展,各行業的數字化業務催生了對大規模全空間多模多態資料進行快速處理的需求。傳統基於中介軟體的實現方式面臨著空間計算效能的嚴峻挑戰。為了進一步解決大規模全空間檢索效率問題,推動空間業務全面線上,GanosBase原生支援了全空間資料儲存類型與海量的計算運算元,以“空間計算全面下推”的方式極大程度提升查詢計算速度。 在提升計算效率的同時,空間資料的大規模增長和空間對象的日益增大可能會帶來愈發沉重的成本問題。此時,往往需要在成本與效率方面做出取捨,部分業務不得不重新遷回線下或者用離線任務的方式完成,業務開發不得不在多種儲存介質中來回切換,營運與研發成本大幅度上升。因此,尋找一種兼顧效率、成本與易用性的全空間資料管理方案成為GanosBase團隊曆時兩年所重點解決的問題,兩年中GanosBase團隊聚焦以下三個核心問題開展能力規劃與建設:

  1. 如何擁有更為廉價的資料庫儲存介質(非外表方式),降低成本。

  2. 如何保障這類廉價儲存的查詢計算效率不會存在大規模衰減。

  3. 如何以更為透明的方式管理和使用多種儲存介質。

GanosBase團隊發布了基於PolarDB PostgreSQL版14資料庫構建的全空間資料多態(冷熱)階層式存放區能力,將OSSObject Storage Service直接作為一種更為廉價的資料庫儲存介質,可以與Block Storage聯合使用。多態(冷熱)階層式存放區能力支援將整個資料庫、單個表乃至表內的特定欄位儲存於不同的介質上,同時確保增刪改查操作的完全透明性,並通過多級緩衝機制保障效能的最小衰減。多態(冷熱)階層式存放區是一種多方兼顧的全空間資料管理方案,同時它一樣也可以面向通用的資料庫類型欄位(BLOBTEXTJSONJSONBANYARRAY等)使用。

功能簡介

PolarDB PostgreSQL版14多態(冷熱)階層式存放區是傳統冷熱分離儲存功能的一個升級功能,在享受優良的讀寫效能的同時,又能將儲存成本降低到極致。多態(冷熱)階層式存放區支援根據資料的冷熱程度進行階層式存放區。此外,它能夠相容OSS、MinIO、HDFS等多種Object Storage Service介質。同時,它為大物件類型和全空間資料類型提供靈活多樣的儲存群組合,簡稱為多態(冷熱)階層式存放區。當前多態儲存只支援OSSObject Storage Service,更多使用說明請參見冷資料階層式存放區概述

image.png

基於多態(冷熱)階層式存放區功能,可以通過簡便的SQL語句將到期資料、大對象資料及全空間資料等轉存至OSS,實現彈性、低成本和高可靠性的資料管理。轉存後,無需對SQL語句進行任何改動,且能夠完全透明地執行增、刪、改、查及表間聯合等複雜分析操作。此外,當資料更新的訪問頻率增加時,也可以通過動態調整物化緩衝,以達到與資料庫雲端硬碟相同水平的訪問效能。

技術優勢

PolarDB PostgreSQL版14實現的多態(冷熱)階層式存放區具有以下幾方面的技術優勢:

  • 成本:支援資料壓縮,平均壓縮率50%,部分可達20%,使成本降為1/10甚至更低。

  • 效能:物化緩衝層加速冷存資料訪問,效能衰減可控制在20%-80%。

  • 易用:資料由冷到熱階層式存放區,冷存後支援增刪改查SQL完全透明。

  • 可靠:藉助OSS的高可靠性,冷資料在不增加儲存的前提下支援快照,資料具備恢複還原的能力。

  • 靈活:靈活的冷熱階層式存放區模式,支援按表、按大欄位、按子分區分別儲存在OSS中。

成本維度

當今時代資料呈爆炸式增長,尤其是帶有時間、空間等多維度資料。隨著時間的推移,積累的資料達到TB甚至PB層級,同時對於過往的資料或輔助性資料,其訪問頻率比較低,此時儲存降本往往是核心訴求。在PolarDB PostgreSQL版冷熱階層式存放區架構中,先將冷資料按規則切成小塊,再對切好的塊資料進行壓縮,最後寫入OSS,達到通用資料壓縮率20%-40%,時空資料壓縮率60%-70%,平均壓縮率50%的效果,相當於將儲存於資料庫雲端硬碟中的資料轉存在OSS中同時資料體量再砍掉一半,最終達到儲存成本降為1/10甚至更低的水平。在此結合PolarDB雲端硬碟的計費標準、OSS單位儲存的成本,以及OSS中實現的壓縮比例,以100 GB資料每月儲存費對比:

雲端硬碟

多態(冷熱)階層式存放區(onOSS)

儲存計費標準

PSL40.238美元/GB/月

  • 本地冗餘:0.0173美元/GB/月

  • 同城冗餘:0.0232美元/GB/月

壓縮率

0

50%

最終費用

0.238*100 GB=23.8美元

  • 本地冗餘:

    • OSS:0.0173*(100 GB*50%)=0.865美元

    • Cache:0.238*1 GB=0.238美元

    共計1.103美元。

  • 同城冗餘:

    • OSS:0.0232*(100 GB*50%)=1.16美元

    • Cache:0.238*1 GB=0.238美元

    共計1.398美元。

最終的儲存費用不到原始的1/10。

效能維度

通常情況下,OSS訪問延遲是資料庫雲端硬碟訪問延遲的上百倍,如果直接存取儲存在OSS中的資料,其讀寫效能會有較大幅度降低。PolarDB PostgreSQL版14多態儲存功能利用資料庫雲端硬碟實現OSS資料的物化緩衝層。根據資料區塊實際訪問情況自動階層式存放區,讀寫操作可首先命中物化緩衝,確保訪問效能,整體更新和插入效能達共用盤90%,點查效能達共用盤80%,資料在物化緩衝中的生命週期由訪問頻率決定,實現降低儲存成本的同時擁有優良的訪問效能。

易用性維度

PolarDB PostgreSQL版實現的多態(冷熱)階層式存放區是一種完全透明的冷熱階層式存放區方案,使用起來比較簡單。首先,資料轉存至OSS後,支援資料的增、刪、改、查操作,支援索引掃描以及聯集查詢等各種複雜操作,SQL完全透明,無需有任何的改動。其次,執行資料轉存的操作也做到了簡單易用,比如分區表可按自訂規則自動轉存至OSS、基表與索引一鍵轉存至OSS等。詳細操作請參見最佳實務

可靠性維度

OSS的持久性可達到99.9999999999%,可用性則為99.995%。同時,OSS具備本地冗餘和同城冗餘功能,從而確保資料在OSS上的可靠性。然而,這並不意味著已經儲存在OSS中的資料可以完全不進行備份和恢複操作。對於儲存在OSS中的資料庫資料,雖然其更新和訪問頻率相對較低,但仍然支援業務情境中的重要查詢分析和資料採礦等功能。一旦發生誤改或誤刪,必須能夠迅速進行還原和恢複。PolarDB PostgreSQL版多態(冷熱)階層式存放區功能支援冷資料的備份恢複,基於Copy-On-Write機制的資料多版本管理,秒級快照,一次快照後,只有被更新的資料區塊會產生副本,無更新的資料區塊不產生副本,以極小的成本做到資料的真正可靠。

靈活性維度

PolarDB PostgreSQL版多態(冷熱)階層式存放區功能支援冷熱靈活搭配,具體支援以下幾種搭配模式:

  • 將整表資料存放區在OSS中,索引儲存在雲端硬碟中,降本後同時保證良好的訪問效能。

  • 將表中的大欄位、輔助性欄位隔離儲存區 (Isolated Storage)在OSS中,其餘欄位儲存在雲端硬碟中。

  • 只將分區表中到期子分區儲存在OSS中,熱分區儲存在雲端硬碟中,這是最經典的冷熱分離模式。這裡面還能衍生出好幾種組合,比如冷分區資料與索引都存入OSS中,溫分區資料存入OSS但索引保留在雲端硬碟中,而熱分區全部在雲端硬碟,使得查詢效能基本無衰減。

image (2).png

最佳實務

案例一:分區表到期子分區自動冷存

背景描述

軌跡資料採用分區表格儲存體,並按月進行分區,隨著時間的推移,三個月之前的軌跡資料訪問頻率大大降低(到期),為了降低儲存成本,需要資料庫自動將超過三個月的分區表進行冷存處理。

操作步驟

  1. 建立測試資料庫,詳細步驟請參見建立資料庫,並執行如下語句準備測試資料。

    --建立分區表
    CREATE TABLE traj(
      tr_id serial,
      tr_lon float,
      tr_lat float,
      tr_time timestamp(6)
    )PARTITION BY RANGE (tr_time);
    
    CREATE TABLE traj_202301 PARTITION OF traj
        FOR VALUES FROM ('2023-01-01') TO ('2023-02-01');
    CREATE TABLE traj_202302 PARTITION OF traj
        FOR VALUES FROM ('2023-02-01') TO ('2023-03-01');
    CREATE TABLE traj_202303 PARTITION OF traj
        FOR VALUES FROM ('2023-03-01') TO ('2023-04-01');
    CREATE TABLE traj_202304 PARTITION OF traj
        FOR VALUES FROM ('2023-04-01') TO ('2023-05-01');
    
    --往分區表中寫入測試資料
    INSERT INTO traj(tr_lon,tr_lat,tr_time) values(112.35, 37.12, '2023-01-01');
    INSERT INTO traj(tr_lon,tr_lat,tr_time) values(112.35, 37.12, '2023-02-01');
    INSERT INTO traj(tr_lon,tr_lat,tr_time) values(112.35, 37.12, '2023-03-01');
    INSERT INTO traj(tr_lon,tr_lat,tr_time) values(112.35, 37.12, '2023-04-01');
    
    --建立分區表索引
    CREATE INDEX traj_idx on traj(tr_id);
  2. 在測試資料庫中建立polar_osfs_toolkit外掛程式,用以支援使用工具類函數,包括主表與索引一鍵轉存OSS、分區表一鍵轉存OSS等。

    CREATE extension polar_osfs_toolkit;
  3. 使用高許可權賬戶串連到postgres資料庫中安裝pg_cron外掛程式,其他注意事項請參見pg_cron

    ---只有高許可權賬戶串連到postgres資料庫中執行該語句才可以建立pg_cron外掛程式
    CREATE EXTENSION pg_cron;
  4. 設定定時執行任務。使用高許可權賬戶串連到postgres資料庫為測試資料庫建立一個名為task1的任務,任務為調用預存程序將超過分區3的歷史分區表自動轉入OSS儲存,函數將返回任務ID:

    -- 每分鐘執行
    SELECT cron.schedule_in_database('task1', '* * * * *', 'select polar_alter_subpartition_to_oss(''traj'', 3);', 'db01');

    返回結果如下:

     schedule_in_database 
    ----------------------
                        1
  5. 查看執行結果及歷史執行記錄。

    • 在測試資料庫中使用psql工具查看分區表的儲存位置:

      \d+ traj_202301

      返回結果如下:

                                                                       Table "public.traj_202301"
       Column  |              Type              | Collation | Nullable |               Default               | Storage | Compression | Stats target | Description 
      ---------+--------------------------------+-----------+----------+-------------------------------------+---------+-------------+--------------+-------------
       tr_id   | integer                        |           | not null | nextval('traj_tr_id_seq'::regclass) | plain   |             |              | 
       tr_lon  | double precision               |           |          |                                     | plain   |             |              | 
       tr_lat  | double precision               |           |          |                                     | plain   |             |              | 
       tr_time | timestamp(6) without time zone |           |          |                                     | plain   |             |              | 
      Partition of: traj FOR VALUES FROM ('2023-01-01 00:00:00') TO ('2023-02-01 00:00:00')
      Partition constraint: ((tr_time IS NOT NULL) AND (tr_time >= '2023-01-01 00:00:00'::timestamp(6) without time zone) AND (tr_time < '2023-02-01 00:00:00'::timestamp(6) without time zone))
      Replica Identity: FULL
      Tablespace: "oss" --已經儲存在OSS
      Access method: heap
    • 可在postgres資料庫中查看定時任務歷史執行記錄。

      SELECT * FROM cron.job_run_details;

該實踐實現按自訂規則自動將到期分區錶轉為冷存,冷存後的分區表不再佔用雲端硬碟儲存空間,大大降低儲存成本,同時增刪改查操作也完全透明。

案例二:單表大欄位階層式存放區

背景描述

大欄位包括BLOBTEXTJSONJSONBANYARRAY以及時空引擎類型的欄位,本案例旨在介紹如何將一張表中的大欄位分離並隔離儲存區 (Isolated Storage)於OSS中,同時實現訪問的透明性,以達到通過按欄位維度進行冷熱資料分離以降低成本的目的。

操作步驟

  1. 建立包含大欄位的表。當前以TEXT類型為例,其餘類型大欄位使用方法類似。

    CREATE TABLE blob_table(id serial, val text);
  2. 設定大欄位儲存位置。

    ALTER TABLE blob_table ALTER COLUMN val SET (storage_type='oss');
  3. 寫入資料並查看儲存。

    • 寫入資料,此時val欄位完全儲存在OSS中。

      INSERT INTO blob_table(val) VALUES((SELECT string_agg(random()::text, ':') FROM generate_series(1, 100000)));
    • 查看val欄位儲存位置。

      WITH tmp AS (SELECT 'pg_toast_'||b.oid||'_'||c.attnum AS tblname FROM pg_class b, pg_attribute c WHERE b.relname='blob_table' AND c.attrelid=b.oid AND c.attname='val') SELECT t.spcname AS storage_engine FROM pg_tablespace t, pg_class r, tmp m WHERE r.relname = m.tblname AND t.oid=r.reltablespace;

      返回結果如下:

       storage_engine 
      ----------------
       oss
      (1 row)
說明
  • 只有在先調用ALTER COLUMN的SQL語句設定大欄位的儲存位置之後寫入的資料才會真正儲存至OSS。

  • 對於已有的資料表,如果希望將某個大欄位轉存至OSS,可以先調用ALTER COLUMN的SQL語句設定大欄位的儲存位置,然後執行VACUUM FULL,將資料重新寫入。如果不執行VACUUM FULL,歷史資料將繼續儲存在雲端硬碟中,而新寫入的資料則將儲存在OSS,該語句是否執行不影響對錶資料的增刪改查操作。需要注意的是,如果資料量較大,執行時間可能會較長,並且在執行過程中,該資料表將無法提供讀寫服務。

案例三:時空分析情境如何?降本增效(進階進階案例)

時空分析是指利用資料庫的能力,對全空間、時空及時序情境中的資料進行資料採礦、統計分析等功能。當前將以遙感影像的統計分析為例,介紹時空分析情境如何通過多態(冷熱)階層式存放區功能降低儲存成本,同時保持良好的分析效率。

說明

本案例為進階進階實踐,您可以選擇性地忽略中間處理步驟,直接關注最終的對比結果。

背景描述

遙感影像(柵格)資料在空間業務中的應用日益廣泛。由於遙感資料的體量較大,並且通常涉及影像瀏覽與分析統計等多項業務,針對分析統計類的非即時業務,降低儲存成本並提升易用性往往具有更大的吸引力。本案例將介紹如何利用經濟實惠的OSS儲存支援遙感影像的入庫管理,並提供同樣高效的統計分析功能。

操作步驟

  1. 資料準備。準備四幅landset遙感影像資料(您可自行準備此類資料)。

    image

  2. 遙感影像資料入庫。

    1. 建立測試資料庫rastdb。

    2. 在測試資料庫中安裝ganos_raster外掛程式,詳細介紹請參見柵格模型

      CREATE EXTENSION ganos_raster CASCADE;
    3. 匯入影像資料。

      CREATE TABLE raster_table (id integer, rast raster);
      INSERT INTO raster_table VALUES (1, ST_ImportFrom('rbt','/home/postgres/LC08_L1TP_113028_20190912_20190917_01_T1.TIF'));
      INSERT INTO raster_table VALUES (2, ST_ImportFrom('rbt','/home/postgres/LC08_L1TP_113029_20191030_20191114_01_T1.TIF'));
      INSERT INTO raster_table VALUES (3, ST_ImportFrom('rbt','/home/postgres/LC08_L1TP_114028_20191005_20191018_01_T1.TIF'));
      INSERT INTO raster_table VALUES (4, ST_ImportFrom('rbt','/home/postgres/LC08_L1TP_114029_20200905_20200917_01_T1.TIF'));
  3. 統計資料佔用的儲存空間。在GanosBase中,Raster類型是一種中繼資料和塊資料單獨儲存、統一管理的模式,基表中儲存了影像的中繼資料,塊表中儲存了影像的塊資料,為了方便統計塊表中資料大小,這裡需要手動建立預存程序:

    CREATE OR REPLACE FUNCTION raster_data_internal_total_size( rast_table_name text, rast_column_name text)
      RETURNS int8 AS $$
    DECLARE
        sql                 text;
        sql2                text;
        rec                 record;
        size                int8;
        totalsize           int8;
        tbloid              Oid;
    BEGIN
        size := 0;
        totalsize := 0;
    
        --查詢raster對象的塊資料表
        sql = format('select distinct(st_datalocation(%s)) as tblname from %s where st_rastermode(%s) = ''INTERNAL'';', rast_column_name, rast_table_name, rast_column_name);
        for rec in
            execute sql
        loop
            sql2 = format('select a.oid from pg_class a, pg_tablespace b where a.reltablespace = b.oid and b.spcname=''oss'' and a.relname=''%s'';', rec.tblname);
            execute sql2 into tbloid;
    
            if (tbloid > 0) then
                size := 0;
            else
                --統計每張資料表的大小
                sql2 = format('select pg_total_relation_size(''%s'');',rec.tblname);
                execute sql2 into size;
            end if;
            totalsize := (totalsize + size);
        end loop;
        return totalsize;
    END;
    $$ LANGUAGE plpgsql;

    建立預存程序完成後,執行統計,結果表示目前影像資料佔用的資料庫儲存空間在1.2 GB左右。

    SELECT pg_size_pretty(raster_data_internal_total_size('raster_table','rast'));

    返回結果如下:

     pg_size_pretty 
    ----------------
     1319 MB
    (1 row)
  4. 統計NDVI。資料存放區在雲端硬碟。首先進行一次NDVI統計。在統計過程中,需要對多幅影像資料進行嵌套拼接(mosaic),利用拼接得到的完整影像進行NDVI計算,並統計所需時間,詳細介紹請參見ST_MosaicFrom

    CREATE TABLE rast_mapalgebra_result(id integer, rast raster);
    
    INSERT INTO rast_mapalgebra_result SELECT 1, ST_MapAlgebra(ARRAY(SELECT st_mosaicfrom(ARRAY(SELECT rast FROM raster_table ORDER BY id), 'rbt_mosaic','','{"srid":4326,"cell_size":[0.005,0.005]')),    '[{"expr":"([0,3] - [0,2])/([0,3] + [0,2])","nodata": true, "nodataValue":0}]',    '{"chunktable":"rbt_algebra","celltype":"32bf"}');

    返回結果如下:

    INSERT 0 1
    Time: 39874.189 ms (00:39.874)
  5. 影像塊資料冷存處理。將遙感影像的塊資料做冷存處理存入OSS,遙感影像的中繼資料依舊儲存在雲端硬碟中,為了方便處理,需要建立預存程序:

    CREATE OR REPLACE FUNCTION raster_data_alter_to_oss( rast_table_name text, rast_column_name text)
      RETURNS VOID AS $$
    DECLARE
        sql                 text;
        sql2                text;
        rec                 record;
    BEGIN
        --查詢raster對象的資料表
        sql = format('select distinct(st_datalocation(%s)) as tblname from %s where st_rastermode(%s) = ''INTERNAL'';', rast_column_name, rast_table_name, rast_column_name);
        for rec in
            execute sql
        loop
            sql2 = format('alter table %s set tablespace oss;',rec.tblname);
            execute sql2;
        end loop;
    END;
    $$ LANGUAGE plpgsql;

    建立完預存程序後,執行冷存處理,冷存後再次統計塊資料表佔用的雲端硬碟儲存空間:

    SELECT raster_data_alter_to_oss('raster_table', 'rast');
    
    --統計冷存後塊資料在雲端硬碟佔用的空間
    SELECT pg_size_pretty(raster_data_internal_total_size('raster_table','rast'));

    返回結果顯示共用盤統計的儲存空間為0,說明此時塊資料都已經儲存在OSS中。

     pg_size_pretty 
    ----------------
     0 bytes
    (1 row)
  6. 重新統計NDVI值。資料區塊儲存在OSS中後,重新做一次NDVI統計計算:

    INSERT INTO rast_mapalgebra_result select 2, ST_MapAlgebra(ARRAY(select st_mosaicfrom(ARRAY(SELECT rast FROM raster_table ORDER BY id), 'rbt_mosaic','','{"srid":4326,"cell_size":[0.005,0.005]')),    '[{"expr":"([0,3] - [0,2])/([0,3] + [0,2])","nodata": true, "nodataValue":0}]',    '{"chunktable":"rbt_algebra","celltype":"32bf"}');

    返回結果如下:

    INSERT 0 1
    Time: 69414.201 ms (01:09.414)

    image

  7. 儲存成本及效能表現對比。

    對比項

    雲端硬碟儲存

    OSS冷存

    對比值

    儲存成本

    1011.834 MB 按0.0232 美元/GB/月,費用為0.023美元。

    10:1

    NDVI統計耗時

    39s

    69s

    1:1.76

    對比結果顯示,使用OSS冷存的費用為共用盤的1/10以下,且計算效能降低控制在1倍以內。這一性價比在不追求即時性(RT)的統計分析情境中具有相當高的價值。

總結

目前,GanosBase已成功支撐數十個行業領域的數千個應用情境。穩定性、成本效益、效能與易用性始終是GanosBase長期追求的目標。全空間多態儲存能力是GanosBasePolarDB PostgreSQL版資料庫上構建的核心級核心競爭力,能夠為全空間資料管理提供真正兼顧成本、效能與易用性的解決方案,歡迎您開通體驗。