快速入門

更新時間:
Copy as MD

GanosBase TSDB是在PolarDB PostgreSQL基礎上以外掛程式的形式實現的時序資料庫,它繼承了PolarDB PostgreSQL叢集擁有的共用儲存、一寫多讀、備份恢複等一切能力,除此之外它可完全相容開源時序資料庫TimescaleDB Apache 2.0版本,並提供連續彙總、時序壓縮、統計分析等時序資料進階功能。本文介紹時序資料庫的基本概念,以及GanosBase TSDB的基本用法,包括啟用與升級維護,同時介紹時序資料庫的使用方法。

適用範圍

支援的PolarDB PostgreSQL的版本如下:

  • PostgreSQL 14(核心小版本2.0.14.13.26.0及以上)。

  • PostgreSQL 16(核心小版本2.0.16.9.8.0及以上)。

說明

您可在控制台查看核心小版本號碼,也可以通過SHOW polardb_version;語句查看。如未滿足核心小版本要求,請升級核心小版本

基本概念

  • 時序資料(Time Series Data):指按照時間順序記錄的資料序列。這類資料的特點是資料點不僅包含數值資訊,還關聯了具體的時間戳記,反映了某一變數隨時間變化的趨勢或模式。時序資料廣泛應用於多個領域,如金融交易、氣象觀測、感應器監測、網站流量分析、疾病傳播研究等。時序資料的關鍵要素包括:

    • 時間戳記:每個資料點都有一個明確的時間標記,表明資料的採集時間。

    • 觀測值:在各個時間點上測量或記錄到的資料值。

    • 順序性:資料點按照時間的先後順序排列,這種順序反映了資料之間的自然時間關係,使得時序資料具有時間序列的特性。

    • 趨勢和周期性:時序資料分析中常關注資料中的長期趨勢、季節性波動、周期性變化以及隨機波動等特徵。

  • 度量(Metrics):時序資料監測指標,如溫度、股價、網路流量等任何可以量化測量的數值,度量可以協助理解時序資料的行為模式、預測未來趨勢,並能及時發現並響應異常情況。

  • 彙總(Aggregation):指在時間序列資料分析中,將較高頻率的資料彙總到較低頻率的過程,簡單來說,就是將資料按時間維度進行合并或匯總,從而減少資料的粒度,但同時能保留資料的主要趨勢或特徵。這種處理方式對於資料降維、趨勢分析、異常檢測以及預測模型的構建都非常有用。

  • 降採樣(Downsampling):時序資料處理的一個常見操作,可以減少時間序列資料的採樣頻率,即降低資料點的數量,同時嘗試保留未經處理資料的關鍵特徵或趨勢。時序降採樣的幾種常見方法:

    • 直接抽樣(Decimation):這是最直接的方法,簡單地每隔N個點取一個資料點。例如,如果原序列每秒採樣10次,您可以選擇只保留每5個點中的第一個,從而實現每秒2次的採樣率。這種方法簡單但可能會丟失高頻資訊。

    • 平均值法(Averaging):在降採樣前,先對連續的資料點進行平均處理。例如,將連續的5個點取平均值作為新的一個資料點。這種方法有助於平滑資料,減少雜訊,但可能會模糊快速變化的細節。

    • 中值法(Median):與平均值法類似,但使用連續資料點的中值代替平均值,這在處理包含異常值的時間序列時更為穩健。

    • 最大值/最小值法:選取連續資料點中的最大值或最小值作為新資料點,適用於需要保留峰值或穀值的情境。

    • 重採樣(Resampling):通過插值等方法調整資料到新的時間點上,然後在新的時間軸上進行均勻採樣。常見的重採樣方法有線性插值、最近鄰插值、立方插值等。重採樣方法更加靈活,可以根據需求調整到任意的採樣頻率,同時儘可能保持原資料的形態。

    • 模型預測降採樣:利用統計模型或機器學習模型預測在較低採樣率下的資料點,比如使用ARIMA、LSTM等模型預測每個新時間點的值,然後使用這些預測值作為降採樣後的資料。這種方法可以更智能地降採樣,但計算成本較高。

GanosBase TSDBTimescaleDB對比

  • TimescaleDB:基於PostgreSQL構建的開源時序資料庫(Time-Series Database),專為處理時間序列資料(如感應器資料、監控指標、金融資料等)最佳化,其設計目標是在保留PostgreSQL完整SQL功能的同時,提供時序資料的高效儲存、快速寫入和複雜查詢能力。

  • GanosBase TSDB:在開源時序資料庫TimescaleDB基礎上開發的時序引擎,依託於PolarDB PostgreSQL叢集,以外掛程式的方式提供,同時完全繼承PolarDB共用儲存、一寫多讀、備份恢複等一切能力。

區別

兩者主要在其提供的功能方面存在差異TimescaleDB Apache 2 Edition是在Apache 2.0協議許可下發布的TimescaleDB版本。Apache 2.0協議開源許可證允許任何人使用這些代碼並將其作為服務提供,但僅提供基礎功能。

對此,GanosBase TSDB在完全相容TimescaleDB的基礎上,額外提供時序連續彙總資料壓縮、OSS冷熱階層式存放區等進階功能。

啟用時序資料庫

PolarDB PostgreSQL叢集中啟用時序資料庫能力,需要將timescaledb添加到shared_preload_libraries參數中。您可以通過控制台修改shared_preload_libraries參數

說明

修改shared_preload_libraries參數後叢集將會重啟,請在修改參數前做好業務安排,謹慎操作。

建立外掛程式

GanosBase TSDB外掛程式依賴TimescaleDB外掛程式,因此您可以使用以下任一方式建立。

  • 建立ganos_tsdb時指定CASCADE,將同時建立TimescaleDB外掛程式。

    CREATE EXTENSION ganos_tsdb CASCADE;
  • 手動建立。先建立TimescaleDB,再建立ganos_tsdb

    CREATE EXTENSION timescaledb;
    CREATE EXTENSION ganos_tsdb;
說明
  • 如在安裝外掛程式時遇到ERROR: Disable the injection of custom functions when creating extension: metadata_insert_trigger (21128)類似錯誤,請聯絡我們開放相關許可權後再執行安裝外掛程式語句。

  • 為避免許可權問題,建議您將擴充安裝在PUBLIC模式下。

    CREATE EXTENSION ganos_tsdb WITH SCHEMA PUBLIC CASCADE;

升級外掛程式

對於已經安裝了GanosBase TSDB或者TimescaleDB外掛程式的叢集,可以通過以下命令升級:

--先升級timescaledb
ALTER EXTENSION timescaledb UPDATE;

--再升級ganos_tsdb
ALTER EXTENSION ganos_tsdb UPDATE;

時序超表

超表(Hypertable)是時序資料庫提供的一種特殊功能的表,可輕鬆處理時間序列資料,使用常規表可以完成的所有操作都可以使用超表完成。

功能特性

  • 超表可自動按時間對資料進行分區。與超表的互動方式與常規表相同,但超表還具有一些額外功能,可更輕鬆地行政時間序列資料。

  • 在時序資料庫中,超表與常規表並存。使用超表來儲存時間序列資料,這可以提高資料寫入和查詢效能,並支援在超表上使用序列功能函數。

  • 藉助超表,時序資料庫可以根據時間參數對時間序列資料進行分區,在後台,由資料庫自動執行設定和維護超表分區的工作。

建立超表

將一張普通資料錶轉為超表的文法如下:

SELECT create_hypertable(
    'table_name',
    'time_column_name',
    'partitioning_column_name',
    number_partitions,
    'associated_schema_name',
    'associated_table_prefix',
    chunk_time_interval,
    create_default_indexes,
    if_not_exists,
    partitioning_func,
    migrate_data,
    chunk_target_size,
    chunk_sizing_func,
    time_partitioning_func
);

具體參數解釋如下:

參數名稱

是否必選

描述

table_name

需要轉為超表的資料表名稱或OID,為了區分,以下稱其為原表,轉為超表後,名稱與原表同名。

time_column_name

原表中具有時序特徵的時間欄位名,支援如下資料類型:

  • TIMESTAMP/TIMESTAMPTZ/DATE類型。

  • 被視為微秒的整數類型。

  • INTERVAL類型。

partitioning_column_name

分區欄位名,預設按原表的時間欄位分區。

number_partitions

分區數量。

associated_schema_name

指定超表所在的Schema。

associated_table_prefix

由於超表由一系列的分塊表組成,塊表會在內部自動建立,這裡可指定塊表的首碼。

chunk_time_interval

超表分塊的時間間隔,預設按7 天分塊。

create_default_indexes

是否在超表的時間欄位上建立B樹索引,取值範圍如下:

  • true(預設):在超表的時間欄位上建立B樹索引。

  • false:不在超表的時間欄位上建立B樹索引。

if_not_exists

如果超表已經建立,是否報錯,取值範圍如下:

  • true:如果超表已經建立,則報錯。

  • false(預設):如果超表已經建立,不報錯。

partitioning_func

如果使用空間分區,可指定自訂的空間分區函數。

migrate_data

如果原表中已經存在資料,是否將資料轉移至超表,取值範圍如下:

  • true:如果原表中已經存在資料,將資料轉移至超表。

  • false(預設):如果原表中已經存在資料,不將資料轉移至超表

chunk_target_size

指定塊表的大小(樣本:'1000MB', 'estimate', or 'off')。

chunk_sizing_func

chunk_target_size配合使用,指定自訂的函數以統計塊表的時間間隔,並應用在新的塊表中。

time_partitioning_func

指定用於時間分區的分區函數。

超表的分區

  • 在建立和使用超表時,它會自動按時間對資料進行分區,也可以按空間對資料進行分區。

  • 每個超表由稱為塊(chunk)的子表組成,每個塊分配一個時間範圍,並且僅包含該範圍內的資料。如果超表也按空間分區,則每個塊也會分配空間值的子集。

  • 超表的每個塊僅儲存特定時間範圍內的資料。當插入尚無塊的時間範圍內的資料時,會自動建立一個塊來儲存它。

預設情況下,按7天時間間隔進行分區塊,也可以使用以下SQL語句修改分區時間間隔。

SELECT set_chunk_time_interval(
    'table_name',
    chunk_time_interval,
    'dimension_name'
);

具體參數解釋如下:

參數名稱

描述

table_name

超表名稱。

chunk_time_interval

超表分塊時間間隔。

dimension_name

選擇性參數,指定分區(維度)策略,預設為NULL。

樣本

以交易資料為例,建立時序超表:

  1. 建立普通表:

    CREATE TABLE transaction_data(
       tm TIMESTAMPTZ NOT NULL,
       id INT NOT NULL,
       price double precision);
  2. 設定普通表的複製標識,必須為DEFAULT模式:

    ALTER TABLE transaction_data replica IDENTITY DEFAULT;
  3. 將普通錶轉換為超表:

    SELECT create_hypertable('transaction_data', 'tm', chunk_time_interval => INTERVAL '1 day');
    說明

    如果該表已存在資料,請在轉換為超表時增加migrate_data參數並設定為true,但如果表資料量較大,轉換過程可能消耗較長時間。

  4. (可選)修改超表分區間隔。

    SELECT set_chunk_time_interval('transaction_data', chunk_time_interval => INTERVAL '2 day');

連續彙總

連續彙總(continuous aggregates)是一種自動化的預電腦制,通過定期或即時更新預先定義的彙總結果(如每小時平均值),將複雜查詢轉換為對預計算結果的快速讀取。它類似於物化視圖(Materialized View),但針對時序資料進行最佳化,支援累加式更新,避免重複計算歷史資料,旨在加速超巨量資料集查詢。

功能優勢

  • 查詢加速:直接查詢預計算結果,避免全表掃描未經處理資料。

  • 節約資源:減少CPU和記憶體的Realtime Compute消耗。

  • 自動化維護:自動處理新舊資料的彙總更新,無需手動觸發。

建立連續彙總

CREATE MATERIALIZED VIEW transaction_min_cagg
    WITH (timescaledb.continuous) -- 聲明為連續彙總
    AS
    SELECT id,
        time_bucket(INTERVAL '1 min', tm) AS bucket, -- 按1分鐘間隔做一次彙總
        AVG(price),
        MAX(price),
        MIN(price)
    FROM transaction_data
    GROUP BY id, bucket;

連續彙總資料存放區

連續彙總結果儲存在獨立的物化視圖中,資料按時間分塊(Chunk)儲存,與超表資料分區對齊。

任務調度

連續彙總是通過任務調度實現資料寫入及重新整理的。通過任務調度功能,可實現自動或手動對彙總結果進行重新整理。

建立任務

建立任務,該任務可自動化調度某個函數或預存程序。

integer add_job(
                proc REGPROC,
                schedule_interval INTERVAL,
                config JSONB DEFAULT NULL,
                initial_start TIMESTAMPTZ DEFAULT NULL,
                scheduled BOOL DEFAULT true,
                check_config REGPROC DEFAULT NULL,
                fixed_schedule BOOL DEFAULT TRUE,
                timezone TEXT DEFAULT NULL
                );

具體的參數解釋如下:

參數名稱

描述

proc

需要執行的函數或預存程序的名稱或OID。

schedule_interval

任務調度時間間隔。

config

任務配置參數。

initial_start

任務運行開始時間,預設為目前時間。

scheduled

是否自動運行,預設為true即自動運行。

check_config

檢查配置參數config是否有效函數,預設為NULL。

fixed_schedule

是否按固定時間間隔運行該任務,預設為true

timezone

時區,預設為NULL。

樣本
  1. 基礎資料準備。建立需要執行的預存程序。

    CREATE OR REPLACE PROCEDURE user_defined_action(job_id int, config jsonb) LANGUAGE PLPGSQL AS
    $$
    BEGIN
      RAISE NOTICE 'Executing action % with config %', job_id, config;
    END
    $$;
  2. 建立任務。返回任務id

    SELECT add_job('user_defined_action','1 hour');
    SELECT add_job('user_defined_action','1h', initial_start => '2024-03-11 00:00:00');

修改任務

修改已建立的任務。

void alter_job(    job_id INTEGER,
        schedule_interval INTERVAL = NULL,
        max_runtime INTERVAL = NULL,
        max_retries INTEGER = NULL,
        retry_period INTERVAL = NULL,
        scheduled BOOL = NULL,
        config JSONB = NULL,
        next_start TIMESTAMPTZ = NULL,
        if_exists BOOL = FALSE,
        check_config REGPROC = NULL,
        fixed_schedule BOOL = NULL,
        initial_start TIMESTAMPTZ = NULL,
        timezone TEXT DEFAULT NULL
        );

具體參數解釋如下:

說明

此處僅為部分參數說明,其他參數介紹可參見建立任務參數說明

參數名稱

描述

job_id

需要修改的目標任務id

max_runtime

任務運行最大時間,預設為NULL。

max_retries

任務運行失敗最大重試次數,預設為NULL。

retry_period

任務運行失敗重試時間間隔,預設為NULL。

樣本
SELECT alter_job(1002, schedule_interval => INTERVAL '2 hours');

手動運行任務

手動運行已存在的任務。

void run_job(job_id int);

具體參數解釋如下:

參數名稱

描述

job_id

需要啟動並執行目標任務id

樣本
CALL run_job(1002);

刪除任務

刪除任務。

void delete_job(job_id int);

具體參數解釋如下:

參數名稱

描述

job_id

需要刪除的目標任務id

樣本
SELECT delete_job(1002);

重新整理連續彙總

手動重新整理

手動重新整理連續彙總的預存程序。

refresh_continuous_aggregate(
    cagg     REGCLASS,
    window_start             "any",
    window_end               "any"
    );

具體的參數解釋如下:

參數名稱

描述

cagg

需要重新整理的連續彙總名稱或OID。

window_start

重新整理視窗開始時間,類型需與連續彙總時間欄位一致。

  • 如果重新整理視窗開始時間非整單位時間,可配合date_trunc使用。例如,按分鐘進行連續彙總,重新整理視窗時間為2024-03-11 13:01:29,則可設定重新整理視窗開始時間為2024-03-11 13:01:00

  • 不建議將該值設定為NULL。當設定為NULL時,資料庫將從表中擷取起始時間,如果表資料量過大,則需要消耗較長時間等待資料重新整理完成。

window_end

重新整理視窗結束時間,類型需與連續彙總時間欄位一致。

當不明確重新整理結束時間,可設定為NULL,表示重新整理到資料表的最新時間。

注意事項

  • 重新整理視窗的時間與表中資料時間相匹配,重新整理連續彙總時,只會重新整理完全符合的時間視窗的資料,對於不完整的時間段,無法計算彙總。

  • 如果多次調用refresh_continuous_aggregate的時間視窗存在重疊,則只針對有新增資料或修改資料的時間段做彙總,對於無資料修改的時間段不會做任何操作。

  • refresh_continuous_aggregate是預存程序函數,使用CALL調用。

樣本

CALL refresh_continuous_aggregate('transaction_min_cagg', '2024-03-11 00:00:00+08'::timestamptz, NULL);

自動重新整理

支援以下兩種方式實現連續彙總的自動重新整理。

(推薦)結合任務調度

通過add_job實現自動重新整理任務,使用更加靈活。但請區分任務啟動時間initial_start和重新整理視窗開始時間window_start,啟動時間需為整時單位,若為NULL表示立即執行,若為將來的時間,則將在設定的時間後開始執行。

樣本

  1. 定義重新整理策略。

    CREATE OR REPLACE PROCEDURE transaction_min_cagg_refresh() LANGUAGE PLPGSQL AS
    $$
    DECLARE
    BEGIN
        -- 重新整理視窗開始時間為'2024-03-11 00:00:00+08',重新整理視窗結束時間為NULL,表示重新整理到資料表的最新時間
        CALL refresh_continuous_aggregate('transaction_min_cagg', '2024-03-11 00:00:00+08'::timestamptz, NULL);
    END
    $$;
  2. 將重新整理任務添加至自動化運行隊列。此處設定為1分鐘自動重新整理一次,重新整理任務開始執行的時間為'2024-04-01 00:00:00+08'

    SELECT add_job('transaction_min_cagg_refresh','1 min', initial_start => '2024-04-01 00:00:00+08'::timestamptz);

使用add_continuous_aggregate_policy函數

針對指定的連續彙總建立重新整理策略,用於定期自動重新整理。

integer add_continuous_aggregate_policy(
                cagg REGCLASS,
                start_offset "any",
                end_offset "any",
                schedule_interval INTERVAL,
                if_not_exists BOOL = false,
                initial_start TIMESTAMPTZ = NULL,
                timezone TEXT = NULL
                );

具體的參數解釋如下:

參數名稱

描述

cagg

需要重新整理的連續彙總名稱或OID。

start_offset

以函數執行時間為基準,定義開始重新整理彙總的位移量,作為重新整理視窗的開始時間。如果設定為NULL,即重新整理視窗的起始時間為超表中資料的最小時間。

start_offset值必須大於end_offset值。

end_offset

以函數執行時間為基準,定義彙總結束的位移量,作為重新整理視窗的結束時間。如果設定為NULL,即重新整理視窗的結束時間為超表中資料的最大時間。

schedule_interval

重新整理間隔時間,預設為1天。

if_not_exists

如果重新整理策略已經建立,是否報錯,取值範圍如下:

  • true:如果重新整理策略已經建立,不報錯只警示。

  • false(預設):如果重新整理策略已經建立,則報錯。

initial_start

函數首次執行時間,預設為NULL。如果指定該值,則與schedule_interval參數配合使用。

time_zone

時區,預設為NULL,表示使用UTC時間。

樣本:

SELECT add_continuous_aggregate_policy('transaction_min_cagg',
    start_offset => '1 hour', -- 處理1小時前的資料(確保資料完整)
    end_offset => INTERVAL '0', -- 處理到目前時間
    schedule_interval => INTERVAL '1 sec' -- 每1秒重新整理一次
    );

即時查詢

在進行連續彙總查詢時,如果未啟用即時查詢功能,則只能訪問當前已完成彙總的資料。您可啟用即時查詢功能查詢新接收但尚未經過彙總的資料。

  • 啟用即時查詢

    ALTER MATERIALIZED VIEW transaction_min_cagg SET (timescaledb.materialized_only = false);
  • 關閉即時查詢

    ALTER MATERIALIZED VIEW transaction_min_cagg SET (timescaledb.materialized_only = true);

嵌套彙總

嵌套彙總是指在連續彙總產生的物化視圖基礎上再建立連續彙總,例如在按小時彙總結果基礎上建立按天彙總,在按天彙總基礎上建立按月彙總等,一方面減少資料冗餘,另一方面提升彙總效能。

  1. 建立第一層彙總,此處按1分鐘彙總。

    CREATE MATERIALIZED VIEW transaction_min_cagg
        WITH (timescaledb.continuous) AS
        SELECT id,
            time_bucket(INTERVAL '1 min', tm) AS bucket,
            AVG(price) as avg,
            MAX(price) as max,
            MIN(price) as min
        FROM transaction_data
        GROUP BY id, bucket;
  2. 建立嵌套彙總,在按1分鐘彙總結果上建立按小時彙總。

    CREATE MATERIALIZED VIEW transaction_one_hour_mview
        WITH (timescaledb.continuous) AS
        SELECT id,
            time_bucket(INTERVAL '1 hour', bucket) AS bucket,
            AVG(avg) as avg,
            MAX(max) as max,
            MIN(min) as min
        FROM transaction_min_cagg
        GROUP BY id, time_bucket(INTERVAL '1 hour', bucket);

時序壓縮

  • 當時序分區被判定為歷史資料時,可以啟用時序資料庫提供的資料壓縮功能,GanosBase TSDB提供整表壓縮和指定分區壓縮的功能,壓縮後可降低資料存放區空間,壓縮率可達70%以上,大大減輕儲存成本。

  • 壓縮後資料只能讀不能寫。

卸載外掛程式

DROP EXTENSION ganos_tsdb CASCADE;
DROP EXTENSION timescaledb CASCADE;