Scheduled SQL:SLS 大規(guī)模日志上的全局分析與調(diào)度
大規(guī)模日志全局分析的需求
數(shù)據(jù)大規(guī)模與時效性
基于時間的數(shù)據(jù)(日志、指標)在日積月累后的數(shù)量是驚人的。以 SLB 七層訪問日志為例,每一個HTTP/HTTPS 訪問請求會記錄一條 access log,假設每天產(chǎn)生1000萬條數(shù)據(jù),則一年為36億條數(shù)據(jù)。一方面,長時間的數(shù)據(jù)存儲需要巨大的存儲空間,而通過減少存儲周期的方式降低存儲空間,雖然控制了存儲成本,但也丟失了有價值的歷史數(shù)據(jù)。另一方面,大量的數(shù)據(jù)將造成分析上的性能壓力。
大部分時序數(shù)據(jù)具有時效性特征。歷史數(shù)據(jù)可以接受分鐘或小時級別的精度,而新產(chǎn)生的數(shù)據(jù)需要更高的精度(例如監(jiān)控、線上問題調(diào)查)。數(shù)據(jù)運營、分析師需要存儲全量的數(shù)據(jù)以備分析,歷史數(shù)據(jù)直接 TTL 刪除是可能最差的選擇。
例如 Elasticsearch rollup、時序數(shù)據(jù)庫的降精度用于解決這部分問題。
一份數(shù)據(jù)在多種場景使用
對于同一份日志,可能被多種用戶角色在多種場景下使用到:
實時的數(shù)據(jù),需要支持關鍵詞告警、時序數(shù)據(jù) ML 巡檢、日志上下文查詢。
亞秒級延遲粒度上,有全文關鍵詞的查詢、交互式 SQL 統(tǒng)計分析的需求。
以天為單位,需要對日志做運營分析,計算轉(zhuǎn)化率、設計運營策略。
一周前的產(chǎn)生的數(shù)據(jù),大部分時候不再會被觸碰到,在支持偶爾的歷史指標查看以外,審計場景下對全量日志的存儲也是必須項。
一份數(shù)據(jù),多處使用,既要滿足業(yè)務需求,成本也是需要關心的。
自定義業(yè)務分析
云上日志設施面對的客戶群呈現(xiàn)多樣化,自定義的業(yè)務需求舉例如下:
電商:計算七日留存率,業(yè)務訪問 SQL 審計日志對用戶信息脫敏,等等。
在線教育:多平臺終端(android、ios、PC)埋點數(shù)據(jù)的規(guī)整,直播課堂生命周期內(nèi)的異常診斷,等等。
游戲:按游戲的數(shù)據(jù)分發(fā)存儲,全文搜索支持工單調(diào)查,等等。
阿里云 SLS 是云原生觀測分析平臺,為Log/Metric/Trace等數(shù)據(jù)提供大規(guī)模、低成本、實時平臺化服務,一站式提供數(shù)據(jù)采集、加工、分析、告警可視化與投遞功能。我們將以業(yè)務為目標的數(shù)據(jù)處理歸納為兩類需求:
ETL:將非結構化的日志做預處理,為日志信息添加業(yè)務字段,數(shù)據(jù)脫敏與分發(fā)等。
分析:全局數(shù)據(jù)大表上的查詢和 SQL 分析,支持布爾搜索、window、aggregate 操作等。
SLS 上的典型分析方案
對于 ETL、分析這兩類計算任務,除了交互式分析以外,還需要常駐作業(yè)模式來處理結果落盤。
根據(jù)不同的業(yè)務需求,這里總結了幾種常見的 SLS 數(shù)據(jù)分析方案。
數(shù)倉 "T+1"
對于結果實時性不敏感的業(yè)務,有較多采用數(shù)倉方案:
數(shù)據(jù)通過 SLS 實時入庫,集中化存儲。
全托管數(shù)據(jù)投遞到 MaxCompute。
業(yè)務規(guī)劃小時級或天級的計算任務,生成下游表,產(chǎn)出業(yè)務報表等結果。
流計算
以 Flink、Spark Streaming(continuous mode)、Kafka Streams 為代表的實時計算系統(tǒng),在數(shù)據(jù)處理語義(exactly-once)、計算結果修正上的能力強大。該方案會用到 SLS 百 ms 秒級端到端延遲的 pub/sub 能力:
數(shù)據(jù)實時推送到 SLS 日志庫。
啟動流計算任務,從多個 shard 實時消費數(shù)據(jù)。
流計算任務根據(jù)算子組合情況(stateless、statefull、groupby 等)切分多個拓撲執(zhí)行,可能涉及到數(shù)據(jù) shuffle、watermark、state store 等機制。
這個方案在算子豐富度、實時能力、性能上綜合表現(xiàn)全面,是一把牛刀,例如在電商實時大屏場景上是非常好的選擇。
如果抱著挑刺的眼光來看:
計算引擎層面做得均衡,但缺乏存儲層的優(yōu)化。例如:一個 logstore 上運行 10 個流計算作業(yè),無論實際需要納入計算范圍的數(shù)據(jù)有多少,最終需要 10 遍全部數(shù)據(jù)流量的訂閱,從業(yè)務角度上看存在網(wǎng)絡、計算資源上的浪費。
對于日志用戶來說,在參數(shù)配置、性能調(diào)優(yōu)、問題 Debug 有復雜性(復雜常常是通用、強大的另一面)。在復雜場景下,DevOps-er 理解業(yè)務需求后,需要設置好高級參數(shù)、選擇好 state store 等。
計算集群部署方式,尤其對于自建集群、數(shù)據(jù)稀疏的應用,其成本上有影響,例如 JobManager/TaskManager 等角色資源需要攤銷。
自建程序做流式消費
還是圍繞 SLS 的 pub/sub 能力,以 SLS SDK 方式調(diào)用 PullData API,例如:
通過 Logstash/Flume 等開源軟件,加載 SLS source connector。
通過函數(shù)計算(SLS 提供 FC 觸發(fā)器),好處是 Serverless 的 runtime,極致彈性計費。
通過 SLS 的 consumer group library 處理數(shù)據(jù),自動負載均衡、failover。
以上對于行處理場景是適用的,適用面上則需要關注:
該方案在絕大部分情況下都不涉及全局計算(窗口、聚集),即使能實現(xiàn)也很復雜。
自建程序、開源軟件需要運維人力以及固定機器投入的成本。
自建程序做查詢、分析
在 SLS 的流式存儲之上,開啟了索引分析功能,帶來了全文索引、列式下推、SQL 計算能力加持。
該方案調(diào)用 SLS GetLogs API,部署一個常駐程序,設置定時觸發(fā)器,周期調(diào)度任務執(zhí)行:
調(diào)用 API 讀取 SLS 索引并計算數(shù)據(jù)。
讀取計算結果寫出到目標做存儲。
用戶除了需要運維程序,還需要考慮以下需求:
SQL 運行可能因計算量巨大而超時,失敗時需調(diào)度層的重試支持。
執(zhí)行延遲時告警支持。
調(diào)度元信息(schedule_time 等)持久化。
web console 管理的需求。
如何將 SQL 計算結果 exactly-once 入庫。
本文后續(xù)重點介紹的 Scheduled SQL,從本質(zhì)上來講,是對該方案的服務化,對以上問題有更全面的考慮。
SLS 告警
對,你沒看錯。有少數(shù)用戶用 SLS 告警曲線救國,圖的是一個全托管、免運維。
SLS 告警功能支持設置定時策略,執(zhí)行多個 SQL 獲取結果,并將結果編排后發(fā)送到內(nèi)置 logstore(internal-alert-history)或自定義的網(wǎng)關/webhook。
需要說明的是,告警的主要設計場景是面向小的計算結果,按觸發(fā)策略、值班表,將事件傳達給接收者。對于嚴苛的業(yè)務,不推薦這種做法(可以關注 Scheduled SQL 功能做遷移):
告警的結果寫出可能出現(xiàn)寫出數(shù)據(jù)大小截斷(1 MB 內(nèi))、 exactly-once 等問題。
告警 1.0 是串行調(diào)度,某一次計算發(fā)生延遲后,多次執(zhí)行實例的 SQL 時間窗口會出現(xiàn)空洞。
SLS 原生數(shù)據(jù)處理方案
用一張圖描述 SLS 原生數(shù)據(jù)處理功能如下,接下來分別按存儲模型展開介紹:
stream 模型
例如通過 Flink、自建消費組程序進行 SLS 數(shù)據(jù)分析,都基于 stream 模型。這是 SLS 最基礎的存儲形式(也稱 LogHub),可以理解為 append-only 的 log 結構,通過 多個 shard 組合實現(xiàn) IO 和存儲的水平擴展。
LogHub 與開源軟件 Kafka 是類似的功能形態(tài),SLS 底層是共享分布式存儲(盤古),這避免了 Kafka 在機器磁盤空間 re-balance、機器替換、存儲規(guī)模的一些缺陷。
stream 存儲模型在機器數(shù)據(jù)場景下有多重優(yōu)勢:
寫入模型簡單,不需要 commit 機制,天生支持流式寫入,客戶端(移動端設備、Agent)友好。
append-only 保證了寫入吞吐的設計上限,滿足業(yè)務高并發(fā)、高吞吐需求。
FIFO 的 changelog 模式,滿足大多數(shù)日志、指標類數(shù)據(jù)的生成與使用場景。
針對流式數(shù)據(jù) ETL 場景,SLS 支持數(shù)據(jù)加工功能,可以實現(xiàn)按量付費、全托管的行處理需求,本文不多介紹,可以參考SLS 數(shù)據(jù)加工的設計與實踐。
table 模型
當 stream 數(shù)據(jù)寫入后,對于 shard 內(nèi)的數(shù)據(jù),可以同時構建一份包括倒排、列存、bitmap 等信息的索引數(shù)據(jù)。shard 內(nèi) stream 數(shù)據(jù)相當于是正文,索引到今天有兩種形式:
Logstore (with index):適用于日志模型,形式上是表結構,一條數(shù)據(jù)由多組 key-value pair 組成。
Metricstore:對于指標類型數(shù)據(jù)有針對性優(yōu)化,有序排列存儲支持快速指標計算,高壓縮率低存儲成本。
例如 Logstore,在計算時稱為 append-only Table 模型。在 SLS 場景下有以下優(yōu)勢:
計算效率高,時間(一級索引)過濾、計算下推都可以直接利用 index 進行,節(jié)省網(wǎng)絡、計算的性能開銷與計算成本。當然,index 會有構建費用,SLS 的一份 index 數(shù)據(jù)可以服務于多個業(yè)務場景(告警、儀表盤、全文搜索、監(jiān)控)來攤銷成本。
OLAP 解決確定性問題,按照條件過濾取到數(shù)據(jù)后,直接進行計算即可,不需要考慮流計算中 watermark、trigger 與 window 配合、state store 數(shù)據(jù)膨脹(特定場景)等復雜問題。
Scheduled SQL 讓 SQL 可調(diào)度
SLS 的每一次 SQL 計算針對預定的一片數(shù)據(jù)做處理,因此,對全部時間區(qū)間(從現(xiàn)在開始一直到未來)數(shù)據(jù)的 SQL 分析依賴于上層調(diào)度,也就是將要介紹的新功能 Scheduled SQL,它支持標準SQL、SLS 查詢和分析語句,按照調(diào)度規(guī)則周期性執(zhí)行,并將運行結果寫入到目標庫中??捎糜谝韵聢鼍埃?/p>
定時分析數(shù)據(jù):根據(jù)業(yè)務需求設置分析語句,定時執(zhí)行,并將分析結果存儲到目標庫中。
全局聚合:對全量、細粒度的數(shù)據(jù)進行聚合存儲,匯總為存儲大小、精度適合的數(shù)據(jù),相當于一定程度的有損壓縮數(shù)據(jù)。例如按照秒級別對 36 億條數(shù)據(jù)進行聚合存儲,存儲結果為 3150 萬條數(shù)據(jù),存儲大小為全量數(shù)據(jù)的0.875%。
投影與過濾:對原始數(shù)據(jù)的字段進行篩選,按照一定條件過濾數(shù)據(jù)并存儲到目標Logstore中。該功能還可以通過數(shù)據(jù)加工實現(xiàn),數(shù)據(jù)加工的DSL語法比SQL語法具備更強的ETL表達能力,更多信息請參見加工原理。
Scheduled SQL 相比于自建程序調(diào)用 SLS API 而言,有以下優(yōu)勢:
SQL 運行 timeout 提升至 600 秒,單次最大處理百億級數(shù)據(jù)。
計算資源池可選:免費(project 級 15 并發(fā))、付費(彈性擴展,參考SQL 獨享實例)。
最小 1 分鐘周期執(zhí)行,支持常駐或固定時間區(qū)間內(nèi)調(diào)度運行。
支持靈活的查詢時間窗口參數(shù)配置,滿足多樣化需求。
exactly-once 寫入目標庫。
完善的作業(yè)實例查看、重試支持(控制臺、API)。
全托管運行,自動處理多種異常,調(diào)度不收費。
實例執(zhí)行失敗集成 SLS 告警通知。
Scheduled SQL 功能介紹
工作機制
Scheduled SQL 涉及以下幾個重要概念:
作業(yè):一個 Scheduled SQL 任務對應一個作業(yè),包括調(diào)度策略、計算規(guī)則等信息。
實例:一個 Scheduled SQL 作業(yè)按照調(diào)度配置按時生成執(zhí)行實例。每一個實例對原始數(shù)據(jù)進行 SQL 計算并將計算結果寫入目標庫。實例ID 是其唯一標識。
創(chuàng)建時間:實例的創(chuàng)建時間。一般是按照您配置的調(diào)度規(guī)則生成,在補運行或追趕延遲時會立即生成實例。
調(diào)度時間:由調(diào)度規(guī)則生成,不會受到上一個實例執(zhí)行超時、延遲、補運行等情況的影響。大部分場景下,連續(xù)生成的實例的調(diào)度時間是連續(xù)的,可處理完整的數(shù)據(jù)集。
流計算里有大量篇幅用于處理數(shù)據(jù)計算的一致性、完整性問題,Scheduled SQL 則是一種以 small-batch 模擬常駐計算的方案,針對這兩個問題的設計是:
1.計算一致性
SQL 每次執(zhí)行會對應到確定的時間窗口,由此得到確定數(shù)據(jù)集再調(diào)度 SQL 計算。Scheduled SQL 實例運行時,SQL 查詢的時間窗口是基于調(diào)度時間渲染得到,左閉右開格式,與實例的創(chuàng)建時間、執(zhí)行時間無關。例如調(diào)度時間為2021/01/01 10:00:00,SQL時間窗口的表達式為[@m - 10m, @m),則實際的SQL時間窗口為[2021/01/01 09:50:00, 2021/01/01 10:00:00)。
SQL 計算的結果在插入目標時,需要考慮數(shù)據(jù)重復可能帶來的業(yè)務影響。對于 append 模式寫,例如 Scheduled SQL 結果寫 Logstore,寫入客戶端與 SLS 服務端實現(xiàn)了 exactly-once 協(xié)議。對于 overwrite 模式寫,更容易做到原子性,未來會規(guī)劃 Scheduled SQL 寫數(shù)據(jù)庫的支持。
2.數(shù)據(jù)的完整性
作業(yè)上設置延遲執(zhí)行參數(shù)從業(yè)務上給與指導,在實例的調(diào)度時間點上,往后延遲 N 秒才真正開始觸發(fā)實例運行,而實例查詢的時間范圍不受延遲參數(shù)影響。例如設置調(diào)度間隔為每小時、延遲執(zhí)行為30秒,那么一天生成24個實例,其中某實例的調(diào)度時間為2021/4/6 12:00:00,執(zhí)行時間為2021/4/6 12:00:30。這個設計在大部分場景下可以解決數(shù)據(jù)遲到問題,但對于寫 logstore 存儲(數(shù)據(jù)寫入后將無法更新)來說,完全避免延遲問題是難以實現(xiàn)的。極端情況下,數(shù)據(jù)遲到問題可通過事后的實例重試來補結果。
將 SQL 查詢的時間窗口按分鐘對齊(例如整分鐘),以保證在 SLS 索引模型優(yōu)化(batch log-group 組成倒排 doc)時依然能保證絕對的計算準確。
調(diào)度場景
Scheduled SQL 作業(yè)依次調(diào)度多個實例執(zhí)行,無論是正常被調(diào)度還是被動異常實例重試的情況,同時只有一個實例處于運行中,不存在多個實例并發(fā)執(zhí)行的情況。
在 SLS 數(shù)據(jù)場景下,主要的幾種調(diào)度場景如下:
場景一:實例延遲執(zhí)行
無論實例是否延遲執(zhí)行,實例的調(diào)度時間都是根據(jù)調(diào)度規(guī)則預先生成的。雖然前面的實例發(fā)生延遲時,可能導致后面的實例也延遲執(zhí)行,但通過追趕執(zhí)行進度,可逐漸減少延遲,直到恢復準時運行。
場景二:從某個歷史時間點開始執(zhí)行Scheduled SQL作業(yè)
在當前時間點創(chuàng)建Scheduled SQL作業(yè)后,按照調(diào)度規(guī)則對歷史數(shù)據(jù)進行處理,從調(diào)度的開始時間創(chuàng)建補運行的實例,補運行的實例依次執(zhí)行直到追上數(shù)據(jù)處理進度后,再按照預定計劃執(zhí)行新實例。
場景三:固定時間內(nèi)執(zhí)行Scheduled SQL作業(yè)
如果需要對指定時間段的日志做調(diào)度,則可設置調(diào)度的時間范圍。如果設置了調(diào)度的結束時間,則最后一個實例(調(diào)度時間小于調(diào)度結束時間)執(zhí)行完成后,不再產(chǎn)生新的實例。
場景四:修改調(diào)度配置對生成實例的影響
修改調(diào)度配置后,下一個實例按照新配置生成。一般建議同步修改SQL時間窗口、調(diào)度頻率等配置,使得實例之間的SQL時間范圍可以連續(xù)。
場景五:重試失敗的實例
正常情況下,一個Scheduled SQL作業(yè)按照調(diào)度時間的遞增順序生成執(zhí)行實例。如果實例執(zhí)行失?。ɡ鐧嘞薏蛔?、源庫不存在、目標庫不存在、SQL語法不合法),系統(tǒng)支持自動重試,當重試次數(shù)超過您配置的最大重試次數(shù)或重試時間超過您配置的最大運行時間時,重試結束,該實例狀態(tài)被置為失敗,然后系統(tǒng)繼續(xù)執(zhí)行下一個實例。
您可以對失敗的實例設置告警通知并進行手動重試。您可以對最近7天內(nèi)創(chuàng)建的實例進行查看、重試操作。調(diào)度執(zhí)行完成后,系統(tǒng)會根據(jù)實際執(zhí)行情況變更實例狀態(tài)為成功或失敗。
Scheduled SQL 在訪問日志上的應用
場景需求
在阿里云上,SLB/OSS 的被用到很多的基礎計算、存儲服務。在使用過程中如果要得到細粒度可觀察性,都繞不過訪問日志,在深度使用后您可能會有體感:
訪問日志與 request 數(shù)一比一關系,數(shù)據(jù)量很大,造成存儲成本增加并拖慢計算。
訪問日志有時效性,近 15 天日志需要交互式查詢分析支持,歷史數(shù)據(jù)需要具備降精度的指標查詢能力。
訪問日志有留存的需求,需要長期存儲以備審計。
整體方案
以 SLB 七層訪問日志為例,這里介紹一種實踐:
基于 Scheduled SQL 功能,將歷史原文數(shù)據(jù)壓縮為低精度數(shù)據(jù),支持長期的索引存儲并大大提升分析效率。
根據(jù)業(yè)務需要,原文數(shù)據(jù)支持全局搜索和無損的 SQL 分析,可以設置存儲周期為 15天。
歷史數(shù)據(jù)原文投遞到 OSS,支持極低成本存儲,低頻的審計撈數(shù)據(jù)操作也是方便的。
整體方案圖如下:
OSS投遞操作步驟參考將日志服務數(shù)據(jù)投遞到OSS。
Scheduled SQL 配置使用增強型資源池,默認 STS 角色授權,最終計算結果寫同區(qū)域 Logstore:
使用Scheduled SQL時,建議根據(jù)業(yè)務情況,同時兼顧數(shù)據(jù)實時性和準確性。
考慮數(shù)據(jù)上傳日志服務存在延遲情況,您可以結合數(shù)據(jù)采集延遲以及業(yè)務能夠容忍的最大結果可見延遲,設置執(zhí)行延遲和SQL時間窗口(結束時間往前一點),避免實例執(zhí)行時SQL時間窗口內(nèi)的數(shù)據(jù)未全部到達。
建議SQL時間窗口按分鐘對齊(例如整分鐘、整小時),以保證上傳局部亂序數(shù)據(jù)時的數(shù)據(jù)準確度。
在這里每分鐘調(diào)度一次 SQL 計算最近一分鐘窗口的數(shù)據(jù),并設置延遲執(zhí)行(如果對于實時性要求不高,建議這個值設置大一些):
Scheduled SQL 寫出到目標 Logstore 數(shù)據(jù)的結果如下圖,其中 tag 字段是系統(tǒng)默認添加的信息,用于數(shù)據(jù)的搠源。
Scheduled SQL 調(diào)度生成的實例信息在任務管理頁面可以查看,對于失敗的任務可以做重試。
方案效果
功能體驗上:
熱、溫數(shù)據(jù)存儲、分析,支持交互式查詢、分析的能力,保留了靈活性。
冷數(shù)據(jù)分析,支持分鐘粒度的自定義指標查詢(例如本文是 host、method、status 維度統(tǒng)計),可以快速實現(xiàn)問題分析,同樣查詢范圍延遲降低兩個數(shù)量級。
冷數(shù)據(jù)存儲,以壓縮格式投遞到 OSS 存儲,保留了審計能力。
存儲成本上:在永久存儲的背景下,存儲量降低到之前的 1/1000,OSS 上的壓縮格式存儲且做到極低的單價。