SLS:海量日誌數據管理利器
日誌是大規模集羣管理系統中非常關鍵的部分,服務器上的各種日誌數據(如訪問日誌、應用日誌等)可以幫助我們回答各種問題,例如:
運維:服務是否正常,流量和QPS是多少;
開發:線上有沒有異常和錯誤發生;
運營:多少賬號開通了服務,其中開通失敗原因是什麼;
客服:系統登錄不上了,是客户的問題還是系統的問題;
安全:誰訪問了不該訪問的數據。
然而要想從日誌中獲取這些信息,通常需要開發大量腳本和工具,從頭到底搭建端對端系統,並且為了保證服務可靠性和穩定性,要做大量維護開發工作。阿里雲自主研發的針對日誌數據的即時、大規模集中式管理服務SLS(Simple Log Service,簡單日誌服務),能夠提供一個從日誌採集、過濾、處理、聚合到在線查詢的完整的海量日誌處理平台,滿足各種類型的日誌處理分析需求,減輕廣大開發者的負擔。
應用價值
SLS從2012年開始主要服務於阿里巴巴內部用户。後來隨着外部用户對日誌服務的需求越來越強烈,我們在2014年4月開始對外開放SLS的試用。為何用户對SLS有如此之高的需求,我們認為出於以下幾方面的原因。

要基於數據分析結果做運營。根據日誌數據,分析每個用户的行為軌跡(如何使用產品,在哪些使用場景下會遇到哪些問題等),對於改善產品設計思路和運營方向都很重要。
要定位細小問題。互聯網化使得任何小問題被放大的概率大大增加。例如,有萬分之五的失敗率不足為奇,但在大促銷等時間段內這個影響就會非常之大。日誌服務有助於在較短時間內精準定位到一些細小的問題。
要快速響應用户需求。在用户反饋訂單失敗,或遇到錯誤,客服藉助日誌服務能馬上找出問題,並儘快解決,這將極大提升用户滿意度,以及對產品和服務的認可程度。
要降低研發成本。雖然可以通過開發信息系統(例如客服系統、運營記錄系統)來滿足運營和運維需求,但開發系統本身的時間、成本、維護負擔等,都會影響企業的核心業務。而使用SLS,用户可以投入很少的研發成本,就能得到很好的日誌服務。
為了便於理解,我們來看看用户是如何使用SLS的。
小A創業開發了一個應用,有10台ECS,分別運行了App、Web服務器等。由於團隊人數有限,他需要身兼運維、開發、運營等多種崗位職責於一身。於是小A藉助於SLS來進行日誌管理服務。
小A首先創建SLS Project,以及對應的日誌類型(Category)和保存時間等選項(例如應用服務器、系統日誌30天輪轉,審計日誌90天輪轉)。
為了能收集應用日誌,小A在SLS控制枱上配置了描述日誌路徑及其格式(LogConfig),定義了每個應用的機器分組(Machine Group)。
設置完成後,SLS客户端和服務端開始提供服務(小A配置了access_log、 errorlog和oplog三種日誌見圖1,併為access_log打開了ODPS的離線歸檔功能,以便進行離線分析)。
當需要查詢日誌時,既可以用API/SDK等方式進行調用,也可以通過SLS提供的控制枱直接服務(例如在access_log中定位validate步驟執行見圖2)。

訪問日誌:通常在線系統的最前端都是Apache或者Nginx類的HTTP服務器,它的日誌記錄了不同用户在特定時間的訪問行為。以下是一條常見的服務器訪問日誌。
213.60.233.243 - - [25/May/2004:00:17:09 +1200] “GET /internet/index.html HTTP/1.1” 200 6792 “http://www.aliyun-inc.com" “Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.6) Gecko/20040413 Debian/1.6-5”
小A比較關心每天從www.aliyun.com過來的流量有多少。於是他在SLS中選中時間段,輸入ref:“http://www.aliyun-inc.com”,控制枱就能馬上篩選出對應的訪問日誌和次數。
分析請求處理是否正常:在經過前端服務器處理後,請求會交由具體的後端服務進行處理。以下是Java應用服務的異常日誌。

日誌中包含了錯誤發生的頁面、傳遞的參數、錯誤發生的接口和具體錯誤堆棧等信息。小A通過查詢“Level:ERORR”及其他關鍵詞篩選每天的錯誤,並找到出錯的地方進行修復。但在查詢過程中難免會遇到因為日誌不嚴謹引起的誤傷情況,此時除了調整日誌輸出外,小A也可以通過在查詢中加上not來排除這些已知原因。
是否有安全隱患或漏洞:在正常提供服務的同時,小A也十分關心是否有漏洞或者安全隱患可能對存儲的數據或者其他敏感信息造成泄露。以下是用户登錄時的訪問日誌。

日誌中包含某個時間點用户從何處登錄特定賬號的記錄。小A可以通過寫一個監控程序調用SLS API獲悉是否有緊急的異常登錄行為。一般黑客入侵會刪除系統中的日誌,但SLS即時收集日誌的機制,能杜絕這種情況的發生。
服務器是否正常:在服務器運行期間,硬件或者系統可能出現各種各樣的故障,通過系統日誌(類似/var/log/messages)用户可以獲悉是否有異常發生。

以上日誌內容表明,mysqld進程由於內存使用超過內核限制而被kill。小A升級了ECS內存後,再次查詢“kill” 或“out of memory”,就可以發現問題已經解決了。

其實以上只是典型的在線服務系統的一部分日誌,還有數據庫、網絡服務、文件系統等的日誌能夠幫助管理人員在出現問題時及時處理。6個月之後,小A的應用非常受歡迎,不僅數據量和機器數目隨之增加,SLS服務能力也隨之動態擴展。
除了以上例子外,我們還可以基於SLS的API進行二次開發,支撐運維、運營和客服等系統。讓我們來看一下在阿里內部使用SLS的幾個典型場景。
應用監控:得益於強大的日誌收集和查詢能力,飛天監控系統神農底層也是基於SLS開發的,現已成為各個集羣標配(圖3)。
性能診斷分析:使用SLS日誌收集和查詢功能可以存儲所有模塊的請求日誌,當發現服務問題時,只需輸入RequestId進行查詢,就能分析該請求的生命週期。例如系統記錄到有一個請求超過10秒,需要快速找到最消耗的時間佔據在哪台機器上、在哪個模塊裏、是哪個參數引起。以往需要各個應用進行調查,而現在輸入RequestId,就能把問題找到(見圖4)。
客服系統:基於SLS可以快速開發客服系統。CNZZ、RDS等控制枱已經通過該方法向終端用户提供日誌,讓用户自主做查詢和分析(見圖5)。
SLS之所以具有如此全面的日誌分析能力,和它與生俱來的基因分不開,即為解決阿里雲的實踐難題而生。下面就從SLS的“身世”開始,解析其背後的技術架構和核心優勢。
創建初衷與研發過程
飛天系統研發初期,為了讓系統順利地運行起來,我們經常要面對“調試基本靠摸,運維基本靠人肉,解決Bug基本靠猜”的困境。為了解決這些問題,最直接的方法就是基於日誌開發工具,以降低人力成本。剛開始兩年中,我們開發了以下幾種工具。
監控工具(神農):針對狀態數據的採集和監控系統。
性能工具(Tracer):跨進程/機器跟蹤請求在多台機器和進程中的執行情況和狀態。
離線分析:將日誌導入ODPS進行離線統計和分析。
雖然這些工具幫我們解決了很多問題,但每次面臨新的業務場景時都需要重新搭建一套服務,重新部署一個腳本、寫工具。這些工具背後用户真正的痛是什麼?
我們發現,開發人員和運維人員的大部分時間和精力都耗費在定位和分析上。然而為什麼開發環境(特別是分佈式環境)調試會變得這麼複雜呢?總體來講,大致有以下幾方面困難。
動態調度:由於計算和數據解耦,計算會被調度到不同的機器上,例如在系統中往往會有多個前端機處理各種請求,這使我們不得不查找所有機器定位特定問題。
跨模塊依賴:在線系統的讀取或寫入,會從HTTP服務器開始,到在線系統的服務器,最後到文件系統的服務器,整個生命週期會與多個系統打交道。
分佈式:數據分佈在十幾台機器上,查詢一次失敗的作業往往需要登錄十幾台機器。
規模與數據量:由於系統每秒鐘會處理大量請求和數據,所以Log產生速度非常快。最痛苦的是問題快找到了,日誌卻被沖垮了,且系統盤SSD小型化使得這個問題更突出。
從以上幾點看,異構系統、機器位置和數據量等都會使傳統調試變得複雜,但問題的複雜性可以分解為以下幾部分:
相關係統數
機器位置數
數據量
本身複雜性
要降低問題複雜度,理想的情況是將分佈式和異構系統的調試降維成單機問題。那麼是否可以給用户提供一種模式,讓他像用單機一樣來調試和診斷複雜系統呢?
於是我們開始研發SLS,解決思路是將日誌集中起來,並提供一套簡單而靈活的日誌接口滿足各類日誌數據需求,優勢在於:構建在飛天系統之上,天生就有擴展性;靈活易用,像瑞士軍刀一樣適配各類日誌需求。因此開發人員和運維人員只需將注意力放在具體的業務邏輯上,所有異構系統、機器等細節問題都由SLS服務解決,將所有機器上日誌當成在一台機器上使用。
例如:有一個業務場景橫向分佈在3台機器(Machine1、Machine2和Machine3)上,縱向每台機器分別有三套服務運行(Scheduler、Executor和JobWorker)(圖6)。
在SLS設計中,由於所有日誌都已中心化存儲,用户不需要再擔心日誌輪轉、硬盤損壞等問題,也無需登錄多台機器寫任何腳本和處理程序。只需要輸入指定查詢條件(InstanceID:“2003…” and Project:“apsara_profiling”),SLS服務端會在秒級掃描指定時間段的所有日誌數據,並且根據語義(and)對結果進行join,把符合條件的日誌反饋給用户。此外,用户還能輸入任意模塊的任意條件進行查找,例如查找錯誤的GET請求,統計一個數據的訪問行為等。

從圖7中可以清楚地看出SLS的架構思路。SLS服務端基於飛天服務模式開發,由伏羲(Fuxi)進行調度,存儲基於盤古(Pangu)和OTS(開放結構化數據服務),在服務前端使用Nginx服務器進行Restful API託管。
除服務端API外,SLS提供了SDK和客户端(Logtail)。Logtail對於SLS API進行了封裝,將日誌數據監控、抓取、過濾和可靠性傳輸等問題進行了處理,減少了用户收集日誌的門檻。
考慮到伴隨日誌即時需求的同時,大部分用户會將日誌用以離線分析,因此SLS服務端還提供了一種ODPS數據同步機制,能夠將SLS中的數據定時歸檔到ODPS表中。因此對於日誌而言,在線查詢和離線分析的需求都能夠簡單地配置使用。
為了服務用户這些需求,SLS有哪些挑戰呢?舉兩個例子。
用户環境千差萬別、日誌多樣化,如何保證日誌收集穩定可靠?
例如,日誌格式有幾百種,如何來適配?如何從文件夾中篩選到特定模式的日誌文件?日誌什麼時候開始寫數據?日誌輪轉怎麼處理?當網絡發生閃斷時,如何保證數據不丟?在用户寫錯程序輸出大量日誌後,如何保護Logtail不消耗過度的性能等?如何快速配置5000台機器的日誌收集?
在過去兩年中,我們花了大量時間從細節中學習,深入用户場景抽象日誌變化的本質原因。在阿里內部SLS的客户端Logtail迭代了不下十幾個版本,從場景覆蓋和對於錯誤處理能力中積累了大量的經驗,不斷把使用體驗做好,把錯誤處理做細。
以文件輪轉為例,輪轉過程中會出現邊界丟少量日誌的情況,同時操作系統的不同行為、日誌輪轉方法(按大小或時間)、輪轉參數(時間命名、順序編號、壓縮等)等都會將這個問題複雜化。為此我們在操作系統文件層面之上抽象了輪轉動作,定義了一套系統原語,能夠追溯輪轉的上下游關係和生命週期,能保證任何輪轉方式都能靈活應對。
對於服務端,如何能夠對一天幾億的日誌進行即時存儲和查詢?
日誌的數據量和規模通常是非常龐大的。對於一個100MB的日誌文件,如果按每條100字節計算有一百萬條。當這些日誌被寫入時,如何保證將日誌產生到可以查詢的時間控制在1分鐘之內?當用户查詢數據時,如何能在儘可能短的時間(例如2秒內)根據篩選條件在幾千萬數據中找到符合的日誌?如何平衡性能和存儲的成本?
針對這些問題,我們最主要的解決方法是採用分佈式、批處理以及多級索引技術。由於日誌大部分情況下是連續流格式,所以我們對相鄰日誌進行切塊,每塊數據內部通過bitmap和linkedlist進行索引存儲,而塊則通過倒排索引的方式建立。這樣既能節省日誌數據龐大的索引空間,又能在不影響索引速度的情況下保證查詢質量。
核心優勢
對日誌研究是從20世紀80年代開始的,在各個領域內積累了豐富的經驗,在安全、監控、運營分析等領域,也有不少關於日誌的垂直化應用。
使用Splunk等日誌服務。Splunk為日誌解決方案提供較完整的解決方案,然而高昂的使用費及有限的免費數據量,加上傳統軟件部署方式使得其使用成本較高。而SLS在規模、性能和服務能力很不錯,只是由於開發時間還不長,在查詢豐富語義上還有較大提升空間,我們會不斷完善SLS查詢能力。
通過MySQL+Web Application搭建解決方案。MySQL在千萬級以下作為存儲非常理想,但超過該規模後,性能和穩定性等指標會直接下降。
開源陣營(Elastic Search+LogStash+Kibana)。利用第三方開源軟件來搭建一套日誌系統,維護和建設成本通常較高,並且ES依賴Lucene主要處理中長文檔,面對日誌這樣的短文檔,索引存儲成本會比較高。而使用SLS可以減少開發時間及維護代價,簡單地點幾下配置,就能獲得全面服務,並且具備彈性擴展能力。
此外,SLS在技術上還有以下亮點。
客户端
功能:支持正則表達式支持所有日誌。
高性能:每秒十MB級別吞吐量(單Core)。
可靠性:處理網絡中斷,文件輪轉,文件刪除,新建日誌等。
管理性:Web管理,自動推送,可部署上萬台機器。
服務端
吞吐量:幾十TB/天。
整體延時:日誌產生後30秒可查詢,最快5秒。
查詢速度:1秒內過億級別日誌。
查詢能力:and or not邏輯組合,支持鍵值以及全文兩種查詢模式。
可靠性:無單點,不丟失數據。
總結與展望
從2012年開始,SLS以一套標準化的接口進行支撐,逐步完善服務環節的各個功能,例如客户端管理、權限控制、增強服務的規模化管理能力。到目前為止,SLS每天接受千萬級查詢請求,處理百TB日誌數據,可以為運維、開發、運營和安全等多個部門提供服務。例如在阿里雲官網所有云產品的日誌數據(ECS、RDS、OTS等)已經全部通過SLS進行管理。
未來,我們會在使用體驗和查詢能力上不斷進行優化,包括提供全套API讓用户來自動化運維自己的集羣,用户可以定義自己的日誌模板、機器分組等信息,自動化管理所有產品的日誌;提供更多的表達條件滿足日誌查詢的需求。