Elasticsearch 效率優化 (1)
現在使用 Kubernetes 容器架構,搭配了 elk 做為我們的 logging solution。但是目前使用預設的配置,在搜尋 log 時效率很慢。 這邊紀錄排查 index 的狀況,並且嘗試做改善。
思路
- 先確認目前 index 狀況,考量可以優化的部分。
- 新建兩個 index,分別為原本的設定 test-old;調整過後的設定 test-new。
- 從舊有的 index 中抓出 n 筆資料,分邊寫入新建的兩的 index。
- 比較兩個 index 效率。
先確認目前 index 狀況,考量可以優化的部分
Index 的設定:可以看到第 9、13、27 行被折疊了大量的行數,也就是說我們使用了很多不必要的欄位。
1GET /kubernetes-prod
1 0 {
2 1 "kubernetes-prod" : {
3 2 "aliases" : { },
4 3 "mappings" : {
5 4 "_meta" : {
6 5 "beat" : "filebeat",
7 6 "version" : "7.9.1"
8 7 },
9 8 "dynamic_templates" : [
10 9 +-----132 lines: {································
11 10 ],
12 11 "date_detection" : false,
13 12 "properties" : {
14 13 +-----20620 lines: "@timestamp" : {···············
15 14 }
16 15 },
17 16 "settings" : {
18 17 "index" : {
19 18 "mapping" : {
20 19 "total_fields" : {
21 20 "limit" : "10000"
22 21 }
23 22 },
24 23 "refresh_interval" : "5s",
25 24 "provided_name" : "kubernetes-prod",
26 25 "query" : {
27 26 "default_field" : [
28 27 +-------875 lines: "message",······················
29 28 ]
30 29 },
31 30 "creation_date" : "1623044585326",
32 31 "priority" : "100",
33 32 "number_of_replicas" : "0",
34 33 "uuid" : "uuid",
35 34 "version" : {
36 35 "created" : "7100099"
37 36 },
38 37 "lifecycle" : {
39 38 "name" : "kubernetes-prod",
40 39 "rollover_alias" : "kubernetes-prod"
41 40 },
42 41 "routing" : {
43 42 "allocation" : {
44 43 "include" : {
45 44 "_tier_preference" : "data_content"
46 45 }
47 46 }
48 47 },
49 48 "number_of_shards" : "1",
50 49 "max_docvalue_fields_search" : "200"
51 50 }
52 51 }
53 52 }
54 53 }
Index lifecycle policies 的配置:原本 index 設計為 一天一個 index,ilm 的部分規則就是 60 天後刪除。這部分 index 太零散。
1GET _ilm/policy/kubernetes-prod
1{
2 "kubernetes-prod" : {
3 "version" : 1,
4 "modified_date" : "2021-02-01T12:37:13.306Z",
5 "policy" : {
6 "phases" : {
7 "hot" : {
8 "min_age" : "0ms",
9 "actions" : {
10 "set_priority" : {
11 "priority" : 100
12 }
13 }
14 },
15 "delete" : {
16 "min_age" : "60d",
17 "actions" : {
18 "delete" : {
19 "delete_searchable_snapshot" : true
20 }
21 }
22 }
23 }
24 }
25 }
26}
這邊預計優化 index 的部分如下:
- 移除不必要的屬性。
- 不需要動態配置 index 結構,使用
dynamic: false
。 - 配置正確的欄位資料型態。
- Index 改為一個環境一個,並配置 ilm 的 rollover 配置。
- Kibana 的 index patterns 使用 filter 處理。
新建兩個 index,分別為 test-old、test-new
test-old 的 json 檔案又臭又長,這邊就不記錄了。
1PUT /test-old
2{json}
test-new 的 json 範例檔案放在 Github 上。
1# 建立 index template
2PUT /_index_template/test-new
3{json}
4
5# 建立 index
6PUT /test-new
查看結果,可以看到 index 已經被建立,並且沒有任何 documents。
1GET _cat/indices?v&index=test*
2
3health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
4green open test-new oaQjuBzFTiKLhnzPpm6bXQ 1 0 0 0 208b 208b
5green open test-old iMNI2tWAQASzUCjYHrWB6Q 1 0 0 0 208b 208b
從舊有的 index 中抓出 n 筆資料,分邊寫入新建的兩的 index
使用 bulk 批次插入資料,注意 json 不可以斷行(資料量過多會出錯)。
1POST /test-new/_bulk
2{ "index":{} }
3{ "message" : "foo" }
4{ "index":{} }
5{ "message" : "bar" }
由於資料過多,使用 Dev Tools 出錯,改使用 curl 匯入,分別匯入 test-old、test-new。
1curl -XPOST --user elastic:password http://elasticsearch.example.com:9200/test-old/_bulk -H "Content-Type: application/json" --data-binary @/Users/chiehtinglee/tmp.json
2
3
4curl -XPOST --user elastic:password http://elasticsearch.example.com:9200/test-old/_bulk -H "Content-Type: application/json" --data-binary @/Users/chiehtinglee/tmp.json
查看是否有執行成功,這邊可以看到 docs.count 各為 1000 筆資料。
1GET _cat/indices?v&index=test*
2
3health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
4green open test-new _DvAB-_rQvKJ1lG1eWsj6Q 1 0 1000 0 210.3kb 210.3kb
5green open test-old iMNI2tWAQASzUCjYHrWB6Q 1 0 1000 0 210.3kb 210.3kb
比較兩個 index 效率
record | old time | old size | new time | new size |
---|---|---|---|---|
1 | 1049 ms | 23.8 kB | 669 ms | 22.7 kB |
2 | 1321 ms | 24.0 kB | 907 ms | 22.6 kB |
3 | 1414 ms | 24.0 kB | 728 ms | 22.6 kB |
4 | 1818 ms | 23.9 kB | 932 ms | 22.8 kB |
5 | 1302 ms | 23.8 kB | 641 ms | 22.8 kB |
6 | 1620 ms | 23.8 kB | 685 ms | 22.8 kB |
7 | 1505 ms | 23.8 kB | 686 ms | 22.7 kB |
7 | 1505 ms | 23.8 kB | 908 ms | 22.6 kB |
8 | 1334 ms | 23.9 kB | 794 ms | 22.9 kB |
9 | 1535 ms | 23.9 kB | 831 ms | 22.7 kB |
10 | 1479 ms | 23.8 kB | 889 ms | 22.7 kB |
這邊比較結果,效率提升約 183%。
- 舊的 index 花費時間平均為 sum(old time) / 10 = 1588.2
- 新的 index 花費時間平均為 sum(new time) / 10 = 867
補充
clone index
確認目前 index 的 setting 狀況,確認有沒有 index.blocks.write
為 true
的設定。
1GET /kubernetes-prod-2021.06.02/_settings
若沒有就配置 index.blocks.write
為 true
,如果要移除則設定為 null
。
1PUT /kubernetes-prod-2021.06.02/_settings
2{
3 "settings": {
4 "index.blocks.write": true # null
5 }
6}
執行 clone index kubernetes-prod-2021.06.02
為 old
1POST /kubernetes-prod-2021.06.02/_clone/old