elasticsearch 使用事項
template的使用
剛開始的時候,每次實驗都去改/etc/elasticsearch/elasticsearch.yml配置文件。事實上在template裏修改settings更方便並且靈活!固然最主要的,仍是調節裏面的properties設定,合理的控制store和analyze了。
template設定也有多種方法。最簡單的就是和存儲數據同樣POST上去。長期的辦法,就是寫成json文件放在配置路徑裏。其中,default配置放在/etc/elasticsearch/下,其餘配置放在/etc/elasticsearch/templates/下。舉例我如今的一個templates/template-logstash.json內容以下:
- {
- "template-logstash" : {
- "template" : "logstash*",
- "settings" : {
- "index.number_of_shards" : 5,
- "number_of_replicas" : 1,
- "index" : {
- "store" : {
- "compress" : {
- "stored" : true,
- "tv": true
- }
- }
- }
- },
- "mappings" : {
- "_default_" : {
- "properties" : {
- "dynamic" : "true",
- },
- },
- "loadbalancer" : {
- "_source" : {
- "compress" : true,
- },
- "_ttl" : {
- "enabled" : true,
- "default" : "10d"
- },
- "_all" : {
- "enabled" : false
- },
- "properties" : {
- "@fields" : {
- "dynamic" : "true",
- "properties" : {
- "client" : {
- "type" : "string",
- "index" : "not_analyzed"
- },
- "domain" : {
- "type" : "string",
- "index" : "not_analyzed"
- },
- "oh" : {
- "type" : "string",
- "index" : "not_analyzed"
- },
- "responsetime" : {
- "type" : "double",
- },
- "size" : {
- "type" : "long",
- "index" : "not_analyzed"
- },
- "status" : {
- "type" : "string",
- "index" : "not_analyzed"
- },
- "upstreamtime" : {
- "type" : "double",
- },
- "url" : {
- "type" : "string",
- "index" : "not_analyzed"
- }
- }
- },
- "@source" : {
- "type" : "string",
- "index" : "not_analyzed"
- },
- "@timestamp" : {
- "type" : "date",
- "format" : "dateOptionalTime"
- },
- "@type" : {
- "type" : "string",
- "index" : "not_analyzed",
- "store" : "no"
- }
- }
- }
- }
- }
- }
注意:POST 發送的 json 內容比存儲的 json 文件內容要少最外層的名字,由於名字是在 url 裏體現的。
mapping簡介
上面template中除了index/shard/replica以外的部分,就是mapping了,你們注意到其中的dynamic,默認狀況下,index會在第一條數據進入的時候自動分析這條數據的狀況,給每一個value找到最恰當的type,而後以此爲該index的mapping。以後再PUT上來的數據,格式若是不符合mapping的,也能存儲成功,可是就沒法檢索了。
mapping中關於store和compress的部分。建議是 disable 掉 _all,可是 enable 住 _source!! 若是連 _source 也 disable 掉的話,一旦你重啓進程,整個 index 裏除了 _id,_timestamp 和 _score 三個默認字段,啥都丟了……
API簡介
ES的API,最基本的就是CRUD操做了,這部分是標準的REST,就不說了。
而後還有三個API比較重要且經常使用,分別是: bulk/count/search。
Bulk顧名思義,把多個單條的記錄合併成一個大數組統一提交,這樣避免一條條發送的header解析,索引頻繁更新,indexing速度大大提升
Count根據POST的json,返回命中範圍內的總條數。固然沒POST時就直接返回該index的總條數了。
Search根據POST的json或者GET的args,返回命中範圍內的數據。這是最重要的部分了。下面說說經常使用的search API:
query
一旦使用search,必須至少提供query參數,而後在這個query的基礎上進行接下來其餘的檢索。query參數又分三類:
"match_all" : { } 直接請求所有;
"term"/"text"/"prefix"/"wildcard" : { "key" : "value" } 根據字符串搜索(嚴格相等/片段/前綴/匹配符);
"range" : { "@timestamp" : { "from" : "now-1d", "to" : "now" } } 根據範圍搜索,若是type是時間格式,可使用內置的now表示當前,而後用-1d/h/m/s來往前推。
filter
上面提到的query的參數,在filter中也都存在。此外,還有比較重要的參數就是鏈接操做:
"or"/"and" : [{"range":{}}, {"prefix":""}] 兩個filter的查詢,交集或者合集;
"bool" : ["must":{},"must_not":{},"should":{}] 上面的and雖然更快,可是隻能支持兩個,超過兩個的,要用 bool 方法;
"not"/"limit" : {} 取反和限定執行數。注意這個limit和mysql什麼的有點不一樣:它限定的是在每一個shards上執行多少條。若是你有5個shards,其實對整個index是limit了5倍大小的設定值。
另外一點比較關鍵的是:filter結果默認是不緩存的,若是經常使用,須要指定 "_cache" : true。
facets
facets接口能夠根據query返回統計數據,最基礎的是terms和statistical兩種。不過在日誌分析的狀況下,最經常使用的是:
"histogram" : { "key_field" : "", "value_field" : "", "interval" : "" } 根據時間間隔返回柱狀圖式的統計數據;
"terms_stats" : { "key_field" : "", "value_field" : "" } 根據key的狀況返回value的統計數據,相似group by的意思。
這裏就涉及到前面mapping裏爲何針對每一個field都設定type的緣由了。由於 histogram 裏的 key_field 只能是 dateOptionalTime 格式的,value_field 只能是 string 格式的;而 terms_stats 裏的 key_field 只能是 string 格式的,value_field 只能是 numberic 格式的。
而咱們都知道,http code那些200/304/400/503神馬的,看起來是數字,咱們卻須要的是他們的count數據,不是算他們的平均數。因此不能由ES動態的認定爲long,得指定爲string。
內存和打開的文件數
若是你的elasticsearch運行在專用服務器上,經驗值是分配一半內存給elasticsearch。另外一半用於系統緩存,這東西也很重要的。
你能夠經過修改ES_HEAP_SIZE環境變量來改變這個設定。在啓動elasticsearch以前把這個變量改到你的預期值。另外一個選擇上球該elasticsearch的ES_JAVA_OPTS變量,這個變量時在啓動腳本(elasticsearch.in.sh或elasticsearch.bat)裏傳遞的。你必須找到-Xms和-Xmx參數,他們是分配給進程的最小和最大內存。建議設置成相同大小。嗯,ES_HEAP_SIZE其實就是乾的這個做用。
你必須確認文件描述符限制對你的elasticsearch足夠大,建議值是32000到64000之間。關於這個限制的設置,另有教程能夠參見。
目錄數
一個可選的作法是把全部日誌存在一個索引裏,而後用ttl field來確保就日誌被刪除掉了。不過當你日誌量夠大的時候,這可能就是一個問題了,由於用TTL會增長開銷,優化這個巨大且惟一的索引須要太長的時間,並且這些操做都是資源密集型的。
建議的辦法是基於時間作目錄。好比,目錄名能夠是YYYY-MM-DD的時間格式。時間間隔徹底取決於你打算保留多久日誌。若是你要保留一週,那一天一個目錄就很不錯。若是你要保留一年,那一個月一個目錄可能更好點。目錄不要太多,由於全文搜索的時候開銷相應的也會變大。
若是你選擇了根據時間存儲你的目錄,你也能夠縮小你的搜索範圍到相關的目錄上。好比,若是你的大多數搜索都是關於最近的日誌的,那麼你能夠在本身的界面上提供一個」快速搜索」的選項只檢索最近的目錄。
輪轉和優化
移除舊日誌在有基於時間的目錄後變得異常簡單:
$ curl -XDELETE 'http://localhost:9200/old-index-name/'
這個操做的速度很是快,和刪除大小差很少的少許文件速度接近。你能夠放進crontab裏半夜來作。
Optimizing indices是在非高峯時間能夠作的一件很不錯的事情。由於它能夠提升你的搜索速度。尤爲是在你是基於時間作目錄的狀況下,更建議去作了。由於除了當前的目錄外,其餘都不會再改,你只須要對這些舊目錄優化一次就一勞永逸了。
$ curl -XPOST 'http://localhost:9200/old-index-name/_optimize'
分片和複製
經過elasticsearch.yml或者使用REST API,你能夠給每一個目錄配置本身的設定。具體細節參見連接。
有趣的是分片和複製的數量。默認狀況下,每一個目錄都被分割成5個分片。若是集羣中有一個以上節點存在,每一個分片會有一個複製。也就是說每一個目錄有一共10個分片。當往集羣裏添加新節點的時候,分片會自動均衡。因此若是你有一個默認目錄和11臺服務器在集羣裏的時候,其中一臺會不存儲任何數據。
每一個分片都是一個Lucene索引,因此分片越小,elasticsearch能放進分片新數據越少。若是你把目錄分割成更多的分片,插入速度更快。請注意若是你用的是基於時間的目錄,你只在當前目錄裏插入日誌,其餘舊目錄是不會被改變的。
太多的分片帶來必定的困難——在空間使用率和搜索時間方面。因此你要找到一個平衡點,你的插入量、搜索頻率和使用的硬件條件。
另外一方面,複製幫助你的集羣在部分節點宕機的時候依然能夠運行。複製越多,必須在線運行的節點數就能夠越小。複製在搜索的時候也有用——更多的複製帶來更快的搜索,同時卻增長建立索引的時間。由於對豬分片的修改,須要傳遞到更多的複製。
映射_source和_all
Mappings定義了你的文檔如何被索引和存儲。你能夠,好比說,定義每一個字段的類型——好比你的syslog裏,消息確定是字符串,嚴重性能夠是整數。怎麼定義映射參見連接。
映射有着合理的默認值,字段的類型會在新目錄的第一條文檔插入的時候被自動的檢測出來。不過你或許會想本身來調控這點。好比,可能新目錄的第一條記錄的message字段裏只有一個數字,因而被檢測爲長整型。當接下來99%的日誌裏確定都是字符串型的,這樣Elasticsearch就無法索引他們,只會記錄一個錯誤日誌說字段類型不對。這時候就須要顯式的手動映射」message」 : {「type」 : 「string」}。如何註冊一個特殊的映射詳見連接。
當你使用基於時間的目錄名時,在配置文件裏建立索引模板可能更適合一點。詳見連接。除去你的映射,你海能夠定義其餘目錄屬性,好比分片數等等。
在映射中,你能夠選擇壓縮文檔的_source。這實際上就是整行日誌——因此開啓壓縮能夠減少索引大小,並且依賴你的設定,提升性能。經驗值是當你被內存大小和磁盤速度限制的時候,壓縮源文件能夠明顯提升速度,相反的,若是受限的是CPU計算能力就不行了。更多關於source字段的細節詳見連接。
默認狀況下,除了給你全部的字段分別建立索引,elasticsearch還會把他們一塊兒放進一個叫_all的新字段裏作索引。好處是你能夠在_all裏搜索那些你不在意在哪一個字段找到的東西。另外一面是在建立索引和增大索引大小的時候會使用額外更多的CPU。因此若是你不用這個特性的話,關掉它。即便你用,最好也考慮一下定義清楚限定哪些字段包含進_all裏。詳見連接。
刷新間隔
在文檔被索引後,Elasticsearch某種意義上是近乎實時的。在你搜索查找文檔以前,索引必須被刷新。默認狀況下,目錄是每秒鐘自動異步刷新的。
刷新是一個很是昂貴的操做,因此若是你稍微增大一些這個值,你會看到很是明顯提升的插入速率。具體增大多少取決於你的用戶能夠接受到什麼程度。
你能夠在你的index template裏保存指望的刷新間隔值。或者保存在elasticsearch.yml配置文件裏,或者經過(REST API)[http://www.elasticsearch.org/guide/reference/api/admin-indices-update-settings.html]升級索引設定。
另外一個處理辦法是禁用掉自動刷新,辦法是設爲-1。而後用REST API手動的刷新。當你要一口氣插入海量日誌的時候很是有效。不過一般狀況下,你通常會採用的就是兩個辦法:在每次bulk插入後刷新或者在每次搜索前刷新。這都會推遲他們本身自己的操做響應。
Thrift
一般時,REST接口是經過HTTP協議的,不過你能夠用更快的Thrift替代它。你須要安裝transport-thrift plugin同時保證客戶端支持這點。好比,若是你用的是pyes Python client,只須要把鏈接端口從默認支持HTTP的9200改到默認支持Thrift的9500就行了。
異步複製
一般,一個索引操做會在全部分片(包括複製的)都完成對文檔的索引後才返回。你能夠經過index API設置複製爲異步的來讓複製操做在後臺運行。你能夠直接使用這個API,也可使用現成的客戶端(好比pyes或者rsyslog的omelasticsearch),都會支持這個。
用過濾器替代請求
一般,當你搜索日誌的時候,你感興趣的是經過時間序列作排序而不是評分。這種使用場景下評分是很可有可無的功能。因此用過濾器來查找日誌比用請求更適宜。由於過濾器裏不會執行評分並且能夠被自動緩存。二者的更多細節參見連接。
批量索引
建議使用bulk API來建立索引它比你一次給一條日誌建立一次索引快多了。
主要要考慮兩個事情:
最佳的批量大小。它取決於不少你的設定。若是要提及始值的話,能夠參考一下pyes裏的默認值,即400。
給批量操做設定時器。若是你添加日誌到緩衝,而後等待它的大小觸發限制以啓動批量插入,千萬肯定還要有一個超時限制做爲大小限制的補充。不然,若是你的日誌量不大的話,你可能看到從日誌發佈到出如今elasticsearch裏有一個巨大的延時。
歡迎關注本站公眾號,獲取更多信息