從 sidecar 模式、Ingestion 架構到倒排索引,一次搞懂集中式日誌系統設計的面試重點
最近看了一支 s09g 的系統設計 Mock Interview,受面者設計「集中式日誌系統」,面試官在 45 分鐘內從 Clarify 一路 DeepDive 到查詢層,把每一層的設計決定都翻過一遍。這類「面試官逐點 feedback」的影片,對準備系統設計面試的人特別有價值——比起「如何設計一個 log system」的教學文,它揭露的是真正的 trade-off 與面試官在意什麼。
這篇整理影片裡面試官挑出的五個關鍵設計決定,包含他自己的「我會怎麼問」與「為什麼這樣問」。每節都附面試官的質疑點,下次你自己上場時可以避開。
Table of Contents
一、Clarify 階段:你花 9 分鐘在錯的問題上
面試一開始面試官就點出一個時間分配問題:受面者光是 Login API 的細節就討論了 9 分鐘。
這個錯誤很常見。受面者很容易陷入「把題目當產品 PRD 在寫」的陷阱,把所有 API 規格、欄位定義都講清楚。但對內部基礎設施(internal infra)的題目來說,public API 的相容性根本不是重點——你內部用,今天跟昨天介面不一樣,沒人會死。
面試官真正的期望是:你把時間花在 non-function requirement,也就是:
- 寫入量級:每分鐘多少筆 log?平均多大?
- 儲存量級:保留多久?每天總量?
- 查詢模式:誰會查?多久查一次?query 的時間區間多大?
- 錯誤容忍:丟一點 log 可以嗎?
這四個數字決定了後面每一層的技術選型。沒問清楚就畫圖,等於在沙地上蓋房子。
順帶一個小技巧:受面者在講 API 時可以包裝一下——「這個介面我用一個 wrapper 抽象掉,實際呼叫端不需要知道底層是 batch 還是 stream」。一句話帶過,面試官不會再追。
二、Ingestion 層:sidecar + 批次壓縮的真實成本
第一個 deep dive 點:log 怎麼從 service 送到 backend?
受面者原本的設計是一條一條用 JSON stream 推到後端。面試官直接否決——理由很扎實:
- 一條 log 一次 HTTP request = 一輪 TCP handshake
- 服務跑在高 QPS 場景時,這些 handshake 是純粹的浪費
- 還會打爆 backend 的 connection pool
正確的設計是 sidecar 模式:
[你的 service] → 寫到本地檔案 (e.g. /var/log/app.log)
↑
[sidecar agent] ← 每 N 秒 batch 讀取 → HTTP POST → centralized log server
這樣做的好處有三層:
- QPS 聚合:1000 條 log 變 1 次 HTTP,省掉 999 個 handshake
- 故障域隔離:如果 log backend 暫時掛掉,service 不會被拖慢,sidecar 把檔案留在本地,等恢復再補傳
- 資源獨立:service 跟 log agent 是兩個 process,log 的資源壓力不會直接打到業務
但面試官點出了真實成本——這些好處不是免費的:
- 延遲成本:你等一個 batch 才能送一次,log 到達後端的時間會延遲 batch interval(常見 30s~1min)。如果你的 log 系統用於即時告警,這個延遲要納入考量
- 維運成本:sidecar 是另一個 deployment unit,要有人 maintain、要單獨 roll out。service 跟 agent 打包在同一 pod 是「方便」,但不是「零成本」
- 故障點:pod 裡多一個 process,就多一個可能出錯的地方
面試官要的不是「sidecar 是好的」這種二元結論,而是你能清楚說出哪些 cost 是 unavoidable、哪些是你選擇承擔的。
三、Ingestion 架構:Load Balancer + Kafka 在哪一邊?
第二個 deep dive 點:架構圖長什麼樣?
受面者先畫了一版:Service → Load Balancer → Kafka → Consumer → Storage。後來又改成 Kafka → LB → Service,自己也解釋不清楚為什麼要加 LB、為什麼 LB 在 Kafka 前後的位置要調。
面試官拆得很細:
為什麼要 LB?解的是 noisy neighbor
如果你的 log system 是 multi-tenant(100 個 team 共用),最大的風險是一個 team 吃掉 50% 資源,其他人被拖累。
LB 的真正用途不是「分流量」那麼表面,而是:
- 依 clientID(team ID)做 sharding
- 每個 team 路由到固定的 backend shard
- 再用一層 hash 處理 team 內的進一步分流
單純的 round-robin LB 解不了 noisy neighbor——A team 流量再大都只是多輪幾次,B team 一樣被打擾。只有 sharding 才能資源隔離。
Kafka 在前面 vs 後面
受面者把 Kafka 放在 LB 後面,被面試官挑戰:「Kafka 自己不是可以做 partition consumer 嗎?為什麼還要 LB?」
受面者的 defense 是 tolerance:Kafka 當 buffer,上游突然 spike 不會打爆 consumer。
這個論點是 make sense 的——Kafka 的設計本來就是 absorb 寫入尖峰。所以 Kafka 放在 ingestion 第一線沒問題。LB 的角色是「分給哪個 ingestion topic/partition」,不是「做 TCP load balancing」。
面試官會追問的是:你能說清楚 Kafka 跟 LB 在這層各負責什麼嗎? 不要混為一談。
四、Storage 層:Wide-column vs Fixed-column 的真實差異
第三個 deep dive 點:log 要存哪?
受面者展開了兩個 option:
Wide-column(Cassandra 類)
- 沒 schema,隨便寫新 column
- 適合「每個 team 有自己的 metadata 欄位」的情境
- 缺點:分析型 query(aggregate、scan)不優,不是設計目的
Fixed-column(傳統 RDB / 預定義欄位)
- 預先知道 timestamp、code location、source control info 這些常見 metadata
- 已知欄位查詢快、有 index 加速
- 動態欄位要塞 JSON,每次 query 要 out-of-line parse JSON
面試官的反擊很犀利:
「如果我根據 metadata(timestamp、code location)查,兩種都能做。如果我要用 regex 匹配 log 內容,兩種都是全表掃描。這個 trade-off 是不是其實沒打到重點?」
這句話戳到重點——當你的 query pattern 是「全表掃某個 regex」時,schema 怎麼設計根本沒差。所以展開方向錯了。
面試官要的答案是:log 系統的瓶頸在 query 層,不在 schema 設計。換句話說,你應該把時間花在「怎麼讓查詢變快」,而不是「選 wide 還是 fixed」。
五、QA 層:為什麼不能把 Storage 當查詢層用?
第四個 deep dive 點(也是這題的真正魔王):debug 的人怎麼查 log?
受面者直接把 query 丟給 storage 層做全表掃。面試官打槍:
先算讀寫比
- 寫:所有 service 全天候在寫 log,每分鐘可能數千到數萬行
- 讀:只有 on-call debug 的人在查,每天可能就 20-30 人
這是典型的 write-many / read-mostly 場景,但讀的總量小但 query pattern 很複雜。
Query window 不可預測
跟 metric collection 不一樣——metric collection 的 query window 通常固定(過去 15 分鐘、過去 1 小時),可以預計算。
log debug 不一樣:
- 我先查過去 1 小時 → 沒定位到 bug
- 放大到過去 24 小時 → 還是沒有
- 拉大到過去 7 天甚至 30 天
這代表你不能 pre-compute。每次 query 都是大範圍的即時搜尋。
解法:倒排索引 + 分片並行
這才是這題真正的 DeepDive 重點——面試官要的兩個關鍵設計:
- Inverted Index + Posting List:把 log 文本切成 token,每個 token 對應到「出現這個 token 的文件列表」。這樣 query「某個 regex」時,先從 inverted index 縮小範圍
- 跨 shard 並行查詢:把 posting list 拆到 N 個 shard,query 同時打 N 個 shard 再合併結果。這樣才能在大資料量下維持查詢延遲
受面者在 storage 層花太多時間在 schema 比較,反而把這題最關鍵的 index 設計跳過了——面試官直接說這是 knowledge gap。
六、面試官最後的時間預算提醒
整場面試 45 分鐘,受面者畫完 high-level diagram 後只剩 18 分鐘。Storage 展開方向錯了,導致最後 1 分鐘根本沒時間 cover analysis 層(query 的進階處理:aggregation、dashboard、anomaly detection)。
面試官最後一句總結很值得記住:
「DeepDive 的重點應該放在 index 上,不是 schema 選型。」
結語:給準備系統設計面試的你
這支影片最珍貴的不是「log system 怎麼設計」的答案,而是面試官怎麼看你的設計決定。整理五個 takeaway:
- Clarify 階段:internal infra 的題目,把時間花在 NFR(量級、查詢模式),不要糾結 API 細節
- Ingestion:sidecar + batch 是對的,但要有 latency cost、維運成本的心理準備
- 架構圖:Kafka 跟 LB 各解什麼問題,要分清楚;noisy neighbor 一定要 sharding,不是 round-robin
- Storage:當 query 是 regex 全文搜尋時,schema 比較毫無意義,把時間花在 index
- Query 層:log debug 的 query window 不可預測 → 不能 pre-compute → inverted index + posting list + sharding 是標準解
系統設計面試不是考你「會什麼」,是考你「能不能在 45 分鐘內,把 trade-off 講清楚」。把這五個觀念記下,下次上場會穩很多。
參考資料
- 影片:[系统设计 Mock] Logger System — s09g(2026-08-05)
- 延伸閱讀:Designing Data-Intensive Applications Chapter 3(Storage)、Chapter 11(Stream Processing)