本文整理自李虓在QCon上海2016的演講,,原題為:《LinkedIn 基于 Kafka 和 ElasticSearch 的實時日志分析系統(tǒng)》?;貜?fù)關(guān)鍵詞「領(lǐng)英」,,下載完整版PPT。 今天,,和跟大家分享我們在用ElasticSearch和Kafka做日志分析的時候遇到的問題,,系統(tǒng)怎么樣一步一步演變成現(xiàn)在這個版本。你如果想拿ElasticSearch和Kafka來做日志分析的話,會有一些啟發(fā),。全文主要包括以下幾個Topic:
首先,什么是日志,?簡單的說日志就是一個結(jié)構(gòu)化的數(shù)據(jù)+時間戳,。計算機開始日志就已經(jīng)存在,從那時候就有各種各樣的工具來幫我們分析,、解析或者查找日志,。 一開始做這個東西的時候,很多團隊覺得不是很需要,,工程師登錄到服務(wù)器上面做一些cat或者grep和簡單的表達式處理就夠了,,可以找到需要的信息。如果不夠的話,,比如在很多臺機器上的話,,有mssh、cssh等工具,。 還不夠的話,,可以自己寫工具,有一次我發(fā)現(xiàn)在我們的生產(chǎn)服務(wù)器上面,,有一個SRE寫了一套系統(tǒng),,從自己的臺式機,做了一個ssh tunnel到實際的生產(chǎn)系統(tǒng)里面做了遠程代碼調(diào)用,,遠程把那些文件拿回來,,這是一個一級的安全生產(chǎn)事故,是非常不負(fù)責(zé)任的事情,,但是這也就暴露了我們確實有這個需求,。 當(dāng)我們有五萬臺服務(wù)器,五百多個微服務(wù)的時候,,你不可能指望每個人都非常熟練的去解決這樣的事情,。開發(fā)或者運維經(jīng)常會遇到這樣的需求,比如拿某兩個時間點之間的所有的日志,,只需要看WARN或者ERROR或者FATAL的消息,,并且有十幾個錯誤是已知的,要忽略,。 這個服務(wù)是跑在好幾個數(shù)據(jù)中心幾百臺服務(wù)器上面,,還需要關(guān)心有沒有新的錯誤,,這個錯誤是不是由于某個特定的用戶造成的,或者某些特定的用戶行為造成的,,比如說他post了什么,,或者request的長度超過一個固定長度;這個服務(wù)器上的錯誤信息有沒有和其他服務(wù)器上的錯誤信息相關(guān)聯(lián),。給我30分鐘我有可能寫出來一個四五行的grep命令去幾百臺服務(wù)器上把日志拉下來,,但如果在凌晨三點鐘,這就是一個不太可能的任務(wù),。 日志分析系統(tǒng)需要滿足以下基本的要求:
還有一些其他擴展性的需求,,包括日志采樣,,提高安全性、保護日志里面包含的信息,,也是后面著重談的一個問題,。 回到四年前,從LinkedIn成立到2012年我們有一個系統(tǒng)叫Splunk,,非常好用,,只有一個問題,,太貴了。2012年的時候,,我們當(dāng)時生產(chǎn)環(huán)境有三,、四千臺的服務(wù)器,續(xù)簽第二年的合約時他們的報價是2000萬美元一年,。這實在是不可以接受的,,并且那個時候是2012年,我們現(xiàn)在的服務(wù)器臺數(shù),、用戶請求數(shù)已經(jīng)翻了差不多十倍,,當(dāng)時的價格如果是2000萬,現(xiàn)在更多,,因為它是根據(jù)數(shù)據(jù)量來算license的,。 從2012年到2014年,因為我們當(dāng)時決定不用Splunk,,就進入了一個混沌期,,這段時間非常痛苦,大家都有需求,,但是沒有人有方法,,很多人開始搞自己的小動作,做些小工具,。我之前看了一下內(nèi)部工具庫,,里面有二、三十個用python或者shell寫的小工具,,這些小工具是用來找一個時間段內(nèi)的log或者特定用戶的log,,但是有很大的浪費,很多工具重復(fù)的寫,,也非常難維護,。 2014年到2015年這一年多的時間我們痛下決心,,一定要做一套能夠橫跨LinkedIn所有l(wèi)og的系統(tǒng),,并且推廣到整個LinkedIn。當(dāng)時選擇了ELK,,它的優(yōu)點就是:開源,,發(fā)布周期非??欤?dāng)然也有缺點,,它非常的新,,所以有很多小毛病。 相信大家很多人已經(jīng)知道ELK是什么——ElasticSearch,、Logstash,、Kibana,。ElasticSearch就是基于Lucene的儲存,索引,,搜索引擎,;Logstash是提供輸入輸出以及轉(zhuǎn)換處理插件的日志標(biāo)準(zhǔn)化管道;Kibana提供可視化和查詢ES的用戶界面,。 每個人花30分鐘就可以在自己的電腦或者生產(chǎn)環(huán)境上搭一個這樣的東西,,Log通過Logstash讀出來,放到ElasticSearch里,,然后Kibana去讀,。這步做完以后其實就能達到非常好的效果。LinkedIn所有的業(yè)務(wù)群都會要求有一個異常面板,,比如說支付系統(tǒng)業(yè)務(wù)群,,它大概有十個左右不同的小服務(wù)。 當(dāng)報警系統(tǒng)發(fā)現(xiàn)支付系統(tǒng)有了各種各樣的問題之后,,我們第一步就是到異常面板來看Log里面有沒有什么東西,,可以根據(jù)時間線上看,有沒有哪些新的服務(wù)在近期有了新的log或者error log數(shù)量不一樣,。并且它會根據(jù)不同的exception/java stack拿出來做count,,這也給分析帶來很大的幫助,還可以寫出很多復(fù)雜的query,。 第一個版本非常簡單,我們只把它應(yīng)用到了一兩個非常關(guān)鍵的系統(tǒng)上,。這套系統(tǒng)做完之后我們做了一個對比,,平均故障解決時間從以前的五十幾分鐘縮短到小于30分鐘。我們的線上系統(tǒng)一般最快會花5到10分鐘才有一個不是很關(guān)鍵的警報出來,,如果能很快發(fā)現(xiàn)問題在哪里,,解決這個問題,比如說一個簡單的rollback操作,,在幾百臺機器上也會花5到10分鐘的時間,,真正留給人根據(jù)log去判斷問題在哪里的時間也只有短短的5到10分鐘。 如果不是有一個異常面板能看到所有的信息,,比如有沒有哪個服務(wù)器的異常比其他服務(wù)器多,,有沒有一個異常是突然今天出了很多次的,或者有沒有一個服務(wù)器今天出了很多的異常,,最起碼要花二十到三十分鐘的時間手工的看log,。 第一個版本有幾個問題,第一是Logstash Agent的維護不是很理想,,Logstash是基于Ruby的,,啟動它就要有幾十兆內(nèi)存被jvm吃掉,,我們想避免在每個機器上都要起一個Logstash。并且在我們使用過程中Logstash非常不穩(wěn)定,,莫名其妙就死掉了,,還需要一個守護進程守護它。第二個是log標(biāo)準(zhǔn)化,,也是非常頭疼的問題,。 第一個Logstash Agent的問題通過引入Kafka解決,引入Kafka后不需要每個host上有agent,。LinkedIn內(nèi)部有專門的SRE團隊維護Kafka,,很便宜,不需要花錢去維護,。對于Log標(biāo)準(zhǔn)化,,我們花了非常多的時間看,LinkedIn有99%的服務(wù)都是java service,,有15種以上log,,最重要的是access log和application log。我們做的一件事情是通過java Container logger標(biāo)準(zhǔn)化直接寫入Kafka,。有的程序直接寫到kafka,,不上磁盤,有的程序還要同時寫到磁盤里面,,這是可配置的,。 這些是通過LinkedIn standard container一起rollout到所有的service上。開發(fā)人員什么都不用管,,只要在程序里寫logger.info/logger.error,,那些信息就會直接進到Kafka。對于程序日志,,默認(rèn)警告以上的級別進入Kafka,,可以在線通過jmx控制。對于訪問日志,,我們有10%采樣,,可以通過ATS入口動態(tài)控制。 這是第二個版本,,可以看到在生產(chǎn)環(huán)境的Java service那邊,,Host上已經(jīng)沒有Logstash,所有的log直接寫入Kafka,,Logstash從Kafka里消費這些日志,,寫到ElasticSearch里面去。 第二個版本還會出現(xiàn)一些問題,,比如說一個服務(wù)出現(xiàn)問題的時候會影響整個ELK cluster,。我們出現(xiàn)過這樣的情況,,一個團隊寫了一個新的服務(wù),把所有的log的級別都定義成error,,整個ElasticSearch就被它沖垮了,。很多時候還會出現(xiàn)網(wǎng)絡(luò)飽和的情況。 很簡單,,第二步非常簡單的決定就是把它進行拆分優(yōu)化:
根據(jù)業(yè)務(wù)需求拆分,,我們拆出來20幾個這樣的相同的集群,這個版本,,還有一些問題,。首先是跨業(yè)務(wù)分組集群的查詢,雖然很多的時候,,一個問題在一個業(yè)務(wù)分組里面就能找到,,但是還有很多的時候要跨到另外一個集群里面才能找到問題到底是從哪開始的,。 第二,千萬不要跨數(shù)據(jù)中心做ElasticSearch的集群,,非常非常差,,根本跑不起來。即使兩個數(shù)據(jù)中心非常近這樣做也不好,,尤其當(dāng)數(shù)據(jù)量上來之后,,會有一些非常詭異的問題。數(shù)據(jù)量非常大的ElasticSearch集群我們會要求它全部在一個機架上,,如果有一個服務(wù)器在另一個機架上都會出現(xiàn)timeout的問題,。 為了解決剛剛說的問題,我們引入Tribe,,用下來的感覺可以用,,但是這明顯不是一個他們支持的功能。Tribe理念很好,,但是它不支持分層,,我們需要兩種不同的Tribe,首先要能跨業(yè)務(wù)分組,,還要跨數(shù)據(jù)中心,。 最好的情況是做一個分層的結(jié)構(gòu),數(shù)據(jù)中心在最外面,,業(yè)務(wù)分組在最里面,,但是從設(shè)計理念上是另外一個概念,所以不行,。只能退而求其次,,在一個數(shù)據(jù)中心里面會有跨所有業(yè)務(wù)分組的一個Tribe,還會對相同的業(yè)務(wù)分組有一個跨數(shù)據(jù)中心的Tribe,,有兩個不同類型的Tribe進行查詢,。 到這一步,基本上功能實現(xiàn)的差不多了,,就開始慢慢的把500多個服務(wù)的日志打到Kafka里面,,大概花了一兩個月,發(fā)現(xiàn)consume跟不上,,遇到了性能瓶頸,。用ElasticSearch超過50或者100臺服務(wù)器,就會遇到很多這樣的瓶頸,。我們花了三個月的時間,,做了各種性能調(diào)優(yōu)。 這一步算是最后一步,首先理解了一下自己的業(yè)務(wù)邏輯,,我們要做的事情非常明白,,非常單一,就是需要實時的,,或者準(zhǔn)實時的log來做在線的trouble shooting,,基本上不會用到14天以前的數(shù)據(jù),保留14天以前的數(shù)據(jù)就是為了看兩周的周期而已,。 今天的問題都解決不完,,根本沒有時間考慮幾個月之前的問題,實際的業(yè)務(wù)狀態(tài)是24小時之內(nèi)的日志查詢的最多,,14天以前用的非常少,,查詢速度要求在15秒之內(nèi),超過30秒就timeout了,。索引速度30秒以內(nèi)可以接受,,超過5分鐘會觸發(fā)警報。 采用冷熱分區(qū)的方式解決這個問題,,我們測試了很多種不同的硬件,,最后選定了在非常重要和數(shù)據(jù)量很大的集群上用ssd做熱索引,24小時之內(nèi)的索引全部上到SSD機器上,,超過24小時就挪到普通的機器上,。相當(dāng)于在集群里邊,有一個熱的Cluster,,數(shù)據(jù)全面走到熱的cluster里面,,24小時以后,會被挪到冷的cluster,。做了這個之后,,系統(tǒng)變得比較穩(wěn)定,功能也正常,,內(nèi)部會根據(jù)需求保留7到14天的數(shù)據(jù),。 這步之后,我們把它推廣到LinkedIn整個公司,,第二天我接到法務(wù)和安全部的電話,。當(dāng)我們做了一個非常容易的系統(tǒng),把所有的log展現(xiàn)給所有人的時候,,如果大家能很輕易的把4億用戶的用戶名、密碼,、郵箱等信息搜出來,,這個事情就非常嚴(yán)重,所以我們又做了幾個調(diào)整。 第一個是定期掃描所有的ES,,根據(jù)特定的關(guān)鍵字來防止敏感信息進入日志,,如果進入馬上報警。還有用戶隱私的問題,,所有Elasticsearch的查詢記錄同樣送入Kafka,,并對敏感業(yè)務(wù)部門的訪問進行隔離,所有訪問日志定期審核,。我們的做法是在前面加一個Nginx,,在nginx上可以做訪問控制,把用戶所有的訪問日志全部送回Kafka做定期審核,,有一個掃描進程定期的掃描各種各樣的關(guān)鍵字,。 這是我們現(xiàn)在生產(chǎn)系統(tǒng)里的狀態(tài),有20多個針對不同業(yè)務(wù)模塊的ELK集群,,1000+服務(wù)器,,主要都是Elasticsearch。1分鐘之內(nèi)生產(chǎn)系統(tǒng)發(fā)生的log我們這邊就可以搜索,,所有的log保留7到14天?,F(xiàn)在大概有500億的索引文檔,500到800T,,之前測試時推到1500到2000T都是可以工作的,。 因為我們是500多個service,20多個集群,,沒有辦法很好的維護這么多集群,,所以是每個業(yè)務(wù)模塊的SRE團隊維護自己的Elasticserach集群。Virtual Team模式確保ELK的及時更新,。還有一點比較關(guān)鍵,,需要保證你的ES不會被沒有授權(quán)的用戶訪問,默認(rèn)的情況下是不接受SSL連接的,,SearchGuard和Sheild這兩種解決方式都是可以解決這個問題的,。 我想著重提一下采樣方式,這個是比較有意思的,,也是比較通用的方式,。采樣方式是10%+特定的用戶,為什么要這么做,?我們調(diào)過不同的比例,,發(fā)現(xiàn)不影響,如果有問題,,10%的采樣就能發(fā)現(xiàn),。為什么還要特定用戶呢,?很多時候,有一些active的用戶會經(jīng)常給你報錯,,給你反饋意見,,需要及時去看到底發(fā)生了什么事情。 對LinkedIn來說有大概百分之零點幾的power user在網(wǎng)站上非?;钴S,,做很多事情,我們需要把他們的log加到sample里,。所有的用戶請求,,都是通過Apache Traffic Server進入數(shù)據(jù)中心,在這層它會去訪問LiX,,詢問是否要對當(dāng)前用戶打標(biāo)簽,,如果打了標(biāo)簽就把這個標(biāo)簽放在InvocationContext里面。 從前臺到后臺所有的服務(wù)器只要touch到這個request,,都會在InvocationContext里看到一個requestID,。通過java container的bydefault得到requestID,把那條訪問的日志發(fā)到Kafka里面,,通過這樣的方式做成sample,。 這樣做有兩點好處,一點是如果有什么問題,,只需要把他的memberID或者requestID拿到最上面一層Tribe里面,,系統(tǒng)就會出現(xiàn)關(guān)于這條request的所有service的log。99.9%的情況可以一目了然的知道哪里出了問題,。做微服務(wù)的大家都知道,,dependence非常亂,我們LinkedIn的情況,,一個request會touch二三十個service,。所以說有這樣一個方式是非常重要的。 我想聊一下我們遇到的幾個坑,,ES集群的默認(rèn)名字是大坑,,如果不改集群名字就把它放在自己的電腦上或者測試系統(tǒng)上跑,一旦相同子網(wǎng)的人加了一個新的node也沒有改名字,,就會自動加到你的集群里面,。不管怎么樣一定要改你的集群名字。 Master,、Data,、Client節(jié)點不要混用,使用單ES節(jié)點,;JVM不要allocate超過30G的heap,,我們測試發(fā)現(xiàn)30G左右的heap可以達到最好的performance,,如果超過30G就沒有辦法完全使用;JVM版本的兼容性也是一個超級大的坑,,它不是最新的兼容,也不是哪個版本以后,,或者以前兼容,,是有幾個版本兼容,再幾個版本不兼容,,再幾個版本兼容,。有一些兼容性的問題一定要注意。 講一下剛才已經(jīng)提到的硬件的選擇,,要根據(jù)數(shù)據(jù)量,,業(yè)務(wù)的情況,索引和查詢速度的要求決定,,像我們的要求是一定要索引快,,因為要做實時的故障排查,數(shù)據(jù)的類型我們只做兩個,,一個是訪問log,,一個是application log,這些決定了我們使用的硬件是12核/64G/2x1TB的硬盤,,有八九百臺都是這樣的配置,。 有一小部分是數(shù)據(jù)量非常大但是對查詢的速度要求不是很高,比如做自動查詢的那套,,我們會把數(shù)據(jù)丟到JBODs里面,,索引速度優(yōu)先考慮的話,會用100臺左右的SSD,。 集群沒有magic number,,必須要用實際的生產(chǎn)數(shù)據(jù),一遍一遍試,,才能試出來用什么樣的配置能達到最好的效果,,這幾個是我們的learning:
還有就是一些工具,剛剛提到主動掃描敏感信息的就是一個script在后臺根據(jù)一些關(guān)鍵字掃描敏感信息,;結(jié)合警報系統(tǒng),,相信每個公司都有自己的警報系統(tǒng),ElasticAlert是一個開源的解決方案,,我們自己也有內(nèi)建的,,根據(jù)讀出來的信息的關(guān)鍵字做警報;循環(huán)刪除index用的Curator,;系統(tǒng)健康狀態(tài)監(jiān)控是自己做的監(jiān)控系統(tǒng),,官方的Marvel也很好用。 做完這套系統(tǒng)以后,,我們并不是完全被動的狀態(tài),,只能用這套系統(tǒng)來做故障排查,我們發(fā)現(xiàn)這套系統(tǒng)里面有些指標(biāo)可以很好的反映開發(fā)人員的代碼的質(zhì)量,。
通過這些發(fā)現(xiàn)一些有意思的metric返回給開發(fā)人員,,幫助他們提高代碼的質(zhì)量,這是一個比較有意思的發(fā)現(xiàn),。國外和國內(nèi)大家做的東西很多很像,,遇到的問題也很像,希望能給大家一些啟發(fā),。 作者介紹李虓(Li Xiao),LinkedIn SRE 團隊高級技術(shù)經(jīng)理,。帶領(lǐng) SRE 團隊負(fù)責(zé) LinkedIn 在線支付系統(tǒng),,高級會員功能,公共 API 接口,,視頻上傳和分享等系統(tǒng)的運維,,同時負(fù)責(zé)搭建 LinkedIn 生產(chǎn)環(huán)境日志檢索系統(tǒng),Rest.Li 框架性能優(yōu)化等跨功能項目,。在加入 LinkedIn 之前有著豐富的 Java 開發(fā)和項目管理經(jīng)驗,。四年前加入 LinkedIn SRE 團隊,致力于讓開發(fā)和運維團隊緊密配合,,在新功能上線和產(chǎn)品穩(wěn)定性之間找到最佳平衡,。 QCon是由InfoQ主辦的全球頂級技術(shù)盛會,每年在倫敦,、北京,、東京、紐約,、圣保羅,、上海、舊金山召開,。 QCon北京2017將于4月16日~18日在北京·國家會議中心舉行,,精心設(shè)計了支撐海量業(yè)務(wù)的互聯(lián)網(wǎng)架構(gòu)、大規(guī)模網(wǎng)關(guān)系統(tǒng),、微服務(wù)實踐,、快速進化的容器生態(tài)、智能化運維,、互聯(lián)網(wǎng)廣告系統(tǒng)實踐,、大數(shù)據(jù)實時計算與流處理和金融科技轉(zhuǎn)型與未來等30來個專題,涵蓋架構(gòu),、大數(shù)據(jù),、云計算,、移動、前端,、人工智能等熱點領(lǐng)域,,將邀請來自Google、Facebook,、阿里巴巴,、騰訊、百度,、美團點評,、愛奇藝等典型互聯(lián)網(wǎng)公司的技術(shù)專家,分享技術(shù)領(lǐng)域最新成果,。敬請期待,。 |
|