快速入門
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及以上)。
基本概念
時序資料(Time Series Data):指按照時間順序記錄的資料序列。這類資料的特點是資料點不僅包含數值資訊,還關聯了具體的時間戳記,反映了某一變數隨時間變化的趨勢或模式。時序資料廣泛應用於多個領域,如金融交易、氣象觀測、感應器監測、網站流量分析、疾病傳播研究等。時序資料的關鍵要素包括:
時間戳記:每個資料點都有一個明確的時間標記,表明資料的採集時間。
觀測值:在各個時間點上測量或記錄到的資料值。
順序性:資料點按照時間的先後順序排列,這種順序反映了資料之間的自然時間關係,使得時序資料具有時間序列的特性。
趨勢和周期性:時序資料分析中常關注資料中的長期趨勢、季節性波動、周期性變化以及隨機波動等特徵。
度量(Metrics):時序資料監測指標,如溫度、股價、網路流量等任何可以量化測量的數值,度量可以協助理解時序資料的行為模式、預測未來趨勢,並能及時發現並響應異常情況。
彙總(Aggregation):指在時間序列資料分析中,將較高頻率的資料彙總到較低頻率的過程,簡單來說,就是將資料按時間維度進行合并或匯總,從而減少資料的粒度,但同時能保留資料的主要趨勢或特徵。這種處理方式對於資料降維、趨勢分析、異常檢測以及預測模型的構建都非常有用。
降採樣(Downsampling):時序資料處理的一個常見操作,可以減少時間序列資料的採樣頻率,即降低資料點的數量,同時嘗試保留未經處理資料的關鍵特徵或趨勢。時序降採樣的幾種常見方法:
直接抽樣(Decimation):這是最直接的方法,簡單地每隔N個點取一個資料點。例如,如果原序列每秒採樣10次,您可以選擇只保留每5個點中的第一個,從而實現每秒2次的採樣率。這種方法簡單但可能會丟失高頻資訊。
平均值法(Averaging):在降採樣前,先對連續的資料點進行平均處理。例如,將連續的5個點取平均值作為新的一個資料點。這種方法有助於平滑資料,減少雜訊,但可能會模糊快速變化的細節。
中值法(Median):與平均值法類似,但使用連續資料點的中值代替平均值,這在處理包含異常值的時間序列時更為穩健。
最大值/最小值法:選取連續資料點中的最大值或最小值作為新資料點,適用於需要保留峰值或穀值的情境。
重採樣(Resampling):通過插值等方法調整資料到新的時間點上,然後在新的時間軸上進行均勻採樣。常見的重採樣方法有線性插值、最近鄰插值、立方插值等。重採樣方法更加靈活,可以根據需求調整到任意的採樣頻率,同時儘可能保持原資料的形態。
模型預測降採樣:利用統計模型或機器學習模型預測在較低採樣率下的資料點,比如使用ARIMA、LSTM等模型預測每個新時間點的值,然後使用這些預測值作為降採樣後的資料。這種方法可以更智能地降採樣,但計算成本較高。
GanosBase TSDB與TimescaleDB對比
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參數後叢集將會重啟,請在修改參數前做好業務安排,謹慎操作。
建立外掛程式
升級外掛程式
時序超表
超表(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 | 是 | 原表中具有時序特徵的時間欄位名,支援如下資料類型:
|
partitioning_column_name | 否 | 分區欄位名,預設按原表的時間欄位分區。 |
number_partitions | 否 | 分區數量。 |
associated_schema_name | 否 | 指定超表所在的Schema。 |
associated_table_prefix | 否 | 由於超表由一系列的分塊表組成,塊表會在內部自動建立,這裡可指定塊表的首碼。 |
chunk_time_interval | 否 | 超表分塊的時間間隔,預設按7 天分塊。 |
create_default_indexes | 否 | 是否在超表的時間欄位上建立B樹索引,取值範圍如下:
|
if_not_exists | 否 | 如果超表已經建立,是否報錯,取值範圍如下:
|
partitioning_func | 否 | 如果使用空間分區,可指定自訂的空間分區函數。 |
migrate_data | 否 | 如果原表中已經存在資料,是否將資料轉移至超表,取值範圍如下:
|
chunk_target_size | 否 | 指定塊表的大小(樣本: |
chunk_sizing_func | 否 | 與 |
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。 |
樣本
以交易資料為例,建立時序超表:
建立普通表:
CREATE TABLE transaction_data( tm TIMESTAMPTZ NOT NULL, id INT NOT NULL, price double precision);設定普通表的複製標識,必須為DEFAULT模式:
ALTER TABLE transaction_data replica IDENTITY DEFAULT;將普通錶轉換為超表:
SELECT create_hypertable('transaction_data', 'tm', chunk_time_interval => INTERVAL '1 day');說明如果該表已存在資料,請在轉換為超表時增加
migrate_data參數並設定為true,但如果表資料量較大,轉換過程可能消耗較長時間。(可選)修改超表分區間隔。
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 | 是否自動運行,預設為 |
check_config | 檢查配置參數 |
fixed_schedule | 是否按固定時間間隔運行該任務,預設為 |
timezone | 時區,預設為NULL。 |
樣本
基礎資料準備。建立需要執行的預存程序。
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 $$;建立任務。返回任務
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 | 需要修改的目標任務 |
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 | 需要啟動並執行目標任務 |
樣本
CALL run_job(1002);刪除任務
刪除任務。
void delete_job(job_id int);具體參數解釋如下:
參數名稱 | 描述 |
job_id | 需要刪除的目標任務 |
樣本
SELECT delete_job(1002);重新整理連續彙總
手動重新整理
手動重新整理連續彙總的預存程序。
refresh_continuous_aggregate(
cagg REGCLASS,
window_start "any",
window_end "any"
);具體的參數解釋如下:
參數名稱 | 描述 |
cagg | 需要重新整理的連續彙總名稱或OID。 |
window_start | 重新整理視窗開始時間,類型需與連續彙總時間欄位一致。
|
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_continuous_aggregate_policy函數
即時查詢
在進行連續彙總查詢時,如果未啟用即時查詢功能,則只能訪問當前已完成彙總的資料。您可啟用即時查詢功能查詢新接收但尚未經過彙總的資料。
啟用即時查詢
ALTER MATERIALIZED VIEW transaction_min_cagg SET (timescaledb.materialized_only = false);關閉即時查詢
ALTER MATERIALIZED VIEW transaction_min_cagg SET (timescaledb.materialized_only = true);
嵌套彙總
嵌套彙總是指在連續彙總產生的物化視圖基礎上再建立連續彙總,例如在按小時彙總結果基礎上建立按天彙總,在按天彙總基礎上建立按月彙總等,一方面減少資料冗餘,另一方面提升彙總效能。
建立第一層彙總,此處按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;建立嵌套彙總,在按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;