ClickHouse Cloud 用物件儲存失效轉移撐住每秒 5000 萬筆 OpenTelemetry 事件擷取
ClickHouse Blog · 2026-08-24
原本的問題
ClickHouse Cloud 目前每秒要接收超過 5000 萬筆 OpenTelemetry 事件,換算壓縮後流量約 10 GBps。真正的難題不是流量本身,而是資料庫端會出現無法預期的 backpressure。系統必須能吸收生產端與寫入容量之間的暫時落差,同時不能遺失資料、不能讓新資料被卡在陳舊的 backlog 後面、也不能為了應付尖峰而長期 over-provision。
第一版架構是標準兩層設計:node 上的 DaemonSet agent 把資料轉送到共用 gateway 層。這套兩層 agent-to-gateway 架構在 backpressure 發生時撐不住,記憶體佇列在資料庫不可用後幾分鐘內就溢位,gateway 跟著當機。第二版改用 OTel Collector 的 file_storage extension,把 WAL 寫進 PVC 搭配 StatefulSet;雖撐過更長中斷,但 immutable pod spec 帶來維運摩擦,復原時沖流 1 TiB WAL backlog 要花約 4 小時,還會讓系統優先處理舊資料而非新進的 telemetry。
採用的方法
第三版、也是目前上線的版本,把物件儲存當成 backpressure 發生時才啟動的「洩壓閥」,採用優先權式失效轉移架構。S3 bucket 依 signal 類型(logs、metrics、traces)分前綴儲存,寫入事件透過 event notification 送進 SQS;gateway 層維持無狀態,並附加一個 failover connector 負責偵測下游是否可用。
failover connector 的接線方式是:把 ClickHouse exporter 的 sending_queue 關掉、S3 exporter 的 sending_queue 打開。前者讓錯誤訊號能冒出來觸發 failover,後者避免 S3 端自己囤積緩衝,暫時性錯誤先靠 inline 同步重試處理。另外有一個獨立的catch-up receiver deployment,專門在下游恢復後把 S3 堆積的 backlog 追回來,佇列淨空時自動 scale to zero。
- S3 bucket 依 signal(logs/metrics/traces)分前綴組織
- Event notification 路由到 SQS 驅動下游消費
- Gateway 層維持無狀態,只掛失效轉移邏輯
- Catch-up receiver 獨立部署,queue 淨空即縮到零
實際效果
團隊在一次 gameday 演練中模擬下游中斷一小時,結果是 120,000 events/秒成功轉存到 S3、零資料遺失,gateway 的資源用量在整個失效轉移過程中沒有增加,下游資料庫恢復後 backlog 也自動被追回並清空。
這套架構讓統一收集 logs、metrics、traces 的管線,從最初每秒 1000 萬 events 平順擴展到目前的 5000 萬,累積儲存量達 177 PiB 未壓縮資料。代價是每個 region 要多維護一組 bucket、queue 與 notification 基礎設施,backlog 沖流期間也會有一段模糊期,難以精確得知哪些資料尚未完成寫入。
| 版本 | 架構 | 失效表現 |
|---|---|---|
| Iteration 1 | DaemonSet agent → 共用 gateway | 記憶體佇列溢位,gateway 數分鐘內當機 |
| Iteration 2 | file_storage extension + PVC WAL | 撐過中斷,但 1 TiB backlog 沖流需約 4 小時 |
| Iteration 3 | S3 失效轉移 + catch-up receiver | 120,000 events/秒零遺失轉移,資源用量不增加 |
原始來源:ClickHouse Blog
PicoMQ 把持久化訊息串流整個搬上物件儲存,改用 HTTP 而非私有協定操作
PicoMQ (GitHub) · 2026-08-25
原本的問題
傳統訊息佇列如 Kafka、RabbitMQ 要求維運方自建有狀態叢集、規劃本地磁碟容量、管理 broker 節點的生命週期。當應用場景是大量、細粒度、生命週期很短的 stream——例如每張訂單一條、每個 session 一條、每個裝置或每個工作各自一條——這種維運成本會被放大到不成比例,因為多數 stream 建立後可能只用幾分鐘就沒有用了。
PicoMQ 的設計前提是把 stream 當成可以隨意建立、閒置時不花錢的「拋棄式」資源:一個部署可以同時存在十條 stream,也可以存在數百萬條。這意味著儲存後端不能再假設每個 node 有本地磁碟能扛住 WAL 與資料本體。
採用的方法
PicoMQ 用 Rust 寫成,核心是名為 S3Stream 的儲存引擎,把資料——包含 write-ahead log 本身——完全放進 S3 相容物件儲存,node 上只保留 cache,是名副其實的零磁碟架構。作者在 Show HN 留言中提到,這個引擎「從零打造、取用了 AutoMQ 的核心原語」而不是在既有方案上擴充,因此原生支援多節點部署,不需要為叢集功能額外做 feature gating。
叢集協調走一份有序的 command log:單節點用 SQLite,多節點用 Postgres。對外同時開放兩種 HTTP 介面——PicoMQ 自家的二進位協定,以及 Durable Streams 標準介面(由 durable-streams/durable-streams 專案定義、面向 agent loop 場景的 append-only stream 規格)。操作方式對應 HTTP 語意:PUT 建立、POST 附加、GET 讀取,長輪詢或 SSE 用來 tail 最新資料。
# 常見部署旗標
picomq --meta-url postgres://... \
--storage s3://bucket/prefix \
--admin-listen 0.0.0.0:9090 \
--auth token
# stream 操作對應的 HTTP method
PUT /streams/{name} # 建立
POST /streams/{name} # 附加訊息
GET /streams/{name} # 讀取 / 長輪詢 / SSE tail
DELETE /streams/{name} # 刪除
- 建立 (create)、附加 (append)、讀取 (read)、追蹤 (tail -f)、關閉 (close)、刪除 (delete) 六種操作
- 單節點部署用 SQLite 做 metadata,叢集部署改用 Postgres
- Docker Compose 提供單節點、叢集、自帶基礎設施三種範本
實際效果
作者在討論串中揭露的效能數字是:單一 stream 最高可達 100 MiB/s 吞吐量,durability 確認的延遲落在約 250ms。作者的立場是多數真實場景並不需要個位數毫秒等級的 ack 延遲,用物件儲存換取營運簡化是划算的取捨。
有留言者提出以 Discord 式聊天室為例的用法——把每個聊天室對應成一條獨立 stream;也有人試算成本,以每天 100 萬則、每則 200 bytes 的訊息量估算,每月花費落在 30 到 150 美元之間,其中儲存費用占比最低。這篇 Show HN 貼文上線約一天內累積 78~81 分、14 則留言。