引言
隨着數字化浪潮下企業數字化轉型進程的不斷加速,以及雲原生趨勢下可觀測性理念的逐漸普及,企業的日誌數據來源越來越豐富, 數據規模也正在快速增長,爲了高效處理分析這些數據, 日誌的集中管理越來越有必要, 數據集中收集之後, 在需要的時候再查詢和分析以充分挖掘這些數據的價值。
現在許多業務場景,對於高精度時間戳的需求越來越強烈,很多已經從秒、毫秒,變成了微秒和納秒。 因爲除了日誌內容本身是一種重要信息之外,日誌之間的相對順序也是因果關係的一種反映,某些場景下如果日誌內容完全相同,但是日誌間的順序錯亂了反映出來的結果可能和真實世界裏面的事件完全相反。接下來我們簡要介紹下對日誌順序一致性有強烈需求的業務場景。
有序業務場景
隨着雲原生時代的到來,越來越多的業務對全局有序有強烈依賴,下面是幾種常見的業務場景。
Trace
在現代IT系統中,尤其是雲原生、微服務系統,一次外部請求往往需要多個內部服務、多箇中間件和多臺機器的相互調用才能完成。在這一系列的調用中,任何階段出現的問題都可能導致外部服務失敗或延遲升高,影響用戶體驗。如果您想要精確定位及分析問題,需要使用分佈式鏈路追蹤技術。
分佈式鏈路追蹤(Distributed Tracing,簡稱Trace)可提供整個服務調用鏈路的調用關係、延遲、結果等信息,非常適用於雲原生、分佈式、微服務等涉及多個服務交互的系統。
在跟蹤(Trace)場景中,日誌的納秒級別排序對於後端日誌處理系統具有重要意義。以下是日誌納秒級別排序對該場景的意義:
- 精確的時間戳關聯
- 時序追溯
- 故障排查和性能優化
- 鏈路追蹤
下圖是某個trace調用下span的時間毫秒級別精度展示
高併發場景
在高併發場景下,全局排序好日誌對於問題定位、時間線理清等方面具有重要性和意義。通過對日誌進行排序,可以更好地理解系統行爲,提高系統的可靠性、性能和可維護性。主要體現在下面幾個方面:
- 跟蹤和分析問題
- 理清時間線
- 監控和性能分析
強一致業務時序
在業務時序強一致的場景中,確保事件的順序和時間的準確性非常重要。比如下面兩個場景:
- 金融交易:在金融交易中,確保交易的順序和時間的準確性非常關鍵。任何交易順序的混亂或時間戳的錯誤都可能導致嚴重的後果,如資金損失或交易失敗。因此,對於金融交易日誌,確保按照nano級別進行排序和處理可以提供更高的時序一致性和準確性。
- 遊戲競技:在多人在線遊戲或競技平臺中,確保事件的順序和時間的準確性對於遊戲結果和公平性非常重要。如果遊戲事件的順序混亂或時間戳錯誤,可能導致遊戲結果的不準確或不公平。在處理遊戲日誌時,nano級別的排序和處理可以提供更精確的時序保證。
SLS支持全局有序和高精度時間戳
當前SLS已經支持高精度時間戳功能,並且直接按照納秒級別進行全局排序。完美地滿足了上述常見業務的全局排序需求。
相比老的非高精度時間戳的版本,會在以下PB結構新增了一個可選的Time_ns字段, 在開啓高精度時間戳功能的時候,用來存放日誌時間裏面的納秒部分。之所以新增這麼一個字段, 而沒有修改Time字段的類型主要是爲了兼容歷史數據。
SLS會基於Time和Time_ns組合出來的nano時間全局排序, 控制檯序查詢結果如下圖所示:
如何開啓全局有序和nano高精度時間戳
從有序業務場景章節我們瞭解了全局有序對業務的重要性, 用戶使用該功能, 需要從數據寫入和查詢兩方面入手, 其中數據寫入主要有兩類途徑,分別是logtail和sdk。
數據寫入
- logtail
logtail可以幫助您無侵入式從服務器或容器中採集文件和標準輸出日誌,自1.8.2版本起支持nano高精度時間戳,安裝和升級請參考幫助文檔:https://help.aliyun.com/zh/sls/user-guide/install-logtail-on-a-linux-server
- 安裝命令
./logtail.sh install {region}
- 升級命令
./logtail.sh upgrade
- 以上命令都可以使用-v參數指定版本,如
./logtail.sh upgrade -v 1.8.2
- logtail 開啓nano採集配置
詳情參考 https://sls.aliyun.com/doc/dataaccess/enableTimeNano.html
- sdk
當前支持了go、c++、java、python, 如其他版本sdk有需要支持,可以通過工單提需求。
下面是python sdk寫入帶有nano時間部分的日誌樣例,用戶可以根據具體業務需要,解析日誌中正確的nano時間部分傳入。後面查詢的時候使用的是秒和納秒部分兩者拼接出來作爲一個整體進行全局排序的。
def put_log_with_nano():
logitemList = []
for i in range(30):
contents = [
('DeviceIP', 11.22.33.55)
]
logItem = LogItem()
nano_time = time.time_ns()
sec_time = int(nano_time / 1000000000);
nano_time_part = nano_time % 1000000000;
logItem.set_time(sec_time)
logItem.set_time_nano_part(nano_time_part)
logItem.set_contents(contents)
logitemList.append(logItem)
request = PutLogsRequest(_project, _logstore, logitems=logitemList)
res = client.put_logs(request)
res.log_print()
數據查詢
數據查詢可以通過控制檯或者sdk的方式。 控制檯當前默認是nano級別排序,但是當前暴露的最小查詢時間範圍是1s, 如果要查詢比秒級更小範圍的查詢,需要使用sdk, sdk語言版本支持情況同數據寫入部分。
- 控制檯
SLS控制檯,會根據高精度的時間信息,自動進行顯示優化,顯示成毫秒、微秒、納秒的形式.
- 微秒形式
- 納秒形式
- sdk
以python 爲例, 撈取[1696743635 s, 1696743635 s +10 ns)區間內滿足myQuery查詢條件的最多100行log, 並以逆序輸出返回結果。
新增參數說明:
- accurate_query設置爲true默認走精確查詢, 在設置爲False情況下,只能保證分鐘級別有序
- from_time_nano_part和to_time_nano_part 會分別和fromTime、toTime組合成nano時間範圍去SLS查詢,SLS會過濾出在這段納秒時間範圍內的滿足查詢條件的log,並以納秒時間戳粒度有序輸出
def query_log_with_nano():
query = "LEVEL:ERROR"
req = GetLogsRequest(_project, _logstore, fromTime=1696743635, toTime=1696743635, query=query, line=100, reverse=True, accurate_query=True, from_time_nano_part=0, to_time_nano_part = 10)
res = client.get_logs(req)
res.log_print()
基本原理簡要介紹
日誌寫入SLS的時候可能會落在不同的shard裏面, 在查詢的時候根據查詢條件和查詢時間範圍,通過倒排索引和寫入過程中存放的高精度時間信息來將各個shard內部滿足條件的log過濾出來並返回給中間節點做進一步的全局排序處理,中間節點處理後再返回給用戶。.
- 寫入
- 查詢
總結
SLS全局有序和高精度時間戳功能的支持解決了特定業務對日誌順序有嚴格要求的痛點, 通過該功能的升級,SLS能夠更準確地對日誌進行排序,爲用戶提供更加精準、可靠的時間順序視圖。
注意事項
nano python sdk目前發佈在pypi官方源,國內某些鏡像源可能還拉取不到,如果pip install -U aliyun-log-python-sdk 沒有拉取到nano版本,可以用pip install -U aliyun-log-python-sdk==0.8.11獲取到SLS支持。
SLS案例中心:https://sls.aliyun.com/doc/
本文爲阿里雲原創內容,未經允許不得轉載。