時間序列分析
雲端服務和IoT裝置會產生遙測數據,可用來取得見解,例如監視服務健康情況、實體生產程式和使用量趨勢。 相較於一般基準模式,執行時間序列分析是識別這些計量模式模式中偏差的一種方式。
Kusto 查詢語言 (KQL) 包含建立、操作和分析多個時間序列的原生支援。 在本文中,瞭解如何使用 KQL 來建立和分析數千個時間序列,以秒為單位,並啟用近乎即時的監視解決方案和工作流程。
建立時間序列
在本節中,我們將使用 make-series
運算子,以簡單且直覺的方式建立大量的標準時間序列,並視需要填入遺漏的值。
時間序列分析中的第一個步驟是分割原始遙測資料表並轉換為一組時間序列。 此資料表通常會包含一個時間戳記資料行、內容相關的維度,以及選擇性計量。 維度可用來分割資料。 目標是依規律的時間間隔,為每個分割區建立數千個時間序列。
輸入資料表 demo_make_series1 會包含 60 萬筆任意 Web 服務流量的記錄。 使用下列命令來取樣 10 筆記錄:
demo_make_series1 | take 10
結果資料表會包含一個時間戳記資料行、三個內容相關的維度資料行,但沒有任何計量:
TimeStamp | BrowserVer | OsVer | 國家/地區 |
---|---|---|---|
2016-08-25 09:12:35.4020000 | Chrome 51.0 | Windows 7 | 英國 |
2016-08-25 09:12:41.1120000 | Chrome 52.0 | Windows 10 | |
2016-08-25 09:12:46.2300000 | Chrome 52.0 | Windows 7 | 英國 |
2016-08-25 09:12:46.5100000 | Chrome 52.0 | Windows 10 | 英國 |
2016-08-25 09:12:46.5570000 | Chrome 52.0 | Windows 10 | 立陶宛共和國 |
2016-08-25 09:12:47.0470000 | Chrome 52.0 | Windows 8.1 | 印度 |
2016-08-25 09:12:51.3600000 | Chrome 52.0 | Windows 10 | 英國 |
2016-08-25 09:12:51.6930000 | Chrome 52.0 | Windows 7 | 荷蘭 |
2016-08-25 09:12:56.4240000 | Chrome 52.0 | Windows 10 | 英國 |
2016-08-25 09:13:08.7230000 | Chrome 52.0 | Windows 10 | 印度 |
由於沒有計量,因此,我們僅能建置一組代表流量計數本身的時間序列,其會使用下列查詢依 OS 進行分割:
let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp from min_t to max_t step 1h by OsVer
| render timechart
- 使用
make-series
運算子來建立含三個時間序列的集合,其中:num=count()
:流量的時間序列from min_t to max_t step 1h
:在時間範圍 (資料表記錄的最舊和最新時間戳記) 內,以 1 小時的間隔來建立時間序列default=0
:指定填滿遺漏間隔的方法以來建立標準時間序列。 或者,使用series_fill_const()
、series_fill_forward()
series_fill_backward()
和series_fill_linear()
來進行變更by OsVer
:依OS分割
- 實際的時間序列資料結構是每個時間間隔中彙總值的數值陣列。 我們使用
render timechart
來產生視覺效果。
在上述資料表中,我們有三個分割區。 我們可以針對每個 OS 版本建立個別的時間序列:Windows 10 (紅色)、7 (藍色) 和 8.1 (綠色),如下圖所示:
時間序列分析函式
在本節中,我們將執行一般序列處理函式。 建立一組時間序列之後,KQL 支援不斷成長的函式清單來處理和分析它們。 我們將描述一些代表性函式來處理和分析時間序列。
篩選
篩選是單一處理中的常見做法,非常適合用於時間序列處理工作 (例如,緩和吵雜的訊號、變更偵測)。
- 有兩個泛型篩選函式:
series_fir()
:套用 FIR 篩選。 用於移動時間序列平均和差異的簡單計算,以進行變更偵測。series_iir()
:套用 IIR 篩選。 用於指數平滑和累計總和。
Extend
時間序列,此時間序列會透過在查詢中新增大小 5 個間隔的新移動平均序列 (名為 ma_num) 來設定:
let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp from min_t to max_t step 1h by OsVer
| extend ma_num=series_fir(num, repeat(1, 5), true, true)
| render timechart
迴歸分析
Azure Data Explorer 支援分段線性回歸分析,以估計時間序列的趨勢。
- 使用 series_fit_line() \(英文\),以使最佳線條擬合至某個時間序列以進行一般趨勢偵測。
- 使用 series_fit_2lines \(英文\) 來偵測趨勢變更 (相對於基準線),這類變更對於監視案例非常實用。
series_fit_line()
時間序列查詢中的 和 series_fit_2lines()
函式範例:
demo_series2
| extend series_fit_2lines(y), series_fit_line(y)
| render linechart with(xcolumn=x)
- 藍色:原始時間序列
- 綠色:擬合線
- 紅色:兩條擬合線
注意
此函式已準確地偵測到跳轉 (層級變更) 點。
季節性偵測
許多計量都會遵循季節性 (週期) 模式。 雲端服務的使用者流量通常會包含每日和每週模式,這類模式在工作日中間最高,在夜晚和週末則最低。 IoT 感應器會定期測量。 實際度量 (例如溫度、壓力或溼度) 可能也會顯示季節性行為。
下列範例會在 Web 服務的一個月流量 (以 2 小時為間隔) 上套用季節性偵測:
demo_series3
| render timechart
- 使用 series_periods_detect() \(英文\) 自動偵測時間序列中的期間。
- 如果我們知道計量應具備特定的相異期間,而且想要確認它們存在,請使用 series_periods_validate() \(英文\)。
注意
如果特定的相異期間不存在,則為異常狀況
demo_series3
| project (periods, scores) = series_periods_detect(num, 0., 14d/2h, 2) //to detect the periods in the time series
| mv-expand periods, scores
| extend days=2h*todouble(periods)/1d
週期 | 分數 | days |
---|---|---|
84 | 0.820622786055595 | 7 |
12 | 0.764601405803502 | 1 |
此函式會偵測每日和每週的季節性。 每日分數會低於每週分數,因為週末與工作日不同。
元素型函式
您可以針對時間序列進行算術和邏輯運算。 我們可以使用 series_subtract() \(英文\) 來計算剩餘的時間序列,即原始未經處理的計量和經過平滑處理之時間序列間的差異,並尋找剩餘訊號中的異常狀況:
let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp in from min_t to max_t step 1h by OsVer
| extend ma_num=series_fir(num, repeat(1, 5), true, true)
| extend residual_num=series_subtract(num, ma_num) //to calculate residual time series
| where OsVer == "Windows 10" // filter on Win 10 to visualize a cleaner chart
| render timechart
- 藍色:原始時間序列
- 紅色:平滑時間序列
- 綠色:剩餘時間序列
大規模的時間序列工作流程
下列範例示範這些函式如何在數千個時間序列上大規模執行 (以秒為單位) 以進行異常偵測。 若要查看四天中 DB 服務讀取計數計量的一些範例遙測記錄,請執行下列查詢:
demo_many_series1
| take 4
timestamp | Loc | Op | DB | DataRead |
---|---|---|---|---|
2016-09-11 21:00:00.0000000 | Loc 9 | 5117853934049630089 | 262 | 0 |
2016-09-11 21:00:00.0000000 | Loc 9 | 5117853934049630089 | 241 | 0 |
2016-09-11 21:00:00.0000000 | Loc 9 | -865998331941149874 | 262 | 279862 |
2016-09-11 21:00:00.0000000 | Loc 9 | 371921734563783410 | 255 | 0 |
以及簡單的統計資料:
demo_many_series1
| summarize num=count(), min_t=min(TIMESTAMP), max_t=max(TIMESTAMP)
num | min_t | max_t |
---|---|---|
2177472 | 2016-09-08 00:00:00.0000000 | 2016-09-11 23:00:00.0000000 |
以 1 小時的讀取計量間隔來建置時間序列 (總共四天 * 24 小時 = 96 點),會產生標準模式波動:
let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h
| render timechart with(ymin=0)
上述行為會讓人產生誤解,因為單一的一般時間序列會彙總自數千個可能具有異常模式的不同執行個體。 因此,我們會針對每個執行個體建立一個時間序列。 實例是由 Loc (位置) 、Op (作業) 和 DB (特定電腦) 所定義。
我們可以建立多少個時間序列?
demo_many_series1
| summarize by Loc, Op, DB
| count
計數 |
---|
18339 |
現在,我們將建立一組 18339 個讀取計數計量的時間序列。 我們會將 by
子句新增至 make-series 陳述式、套用線性迴歸,然後選取前兩個趨勢下降最明顯的時間序列:
let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h by Loc, Op, DB
| extend (rsquare, slope) = series_fit_line(reads)
| top 2 by slope asc
| render timechart with(title='Service Traffic Outage for 2 instances (out of 18339)')
顯示執行個體:
let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h by Loc, Op, DB
| extend (rsquare, slope) = series_fit_line(reads)
| top 2 by slope asc
| project Loc, Op, DB, slope
Loc | Op | DB | slope |
---|---|---|---|
Loc 15 | 37 | 1151 | -102743.910227889 |
Loc 13 | 37 | 1249 | -86303.2334644601 |
在不到兩分鐘內,已分析接近 20,000 個時間序列,並偵測到讀取計數突然下降的兩個異常時間序列。
這些與快速效能結合的進階功能提供獨特的強大解決方案,以供時間序列分析使用。
相關內容
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應