Grafana Loki 在小規模可觀測性場景確實夠用,但日誌量一爬到三位數 GB,Loki 的記憶體曲線就頂到上限、查詢從秒級退化到分鐘級、沒帶標籤的全文搜尋直接 timeout。VictoriaLogs 用 columnar 儲存加 per-token 索引把同樣工作量壓進三分之一的 RAM 跟磁碟,查詢延遲還順帶縮到 1/12。這套日誌儲存方案在 2026 年初進入正式 GA,採集端對 Loki 協定相容,搬遷成本接近零。
VictoriaLogs 由 VictoriaMetrics 團隊在同一套 mergeset 引擎邏輯上延伸出來。設計目標寫得很直接:把日誌全文檢索的成本壓到接近指標儲存的水準。對照組是同樣 500GB / 7 天的工作量,公開 benchmark 拿到的數字是 Loki 三分之一的記憶體、37% 更少的磁碟、12 倍的查詢速度。本文要拆的是這些數字背後的儲存設計,以及怎麼把它接上現有的 Vector、Fluent Bit、Grafana Alloy 採集鏈。
Loki 的標籤索引貴在哪
Loki 對外的賣點一直是「只索引標籤,不索引內容」。聽起來合理:標籤少,索引就小,記憶體就省。實際走到大流量產環境之後就會看到代價。
第一個問題是 cardinality。一旦把 pod_name、request_id、trace_id 這種高基數欄位放進標籤,每個獨特組合都會在記憶體裡開一個 stream。Loki 沒有夠強的硬性限制機制,預設配置下幾百萬個 stream 就能把 ingester 的記憶體吃光,OOM kill 是日常。
第二個問題是查詢路徑。Loki 的查詢只在標籤層做剪枝,剩下的全文比對是逐 chunk 解壓縮、逐行 regex 掃過去。如果搜尋條件沒帶夠精準的標籤,整個時間範圍裡的 chunk 都得拉回 querier 解壓——500GB 規模的「大海撈針」查詢實測 12 秒、否定查詢直接 timeout,都是這個機制下的必然結果。
第三個問題是運維面。Loki 的單體模式只能撐到一定吞吐量,要繼續往上得拆成 distributor / ingester / querier 微服務,再加 Memcached、加 object storage、加 compactor。光把這套架構穩定跑起來就已經是一個全職工程師的工作量。
per-token 索引換來的代價平衡
VictoriaLogs 的儲存模型走的是反方向:所有欄位都建索引,但用 columnar 儲存把成本壓下來。
寫入時,每筆日誌被拆成若干欄位(_msg、_time、_stream、自訂結構化欄位),每個欄位獨立壓縮存成一欄。_msg 內文則再被切成 tokens 建反向索引。這套設計直接借自 VictoriaMetrics 的 mergeset 引擎,欄位之間的壓縮比通常落在 10 倍到 30 倍之間。
查詢時,per-token 索引讓「找出某行特定字串」這種需求不必再掃整個時間窗。實測同樣的 needle-in-haystack 查詢在 500GB 資料集上,Loki 跑 12 秒,VictoriaLogs 跑 900 毫秒。差距不是調整參數能補的,是儲存結構本身的差別。
partition 切分方式是按日分桶(partitions/YYYYMMDD/),這讓資料分層、備份、刪除舊資料的操作都能在不影響線上服務的前提下完成。要把三個月前的資料搬到便宜的 HDD 或 S3 做冷儲存,rsync 整個 partition 目錄就行,不需要走複雜的 API。
至於記憶體佔用,同樣的 500GB / 7 天工作量,Loki 穩態下吃 6 到 7 GiB、爆量時還會被 OOM kill;VictoriaLogs 穩態 1.3 GiB、峰值也只到 2 GiB 左右。這個差距讓單台 4 GB RAM 的 VPS 從「勉強堪用」變成「綽綽有餘」。
LogsQL 比 LogQL 多了什麼
語法層面,LogsQL 抓住了一個 LogQL 一直沒處理好的點:把全文檢索當作第一公民。
最簡單的查詢就是一個字:
1 | error |
這會找到 _msg 欄位裡包含 error 的所有日誌。要找精確字串就加引號:
1 | "connection refused" |
組合條件時 AND 可以省略:
1 | _time:1h log.level:error -app:buggy_service |
這條的意思是:過去一小時內,log.level 欄位為 error、但排除 app 為 buggy_service 的紀錄。負號代表排除,這在 LogQL 裡要寫成相對冗長的 != 跟 !~ 組合。
stream filter 用 {} 包起來,跟 Loki 的習慣對齊:
1 | {app="nginx"} _time:5m 500 |
聚合走 pipe 串接,這個設計比 LogQL 的函式包裹更接近 shell 的直覺:
1 | _time:1h error | stats by (host) count() as cnt | sort by (cnt) desc |
對從 Splunk 或 Sumo Logic 轉過來的工程師,這套寫法的學習曲線會比 LogQL 那種 PromQL-style 的語法平緩許多。
採集層相容現有的工具鏈
VictoriaLogs 對外暴露多套相容協定,採集端基本不用換:
- OpenTelemetry Collector 直接送 OTLP/HTTP
- Vector 走原生 sink
- Fluent Bit、Fluentd、Logstash 用 HTTP output
- Promtail 改個 URL 就能繼續用
- Grafana Alloy 近期版本內建支援
- Journald、syslog 直送也有對應的 endpoint
這意味著從 Loki 切換到 VictoriaLogs 不必動採集端的設定。對已經部署 Promtail 或 Alloy 的環境,唯一要改的是把 clients.url 指到 VictoriaLogs 的 /insert/loki/api/v1/push——這個端點刻意做了 Loki 協定相容,讓搬遷成本接近零。
視覺化層也是。Grafana 裝個官方 plugin 就能用 LogsQL 查 VictoriaLogs,原本的 dashboard 改 datasource 就能繼續跑。對需要保留 Loki 邏輯不動的環境,VictoriaLogs 還支援 LogQL 查詢端的相容模式。
單節點部署:一支 binary 加 Docker Compose
VictoriaLogs 的單節點版本是一支 Go 編譯出來的 binary,沒有外部相依。最小可用的 Docker Compose 大致長這樣:
1 | services: |
-retentionPeriod 支援從 1d 到 100y,也可以改用 -retention.maxDiskSpaceUsageBytes 走磁碟容量上限。預設值只有 7 天,正式環境一定要改。
對外暴露的部分,建議在前面套一層 Caddy 或 Nginx 做 TLS 跟 basic auth。VictoriaLogs 本身也有 -httpAuth.username 跟 -httpAuth.password 參數,但走反代解決會更有彈性,也能順便處理跨服務的權限收斂。
多租戶用 AccountID 跟 ProjectID HTTP header 區分,寫入跟查詢都得帶上對應的 header 才會落到同一個邏輯空間。這個機制在 SaaS 場景或公司內部多團隊共用一台儲存實例時特別好用。
高可用方案官方推薦的是雙寫兩台單節點再用 vmauth 做查詢端 load balance,避開了 cluster 模式的部署複雜度。對絕大多數中小規模的場景,這個方案的容錯能力已經夠用,又不會引入額外的故障點。
該選 Loki 還是 VictoriaLogs
兩邊都不需要過度吹捧。場景對的時候各有勝場。
選 Loki 的情境:團隊已經跑了一兩年的 Loki,運維跟 dashboard 都成熟;查詢模式以標籤為主、全文檢索很少;對 Grafana 生態的整合深度有強要求;日均日誌量在 50GB 以內,記憶體跟磁碟成本不構成壓力。
選 VictoriaLogs 的情境:剛開始建立可觀測性技術棧、沒有歷史包袱;查詢需求以全文檢索或 ad-hoc 探索為主;資源密度有實質限制(VPS 預算固定、要在同一台機器上同時跑指標跟日誌);不想花全職工程師力氣維護 Loki 微服務拓樸。
實務上對新建環境,VictoriaLogs 的綜合分數明顯高一些。少一個元件就少一個故障點,少幾 GiB 記憶體預算就能多塞別的服務。把 VictoriaMetrics + VictoriaLogs 跟 Grafana Alloy 湊在一起,會得到一套完全 columnar 的可觀測性堆疊,硬體成本只有傳統 ELK + Loki 組合的零頭。
從 Loki 搬遷的實務順序
對已經跑 Loki 的環境,沒必要一次切換。建議的順序:
第一步是並行寫入。讓 Promtail 或 Alloy 同時送一份到 Loki 跟 VictoriaLogs,跑兩三週,確認新平台沒漏資料、查詢結果一致。VictoriaLogs 的吞吐能力撐得住雙寫,這段時間不會額外加重採集端壓力。
第二步是切查詢流量。Grafana datasource 加一條 VictoriaLogs,讓部分 dashboard 跟 alert 走新後端。觀察 query latency 跟錯誤率,確認 LogsQL 改寫過的查詢行為符合預期。
第三步是停寫 Loki。確認新後端穩定後關閉 Loki 寫入,Loki 那邊保留唯讀模式跑到資料過期或主動清理。
整個過程裡,採集端的設定變動最小。對運維面真正花時間的是查詢語法的改寫,但 LogsQL 的學習曲線本身就比 LogQL 平緩,這部分的成本通常被高估。
結論
Loki 在 2020 年解決了當時 ELK Stack 的成本問題,但 2026 年看回去,它對標籤索引的依賴反而成了新的瓶頸。VictoriaLogs 用 columnar 加 per-token 索引把同樣的工作量壓進三分之一的資源,採集端跟視覺化端又都向後相容,搬遷成本比預期低很多。
部署 VictoriaLogs 不需要叢集、不需要 object storage、不需要 Memcached,一台中階 VPS 就能撐到日均百 GB 的日誌吞吐。columnar 儲存對 I/O 隨機讀寫跟記憶體頻寬都敏感,搭配 NVMe SSD 跟現代 CPU 才能把效能跑滿。NCSE Network 提供位於臺灣是方電信機房的 VPS 服務,採用 Intel Gold CPU 與 NVMe SSD,適合作為自架可觀測性技術棧的儲存節點,詳細規格與報價可以到 ncse.tw 查看。