百億級(jí)日志系統(tǒng)架構(gòu)設(shè)計(jì)及優(yōu)化
原創(chuàng)【51CTO.com原創(chuàng)稿件】日志數(shù)據(jù)是最常見(jiàn)的一種海量數(shù)據(jù),以擁有大量用戶群體的電商平臺(tái)為例,雙 11 大促活動(dòng)期間,它們可能每小時(shí)的日志數(shù)量達(dá)到百億規(guī)模,海量的日志數(shù)據(jù)暴增,隨之給技術(shù)團(tuán)隊(duì)帶來(lái)嚴(yán)峻的挑戰(zhàn)。
本文將從海量日志系統(tǒng)在優(yōu)化、部署、監(jiān)控方向如何更適應(yīng)業(yè)務(wù)的需求入手,重點(diǎn)從多種日志系統(tǒng)的架構(gòu)設(shè)計(jì)對(duì)比;后續(xù)調(diào)優(yōu)過(guò)程:橫向擴(kuò)展與縱向擴(kuò)展,分集群,數(shù)據(jù)分治,重寫數(shù)據(jù)鏈路等實(shí)際現(xiàn)象與問(wèn)題展開(kāi)。
日志系統(tǒng)架構(gòu)基準(zhǔn)
有過(guò)項(xiàng)目開(kāi)發(fā)經(jīng)驗(yàn)的朋友都知道:從平臺(tái)的最初搭建到實(shí)現(xiàn)核心業(yè)務(wù),都需要有日志平臺(tái)為各種業(yè)務(wù)保駕護(hù)航。
如上圖所示,對(duì)于一個(gè)簡(jiǎn)單的日志應(yīng)用場(chǎng)景,通常會(huì)準(zhǔn)備 master/slave 兩個(gè)應(yīng)用。我們只需運(yùn)行一個(gè) Shell 腳本,便可查看是否存在錯(cuò)誤信息。
隨著業(yè)務(wù)復(fù)雜度的增加,應(yīng)用場(chǎng)景也會(huì)變得復(fù)雜。雖然監(jiān)控系統(tǒng)能夠顯示某臺(tái)機(jī)器或者某個(gè)應(yīng)用的錯(cuò)誤。
然而在實(shí)際的生產(chǎn)環(huán)境中,由于實(shí)施了隔離,一旦在上圖下側(cè)的紅框內(nèi)某個(gè)應(yīng)用出現(xiàn)了 Bug,則無(wú)法訪問(wèn)到其對(duì)應(yīng)的日志,也就談不上將日志取出了。
另外,有些深度依賴日志平臺(tái)的應(yīng)用,也可能在日志產(chǎn)生的時(shí)候就直接采集走,進(jìn)而刪除掉原始的日志文件。這些場(chǎng)景給我們?nèi)罩鞠到y(tǒng)的維護(hù)都帶來(lái)了難度。
參考 Logstash,一般會(huì)有兩種日志業(yè)務(wù)流程:
- 正常情況下的簡(jiǎn)單流程為:應(yīng)用產(chǎn)生日志→根據(jù)預(yù)定義的日志文件大小或時(shí)間間隔,通過(guò)執(zhí)行 Logrotation,不斷刷新出新的文件→定期查看→定期刪除。
- 復(fù)雜應(yīng)用場(chǎng)景的流程為:應(yīng)用產(chǎn)生日志→采集→傳輸→按需過(guò)濾與轉(zhuǎn)換→存儲(chǔ)→分析與查看。
我們可以從實(shí)時(shí)性和錯(cuò)誤分析兩個(gè)維度來(lái)區(qū)分不同的日志數(shù)據(jù)場(chǎng)景:
實(shí)時(shí),一般適用于我們常說(shuō)的一級(jí)應(yīng)用,如:直接面向用戶的應(yīng)用。我們可以自定義各類關(guān)鍵字,以方便在出現(xiàn)各種 error 或 exception 時(shí),相關(guān)業(yè)務(wù)人員能夠在第一時(shí)間被通知到。
準(zhǔn)實(shí)時(shí),一般適用于一些項(xiàng)目管理的平臺(tái),如:在需要填寫工時(shí)的時(shí)候出現(xiàn)了宕機(jī),但這并不影響工資的發(fā)放。
平臺(tái)在幾分鐘后完成重啟,我們可以再登錄填寫,該情況并不造成原則性的影響。因此,我們可以將其列為準(zhǔn)實(shí)時(shí)的級(jí)別。
除了直接采集錯(cuò)誤與異常,我們還需要進(jìn)行分析。例如:僅知道某人的體重是沒(méi)什么意義的,但是如果增加了性別和身高兩個(gè)指標(biāo),那么我們就可以判斷出此人的體重是否為標(biāo)準(zhǔn)體重。
也就是說(shuō):如果能給出多個(gè)指標(biāo),就可以對(duì)龐大的數(shù)據(jù)進(jìn)行去噪,然后通過(guò)回歸分析,讓采集到的數(shù)據(jù)更有意義。
此外,我們還要不斷地去還原數(shù)字的真實(shí)性。特別是對(duì)于實(shí)時(shí)的一級(jí)應(yīng)用,我們要能快速地讓用戶明白他們所碰到現(xiàn)象的真實(shí)含義。
例如:商家在上架時(shí)錯(cuò)把商品的價(jià)格標(biāo)簽 100 元標(biāo)成了 10 元。這會(huì)導(dǎo)致商品馬上被搶購(gòu)一空。
但是這種現(xiàn)象并非是業(yè)務(wù)的問(wèn)題,很難被發(fā)現(xiàn),因此我們只能通過(guò)日志數(shù)據(jù)進(jìn)行邏輯分析,及時(shí)反饋以保證在幾十秒之后將庫(kù)存修改為零,從而有效地解決此問(wèn)題??梢?jiàn),在此應(yīng)用場(chǎng)景中,實(shí)時(shí)分析就顯得非常有用。
最后是追溯,我們需要在獲取歷史信息的同時(shí),實(shí)現(xiàn)跨時(shí)間維度的對(duì)比與總結(jié),那么追溯就能夠在各種應(yīng)用中發(fā)揮其關(guān)聯(lián)性作用了。
上述提及的各個(gè)要素都是我們管理日志的基準(zhǔn)。如上圖所示,我們的日志系統(tǒng)采用的是開(kāi)源的 ELK 模式:
- ElasticSearch(后簡(jiǎn)稱 ES),負(fù)責(zé)后端集中存儲(chǔ)與查詢工作。
- 單獨(dú)的 Beats 負(fù)責(zé)日志的搜集。FileBeat 則改進(jìn)了 Logstash 的資源占用問(wèn)題;TopBeat 負(fù)責(zé)搜集監(jiān)控資源,類似系統(tǒng)命令 top 去獲取 CPU 的性能。
由于日志服務(wù)對(duì)于業(yè)務(wù)來(lái)說(shuō)僅起到了維穩(wěn)和保障的作用,而且我們需要實(shí)現(xiàn)快速、輕量的數(shù)據(jù)采集與傳輸,因此不應(yīng)占用服務(wù)器太多資源。
在方式上我們采用的是插件模式,包括:input 插件、output 插件、以及中間負(fù)責(zé)傳輸過(guò)濾的插件。這些插件有著不同的規(guī)則和自己的格式,支持著各種安全性的傳輸。
日志系統(tǒng)優(yōu)化思路
有了上述日志的架構(gòu),我們針對(duì)各種實(shí)際的應(yīng)用場(chǎng)景,進(jìn)一步提出了四個(gè)方面的優(yōu)化思路:
基礎(chǔ)優(yōu)化
內(nèi)存:如何分配內(nèi)存、垃圾回收、增加緩存和鎖。
網(wǎng)絡(luò):網(wǎng)絡(luò)傳輸序列化、增加壓縮、策略、散列、不同協(xié)議與格式。
CPU:用多線程提高利用率和負(fù)載。
此處利用率和負(fù)載是兩個(gè)不同的概念:
- 利用率:在用滿一個(gè)核后再用下一個(gè)內(nèi)核,利用率是逐步升高的。
- 負(fù)載:一下子把八個(gè)核全用上了,則負(fù)載雖然是滿的,但是利用率很低。即,每核都被占用了,但是所占用的資源卻不多,計(jì)算率比較低下。
磁盤:嘗試通過(guò)文件合并,減少碎片文件的產(chǎn)生,并減少尋道次數(shù)。同時(shí)在系統(tǒng)級(jí)別,通過(guò)修改設(shè)置,關(guān)閉各種無(wú)用的服務(wù)。
平臺(tái)擴(kuò)展
做加減法,或稱替代方案:無(wú)論是互聯(lián)網(wǎng)應(yīng)用,還是日常應(yīng)用,我們?cè)诓樵儠r(shí)都增加了分布式緩存,以有效提升查詢的效率。另外,我們將不被平臺(tái)使用到的地方直接關(guān)閉或去除。
縱向擴(kuò)展:如增加擴(kuò)展磁盤和內(nèi)存。
橫向擴(kuò)展:加減/平行擴(kuò)展,使用分布式集群。
數(shù)據(jù)分治
根據(jù)數(shù)據(jù)的不同維度,對(duì)數(shù)據(jù)進(jìn)行分類、分級(jí)。例如:我們從日志中區(qū)分error、info、和 debug,甚至將 info 和 debug 級(jí)別的日志直接過(guò)濾掉。
數(shù)據(jù)熱點(diǎn):例如:某種日志數(shù)據(jù)在白天的某個(gè)時(shí)間段內(nèi)呈現(xiàn)暴漲趨勢(shì),而晚上只是平穩(wěn)產(chǎn)生。我們就可以根據(jù)此熱點(diǎn)情況將它們?nèi)〕鰜?lái)單獨(dú)處理,以打散熱點(diǎn)。
系統(tǒng)降級(jí)
我們?cè)趯?duì)整體業(yè)務(wù)進(jìn)行有效區(qū)分的基礎(chǔ)上,通過(guò)制定一些降級(jí)方案,將部分不重要的功能停掉,以滿足核心業(yè)務(wù)。
日志系統(tǒng)優(yōu)化實(shí)踐
面對(duì)持續(xù)增長(zhǎng)的數(shù)據(jù)量,我們雖然增加了許多資源,但是并不能從根本上解決問(wèn)題。
特別體現(xiàn)在如下三方面:
- 日志產(chǎn)生量龐大,每天有幾百億條。
- 由于生產(chǎn)環(huán)境隔離,我們無(wú)法直接查看到數(shù)據(jù)。
- 代理資源限制,我們的各種日志采集和系統(tǒng)資源采集操作,不可超過(guò)業(yè)務(wù)資源的一個(gè)核。
一級(jí)業(yè)務(wù)架構(gòu)
我們?nèi)罩鞠到y(tǒng)的層次相對(duì)比較清晰,可簡(jiǎn)單分為數(shù)據(jù)接入、數(shù)據(jù)存儲(chǔ)和數(shù)據(jù)可視化三大塊。
具體包括:
- Rsyslog,是目前我們所接觸到的采集工具中最節(jié)省性能的一種。
- Kafka,具有持久化的作用。當(dāng)然它在使用到達(dá)一定數(shù)據(jù)量級(jí)時(shí),會(huì)出現(xiàn) Bug。
- Fluentd,它與 Rsyslog 類似,也是一種日志的傳輸工具,但是它更偏向傳輸服務(wù)。
- ES 和 Kibana。
該架構(gòu)在實(shí)現(xiàn)上會(huì)用到 Golang、Ruby、Java、JS 等不同的語(yǔ)言。在后期改造時(shí),我們會(huì)將符合 Key-Value 模式的數(shù)據(jù)快速地導(dǎo)入 HBase 之中。
基于 HBase 的自身特點(diǎn),我們實(shí)現(xiàn)了它在內(nèi)存層的 B+ 樹(shù),并且持久化到我們的磁盤之上,從而達(dá)到了理想的快速插入的速度。這也正是我們?cè)敢膺x擇 HBase 作為日志方案的原因。
二級(jí)業(yè)務(wù)架構(gòu)
我們直接來(lái)看二級(jí)業(yè)務(wù)架構(gòu)的功能圖,它是由如下流程串聯(lián)而成的:
- 在完成了數(shù)據(jù)采集之后,為了節(jié)省自己占用磁盤的空間,許多應(yīng)用會(huì)完全依賴于我們的日志系統(tǒng)。因此在數(shù)據(jù)采集完以后,我們?cè)黾恿艘粋€(gè)持久緩存。
- 完成緩存之后系統(tǒng)執(zhí)行傳輸。傳輸?shù)倪^(guò)程包括:過(guò)濾和轉(zhuǎn)換,這個(gè)過(guò)程可以進(jìn)行數(shù)據(jù)抽稀。值得強(qiáng)調(diào)的是:如果業(yè)務(wù)方盡早合作并給予我們一些約定的話,我們就能夠通過(guò)格式化來(lái)實(shí)現(xiàn)結(jié)構(gòu)化的數(shù)據(jù)。
- 隨后執(zhí)行的是分流,其主要包括兩大塊:一種是 A 來(lái)源的數(shù)據(jù)走 A 通道,B 來(lái)源的數(shù)據(jù)走 B 通道。另一種是讓 A 數(shù)據(jù)流入到我們的存儲(chǔ)設(shè)備,并觸發(fā)保護(hù)機(jī)制。即為了保障存儲(chǔ)系統(tǒng),我們額外增加了一個(gè)隊(duì)列。
例如:隊(duì)列為 100,里面的一個(gè) chunk 為 256 兆,我們現(xiàn)在設(shè)置高水位為 0.7、低水位為 0.3。
在寫操作的堆積時(shí),由于我們?cè)O(shè)置了 0.7,即 100 兆赫。那么在一個(gè) 256 兆會(huì)堆積到 70 個(gè) chunk 時(shí),我們往該存儲(chǔ)平臺(tái)的寫速度就已經(jīng)跟不上了。
此時(shí)高水位點(diǎn)會(huì)被觸發(fā),不允許繼續(xù)寫入,直到整個(gè)寫入過(guò)程把該 chunk 消化掉,并降至 30 個(gè)時(shí),方可繼續(xù)往里寫入。我們就是用該保護(hù)機(jī)制來(lái)保護(hù)后臺(tái)以及存儲(chǔ)設(shè)備的。
- 接著是存儲(chǔ),由于整個(gè)數(shù)據(jù)流的量會(huì)比較大,因此在存儲(chǔ)環(huán)節(jié)主要執(zhí)行的是存儲(chǔ)的索引、壓縮、和查詢。
- 最后是 UI 的一些分析算法,運(yùn)用 SQL 的一些查詢語(yǔ)句進(jìn)行簡(jiǎn)單、快速地查詢。
通常從采集(logstash/rsyslog/heka/filebeat)到面向緩存的 Kafka 是一種典型的寬依賴。
所謂寬依賴,是指每個(gè) App 都可能跟每個(gè) Broker 相關(guān)聯(lián)。在 Kafka 處,每次傳輸都要在哈希之后,再把數(shù)據(jù)寫到每個(gè) Broker 上。
而窄依賴,則是其每一個(gè) Fluentd 進(jìn)程都只對(duì)應(yīng)一個(gè) Broker 的過(guò)程。最終通過(guò)寬依賴過(guò)程寫入到 ES。
采集
如 Rsyslog 不但占用資源最少,而且可以添加各種規(guī)則,它還能支持像 TSL、SSL 之類的安全協(xié)議。
Filebeat 輕量,在版本 5.x 中,Elasticsearch 具有解析的能力(像 Logstash 過(guò)濾器)— Ingest。
這也就意味著可以將數(shù)據(jù)直接用 Filebeat 推送到 Elasticsearch,并讓 Elasticsearch 既做解析的事情,又做存儲(chǔ)的事情。
Kafka
接著是 Kafka,Kafka 主要實(shí)現(xiàn)的是順序存儲(chǔ),它通過(guò) topic 和消息隊(duì)列的機(jī)制,實(shí)現(xiàn)了快速地?cái)?shù)據(jù)存儲(chǔ)。
而它的缺點(diǎn):由于所有的數(shù)據(jù)都向 Kafka 寫入,會(huì)導(dǎo)致 topic 過(guò)多,引發(fā)磁盤競(jìng)爭(zhēng),進(jìn)而嚴(yán)重拖累 Kafka 的性能。
另外,如果所有的數(shù)據(jù)都使用統(tǒng)一標(biāo)簽的話,由于不知道所采集到的數(shù)據(jù)具體類別,我們將很難實(shí)現(xiàn)對(duì)數(shù)據(jù)的分治。
因此,在后面的優(yōu)化傳輸機(jī)制方面,我們改造并自己實(shí)現(xiàn)了順序存儲(chǔ)的過(guò)程,進(jìn)而解決了一定要做持久化這一安全保障的需求。
Fluentd
Fluentd 有點(diǎn)類似于 Logstash,它的文檔和插件非常齊全。其多種插件可保證直接對(duì)接到 Hadoop 或 ES。
就接入而言,我們可以采用 Fluentd 到 Fluentd 的方式。即在原有一層數(shù)據(jù)接入的基礎(chǔ)上,再接一次 Fluentd。同時(shí)它也支持安全傳輸。當(dāng)然我們?cè)诤竺嬉矊?duì)它進(jìn)行了重點(diǎn)優(yōu)化。
ES+Kibana
最后我們用到了 ES 和 Kibana。ES 的優(yōu)勢(shì)在于通過(guò) Lucene 實(shí)現(xiàn)了快速的倒排索引。
由于大量的日志是非結(jié)構(gòu)化的,因此我們使用 ES 的 Lucene 進(jìn)行包裝,以滿足普通用戶執(zhí)行非結(jié)構(gòu)化日志的搜索。而 Kibana 則基于 Lucene 提供可視化顯示工具。
問(wèn)題定位與解決
下面介紹一下我們碰到過(guò)的問(wèn)題和現(xiàn)象,如下這些都是我們著手優(yōu)化的出發(fā)點(diǎn):
- 傳輸服務(wù)器的 CPU 利用率低下,每個(gè)核的負(fù)載不飽滿。
- 傳輸服務(wù)器 Full gc 的頻次過(guò)高。由于我們是使用 Ruby 來(lái)實(shí)現(xiàn)的過(guò)程,其內(nèi)存默認(rèn)設(shè)置的數(shù)據(jù)量有時(shí)會(huì)過(guò)大。
- 存儲(chǔ)服務(wù)器出現(xiàn)單波峰現(xiàn)象,即存儲(chǔ)服務(wù)器磁盤有時(shí)會(huì)突然出現(xiàn)性能直線驟升或驟降。
- 頻繁觸發(fā)高水位。如前所述的高水位保護(hù)機(jī)制,一旦存儲(chǔ)磁盤觸發(fā)了高水位,則不再提供服務(wù),只能等待人工進(jìn)行磁盤“清洗”。
- 如果 ES 的一臺(tái)機(jī)器“掛”了,則集群就 hang 住了。即當(dāng)發(fā)現(xiàn)某臺(tái)機(jī)器無(wú)法通訊時(shí),集群會(huì)認(rèn)為它“掛”了,則快速啟動(dòng)數(shù)據(jù)恢復(fù)。而如果正值系統(tǒng)繁忙之時(shí),則此類數(shù)據(jù)恢復(fù)的操作會(huì)更加拖累系統(tǒng)的整體性能。
由于所有數(shù)據(jù)都被寫入 Kafka,而我們只用到了一個(gè) topic,這就造成了每一類數(shù)據(jù)都要經(jīng)過(guò)不一定與之相關(guān)的規(guī)則鏈,并進(jìn)行不一定適用的規(guī)則判斷,因此數(shù)據(jù)的傳輸效率整體被降低了。
Fluentd 的 host 輪詢機(jī)制造成高水位頻發(fā)。由于 Fluentd 在與 ES 對(duì)接時(shí)遵循一個(gè)默認(rèn)策略:首選前五臺(tái)進(jìn)行數(shù)據(jù)寫入,即與前五臺(tái)的前五個(gè)接口交互。
在我們的生產(chǎn)環(huán)境中,F(xiàn)luentd 是用 CRuby 寫的。每一個(gè)進(jìn)程屬于一個(gè) Fluentd 進(jìn)程,且每一個(gè)進(jìn)程都會(huì)對(duì)應(yīng)一個(gè) host 文件。
而該 host 文件的前五個(gè)默認(rèn)值即為 ES 的寫入入口,因此所有機(jī)器都會(huì)去找這五個(gè)入口。
倘若有一臺(tái)機(jī)器宕機(jī),則會(huì)輪詢到下一臺(tái)。如此直接造成了高水位的頻繁出現(xiàn)、和寫入速度的下降。
眾所周知,對(duì)日志的查詢是一種低頻次的查詢,即只有在出現(xiàn)問(wèn)題時(shí)才會(huì)去查看。但是在實(shí)際操作中,我們往往通過(guò)檢索的方式全部取出,因此意義不大。
另外 ES 為了達(dá)到較好的性能,會(huì)將數(shù)據(jù)存儲(chǔ)在 raid0 中,存儲(chǔ)的時(shí)間跨度往往會(huì)超過(guò) 7 天,因此其成本也比較高。
通過(guò)對(duì)數(shù)據(jù)的實(shí)時(shí)線分析,我們發(fā)現(xiàn)并未達(dá)到寫入/寫出的平衡狀態(tài)。
為了提高 Fluentd 的利用率,我們用 Kafka 去數(shù)據(jù)的時(shí)候提高了量,原來(lái)是 5 兆,現(xiàn)在我們改到了 6 兆。
如果只是單純傳輸,不論計(jì)算的話,其實(shí)可以改更高。只不過(guò)因?yàn)槲覀兛紤]到這里包含了計(jì)算的一些東西,所以只提到了 6 兆。
我們的 Fluentd 是基于 JRuby 的,因?yàn)?JRuby 可以多線程,但是我們的 CRuby 沒(méi)有任何意義。
為了提高內(nèi)存,我把 Ruby 所有的內(nèi)存機(jī)制了解了一下,就是散列的一些 host 文件,因?yàn)槲覀兠總€(gè)進(jìn)程都選前五列就可以了,我多開(kāi)了幾個(gè)口。ES 的優(yōu)化這一塊,在上 ES 之前,我們已經(jīng)有人做過(guò)一次優(yōu)化了。
因?yàn)榛谖覄偛耪f(shuō)的有時(shí)候日志量很高,有時(shí)候日志量很少。我們會(huì)考慮做動(dòng)態(tài)配置。
因?yàn)?ES 就是支持動(dòng)態(tài)配置的,所以它動(dòng)態(tài)配置的時(shí)候,我們?cè)谀承﹫?chǎng)景下可以提高它的寫入速度,某些場(chǎng)景下可以支持它的這種查詢效率。我們可以嘗試去做一些動(dòng)態(tài)配置負(fù)載。
改造一:存儲(chǔ)降低
降低存儲(chǔ)在整體架構(gòu)上并沒(méi)有太大變化,我們只是在傳輸?shù)?Fluentd 時(shí)把天數(shù)降下來(lái),改成了一天。
同時(shí),我們直接進(jìn)行了分流,把數(shù)據(jù)往 Hadoop 里寫,而把一些符合 Kibana 的數(shù)據(jù)直接放入 ES。
上面提過(guò),日志查詢是低頻次的,一般需要查詢兩天以上數(shù)據(jù)的可能性很小,因此我們降低存儲(chǔ)是非常有意義的。
改造二:數(shù)據(jù)分治
我們?cè)谌罩疚募?jié)點(diǎn)數(shù)較少(機(jī)器數(shù)量小于 5 臺(tái))的情況下,去掉了 Kafka 層。由于 Fluentd 可以支持?jǐn)?shù)據(jù)和大文件存儲(chǔ),因此數(shù)據(jù)能夠被持久化地存入磁盤。
我們給每個(gè)應(yīng)用都直接對(duì)應(yīng)了一個(gè) tag,以方便各個(gè)應(yīng)用對(duì)應(yīng)到自己的 tag、遵循自己的固定規(guī)則、并最終寫入 ES,這樣就方便了出現(xiàn)問(wèn)題的各自定位。
另外,我們運(yùn)用延遲計(jì)算和文件切分也能快速地找到問(wèn)題的根源。因此我們節(jié)約了 Kafka 和 ES 各種計(jì)算資源。
在實(shí)際操作中,由于 HBase 不用去做 raid,它自己完全能夠控制磁盤的寫入,因此我們進(jìn)行了數(shù)據(jù)壓縮。就其效果而言,ES 的存儲(chǔ)開(kāi)銷大幅降低。
在后期,我們也嘗試過(guò)一種更為極端的方案:讓用戶直接通過(guò)客戶端的 Shell 去查詢數(shù)據(jù),并采用本地緩存的留存機(jī)制。
優(yōu)化效果
優(yōu)化的效果如下:
- 服務(wù)器資源的有效利用。在實(shí)施了新的方案之后,我們省了很多服務(wù)器,而且單臺(tái)服務(wù)器的存儲(chǔ)資源也節(jié)省了 15%。
- 單核處理每秒原來(lái)能夠傳輸 3000 條,實(shí)施后提升到了 1.5~1.8 萬(wàn)條。而且,在服務(wù)器單獨(dú)空跑,即不加任何計(jì)算時(shí),單核每秒能傳輸近 3 萬(wàn)條。
- 很少觸發(fā) ES 保護(hù)機(jī)制。原因就是我們已把數(shù)據(jù)分流出來(lái)了。
- 以前歷史數(shù)據(jù)只能存 7 天,由于我們節(jié)省了服務(wù)器,因此我們現(xiàn)在可以存儲(chǔ)更長(zhǎng)時(shí)間的數(shù)據(jù)。而且,對(duì)于一些他人查詢過(guò)的日志,我們也會(huì)根據(jù)最初的策略,有選擇性地保留下來(lái),以便追溯。
日志系統(tǒng)優(yōu)化總結(jié)
關(guān)于日志平臺(tái)優(yōu)化,我總結(jié)了如下幾點(diǎn):
- 由于日志是低頻次的,我們把歷史數(shù)據(jù)存入了廉價(jià)存儲(chǔ)之中,普通用戶需要的時(shí)候,我們?cè)賹?dǎo)到 ES 里,通過(guò) Kibana 的前端界面便可快速查詢到。而對(duì)于程序員來(lái)說(shuō),則不需要到 ES 便可直接查詢到。
- 數(shù)據(jù)存在的時(shí)間越長(zhǎng),則意義越小。我們根據(jù)實(shí)際情況制定了有效的、留存有意義數(shù)據(jù)的策略。
- 順序?qū)懕P替代內(nèi)存。例如:區(qū)別于平常的隨機(jī)寫盤,我們?cè)诓僮髯x寫一個(gè)流文件時(shí)采取的是按順序?qū)憯?shù)據(jù)的模式。
而在存儲(chǔ)量大的時(shí)候,則應(yīng)當(dāng)考慮 SSD。特別是在 ES 遇到限流時(shí),使用 SSD 可以提升 ES 的性能。
- 提前定制規(guī)范,從而能夠有效解決后期分析等工作。
日志格式
如上圖所示,常用的日志格式類型包括:uuid、timestamp、host 等。
特別是 host,由于日志會(huì)涉及到幾百個(gè)節(jié)點(diǎn),有了 host 類型,我們就能判定是哪臺(tái)機(jī)器上的標(biāo)準(zhǔn)。而圖中其他的環(huán)境變量類型,則能夠有效地追溯到一些歷史的信息。
日志方案
如上圖所示,我們通過(guò) Rsyslog 可以直接將采集端的數(shù)據(jù)寫入文件或數(shù)據(jù)庫(kù)之中。
當(dāng)然,對(duì)于一些暫時(shí)用不上的日志,我們不一定非要實(shí)施過(guò)濾傳輸?shù)囊?guī)則。
如上圖,F(xiàn)luentd 也有一些傳輸?shù)囊?guī)則,包括:Fluentd 可以直接對(duì)接 Fluentd,也可以直接對(duì)接 MongoDB、MySQL 等。
另外,我們也有一些組件可以快速地對(duì)接插件和系統(tǒng),例如讓 Fluentd 和 Rsyslog 能夠直接連到 ES 上。
這是我個(gè)人給大家定制的一些最基本的基線,我認(rèn)為日志從采集、緩存、傳輸、存儲(chǔ),到最終可視化,分成了三套基線。
采集到存儲(chǔ)是最簡(jiǎn)單的一個(gè),像 Rsyslog 到 hdfs 或者其他 filesystem,我們有這種情況。
比較常見(jiàn)的情況,就是從采集、傳輸、到存儲(chǔ)可視化,然后形成最終我們現(xiàn)在最復(fù)雜的一套系統(tǒng),大家可以根據(jù)實(shí)際情況取舍。
最后是我考慮到一個(gè)實(shí)際情況,假如這個(gè)案例,我們盡可能少的占有服務(wù)器,然后傳輸需要過(guò)濾轉(zhuǎn)換,日志可以比較簡(jiǎn)單,符合這種 Key value(KV)格式。
我們可以按照取了一個(gè) Rsyslog、取了一個(gè) Fluentd、取了一個(gè) Hbase,取了一個(gè) echars 等這么一個(gè)方式做一個(gè)方案就可以了。
我覺(jué)得 Rsyslog、Fluentd、heka 這些都可以做采集。然后傳輸這塊有 Fluentd 傳輸,因?yàn)?Fluentd 和 Kafka 到插件非常靈活可以直接對(duì)接我們很多存儲(chǔ)設(shè)備,也可以對(duì)應(yīng)很多的文件、連 ES 都可以。
可視化可以用 Kibana,主要是跟 ES 結(jié)合得比較緊密,它們結(jié)合在一起需要一點(diǎn)學(xué)習(xí)成本。
楊津萍,大數(shù)據(jù)架構(gòu)師,從業(yè)十余年,專攻 Web 架構(gòu)及大數(shù)據(jù)架構(gòu)。開(kāi)源的熱衷人員,對(duì)大數(shù)據(jù)類項(xiàng)目,如 Hadoop、Hive、Shark 等,有過(guò)開(kāi)源貢獻(xiàn)。 目前在凡普金科擔(dān)任大數(shù)據(jù)架構(gòu)師職位。
【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為51CTO.com】