鍵設(shè)計:單二進制如何做到零丟數(shù)據(jù))
OpenObserve 寫入鏈路上的 3 個關(guān)鍵設(shè)計單二進制如何做到零丟數(shù)據(jù)【免費下載鏈接】openobserveOpen source observability platform for logs, metrics, traces, frontend monitoring, pipelines and LLM observability. A sophisticated, simple and highly performant alternative to Datadog, Splunk, and Elasticsearch with 140x lower storage costs and single binary deployment.項目地址: https://gitcode.com/GitHub_Trending/op/openobserveOpenObserveO2是一個開源可觀測性平臺主打比 Elasticsearch 低 140 倍存儲成本、單二進制部署。這篇文章不聊功能清單直接鉆進它的寫入鏈路ingester 怎么保證崩潰不丟日志、compaction 怎么收拾小文件、search 怎么在海量 Parquet 里不掃全盤。看完你會明白便宜和不丟這兩件事是怎么同時成立的。路徑一句話用途src/ingester/寫入核心memtable 內(nèi)存寫、WAL 崩潰恢復(fù)、內(nèi)存/磁盤熔斷src/compaction/后臺整理小時級合并、增量 compaction、Bloom 過濾、保留策略src/search_service/查詢側(cè)分區(qū)裁剪、分布式搜索調(diào)度README.md架構(gòu)與部署總覽整倉的入口建議順序先看 ingester寫入是一切的底再看 compaction它是寫入的善后最后看 search前兩個的下游。寫入中途斷電會發(fā)生什么WAL 的 5 個步驟高吞吐寫入場景里進程被 OOM 殺掉、節(jié)點被驅(qū)逐都是常態(tài)所以寫入鏈路必須回答一個問題寫到一半崩了數(shù)據(jù)怎么辦O2 的做法是數(shù)據(jù)先進內(nèi)存memtableflush 時落 Parquet但落盤被拆成 5 步中間用 lock 文件當(dāng)進度標(biāo)記寫.par→ 建 lock 文件 → 刪 wal →.par改名.parquet→ 刪 lock。重啟時check_uncompleted_lock_files掃一遍 lock 文件就能判斷崩潰發(fā)生在第幾步、從哪一步續(xù)。這里有個為什么值得停一下為什么不直接寫.parquet因為一個寫到一半的.parquet和一個寫完整的文件長得一樣查詢側(cè)沒法區(qū)分讀它要么報錯要么讀到臟數(shù)據(jù)。而.par lock 的組合把進行中變成了顯式狀態(tài)每步都可冪等續(xù)跑——本質(zhì)上是個落盤狀態(tài)機。代碼注釋里甚至列出了 4 種崩潰位置各自該怎么恢復(fù)。配套的還有兩道熔斷器check_memory_circuit_breaker和check_disk_circuit_breaker在內(nèi)存占用、磁盤空間逼近閾值前就主動拒絕寫入把硬 OOM / 磁盤寫滿降級成可控的寫失敗。 打開 src/ingester/src/wal.rs文件頭部的注釋就是這份恢復(fù)設(shè)計文檔對著check_uncompleted_lock_files看每個分支。小文件為什么還要被合并一遍compaction理解了寫入路徑合并就是順理成章的善后flush 出來的是一堆小 Parquet高吞吐時當(dāng)前小時能堆幾千個查詢?nèi)兟DJ接|發(fā)條件行為定時 compaction每小時只合并已完整結(jié)束的小時增量 compaction當(dāng)前小時文件數(shù)超過ZO_COMPACT_PENDING_FILES_TRIGGER立即排隊合并只封卷滿尺寸的文件組余下留給下輪增量模式里有個精妙的分布式取舍文件計數(shù)器PENDING_FILES是每個 ingester 節(jié)點本地內(nèi)存里的不全局精確。但沒關(guān)系——合并任務(wù)靠唯一索引ON CONFLICT DO NOTHING去重真正合哪些文件由 merge worker 讀全局file_list 決定。本地計數(shù)只是廉價信號決策點是單一的。這就是很多分布式系統(tǒng)共用的思路不追求全局一致只追求決策唯一。 src/compaction/src/incremental.rs 的模塊注釋把為什么需要它、為什么默認關(guān)著寫得比多數(shù)設(shè)計文檔還清楚值得逐句讀。搜索是怎么不掃全盤的數(shù)據(jù)經(jīng) compaction 后仍是海量文件查詢側(cè)的第一原則是先縮小范圍再碰數(shù)據(jù)按時間范圍 分區(qū)鍵先圈定候選文件generate_partitions用Bloom 過濾整文件排除——構(gòu)建側(cè)在 src/compaction/src/bloom/按 (文件, 字段) 生成并轉(zhuǎn)置成小時級.bf文件剪枝側(cè)在 src/search_service/src/bloom_pruner.rs。為什么需要 Bloom 而不是直接看 Parquet 元數(shù)據(jù)行組 min/max 對數(shù)值列夠用但字符串字段幾乎剪不掉。Bloom 讓這個文件一定不含該值這個判斷不用打開文件就能做。?? 翻車現(xiàn)場4 個高頻坑坑 1崩潰恢復(fù)日志看不懂現(xiàn)象進程被 kill 后重啟日志刷出一堆.par/.lock相關(guān)輸出。根因落盤 5 步在第 2~4 步之間中斷留下了帶或不帶 lock 的孤兒.par。正確姿勢啟動日志里搜Scanning lock files與found uncompleted wal file確認恢復(fù)在跑跑完后數(shù)據(jù)目錄還殘留.par的話再找Clean orphan par files日志確認孤兒清理已完成。坑 2熔斷器靜默拒寫現(xiàn)象寫入突然開始報錯但機器沒 OOM、磁盤也沒滿。根因內(nèi)存或磁盤熔斷器在閾值內(nèi)提前攔截這是設(shè)計行為不是故障。正確姿勢檢查配置字段common.memory_circuit_breaker_ratio和common.disk_circuit_breaker_threshold為 0 或 false 表示對應(yīng)熔斷關(guān)閉——grep這兩個字段名即可確認當(dāng)前生效值。坑 3增量 compaction 默認是關(guān)的現(xiàn)象高吞吐時當(dāng)前小時幾千個小文件最近一小時查詢特別慢。根因ZO_COMPACT_PENDING_FILES_TRIGGER默認 0 禁用只有定時的小時級合并在跑。正確姿勢grep ZO_COMPACT_PENDING_FILES_TRIGGER確認環(huán)境值非 0 才會按閾值觸發(fā)增量合并且任務(wù)完成后會被刪除、下輪可再觸發(fā)???4本地編譯全綠 ≠ enterprise 代碼沒問題現(xiàn)象cargo clippy本地通過CI 的 enterprise 特性構(gòu)建卻掛了。根因默認 features 下#[cfg(feature enterprise)]的代碼根本不參與編譯綠色證明不了它。正確姿勢在 diff 里grep cfg(feature enterprise)有命中就在 PR 里說明本地?zé)o法驗證倉庫 CLAUDE.md 把這條寫成了硬性規(guī)則。你的下一步git clone https://gitcode.com/GitHub_Trending/op/openobserve按 README.md Quick Start 里的 docker 命令 2 分鐘起一個單二進制實例打開 src/ingester/src/wal.rs對照頭部注釋的 4 種崩潰情形在check_uncompleted_lock_files里逐條找到處理分支打開 src/compaction/src/incremental.rs確認ZO_COMPACT_PENDING_FILES_TRIGGER的默認值是 0再去看它非 0 時走的分支。這個倉庫的價值不在功能列表而在寫入鏈路上能讀到的工程取舍狀態(tài)機讓崩潰恢復(fù)冪等、熔斷給資源兜底、用本地信號 單一決策點替代分布式一致?!久赓M下載鏈接】openobserveOpen source observability platform for logs, metrics, traces, frontend monitoring, pipelines and LLM observability. A sophisticated, simple and highly performant alternative to Datadog, Splunk, and Elasticsearch with 140x lower storage costs and single binary deployment.項目地址: https://gitcode.com/GitHub_Trending/op/openobserve創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考