用ElasticSearch存储日志
介紹
如果你使用elasticsearch來(lái)存儲(chǔ)你的日志,本文給你提供一些做法和建議。
如果你想從多臺(tái)主機(jī)向elasticsearch匯集日志,你有以下多種選擇:
- Graylog2 安裝在一臺(tái)中心機(jī)上,然后它負(fù)責(zé)往elasticsearch插入日志,而且你可以使用它那個(gè)漂亮的搜索界面~
 - Logstash 他有很多特性,包括你能輸入什么日志,如何變換過(guò)濾,最好輸出到哪里。其中就有輸出到elasticsearch,包括直接輸出和通過(guò)RabbitMQ的river方式兩種。
 - Apache Flume 這個(gè)也可以從海量數(shù)據(jù)源中獲取日志,用”decorators”修改日志,也有各種各樣的”sinks”來(lái)存儲(chǔ)你的輸出。和我們相關(guān)的是elasticflume sink。
 - omelasticsearch Rsyslog的輸出模塊。你可以在你的應(yīng)用服務(wù)器上通過(guò)rsyslog直接輸出到elasticsearch,也可以用rsyslog傳輸?shù)街行姆?wù)器上來(lái)插入日志。或者,兩者結(jié)合都行。具體如何設(shè)置參見(jiàn)rsyslog Wiki。
 - 定制方案。比如,專門(mén)寫(xiě)一個(gè)腳本從天南海北的某個(gè)服務(wù)器傳輸你的日志到elasticsearch。
 
根據(jù)你設(shè)定的不同,最佳配置也變化不定。不過(guò)總有那么幾個(gè)有用的指南可以推薦一下:
內(nèi)存和打開(kāi)的文件數(shù)
如果你的elasticsearch運(yùn)行在專用服務(wù)器上,經(jīng)驗(yàn)值是分配一半內(nèi)存給elasticsearch。另一半用于系統(tǒng)緩存,這東西也很重要的。
你可以通過(guò)修改ES_HEAP_SIZE環(huán)境變量來(lái)改變這個(gè)設(shè)定。在啟動(dòng)elasticsearch之前把這個(gè)變量改到你的預(yù)期值。另一個(gè)選擇上球該elasticsearch的ES_JAVA_OPTS變量,這個(gè)變量時(shí)在啟動(dòng)腳本(elasticsearch.in.sh或elasticsearch.bat)里傳遞的。你必須找到-Xms和-Xmx參數(shù),他們是分配給進(jìn)程的最小和最大內(nèi)存。建議設(shè)置成相同大小。嗯,ES_HEAP_SIZE其實(shí)就是干的這個(gè)作用。
你必須確認(rèn)文件描述符限制對(duì)你的elasticsearch足夠大,建議值是32000到64000之間。關(guān)于這個(gè)限制的設(shè)置,另有教程可以參見(jiàn)。
目錄數(shù)
一個(gè)可選的做法是把所有日志存在一個(gè)索引里,然后用ttl field來(lái)確保就日志被刪除掉了。不過(guò)當(dāng)你日志量夠大的時(shí)候,這可能就是一個(gè)問(wèn)題了,因?yàn)橛肨TL會(huì)增加開(kāi)銷,優(yōu)化這個(gè)巨大且唯一的索引需要太長(zhǎng)的時(shí)間,而且這些操作都是資源密集型的。
建議的辦法是基于時(shí)間做目錄。比如,目錄名可以是YYYY-MM-DD的時(shí)間格式。時(shí)間間隔完全取決于你打算保留多久日志。如果你要保留一周,那一天一個(gè)目錄就很不錯(cuò)。如果你要保留一年,那一個(gè)月一個(gè)目錄可能更好點(diǎn)。目錄不要太多,因?yàn)槿乃阉鞯臅r(shí)候開(kāi)銷相應(yīng)的也會(huì)變大。
如果你選擇了根據(jù)時(shí)間存儲(chǔ)你的目錄,你也可以縮小你的搜索范圍到相關(guān)的目錄上。比如,如果你的大多數(shù)搜索都是關(guān)于最近的日志的,那么你可以在自己的界面上提供一個(gè)”快速搜索”的選項(xiàng)只檢索最近的目錄。
輪轉(zhuǎn)和優(yōu)化
移除舊日志在有基于時(shí)間的目錄后變得異常簡(jiǎn)單:
$ curl -XDELETE 'http://localhost:9200/old-index-name/'這個(gè)操作的速度非常快,和刪除大小差不多的少量文件速度接近。你可以放進(jìn)crontab里半夜來(lái)做。
Optimizing indices是在非高峰時(shí)間可以做的一件很不錯(cuò)的事情。因?yàn)樗梢蕴岣吣愕乃阉魉俣取S绕涫窃谀闶腔跁r(shí)間做目錄的情況下,更建議去做了。因?yàn)槌水?dāng)前的目錄外,其他都不會(huì)再改,你只需要對(duì)這些舊目錄優(yōu)化一次就一勞永逸了。
$ curl -XPOST 'http://localhost:9200/old-index-name/_optimize'分片和復(fù)制
通過(guò)elasticsearch.yml或者使用REST API,你可以給每個(gè)目錄配置自己的設(shè)定。具體細(xì)節(jié)參見(jiàn)鏈接。
有趣的是分片和復(fù)制的數(shù)量。默認(rèn)情況下,每個(gè)目錄都被分割成5個(gè)分片。如果集群中有一個(gè)以上節(jié)點(diǎn)存在,每個(gè)分片會(huì)有一個(gè)復(fù)制。也就是說(shuō)每個(gè)目錄有一共10個(gè)分片。當(dāng)往集群里添加新節(jié)點(diǎn)的時(shí)候,分片會(huì)自動(dòng)均衡。所以如果你有一個(gè)默認(rèn)目錄和11臺(tái)服務(wù)器在集群里的時(shí)候,其中一臺(tái)會(huì)不存儲(chǔ)任何數(shù)據(jù)。
每個(gè)分片都是一個(gè)Lucene索引,所以分片越小,elasticsearch能放進(jìn)分片新數(shù)據(jù)越少。如果你把目錄分割成更多的分片,插入速度更快。請(qǐng)注意如果你用的是基于時(shí)間的目錄,你只在當(dāng)前目錄里插入日志,其他舊目錄是不會(huì)被改變的。
太多的分片帶來(lái)一定的困難——在空間使用率和搜索時(shí)間方面。所以你要找到一個(gè)平衡點(diǎn),你的插入量、搜索頻率和使用的硬件條件。
另一方面,復(fù)制幫助你的集群在部分節(jié)點(diǎn)宕機(jī)的時(shí)候依然可以運(yùn)行。復(fù)制越多,必須在線運(yùn)行的節(jié)點(diǎn)數(shù)就可以越小。復(fù)制在搜索的時(shí)候也有用——更多的復(fù)制帶來(lái)更快的搜索,同時(shí)卻增加創(chuàng)建索引的時(shí)間。因?yàn)閷?duì)豬分片的修改,需要傳遞到更多的復(fù)制。
映射_source和_all
Mappings定義了你的文檔如何被索引和存儲(chǔ)。你可以,比如說(shuō),定義每個(gè)字段的類型——比如你的syslog里,消息肯定是字符串,嚴(yán)重性可以是整數(shù)。怎么定義映射參見(jiàn)鏈接。
映射有著合理的默認(rèn)值,字段的類型會(huì)在新目錄的第一條文檔插入的時(shí)候被自動(dòng)的檢測(cè)出來(lái)。不過(guò)你或許會(huì)想自己來(lái)調(diào)控這點(diǎn)。比如,可能新目錄的第一條記錄的message字段里只有一個(gè)數(shù)字,于是被檢測(cè)為長(zhǎng)整型。當(dāng)接下來(lái)99%的日志里肯定都是字符串型的,這樣Elasticsearch就沒(méi)法索引他們,只會(huì)記錄一個(gè)錯(cuò)誤日志說(shuō)字段類型不對(duì)。這時(shí)候就需要顯式的手動(dòng)映射”message” : {“type” : “string”}。如何注冊(cè)一個(gè)特殊的映射詳見(jiàn)鏈接。
當(dāng)你使用基于時(shí)間的目錄名時(shí),在配置文件里創(chuàng)建索引模板可能更適合一點(diǎn)。詳見(jiàn)鏈接。除去你的映射,你海可以定義其他目錄屬性,比如分片數(shù)等等。
在映射中,你可以選擇壓縮文檔的_source。這實(shí)際上就是整行日志——所以開(kāi)啟壓縮可以減小索引大小,而且依賴你的設(shè)定,提高性能。經(jīng)驗(yàn)值是當(dāng)你被內(nèi)存大小和磁盤(pán)速度限制的時(shí)候,壓縮源文件可以明顯提高速度,相反的,如果受限的是CPU計(jì)算能力就不行了。更多關(guān)于source字段的細(xì)節(jié)詳見(jiàn)鏈接。
默認(rèn)情況下,除了給你所有的字段分別創(chuàng)建索引,elasticsearch還會(huì)把他們一起放進(jìn)一個(gè)叫_all的新字段里做索引。好處是你可以在_all里搜索那些你不在乎在哪個(gè)字段找到的東西。另一面是在創(chuàng)建索引和增大索引大小的時(shí)候會(huì)使用額外更多的CPU。所以如果你不用這個(gè)特性的話,關(guān)掉它。即使你用,最好也考慮一下定義清楚限定哪些字段包含進(jìn)_all里。詳見(jiàn)鏈接。
刷新間隔
在文檔被索引后,Elasticsearch某種意義上是近乎實(shí)時(shí)的。在你搜索查找文檔之前,索引必須被刷新。默認(rèn)情況下,目錄是每秒鐘自動(dòng)異步刷新的。
刷新是一個(gè)非常昂貴的操作,所以如果你稍微增大一些這個(gè)值,你會(huì)看到非常明顯提高的插入速率。具體增大多少取決于你的用戶可以接受到什么程度。
你可以在你的index template里保存期望的刷新間隔值。或者保存在elasticsearch.yml配置文件里,或者通過(guò)(REST API)[http://www.elasticsearch.org/guide/reference/api/admin-indices-update-settings.html]升級(jí)索引設(shè)定。
另一個(gè)處理辦法是禁用掉自動(dòng)刷新,辦法是設(shè)為-1。然后用REST API手動(dòng)的刷新。當(dāng)你要一口氣插入海量日志的時(shí)候非常有效。不過(guò)通常情況下,你一般會(huì)采用的就是兩個(gè)辦法:在每次bulk插入后刷新或者在每次搜索前刷新。這都會(huì)推遲他們自己本身的操作響應(yīng)。
Thrift
通常時(shí),REST接口是通過(guò)HTTP協(xié)議的,不過(guò)你可以用更快的Thrift替代它。你需要安裝transport-thrift plugin同時(shí)保證客戶端支持這點(diǎn)。比如,如果你用的是pyes Python client,只需要把連接端口從默認(rèn)支持HTTP的9200改到默認(rèn)支持Thrift的9500就好了。
異步復(fù)制
通常,一個(gè)索引操作會(huì)在所有分片(包括復(fù)制的)都完成對(duì)文檔的索引后才返回。你可以通過(guò)index API設(shè)置復(fù)制為異步的來(lái)讓復(fù)制操作在后臺(tái)運(yùn)行。你可以直接使用這個(gè)API,也可以使用現(xiàn)成的客戶端(比如pyes或者rsyslog的omelasticsearch),都會(huì)支持這個(gè)。
用過(guò)濾器替代請(qǐng)求
通常,當(dāng)你搜索日志的時(shí)候,你感興趣的是通過(guò)時(shí)間序列做排序而不是評(píng)分。這種使用場(chǎng)景下評(píng)分是很無(wú)關(guān)緊要的功能。所以用過(guò)濾器來(lái)查找日志比用請(qǐng)求更適宜。因?yàn)檫^(guò)濾器里不會(huì)執(zhí)行評(píng)分而且可以被自動(dòng)緩存。兩者的更多細(xì)節(jié)參見(jiàn)鏈接。
批量索引
建議使用bulk API來(lái)創(chuàng)建索引它比你一次給一條日志創(chuàng)建一次索引快多了。
主要要考慮兩個(gè)事情:
- 最佳的批量大小。它取決于很多你的設(shè)定。如果要說(shuō)起始值的話,可以參考一下pyes里的默認(rèn)值,即400。
 - 給批量操作設(shè)定時(shí)器。如果你添加日志到緩沖,然后等待它的大小觸發(fā)限制以啟動(dòng)批量插入,千萬(wàn)確定還要有一個(gè)超時(shí)限制作為大小限制的補(bǔ)充。否則,如果你的日志量不大的話,你可能看到從日志發(fā)布到出現(xiàn)在elasticsearch里有一個(gè)巨大的延時(shí)。
 
總結(jié)
以上是生活随笔為你收集整理的用ElasticSearch存储日志的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: js中的==与===的区别
 - 下一篇: python拍照搜题_OCR拍照搜题