聊一聊時序資料庫和TimescaleDB

資料庫工作筆記發表於2023-12-19

來源:PostgreSQL學徒

前言

現今時序資料的應用場景十分廣泛,許多型別的資料都是時序資料,像感測器測量、工廠裝置健康、交通物流等等。現代業務對資料價值挖掘的需求已不僅僅停留在簡單計算和繪製圖表的層面上,而是需要更多精細、複雜的計算分析,高壓縮比,高寫入吞吐量,以及高速的時間序列查詢,是時序資料庫相比於關聯式資料庫在處理海量時序資料方面的最基本的能力和優勢。隨著近幾年IoT、IIoT、AIoT和智慧城市快速發展,時序資料庫也成為資料架構技術棧的標配。

為什麼需要時序資料庫

透過保留資料固有的時間序列性質,我們可以記錄下事物是如何隨時間變化的事實,正因如此,這一反應真實的客觀屬性使得時序資料在特定的場景中充滿了商業價值,透過分析時序資料,為決策者提供依據。一個單純的溫度數字 37.5° 沒有任何意義,結合上下文,讓一個個"靜態畫面"變成一個動畫,時序便是這樣一種視角,以洞悉過去,展望未來,決斷現在。想要記錄並分析時序資料也帶來一個明顯的問題:由於時序資料產生的速度非常快,且規模龐大,如何以一種高效能的方式記錄、查詢和分析如此大規模的資料,成為了一個難題,時序資料庫應運而生。

時序資料的特徵

  1. 多:資料格式多樣,時序、空間、JSON、結構化、非結構化等等
  2. 大:資料體量龐大,資料儲存和處理成本高
  3. 高:資料時效性高,對實時處理能力要求高,資料都有統計、聚合等實時計算操作,而不是傳統 T+N 的離線分析方式
  4. 小:資料價值密度小,獲取有效資料代價高
  5. 少:資料很少有更新或刪除操作,資料已寫入操作為主,讀操作為輔

因此時序資料的特徵決定了一款優秀的時序資料庫應具備的特點:

  1. 壓縮能力:資料壓縮可以降低儲存成本,同時還不能影響近期資料的寫入、更新、明細查詢的效率,同時搭配分級儲存,熱、溫、冷多級儲存。
  2. 留存能力:時序資料的價值隨著時間的流逝不斷降低,需要過期資料保留策略,自動管理資料生命週期
  3. 分片,水平擴充套件:單節點容易成為瓶頸,需要有水平擴充套件的能力,分散式支援
  4. 寫入效能:高寫入吞吐量是時序資料的關鍵特點,併發寫入量大
  5. 易用性:SQL,多語言聯結器,RESTful介面等等
  6. 高效分析能力:資料存入之後,最終的目的是挖掘出資料中的價值,單條資料價值低,因此往往是一次查詢多條、多個範圍的資料,或者進行聚合等,這需要資料庫提供強大的分析能力。

TimescaleDB簡介

TimescaleDB 是基於 PostgreSQL 打造的一款時序資料庫,採用外掛的形式,可以跟隨社群主版本,融合 PostgreSQL 生態,使得PostgreSQL 也一躍成為一款優秀的時序資料庫。TimescaleDB 在 PostgreSQL 的總時間的十五分之一內載入十億行資料庫,並且在更大資料寫入量時,吞吐量甚至超過 PostgreSQL 20 倍。

聊一聊時序資料庫和TimescaleDB

聊一聊時序資料庫和TimescaleDB

TimescaleDB包含以下特性:

  • Open source (Apache 2.0, Timescale License)
  • Self-hosted / Cloud (AWS, Azure, GCP) / Fully-managed (SaaS)
  • PostgreSQL ecosystem + TimescaleDB tools (Promscale, Tune, etc)
  • Hypertables and distributed hypertables
  • Full SQL + TimescaleDB hyperfunctions,除了完善的 SQL 能力,還提供了很多面向時序的分析函式,比如 time_bucket,支援任意時間間隔,比如要統計過去 5 分鐘的平均車速;last(temperture,time) 根據聚合的時間返回最新的溫度值;更多資訊可以參考
  • Real-time continuous aggregates,持續聚集、實時聚集,當新增新資料或修改舊資料時,會在後臺自動重新整理
  • Data retention,搭配 drop_chunks 和作業實現
  • Downsampling
  • User-defined actions,User-defined actions let you schedule custom-defined procedures to run within Timescale.
  • Native compression,壓縮需要制定 segment_by 和 order by,一般選擇有查詢需求,有重複值的欄位設定為 segment_by;其次支援多樣的壓縮演算法,Delta-delta encoding, Simple-8b, XOR-based compression 等等
  • Massive scaling
  • Function pipelines*

除此之外,有一點必須要提一下:TimescaleDB 還支援了 Index skip scan,加速 distinct。

另外關於 TimescaleDB 的壓縮,也有"列存"的概念,不過並非 CK 這類的原生列存,其本質上就是利用陣列儲存多值,多條記錄,給定一批資料(約 1,000 行),每列資料都會聚合到一個陣列中,每個陣列元素對應於原始行之一的值,比如原來的資料是

| Timestamp | Device ID | Status Code | Temperature |
|-----------|-----------|-------------|-------------|
| 12:00:01  | A         | 0           | 70.11       |
| 12:00:01  | B         | 0           | 69.70       |
| 12:00:02  | A         | 0           | 70.12       |
| 12:00:02  | B         | 0           | 69.69       |
| 12:00:03  | A         | 0           | 70.14       |
| 12:00:03  | B         | 4           | 69.70       |

透過壓縮,轉變為如下形式:

| Device ID | Timestamp                      | Status Code | Temperature           |
|-----------|--------------------------------|-------------|-----------------------|
| A         | [12:00:01, 12:00:02, 12:00:03] | [0, 0, 0]   | [70.11, 70.12, 70.14] |
| B         | [12:00:01, 12:00:02, 12:00:03] | [0, 0, 4]   | [69.70, 69.69, 69.70] |

即使在應用壓縮演算法之前,這種格式也可以透過大大減少 Timescale 的內部每一行的儲存開銷來節省儲存空間 (Tupleheader至少23個位元組)。

聊一聊時序資料庫和TimescaleDB

壓縮效率槓槓的

聊一聊時序資料庫和TimescaleDB

架構

TimescaleDB 中的表叫做超表——Hypertable,每個分片叫做一個"chunk",超表可以理解成一個虛擬層、代理層,一個檢視,實際是一個分割槽表,各個 chunk 是透過繼承實現的分割槽表,這些對於使用者是完全透明的,使用超表和使用普通的表無異,不過既然是分割槽表,那麼唯一索引必須包含分割槽列這個限制還是存在的。

In other words, TimescaleDB exposes what look like regular tables, but are actually only an abstraction (or a virtual view) of many individual tables comprising the actual data. This single-table view, which we call a hypertable, is comprised of many chunks, which are created by partitioning the hypertable's data in either one or two dimensions: by a time interval, and by an (optional) "partition key" such as device id, location, user id, etc.

聊一聊時序資料庫和TimescaleDB

資料會自動按時間和空間分片,當然還可以選擇space partition,語法很簡單,透過 create_hypertable 將其轉化為超表,chunk 實際儲存在 _timescaledb_internal 模式下。

聊一聊時序資料庫和TimescaleDB

另外,TimescaleDB還支援分散式部署,AN 節點即訪問節點 (Access Node),DN (data node) 節點存放分片資料,藉助 PG 原生的預備事務實現兩階段事務,保證一致性,因此需要配置 max_prepared_transactions。

聊一聊時序資料庫和TimescaleDB

不過可惜的是,後續 TimescaleDB 不再維護分散式了,也就意味著後續版本不會再支援叢集部署了。TimescaleDB 官方認為分散式實現帶來了諸多挑戰與限制,並且當前 TimescaleDB 部署中只有 1% 的量是叢集模式,維護此功能所涉及的複雜性已成為一個重大障礙,維護需要耗費巨大精力,因此 TimescaleDB 選擇的是捨棄叢集模式,在單機模式下繼續深入,持續最佳化寫入和讀取能力,目前 TimescaleDB 已將單節點部署擴充套件為每秒處理 200 萬次插入,並不斷利用雲技術來解決擴充套件性問題。

Multi-node support has been deprecated. TimescaleDB 2.13 is the last version that will include multi-node support. Multi-node support in 2.13 is available for PostgreSQL 13, 14 and 15. This decision was not made lightly, and we want to provide a clear understanding of the reasoning behind this change and the path forward.

分散式超表的使用方式也很簡單,新增節點,建立分散式超表:

聊一聊時序資料庫和TimescaleDB

叢集模式隨著節點的增加,可近線性地提升寫入和讀取能力,所以 TimescaleDB 官方放棄繼續支援叢集模式,還是有點令人扼腕的。

聊一聊時序資料庫和TimescaleDB

但是另一方面,看一下目前分散式超表的限制,也就能理解為何官方會這麼選擇了

  • Distributed scheduling of background jobs is not supported. Background jobs created on an access node are scheduled and executed on this access node without distributing the jobs to data nodes.  在訪問節點上建立的後臺作業會在此訪問節點上排程和執行,而不會將作業分發到資料節點。
  • Continuous aggregates can aggregate data distributed across data nodes, but the continuous aggregate itself must live on the access node. This could create a limitation on how far you can scale your installation, but because continuous aggregates are downsamples of the data, this does not usually create a problem.  持續聚集可以聚合分佈在資料節點上的資料,但持續聚集本身必須存在於訪問節點上。
  • Reordering chunks is not supported. 不支援重排 chunks,類似於 CLUSTER
  • Tablespaces cannot be attached to a distributed hypertable on the access node. It is still possible to attach tablespaces on data nodes.
  • Roles and permissions are assumed to be consistent across the nodes of a distributed database, but consistency is not enforced.
  • Joins on data nodes are not supported. Joining a distributed hypertable with another table requires the other table to reside on the access node. This also limits the performance of joins on distributed hypertables. 資料節點上不支援關聯。將分散式超表與另一個表進行關聯的話,需要另一個表也存在於訪問節點上。
  • Tables referenced by foreign key constraints in a distributed hypertable must be present on the access node and all data nodes. This applies also to referenced values.
  • Parallel-aware scans and appends are not supported.
  • Distributed hypertables do not natively provide a consistent restore point for backup and restore across nodes. Use the create_distributed_restore_point command, and make sure you take care when you restore individual backups to access and data nodes. 分散式超級表不本質上提供跨節點備份和恢復的一致還原點。
  • For native replication limitations, see the native replication section.
  • User defined functions have to be manually installed on the data nodes so that the function definition is available on both access and data nodes. This is particularly relevant for functions that are registered with set_integer_now_func.

小結

TimescaleDB 是基於 PostgreSQL 的時序資料庫外掛,完全繼承了 PostgreSQL 的功能,可以跟隨社群版本,融合 PostgreSQL 生態,使得 PostgreSQL 面對多樣複雜的場景也能夠遊刃有餘, TimescaleDB(時序) + Postgis(地理) + Citus(分散式) + pgvector(向量檢索) + AGE(圖) + pipelinedb(流式處理) ... 表示要打十個。

總而言之,TimescaleDB 透過 hack 儲存層,使得 PostgreSQL 搖身一變,成為一個時序資料庫,並且有鼻有眼,做的還不賴。Give it a try!

聊一聊時序資料庫和TimescaleDB

參考

https://www.timescale.com/blog/building-columnar-compression-in-a-row-oriented-database/  

TimescaleDB 2.0



來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70027826/viewspace-3000559/,如需轉載,請註明出處,否則將追究法律責任。

相關文章