ELK 使用小技巧(第 1 期)

ELK Tips 主要介紹一些 ELK 使用過程當中的小技巧,內容主要來源爲 Elastic 中文社區。編程

1、Logstash

一、Logstash 字符串分割(Split)

如下配置將 message 內容按照 \t 進行切分,爲了使 \t 生效須要將 logstah.yml 中配置項 config.support_escapes 設置爲 true,當設置爲 true 時,帶引號的字符串將處理轉義字符,默認值爲 falsejson

filter {
  mutate {
    split => {"message" => "\t"}
    add_field => {
      "ftimeold" => "%{[message][0]}"
    }
  }
}
複製代碼

二、Logstash 按文件讀取內容並存儲到 ES

下面的配置將讀取/home/txts/*下的文件,並讀取整個文件內容,而後將文件內容存儲到 test-text 索引中,同時該條記錄的 _id 爲文檔的文件名。這裏須要注意的是,想讀取到文檔末尾時,分隔符需設置爲 EOFbash

input {
  file {
    path => ["/home/txts/*"]
    start_position => "beginning"
    mode => "read"
    delimiter => "EOF"
    file_completed_action => "log"
    file_completed_log_path => "/home/logs/file.log"
  }
}
output {
  elasticsearch {
    hosts => ["http://192.168.3.214:9200/"] index => "test-text" document_id => "%{path}" } stdout {} } 複製代碼

三、ES Ingest Node 腳本案例

Ingest Node 可使用多種過濾器對數據進行處理,其中 Script 腳本的功能很是強大,下面的案例實現了將一個 Json 結構進行了 Flat 化:session

{
    "script" : {
      "lang" : "painless",
      "source" : "def dict = ['result': new HashMap()]; for (entry in ctx['json'].entrySet()) { dict['result'][entry.getKey()] = entry.getValue(); } ctx['osquery'] = dict; ctx.remove('json');"
    }
}
複製代碼

四、Logstash input file 插件中 sincedb 維護問題

  1. 若是不想保存 sincedb,可使用下面配置:sincedb_path => "/dev/null"
  2. 若是但願被掃描的記錄超過一段時間後自動被清除,可使用 sincedb_clean_after => "2 weeks" 來實現,sincedb_clean_after 表示當一個文件在設定的時間內沒有發生過任何變化,則關於這個文件的掃描記錄將不會存儲到 sincedb 裏面,簡單來講就是一條記錄的過時時間。

2、Elasticsearch

一、ES 查詢結果的一致性

爲了保證用戶每次查詢結果的一致性(文檔在結果中的順序),能夠在查詢 url 裏添加 preference=<some string> 這個參數,其中<some string>能夠是用戶的 session ID,這樣某一個用戶查詢的時候,查詢會被固定在某幾個 shard。app

二、同義詞的擴展或收縮

  • 簡單擴展,把同義詞列表中的任意一個詞擴展成同義詞列表全部的詞:jump,hop,leap
  • 簡單收縮,把左邊的多個同義詞映射到了右邊的單個詞:leap,hop => jump
  • 類型擴展,徹底不一樣於簡單收縮或擴張,並非平等看待全部的同義詞,而是擴大了詞的意義使被拓展的詞更爲通用:
"cat => cat,pet",
"kitten => kitten,cat,pet",
"dog => dog,pet"
"puppy => puppy,dog,pet"
複製代碼

三、設置某個索引爲只讀狀態

index.blocks.write 設置爲 true 來禁止對索引的寫操做,但索引的 metadatra 能夠正常寫。less

PUT indexName/_settings
{
    "index.blocks.write": true
}
複製代碼

四、Failed to process cluster event (put-mapping) within 30s

這個是建立 mapping 的時候超時了,默認是 30s 應該是集羣處理不過來了。索引文件太多,使得集羣的狀態數據過多過大,在每一個小時新建索引和設置索引 mapping 的時候,就產生集羣狀態更新任務交給 master 處理,master 在變動狀態數據的時候是單線程處理的,若是集羣總的狀態數據很大,master處理這些任務就容易出現超時。dom

解決辦法:elasticsearch

  • 控制集羣的總的索引數量,shard 數量;
  • 若是同時建立的索引很是多,最好避免經過寫入數據自動建立索引;
  • 能夠經過 cron 任務,預先順序的建立好索引

五、Get 查詢獲取不到數據,可是用 _search 就能夠查詢到

這種狀況通常在索引時候加入了路由字段(routing),那麼在 get,delete,update 操做中都必須使用路由字段。ui

PUT my_index/my_type/1?routing=user1&refresh=true 
{
  "title": "This is a document"
}

GET my_index/my_type/1?routing=user1
複製代碼

六、ES 5.X 版本多個 type 的數據遷移到 6.X

把 5.x 集羣中的索引按不一樣 type 拆分 reindex 到 6.x 集羣索引中,而後將拆分出來的多個索引使用別名進行組織;例如 5.x 集羣中有索引 IndexA,該索引上有 typeA 和 typeB,reindex 到 6.x 集羣IndexA_TypeAIndexB_TypeB,reindex 語句以下所示:url

POST _reindex
{
  "source": {
    "index": "IndexA",
    "type": "TypeA",
    "size": 10000
  },
  "dest": {
    "index": "IndexA_TypeA"
  }
}
複製代碼

最後給 6.x 集羣的IndexA_TypeAIndexB_TypeB添加別名 IndexA,用戶查詢時使用的索引名稱就不用變化。

POST _aliases  
{
    "actions": [
        {"add": {"index": "IndexA_TypeA", "alias": "IndexA"}},
        {"add": {"index": "IndexA_TypeB", "alias": "IndexA"}}
    ]
}
複製代碼

七、reindex 將多個索引合併成一個索引,須要從新設置新索引的 mapping 嗎?

須要在 reindex 以前爲新索引從新設置 mapping ,reindex 只是經過相似 scroll 的方式把數據 bulk 到新的索引,不會自動同步原索引的 mappings 信息。

八、集羣的 discovery.zen.ping.unicast.hosts 配置

只須要配置主節點(master)地址便可。

discovery.zen.ping.unicast.hosts:
   - 192.168.1.10:9300
   - 192.168.1.11 
   - seeds.mydomain.com 
複製代碼

九、ES 的 path.data 配置多個盤的路徑,查詢效率與單個存儲盤的效率比,哪一個效率高些?

想最大程度發揮磁盤讀寫 io,仍是推薦 RAID0。

使用多路徑不必定會提高讀寫速度,和集羣 shard 的數量有關係;主要是由於一個 shard 對應的文件,只會放到其中一塊磁盤上,不會跨磁盤存儲。好比一個極端的場景,集羣 shard 數量比較少,每一個結點上就一個shard,那麼讀寫只會有一塊磁盤發揮做用,其餘磁盤都空閒的。

多路徑對讀寫有提高比較大的場景,是每一個結點上 shard 數量至少比盤的數量多,而且 shard 大小也差異不太多;shard 數量比較少,shard 大小差異太大,可能產生讀寫熱點問題,即有的磁盤磁盤很忙,有的很閒。

ES 不會將一個索引的主副分片分配到同一臺機器,因此即便一臺機器的 RAID0 壞了,不會致使數據丟失,僅僅是副本沒有了。

用 RAID0 的負面影響主要是磁盤損壞的時候,須要恢復的數據比較多;多路徑磁盤,壞一塊只會丟一部分數據,恢復數據會比較快;可是他也有缺陷,好比容易出現讀寫熱點問題以及磁盤空間使用不均勻問題。

十、查詢索引分片(Shard)位置的接口

# 推薦
GET /_cat/shards/<index_name>?v

GET /_cluster/state/routing_table
複製代碼

十一、multi_match 與 match_phrase 的區別

  • multi_match 是對 boolQuery().should(matchQuery(field, keyword)) 的一種簡化,簡單說就是一個關鍵詞,匹配多個字段,匹配方式爲 matchQuery,正常的全文匹配。
  • match_phrase 簡單說就是要匹配一個短語,例如你輸入的文本爲:中國人,若是被分詞爲:中國/人,那麼查找時候會在指定的字段先查找到 "中國" 這個 term,而後在 "中國" 這個 term 後面去查找 "人"這個term(有順序要求),若是匹配到則認爲匹配成功;因此更像是在匹配一個短語(連貫的句子)。

十二、analyzer, tokenizer, token-filter 有什麼區別

  • analyzer :分析器,analyzer = 1 個 tokenizer + 若干個 token-filter;
  • tokenizer :分詞器,主要用於對文本進行切割;
  • token-filter :過濾器,主要對 tokenizer 切割後的 term 進行再次處理。

1三、_source 字段的用途

簡單來講:_source 字段用於存儲最原始的 JSON 文檔內容(建立索引時傳遞的),這個字段不能被搜索,它能夠在 get 或者 search 請求階段進行返回;此外它會參與字段高亮計算、文檔的更新等操做,通常不推薦關閉 _source 字段。

3、Kibana

一、kibana 表格默認排序

在設計表格的時候直接點擊須要排序的那一列,而後讓它按照倒序或者正序排序,而後點擊保存便可,這樣這個表格默認就是按照這一列倒序或者正序排列的。

kibana 排序設置


Any Code,Code Any!

掃碼關注『AnyCode』,編程路上,一塊兒前行。

相關文章
相關標籤/搜索