ELK 使用小技巧(第 1 期)
以下配置將 message
內容按照 \t
進行切分,為了使 \t
生效需要將 logstah.yml 中配置項 config.support_escapes
設定為 true,當設定為 true 時,帶引號的字串將處理轉義字元, 預設值為 false 。
filter { mutate { split => {"message" => "\t"} add_field => { "ftimeold" => "%{[message][0]}" } } } 複製程式碼
2、Logstash 按檔案讀取內容並存儲到 ES
下面的配置將讀取 /home/txts/*
下的檔案,並讀取整個檔案內容,然後將檔案內容儲存到 test-text
索引中,同時該條記錄的 _id
為文件的檔名。這裡需要注意的是,想讀取到文件末尾時,分隔符需設定為 EOF
。
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 {} } 複製程式碼
3、ES Ingest Node 指令碼案例
Ingest Node 可以使用多種過濾器對資料進行處理,其中 Script 指令碼的功能非常強大,下面的案例實現了將一個 Json 結構進行了 Flat 化:
{ "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');" } } 複製程式碼
4、Logstash input file 外掛中 sincedb 維護問題
- 如果不想儲存 sincedb,可以使用下面配置:
sincedb_path => "/dev/null"
; - 如果希望被掃描的記錄超過一段時間後自動被清除,可以使用
sincedb_clean_after => "2 weeks"
來實現,sincedb_clean_after
表示當一個檔案在設定的時間內沒有發生過任何變化,則關於這個檔案的掃描記錄將不會儲存到 sincedb 裡面,簡單來說就是一條記錄的過期時間。
二、Elasticsearch
1、ES 查詢結果的一致性
為了保證使用者每次查詢結果的一致性(文件在結果中的順序),可以在查詢 url 裡新增 preference=<some string>
這個引數,其中 <some string>
可以是使用者的 session ID,這樣某一個使用者查詢的時候,查詢會被固定在某幾個 shard。
2、同義詞的擴充套件或收縮
- 簡單擴充套件 ,把同義詞列表中的任意一個詞擴充套件成同義詞列表所有的詞:
jump,hop,leap
; - 簡單收縮 ,把左邊的多個同義詞對映到了右邊的單個詞:
leap,hop => jump
; - 型別擴充套件 ,完全不同於簡單收縮或擴張,並不是平等看待所有的同義詞,而是擴大了詞的意義使被拓展的詞更為通用:
"cat=> cat,pet", "kitten => kitten,cat,pet", "dog=> dog,pet" "puppy=> puppy,dog,pet" 複製程式碼
3、設定某個索引為只讀狀態
index.blocks.write
設定為 true 來禁止對索引的寫操作,但索引的 metadatra 可以正常寫。
PUT indexName/_settings { "index.blocks.write": true } 複製程式碼
4、Failed to process cluster event (put-mapping) within 30s
這個是建立 mapping 的時候超時了,預設是 30s 應該是叢集處理不過來了。 索引檔案太多 ,使得叢集的狀態資料過多過大,在每個小時新建索引和設定索引 mapping 的時候,就產生叢集狀態更新任務交給 master 處理,master 在變更狀態資料的時候是 單執行緒處理 的,如果叢集總的狀態資料很大,master處理這些任務就容易出現超時。
解決辦法:
- 控制叢集的總的索引數量,shard 數量;
- 如果同時建立的索引非常多,最好避免通過寫入資料自動建立索引;
- 可以 通過 cron 任務,預先順序的建立好索引 。
5、Get 查詢獲取不到資料,但是用 _search 就可以查詢到
這種情況一般在索引時候加入了路由欄位(routing),那麼在 get,delete,update 操作中都必須使用路由欄位。
PUT my_index/my_type/1?routing=user1&refresh=true { "title": "This is a document" } GET my_index/my_type/1?routing=user1 複製程式碼
6、ES 5.X 版本多個 type 的資料遷移到 6.X
把 5.x 叢集中的索引按不同 type 拆分 reindex 到 6.x 叢集索引中,然後將拆分出來的多個索引使用別名進行組織;例如 5.x 叢集中有索引 IndexA,該索引上有 typeA 和 typeB,reindex 到 6.x 叢集 IndexA_TypeA
和 IndexB_TypeB
,reindex 語句如下所示:
POST _reindex { "source": { "index": "IndexA", "type": "TypeA", "size": 10000 }, "dest": { "index": "IndexA_TypeA" } } 複製程式碼
最後給 6.x 叢集的 IndexA_TypeA
和 IndexB_TypeB
新增別名 IndexA,使用者查詢時使用的索引名稱就不用變化。
POST _aliases { "actions": [ {"add": {"index": "IndexA_TypeA", "alias": "IndexA"}}, {"add": {"index": "IndexA_TypeB", "alias": "IndexA"}} ] } 複製程式碼
7、reindex 將多個索引合併成一個索引,需要重新設定新索引的 mapping 嗎?
需要在 reindex 之前為新索引重新設定 mapping ,reindex 只是通過類似 scroll 的方式把資料 bulk 到新的索引,不會自動同步原索引的 mappings 資訊。
8、叢集的 discovery.zen.ping.unicast.hosts 配置
只需要配置主節點(master)地址即可。
discovery.zen.ping.unicast.hosts: - 192.168.1.10:9300 - 192.168.1.11 - seeds.mydomain.com 複製程式碼
9、ES 的 path.data 配置多個盤的路徑,查詢效率與單個儲存盤的效率比,哪個效率高些?
想最大程度發揮磁碟讀寫 io,還是推薦 RAID0。
使用多路徑不一定會提升讀寫速度,和叢集 shard 的數量有關係;主要是因為一個 shard 對應的檔案,只會放到其中一塊磁碟上,不會跨磁碟儲存。比如一個極端的場景,叢集 shard 數量比較少,每個結點上就一個shard,那麼讀寫只會有一塊磁碟發揮作用,其他磁碟都空閒的。
多路徑對讀寫有提升比較大的場景,是每個結點上 shard 數量至少比盤的數量多,並且 shard 大小也差別不太多;shard 數量比較少,shard 大小差別太大,可能產生讀寫熱點問題,即有的磁碟磁碟很忙,有的很閒。
ES 不會將一個索引的主副分片分配到同一臺機器,所以即使一臺機器的 RAID0 壞了,不會導致資料丟失,僅僅是副本沒有了。
用 RAID0 的負面影響主要是磁碟損壞的時候,需要恢復的資料比較多;多路徑磁碟,壞一塊只會丟一部分資料,恢復資料會比較快;但是他也有缺陷,比如容易出現讀寫熱點問題以及磁碟空間使用不均勻問題。
10、查詢索引分片(Shard)位置的介面
# 推薦 GET /_cat/shards/<index_name>?v GET /_cluster/state/routing_table 複製程式碼
11、multi_match 與 match_phrase 的區別
boolQuery().should(matchQuery(field, keyword))
12、analyzer, tokenizer, token-filter 有什麼區別
- analyzer :分析器,analyzer = 1 個 tokenizer + 若干個 token-filter;
- tokenizer :分詞器,主要用於對文字進行切割;
- token-filter :過濾器,主要對 tokenizer 切割後的 term 進行再次處理。
13、_source 欄位的用途
簡單來說:_source 欄位用於儲存最原始的 JSON 文件內容(建立索引時傳遞的),這個欄位不能被搜尋,它可以在 get 或者 search 請求階段進行返回;此外它會參與欄位高亮計算、文件的更新等操作,一般不推薦關閉 _source 欄位。
三、Kibana
1、kibana 表格預設排序
在設計表格的時候直接點選需要排序的那一列,然後讓它按照倒序或者正序排序,然後點選儲存即可,這樣這個表格預設就是按照這一列倒序或者正序排列的。

Any Code,Code Any!
掃碼關注『AnyCode』,程式設計路上,一起前行。
