您在使用阿里云日志服務(SLS)查詢分析和和流處理時,難免會碰到數據口徑差異,您可以使用兩種時間戳(__time__和__receive_time__)解決。
問題現象
在使用日志服務查詢分析時,難免會碰到源端時間字段同步到目標端之后,發生時間不一致的問題。例如:
SLS一周前的數據同步到MaxCompute之后,相同的時間間隔數據條數不一致。
SLS的數據通過數據加工同步到另一個Logstore之后,在目標端找不到設置時間間隔中的數據。
可能原因
在查詢分析模式下,日志數據按照一定的時間窗口或數據量進行批處理,并輸出結果。在這種模式下,數據被收集和聚合后進行分析,可以進行復雜的查詢和計算。
在流處理模式下,日志數據以流的形式連續到達,并立即進行處理。下游的流式任務根據__receive_time__字段進行篩選和處理。這種模式下,數據流實時處理,可以立即響應和反饋結果。
如圖所示,對于兩種不同模式,同樣都是從2023-05-24的00:00到18:00,流模式是包含綠色數據塊的,但查詢分析中是不包含綠色數據塊的。也就是說,查詢分析和流模式所使用的數據口徑是不一樣的,直接使用相同數據間隔沒有辦法得到一致的結果。
解決方案
SLS數據的數據時間
__time__(日志時間):日志時間是指日志的發送時間或者數據的創建時間,例如用戶訪問網頁的時間、商品的出售時間等等。在SLS中,主要有兩種使用方法:
Logtail:Logtail是阿里云日志服務提供的一種輕量級日志采集工具。Logtail采集日志時,會自動在日志數據中添加創建時間。如果這個時間戳和應用程序日志時間的定義不一樣(例如,事務日志是在事件發生之后基于數據庫記錄創建的,但業務需要定義數據中的create_time字段為日志時間),Logtail支持設置時區偏移,或者通過插件配置將日志行中的時間字段(業務時間)轉換為__time__字段的值。
API/SDK:使用API或SDK向日志服務寫入日志時,可以顯式地指定__time__字段的值(默認是發送時間)。
__receive_time__(到達時間) :到達時間是指表示日志到達并保存到服務端的時間。在日志服務中,到達時間是一個系統標簽(Tag),不允許修改。如果在創建Logstore的時候,開啟了管理Logstore的功能,那么服務端就會在收到日志時自動添加時間戳作為日志標簽字段。這個時間戳一般和業務處理無關。如果數據沒有記錄日志時間,則可以考慮使用到達時間,因為他在進入日志服務之后就不會發生變化。如圖所示,如果日志在數據管道中沒有延遲,那么就可以將到達時間作為日志發生的近似時間。
當一條日志數據到達日志服務時,日志服務將日志時間(字段名稱為__time__)和到達時間(字段名稱為__tag__:__receive_time__)做差,日志服務通過計算它們之間的差值把日志分為如下兩類:
如果差值位于
(-180,900]
(單位:秒)范圍內,說明是實時數據。這意味著日志數據可以立即使用和分析,適用于實時監控和快速響應的場景。如果差值位于[-7*86400,-180](單位:秒)范圍內,說明是歷史數據。這意味著日志數據已經存在一段時間,適用于補數據、性能分析和長期趨勢分析等場景。
SLS的兩種使用場景
通過記錄這兩種時間戳,我們可以在日志服務中進行不同的操作和分析,適用于兩種不同的使用場景:
查詢和分析
在常見的業務場景中,使用__time__字段可以按照日志時間進行查詢和排序,以便在特定時間范圍內檢索和分析日志數據。
流處理功能
使用__receive_time__字段可以通過流式消費(加工、投遞、消費、計算)進行數據處理,還能幫助我們了解日志數據到達系統的延遲情況,判斷日志數據的實時性和延遲程度。
使用這兩種時間戳有助于我們更好地理解和分析日志數據,從而滿足不同的應用場景和需求。同時,它們還使得在日志服務中進行實時監控、故障排查和性能分析等操作變得更加便捷。
方案示例
下列兩個問題的解決方案分別用SQL和SPL解決。關于SPL,更多參見SPL概述。
用流式消費怎樣計算滿足__time__窗口條件的日志行數。
在SLS的查詢界面查詢2023-05-23的00:00到18:00的數據N條,假設到達服務端的延時是1分鐘,對于流式處理可以使用__receive_time__獲得同樣的N條日志。
SQL
* | select * from log where __time__ >= to_unixtime('2023-05-23 00:00:00') and __time__ < to_unixtime('2023-05-23 18:00:00')
SPL
* | where "__tag__:__receive_time__" >= to_unixtime('2023-05-23 00:01:00') and __time__ < to_unixtime('2023-05-23 18:01:00')
用查詢分析怎樣計算滿足__receive_time__窗口條件的日志行數。
在SLS的數據加工界面設置處理2023-05-23的00:00到18:00的數據N條,假設到達服務端的延時是1分鐘,對于查詢分析可以使用__time__獲得同樣的N條日志。
SQL
* | select * from log where __time__ >= to_unixtime('2023-05-22 23:59:00') and __time__ < to_unixtime('2023-05-23 17:59:00')
SPL
* | where "__tag__:__receive_time__" >= to_unixtime('2023-05-23 00:00:00') and "__tag__:__receive_time__" < to_unixtime('2023-05-23 18:00:00')