https://softwareengineeringdaily.com/podcasts/scaling-time-series-workloads-on-postgres/
感測器讀數、金融行情、應用程式遙測,都是一路往下寫、很少回頭改,查的時候又幾乎總是一段時間。TimescaleDB 是 Tiger Data 的開源資料庫,以 PostgreSQL extension 把時序能力加進 Postgres。它是 extension,不是 fork。SQL 還是同一套,交易跟分析可以留在同一個系統,不必把資料拆到兩套工具。
這一集是 Tiger Data 產品管理總監 Brandon Purcell,跟 Kevin Ball 談這件事。Kevin Ball,節目裡也叫 KBall,是 Mento 的工程副總,也單獨帶工程師跟工程主管。他共同創辦過兩家公司、當過 CTO,辦過 San Diego JavaScript Meetup,也在 Latent Space 底下組 AI in Action。Brandon 的 Postgres 資歷快二十年。早年在軍中就寫過程式,接著進 Adobe 做過好幾個角色,後來跟幾個人做出 Spatial Key,一家蓋在 Postgres 上的地理空間分析平台。一開始橫向做很多產業,後來轉進保險,從核保、事件應變到投資組合管理。大約十三年後公司賣掉。他當時是 CTO,休息一段之後想回到技術跟產品。他說自己喜歡 Postgres,也覺得 Tiger Data 把 Postgres 往上推了一階。
寫得多、改得少,一張表會胖到查不動
做網站的人多半從關聯式物件開始,一筆一筆的紀錄。時序是另一種形狀。一台裝置、或一整群裝置,週期性吐讀數。製造、機器人、醫療器材、金融跟加密貨幣交易、智慧建築、工業系統,都有這種流。Brandon 隨口估,大概六成的情況是從關聯式資料庫起手,開發者裡 Postgres 又用得最多。資料一累積,vanilla Postgres 開始卡住:寫入變瓶頸,表一腫讀就變慢,單一表上的索引跟著長大,時間範圍的查詢也吃力。
他講的實體世界還在變多。太陽能這類設備週期性吐讀數,裝置可以到幾十萬、甚至幾百萬台。他們有一個客戶,兩千兩百萬台裝置,每隔幾秒、每一秒、有的甚至不到一秒就吐一筆。寫進來的量,以及隨時間堆高的量,會用關聯式資料庫本來不太碰到的方式去壓系統。
同一套系統卻還是要交易、要關聯。人通常從 Postgres 開始,長到查詢變慢、寫入變慢,面前兩條路。一條把分析拆出去,另外養一套分析庫,交易庫留下。另一條用 TimescaleDB,把兩邊放在同一個系統。拆出去就要管多條資料管線,那些系統的 SQL 多半又跟 Postgres 有一點不一樣,應用程式得改寫一段。留在 extension 裡,他說應用程式可以完全不用改。
Brandon 自己做過很多網站。網站多半是 CRUD,讀寫交錯。有東西持續吐時序,問題就不一樣。人碰到寫入爆、讀變慢,常常拿問題去問 LLM,或自己搜,然後撞上 TimescaleDB。他說進公司之前,根本不知道有這個產品。KBall 則是從做網站的人看過去:實體世界那種測試基礎設施,資料量很不真實。
表的長相不變,底下按時間切塊
開發者看到的模型沒有變。一筆讀數、一個 timestamp、再加上這台裝置帶的屬性,搬進 Timescale 之後欄位還是那些。底下多出來的是 hypertable。大家懂的還是 table。hypertable 做自動分區,依時間把資料切成一塊一塊 chunk,查的時候不必一次把全部讀進來。
從上面看,它仍是一張表。Brandon 說價值常常出現在這種規模:幾十億列再往上堆,時間拉過十年。你若只查比較近的資料,query planner 只會碰到該碰到的 chunk。
chunk 其實就是表,上面再疊一層 Timescale 用來組織它們的 metadata。列存那側的索引也拆到每個 chunk。一張巨大的表最痛的地方之一,是索引肥到每次插入都要更新它。切塊之後,這個成本關在當下那一塊。
預設 chunk 是七天。量很大可以收到一小時。他說從開發者的角度看,出廠設定多半就能開始。分區也不只時間,還有數值分區,以及帶時間成分的 UUID v7。
KBall 十年前碰過這個痛。當時是幾億列,就得規劃分割表,而且分割做在應用層。他以為這套大概就是依日、月、年切時間桶。Brandon 說,Postgres 自帶的其他分區方案可以用,在這個問題域裡他覺得多半不必。人查資料,時間幾乎總是其中一個條件;裝置世界再加裝置或其他欄位。他們內部有個叫 segment by 的做法,決定資料怎麼切進 batch,通常是 device ID、某種 tenant ID 或 user ID。引擎把相近的資料擺在一起,壓縮更緊,查也更快。這就是列存跟欄存混用時,重新分組、做出邏輯 batch 的那一步。
Join 還在資料庫裡。裝置或使用者的 metadata 常常放在沒有按時間切的普通表,可以直接 join。拆成兩套系統,這件事得拉回應用層:各自查完,再在程式裡拼。留在 Postgres,就是寫一條查詢、join、聚合、丟回給使用者。KBall 記得,分割一旦做到應用層,以前在 SQL 裡能做的事突然得搬進程式。
extension 的做法是攔查詢,讓 query planner 去跑,把請求送到對的 chunk。Brandon 用過很多年 PostGIS,對 Postgres 能擴充到什麼程度一直很驚訝。TimescaleDB 走同一條:靠可擴充性去碰 query planner,並且把「少碰 chunk」這條路磨很久。歷史可以很長,查詢只摸需要的那幾塊。
寫入的衰退關在正在寫的那一塊
很多人是寫入先爆,後面談效能卻常在講讀。chunk 改了有沒有用,索引要不要動,vanilla Postgres 裡本來就有寫入重的索引取捨。
Brandon 說那些原則還在,差別主要在 chunk。追加寫入時,要想的是這一塊在轉成欄存、壓下去之前,當列存會有多大。chunk 很多,索引主要只擔心正在寫的那一塊。
一般 Postgres 表寫久了,每秒能吞的列數會線性往下掉。TimescaleDB 若 chunk 切得對,他說這條線不會往下掉。路由也允許把舊的歷史資料回補進舊 chunk。預設先進列存,再依政策轉成欄存。直接寫進欄存也做得到,這塊還在演進。他說在普通硬體上,寫入可以到每秒一百萬列以上。vanilla Postgres 很難做到,資料一大就掉很快。
KBall 追問:vanilla Postgres 的衰退跟著整張表走,TimescaleDB 是不是就跟著 chunk 走?Brandon 說他看到的線差不多是平的。他記得有一份獨立測試,不確定是不是微軟做的。chunk 大小對查詢的影響,大概大於對寫入的影響。除非一塊設成三十天或兩個月、而且資料非常多,單一 chunk 不至於長到幾千萬、幾億列,資料會散開。
hypercore 把舊資料壓進欄存
chunk 裡面還有 hypercore,列存跟欄存混在一起。Postgres 典型是列存,一列一列排。透過政策可以自動搬,開發者也能自己控,資料會再進欄存。搬過去是為了壓縮。
欄存以前很不能改。他們改過之後,裡面的資料現在可以動。空間上,他說使用者那邊常見省下九成,最高看過百分之九十八,常常是因為讀數高度重複。
另一頭是向量化。處理器用 SIMD,一次對欄存跑多個 batch。人會以為壓完查起來更慢。他把壓縮跟向量化放在一起時,看過查詢加速十倍、一百倍、到一千倍。
列存常見的 B-tree 之外,還有 sparse index,像 min max 跟 Bloom filter。查詢可以先讀 batch 或 chunk 上的 metadata,不必下到每一列,也不必先解壓縮。加總、取第一筆、取最後一筆,時序裡很常見,會快很多,因為讀的是 metadata。
遷移很短。幾個指令,把普通表轉成 hypertable,或從零建一張。之後插入或搬資料,系統依 timestamp 放進對的 chunk。
彙總自己更新,離線回補會重算整段
時序另一個日常是彙總:按天、按週,或同一份資料要好幾個粒度。vanilla Postgres 可能用 materialized view、stored procedure,或應用程式自己算完倒進表。
Timescale 往前做了 continuous aggregates。背後仍是 materialized view,會再建一張 hypertable,用 time_bucket 依時間範圍分桶。Brandon 說他總忘了 Postgres 裡對等的函式叫什麼。彙總依你設的政策自己更新:多久一次、往回補多遠。hypertable 有變動,彙總層跟著動。
人還常把它們疊成階層。裝置每一分鐘吐一筆,可以做五分鐘、一小時、一天、一週,四層彼此往上蓋,排程自動跑。他說這樣可以把幾千億列拆進時間桶,查詢落到很低的毫秒。Tiger Cloud 上有客戶,用他認為不算特別的硬體,每秒兩萬到三萬次查詢,一天打到幾十億次。
這裡也是現在還粗的地方。實體世界跟純粹追加寫入不一樣,裝置會離線。他們有一個做船運的客戶,裝置可以離線兩週到一個月,然後一整批資料突然回來,時間往回蓋兩週或一個月。materialized view 得把這麼長的一段全部更新,CPU 跟磁碟 I/O 都很重。refresh 政策要設對。他們打算加 granular refresh:tenant 可以是一台裝置、一個使用者,或你定義的單位。回補時只更新有變的那台,今天的 continuous aggregates 是整段時間一起更新。
改 chunk 大小只影響新的塊。舊的要用函式手動 split、combine。他們正在把這段的鎖定縮小。過程中若同時有 DDL、讀取或其他操作,鎖還是會卡住。開發者呼叫的就是這些函式。
想看底下在做什麼,主控台看得到。節目前半他把託管叫 Tiger Cloud,講產品線時又說 Timescale Cloud。雲上有 exporter 接到 Datadog、Prometheus。路線上,Postgres 既有指標之外,還要細到壓縮政策、continuous aggregate 的 refresh(他口裡的 CAG)背後在做什麼。SQL 沒有另一套。熟悉 Postgres 的人,要額外學的主要是 hypertable 跟 continuous aggregates。API 文件裡有函式可以碰到特定 chunk。產品開源,想看實作可以直接看程式碼。
熱的兩年留在庫裡,八年撕到 S3
開源把 extension 插進正在跑的 Postgres 就有。KBall 問,硬體也不用很華麗,為什麼還上雲。
Brandon 先講託管,把維運從團隊身上拿掉,類似他以前為地理空間產品大量用過的 AWS RDS。上面有 read replica、HA replica,由他們的團隊管;外面坐一層連線用的 load balancer。單一台不夠,可以再加 read replica。
他特別點名 tiered data。想留很長的歷史,又不必全部維持隨時能查的熱資料。舉例:十年裡前兩年放熱的,另外八年分層出去。在 AWS,那八年會撕到 S3,背後以 Iceberg 放著。整段時間對外仍是一張表。查前兩年打熱資料;範圍超出這兩年,系統把結果合起來,十年都能查。自己做的話,得有歸檔方案跟搬資料的管線。這裡是設一條 tiering 政策,依日期自動往外搬。
他們也在往倉儲、分析庫、lakehouse 走。產品叫 Tiger Lake,他說正式版預計在錄這集的當年稍晚推出,當時還在 beta,做雙向連通。別的團隊常把資料放成 Iceberg,再推到 Snowflake、Databricks。雙向包括把資料拉進來,讓 Tiger Data 或 Timescale 變成儀表板用的營運庫,因為那裡要快;資料科學或分析團隊則用 Snowflake、Databricks,或 AWS 上的 Athena 消費同一份。合規也會要多份副本放在多個地方。不必自己建管線,打開功能,依你選的資料,Tiger Lake 自動寫出到 S3。Azure 上有對等做法。
他要的是人少管管線,時間放回業務問題,多個團隊用同一份資料。來源可以直接寫進 Postgres、寫進 Tiger Data,再往下游送;也可以某個團隊先寫進 S3,再拉進來變成能查的營運資料。他補了一句:AI 讓開發變容易,管線若還得自己顧,人就還是在搬資料。
七十 TB 壓到五 TB,才上得了 NVMe
新專案若本來就從 Postgres 開始,關聯式的東西都在。應用裡只要有時序、而且會長大,他認為一開始就用不會走錯。本地五分鐘可以拉起 Docker image,一行 curl 就能裝。時序條數即使不多,也可以先從這裡起。能見度這幾年高了,人比較敢在新系統直接上。
既有系統那一側,通常是量已經很大。查詢或寫入未必已經出事,光是磁碟足跡就痛。他說錄製前幾週跟 CERN 做了一場 webinar。CERN 之前用另一套資料庫,後來遷到 TimescaleDB。他們點出的數字,是強子對撞機跟 CERN 其他裝置的時序大約七十 TB。靠壓縮,足跡從七十 TB 降到五 TB,於是改放到更快的 SSD、NVMe SSD。七十 TB 原先攤在更多磁碟上,現在塞得進更快的碟,效能是預設就上來。壓縮讓人用更普通的硬體,多個使用者同時打的吞吐也好一些;量大的寫入若本來就吃緊,也一起受益。
同一套庫可以不另開向量資料庫。有 PG Vector,也有他們的 extension PG Vector Scale,資料集變大時把規模撐出去。向量嵌入可以跟其他資料、跟 hypertable 裡的時序放在一起。他們還寫了開源的 PG Text Search 做文字搜尋,看過的規模可以跟 Elasticsearch 放在一起比。文字搜尋加向量嵌入,可以做成混合搜尋。遙測裡常見的用法,是先用 metadata 或文字描述搜,再回到底下的讀數。否則可能得拆成向量庫、時序庫、關聯庫,再到應用層 join。放在一處,再加上壓縮,足跡也小。
KBall 說他訪問資料庫公司常問:為什麼是你們,不是 Postgres?Brandon 的答案是乾脆用 Postgres 做。這也是他加入的原因之一。開源,社群裡還有一大堆 extension 可以並排裝。
給 agent 的 fork,現在還得整庫複製
路線上,Tiger Lake 還要繼續做進 Snowflake、Databricks 的連接器。開發體驗要更接近開箱,少做調參,continuous aggregates 要更好設。CLI 跟 MCP 不只負責安裝。開發者常問:我怎麼知道設對了?他們想把解決方案架構團隊帶客戶時累積的判斷,做成能驗證設定的指引。
另一塊是 agent 對著資料庫做事。內部在做儲存引擎的下一步,叫 Fluid Storage。它是零複製的儲存:fork 不必先把底層資料拷一份,之後的變更再以 diff 疊上去。配上 CLI 跟 MCP,在 CI/CD 或 Jenkins 裡可以把正式庫很快 fork 出去。他說正式庫可以在幾秒或幾分鐘內 fork 出來,讓 agent 對著那份資料做事,用完再拆掉。碰的是正式資料,又不會把正式環境的效能拖下去,破壞性操作也不必直接打在正式庫上。
KBall 說他光為了 QA 就想要。應用程式的分支已經好複製,資料一重就痛:得先拷一份正式資料再改,多數環境很花時間。命令列今天已經可以 fork。痛在庫一大就得整份複製。EC2 上若是 EBS 撐著的資料,搬起來要很久。Fluid Storage 要改的就是這段;需要的話也可以用來拉 read replica。尖峰時把多台放在 load balancer 後面,流量過去再縮回來。
讓 coding agent 直接上手,是已經在做的事。學習曲線還在,所以有 CLI、MCP,以及 PGAI guide,用來引導 coding agent 用這些能力。Brandon 自己做過一個 side project,把整間智慧家庭的遙測收進來,用 MQTT 推進去。大半是把想要的東西描述給 coding agent,資料庫那側他甚至沒親手碰。schema、hypertable、continuous aggregate 都長出來,幾個小時就跑起來,再接回 Home Assistant。他覺得懂 Postgres、懂這些概念仍然有用;往下走,力氣會放在做東西。他們把生意放在實體世界,從資料中心到太陽能,裝置數跟吐出來的量都在爆,要留很長的歷史,又留住 Postgres 的開發方式。
現在還會卡的第一件事是 chunk 調對。資料要先進去夠多才調得準。雲端已經有一個引擎會建議怎麼切,他們想把建議搬回 CLI 跟 MCP。continuous aggregates 設對是另一個坎,尤其是離線回補。
地端還有第三條。開源 TimescaleDB、託管 Timescale Cloud 之外,他們在做 TimescaleDB Enterprise,給工業與實體世界的現場,是開源方案的地端版本,有自己的主控台,可以拉起帶 read replica 的 HA、連線 load balancing、備份。這些若自己組,得從開源開始,再疊 etcd、Patroni 和其他東西。Enterprise 想把這包直接給出來。
裡面有 Postgres connector。想試 TimescaleDB 或 Timescale Cloud,可以把 connector 指向自己的庫,即時複製想要的表,把 WAL 重放寫進去,並維持同步。正式庫繼續跑,旁邊平行試,不必先 pg_dump 再 pg_restore。同一條也用在 Enterprise 的分層複製。他舉正在合作的資料中心營運商:一棟建築裡不同的 pod,裡面是一堆 GPU。pod 往上收到建築,再收到企業。connector 可以跨層複製。有人在 pod 上監控,也可能有一組人在看整座運轉或整座資料中心,資料就往上走。
版本上,他們支援過 Postgres 15 到 18。他說錄這集當天,GitHub 上要出來的版本他以為是 2.29,會把 PG 15 標成棄用,留下 16、17、18,19 出來後也會跟上。本地可以到 TimescaleDB 的 GitHub,一行 curl 裝起來;也可以到 timescale.com 申請評估,有三十天免費,還附點數。他建議一開始就用 CLI 跟 MCP,把使用情境寫給 coding agent,工具會依文件裡的做法去建 schema。主控台裡也有精靈。住在命令列的人留在命令列;想少碰指令的,走雲上的主控台。
KBall 把 CLI 跟 MCP 當成第一入口:大家愈來愈用 coding agent 去摸工具,這條路得修好。Brandon 說工具不會停在起手。他們還在做除錯、驗證、把慢查詢指出來。他看到可以做出獨立的 agent,盯著資料庫跟系統,即時給建議。起手之後的監控,背後是同一套工具。