ELK 使用小技巧(第 2 期)
ELK Tips 主要介紹一些 ELK 使用過程中的小技巧,內容主要來源為 Elastic 中文社群。
一、Logstash
1、Filebeat :Non-zero metrics in the last 30s
INFO [monitoring] 1og/log.go:124 Non-zero metrics in the last 30s
filebeat.inputs: - type: log enabled: true paths: - /var/log/*.log output.elasticsearch: hosts: ["https://localhost:9200"] username: "filebeat_internal" password: "YOUR_PASSWORD" enabled: true 複製程式碼
input 和 output 下 enabled 屬性預設值為 true,因此懷疑另有其因。
2、Logstash 按月生成索引
output { if [type] == "typeA"{ elasticsearch { hosts=> "127.0.0.1:9200" index => "log_%{+YYYY_MM}" } } } 複製程式碼
按照日的原理類似:%{+YYYY.MM.dd}
3、Filebeat 通過配置刪除特定欄位
Filebeat 實現了類似 Logstash 中 filter 的功能,叫做處理器(processors),processors 種類不多,儘可能在保持 Filebeat 輕量化的基礎上提供更多常用的功能。
下面列幾種常用的 processors:
add_cloud_metadata add_locale decode_json_fields drop_event drop_fields include_fields rename add_kubernetes_metadata add_docker_metadata add_host_metadata dissect dns add_process_metadata
processors 的使用方式:
- type: <input_type> processors: - <processor_name>: when: <condition> <parameters> ... 複製程式碼
4、LogStash 採集 FTP 日誌檔案
exec { codec => plain { } command => "curl ftp://server/logs.log" interval => 3000} } 複製程式碼
5、Logstash docker-compose 啟動失敗(Permission denied)
在 docker-compose 中使用 user 選項設定使用 root 使用者啟動 docker,能解決許可權問題。
$ cat docker-compose.yml version: '2' services: logstash: image: docker.elastic.co/logstash/logstash:6.4.2 user: root command: id 複製程式碼
6、Metricize filter plugin
將一條訊息拆分為多條訊息。
# 原始資訊 { type => "type A" metric1 => "value1" metric2 => "value2" } # 配置資訊 filter { metricize { metrics => [ "metric1", "metric2" ] } } # 最終輸出 {{ type => "type A"type => "type A" metric => "metric1"metric => "metric2" value => "value1"value => "value2" }} 複製程式碼
二、Elasticsearch
1、ES 倒排索引內部結構
Lucene 的倒排索引都是按照欄位(field)來儲存對應的文件資訊的,如果 docName 和 docContent 中有“蘋果”這個 term,就會有這兩個索引鏈,如下所示:
docName: "蘋果" -> "doc1, doc2, doc3..." docContent: "蘋果" -> "doc2, doc4, doc6..." 複製程式碼
2、Jest 和 RestHighLevelClient 哪個好用點
RestHighLevelClient 是官方元件,會一直得到官方的支援,且會與 ES 保持同步更新,推薦使用官方的高階 API。
Jest 由於是社群維護,所以更新會有一定延遲,目前最新版對接 ES6.3.1,近一個月只有四個 issue,說明整體活躍度較低,因此不推薦使用。
此外推薦一份 TransportClient 的中文使用手冊,翻譯的很不錯: ofollow,noindex">github.com/jackiehff/e… 。
3、ES 單分片使用 From/Size 分頁遇到重複資料
常規情況下 ES 單分片使用 From/Size 是不會遇到資料重複的,資料重複的可能原因有:
- 沒有新增排序;
- 添加了按得分排序,但是查詢語句全部為 filter 過濾條件(此時得分都一致);
- 添加了排序,但是有索引中文件的新增、修改、刪除等操作。
對於多分片,推薦新增 preference 引數來實現分頁結果的一致性。
4、The number of object passed must be even but was [1]
ES 在呼叫 setSource 的時候傳入 Json 物件後會報錯:The number of object passed must be even but was [1],此時可以推薦將 Json 物件轉為 Map 集合,或者把 Json 物件轉為 json 字串,不過傳入字串的時候需要設定型別。
IndexRequest indexRequest = new IndexRequest("index", "type", "id"); JSONObject doc = new JSONObject(); //indexRequest.source(jsonObject); 錯誤的使用方法 //轉為 Map 物件 indexRequest.source(JSONObject.parseObject((String) doc.get("json"), Map.class)); //轉為 Json 字串(宣告字串型別) indexRequest.source(JSON.toJSONString(doc), XContentType.JSON); 複製程式碼
5、跨叢集搜尋
ES 6.X 原生支援跨叢集搜尋,具體配置請參考: www.elastic.co/guide/en/ki…
PUT _cluster/settings { "persistent": { "cluster": { "remote": { "cluster_one": { "seeds": [ "127.0.0.1:9300" ] }, "cluster_two": { "seeds": [ "127.0.0.1:9301" ] }, "cluster_three": { "seeds": [ "127.0.0.1:9302" ] } } } } } 複製程式碼
ES 6.5 推出了新功能,跨叢集同步(Cross-cluster replication),感興趣的可以自行了解。
6、ES 排序時設定空值排序位置
GET /_search { "sort" : [ { "price" : {"missing" : "_last"} } ], "query" : { "term" : { "product" : "chocolate" } } } 複製程式碼
7、ES 冷歸檔資料如何處理
使用相對低配的大磁碟機器配置為 ES 的 Warm Nodes,可以通過 index.routing.allocation.require.box_type
來設定索引是冷資料或者熱資料。如果索引極少使用,可以 close 索引,然後在需要搜尋的時候 open 即可。
8、ES 相似文章檢測
對於大文字的去重,可以參考 SimHash 演算法,通過 SimHash 可以提取到文件指紋(64位),兩篇文章通過 SimHash 計算海明距離即可判斷是否重複。海明距離計算,可以通過外掛實現: github.com/joway/elast…
9、Terms 聚合查詢優化
- 如果只需要聚合後前 N 條記錄,推薦在 Terms 聚合時新增上
"collect_mode": "breadth_first"
; - 此外可以通過設定
"min_doc_count": 10
來限制最小匹配文件數; - 如果對返回的 Term 有所要求,可以通過設定
include
和exclude
來過濾 Term; - 如果想獲取全部 Term 聚合結果,但是聚合結果又很多,可以考慮將聚合分成多個批次分別取回(Filtering Values with partitions)。
10、Tomcat 字符集造成的 ES 查詢無結果
兩個系統連線同一個 ES 服務,配置和程式碼完全一致,同一個搜尋條件,一個能夠搜尋出來東西,一個什麼都搜尋不出來,排查結果是因為其中一個系統的 tomcat 配置有問題,導致請求的時候亂碼了,所以搜不到資料。
11、ES 索引設定預設分詞器
預設情況下,如果欄位不指定分詞器,ES 或使用 standard 分詞器進行分詞;可以通過下面的設定更改預設的分詞器。
2.X 支援設定預設的索引分詞器(default_index)和預設的查詢分詞器(default_search),6.X 已經不再支援。
PUT /index { "settings": { "analysis": { "analyzer": { "default": { "type": "ik_max_word", "tokenizer": "ik_max_word" } } } } } 複製程式碼
12、ES 中的魔法引數
- 索引名:_index
- 型別名:_type
- 文件Id:_id
- 得分:_score
- 索引排序:_doc
如果你對排序沒有特別的需求,推薦使用 _doc 進行排序,例如執行 Scroll 操作時。
13、ES 延遲執行資料上卷(Rollup )
Rollup job 有個 delay 引數控制 job 執行的延遲時間,預設情況下不延遲執行,這樣如果某個 interval 的資料已經聚合好了,該 interval 遲到的資料是不會處理的。
好在 rollup api 可以支援同時搜尋裸索引和 rollup 過的索引,所以如果資料經常有延遲的話,可以考慮設定一個合適的 delay,比如 1h、6h 甚至 24h,這樣 rollup 的索引產生會有延遲,但是能確保遲到的資料被處理。
從應用場景上看,rollup 一般是為了對歷史資料做聚合存放,減少儲存空間,所以延遲幾個小時,甚至幾天都是合理的。搜尋的時候,同時搜尋最近的裸索引和歷史的 rollup 索引,就能將兩者的資料組合起來,在給出正確的聚合結果的情況下,又兼顧了效能。
Rollup 是實驗性功能,不過非常有用,特別是使用 ES 做資料倉庫的場景。
14、ES6.x 獲取所有的聚合結果
ES2.x 版本中,在聚合查詢時,通過設定 setSize(0)
就可以獲取所有的聚合結果,在ES6.x 中直接設定 setSize(Integer.MAX_VALUE)
等效於 2.x 中設定為 0。
15、ES Jar 包衝突問題
經常會遇到 ES 與業務整合時出現 Jar 包衝突問題,推薦的解決方法是使用 maven-shade-plugin
外掛,該外掛通過將衝突的 Jar 包更換一個名稱空間的方式來解決 Jar 包的衝突問題,具體使用可以參考文章: www.jianshu.com/p/d9fb7afa6… 。
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.1</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <relocations> <relocation> <pattern>com.google.guava</pattern> <shadedPattern>net.luculent.elasticsearch.guava</shadedPattern> </relocation> <relocation> <pattern>com.fasterxml.jackson</pattern> <shadedPattern>net.luculent.elasticsearch.jackson</shadedPattern> </relocation> <relocation> <pattern>org.joda</pattern> <shadedPattern>net.luculent.elasticsearch.joda</shadedPattern> </relocation> <relocation> <pattern>com.google.common</pattern> <shadedPattern>net.luculent.elasticsearch.common</shadedPattern> </relocation> <relocation> <pattern>com.google.thirdparty</pattern> <shadedPattern>net.luculent.elasticsearch.thirdparty</shadedPattern> </relocation> </relocations> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" /> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> </configuration> </execution> </executions> </plugin> </plugins> 複製程式碼
16、ES 如何選擇 Shard 儲存文件?
ES 採用 djb2 雜湊演算法對要索引文件的指定(或者預設隨機生成的) _id
進行雜湊,得到雜湊結果後對索引 shard 數目 n 取模,公式如下: hash(_id) % n
;根據取模結果決定儲存到哪一個 shard 。
三、Kibana
1、在 Kiabana 的 Discovery 介面顯示自定義欄位
Kibana 的 Discovery 介面預設只顯示 time 和 _source 兩個欄位,這個介面的左半部分,在 Popular 下面展示了很多,你只需要在你需要展示的欄位後面點選 add 即可將自定義的欄位新增到 discovery 介面。

2、filebeat 的 monitor 指標的說明
- Total :'All events newly created in the publishing pipeline'
- Emitted : 'Events processed by the output (including retries)'
- Acknowledged :'Events acknowledged by the output (includes events dropped by the output)'
- Queued :'Events added to the event pipeline queue'
四、社群文章精選
- Elastic認證考試心得
- 一文快速上手Logstash
- 當Elasticsearch遇見Kafka--Kafka Connect
- elasticsearch冷熱資料讀寫分離
- elasticsearch優秀實踐
- ELK 使用小技巧(第 1 期)
Any Code,Code Any!
掃碼關注『AnyCode』,程式設計路上,一起前行。
