開發與維運

Nginx Access Log 指標預聚合實踐

背景

Nginx 完成請求處理後會記錄客戶端請求信息到 access log。與業務請求數量成正比,access log 文件內容日積月累,佔用大量磁盤的存儲空間的同時,數據量增長也使分析 access log 變得困難。

阿里雲日誌服務(SLS)是雲原生觀測分析平臺,為Log/Metric/Trace等數據提供大規模、低成本、實時平臺化服務。一站式提供數據採集、加工、分析、告警可視化與投遞功能,全面提升研發、運維、運營和安全等場景數字化能力。

在 web 服務器上部署  Logtail 客戶端,實時採集 Nginx access log 數據到 SLS 存儲:

image-20210715214622219.png

  • 問題一:存儲空間持續增加

以 34K TPS 的請求量計算,每條日誌 500 Bytes,一個月累計後達到 42 TB。但 access log 隨時間推移逐漸從溫數據變為冷數據,這帶來一筆不小的存儲開銷。

image-20210715220619165.png

  • 問題二:分析計算消耗大

假設對 30 天的數據分析小時級流量特徵,如果每次對全量數據做即時分析,計算成本是巨大的,計算延時的增加也影響了體驗。

以 host、method 分組計算小時級流量特徵為例:

* | select (__time__ - __time__ % 3600) as dt, method, host, sum(request_length)/1024.0/1024.0 as request_MB, sum(body_byte_sent)/1024.0/1024.0 as body_sent_MB, avg(upstream_response_time) as avg_latency, avg(request_time) as avg_request_time group by dt, method, host order by dt asc limit 10000

隨著查詢時間範圍增加,計算引擎需要掃描更多的數據量做計算,增加了資源開銷與分析延時。

數據查詢範圍

掃描日誌條數

計算耗時

24 hours

14,397,600

1,390ms

30 days

431,884,800

13,291ms

方案

本文介紹一種預計算方案:

  1. 優化冷數據:歷史數據降精度存儲。
  2. 降分析延時:將全量數據計算拆分為多次增量計算。

具體來說,是將 SQL 計算任務託管在後臺,週期性運行,得到一個個時間區間的統計值,將這些統計結果寫入存儲庫,可達到如下效果:

  1. 降維後的數據滿足固定的統計需求,對於 30 天前的日誌原文,如不需要做細節問題調查,甚至可以縮短存儲 TTL 到 7 天。
  2. 統計結果直接存儲下來,可以被多種下游系統直接使用,例如可視化大盤、告警監控、入庫數倉等。
  3. 查詢引擎在降維後數據上計算,由於要處理的數據量大大降低,達到秒開的效果。

Scheduled SQL 實踐

Scheduled SQL 是一項由 SLS 全託管的功能,解決場景需求:

  1. 定時分析數據:根據業務需求設置 SQL 語句或查詢分析語句,定時執行數據分析,並將分析結果存儲到目標庫中。
  2. 全局聚合:對全量、細粒度的數據進行聚合存儲,彙總為存儲大小、精度適合的數據,相當於一定程度的有損壓縮數據。

image-20210601122007945.png

本節介紹如何通過 Scheduled SQL 對 Nginx access log 做指標預計算。

原始日誌庫中執行 SQL 分析

索引字段配置如下:

image-20210718112045691.png

指標要求:按照時間( 5 分鐘粒度)、請求方法(method)、主機(host)維度分組,統計每個時間段內客戶端請求服務端的流量總計(request_MB)、服務端返回給客戶端的流量總計(body_sent_MB)、後端響應平均延時(avg_latency)、客戶端請求平均耗時(avg_request_time)。

SQL 代碼如下:

* | select (__time__ - __time__ % 300) as dt, method, host, sum(request_length)/1024.0/1024.0 as request_MB, sum(body_byte_sent)/1024.0/1024.0 as body_sent_MB, avg(upstream_response_time) as avg_latency, avg(request_time) as avg_request_time group by dt, method, host order by dt asc limit 10000

在 SLS 控制檯上分析預覽:

image-20210718115803961.png

確認結果符合預期後,以當前  SQL 語句創建 Scheduled SQL 作業。

計算配置

資源池有免費(Project 級別 15 並行度)、增強型(收費,但資源可擴展,適用於大量計算且有 SLA 要求的業務場景)兩種,按照你的需求來設置即可。

image-20210718115842090.png

注意為目標庫 nginx_access_log_rollup 也提前準備好數據索引,如下圖:

image-20210718120023711.png

調度配置

設置 SQL 每 5 分鐘執行一次,每次執行處理最近 5 分鐘窗口的數據。

注意:

1. 設置延遲執行參數,上游 Logstore 的數據到來可能延遲,建議設置大一些的值做等待來保證計算數據的完整性。

2. SQL 運行超過指定次數或指定時間後,這一次的 SQL 實例會失敗並繼續下一個實例的調度。

image-20210718114004043.png

實例查看、管理

可以在控制檯上查看剛才創建的 Scheduled SQL 作業:

image-20210718120205278.png

在作業管理頁面內,可以查看到每一次執行的實例列表。

image-20210718120412831.png

每個實例信息中有 SQL 查詢區間,如果任務失敗(權限、SQL 語法等原因)或 SQL 處理行數指標為 0(數據遲到或確實沒有數據),可以對指定實例做重試運行(失敗告警功能開發中)。

效果

Nginx access log 預計算之後數據格式:

image-20210718120250125.png

預計算結果之上用 SQL 分析流量、延時的時間趨勢,對分析結果添加儀表盤來實現一個業務大盤。

image-20210718123329509.png

  • 延時統計

統計 client 請求延時趨勢圖:

* | select from_unixtime(dt - dt % 3600) as t, concat('host:', host, '#method:', method) as host_method, round(max(avg_request_time), 3) as max_request_time group by dt, host_method order by dt asc limit 10000

選擇流圖,圖表類型為線圖:

image-20210718135615865.png

服務端響應延時用相同方式處理,SQL 語句:

* | select from_unixtime(dt - dt % 3600) as t, concat('host:', host, '#method:', method) as host_method, round(max(avg_latency), 3) as max_latency group by dt, host_method order by dt asc limit 10000

  • 流量統計

統計 response 流量趨勢圖:

* | select from_unixtime(dt - dt % 3600) as t, concat('host:', host, '#method:', method) as host_method, round(sum(body_sent_MB), 3) as sum_body_sent_MB group by dt, host_method order by dt asc limit 10000

選擇流圖,圖表類型為面積圖:

image-20210718135738078.png

request 流量用相同方式處理,SQL 語句:

* | select from_unixtime(dt - dt % 3600) as t, concat('host:', host, '#method:', method) as host_method, round(sum(request_MB), 3) as sum_request_MB group by dt, host_method order by dt asc limit 10000

  • 流量、延時分析大盤

將以上四個圖表保存到儀表盤中,效果如下:

image-20210718201129391.png

更多內容請參考:

採集 Nginx access log

使用 Scheduled SQL

Leave a Reply

Your email address will not be published. Required fields are marked *