本文爲博客園做者所寫: 一寸HUI,我的博客地址:https://www.cnblogs.com/zsql/html
最近在作es相關的工做,因此記錄下本身的一些想法,可能不少方面不會很全面,可是基本都是通過驗證的。本文主要是圍繞着思考,從多個方面進行考慮,怎麼設計索引比較好,直接進入主題吧,本文的es版本爲elasticsearch7.8.1。sql
首先索引建立後,索引的分片只能經過_split和_shrink接口對其進行成倍的增長和縮減,主要是由於es的數據是經過_routing分配到各個分片上面的,因此本質上是不推薦去改變索引的分片數量的,由於這樣都會對數據進行從新的移動。還有就是索引只能新增字段,不能對字段進行修改和刪除,缺少靈活性,因此每次都只能經過_reindex重建索引了。還有就是一個分片的大小以及因此分片數量的多少嚴重影響到了索引的查詢和寫入性能。因此可想而知,設計一個好的索引可以減小後期的運維管理和提升很多性能。因此前期對索引的設計是至關的重要的。app
在設計索引以前咱們要明白索引有些什麼內容,明白索引的構成,好比索引的基本配置setting,映射mapping,還有重要的分片,副本,模板,索引的生命週期等。知道這些以後就能夠有針對性的設計了。首先要結合公司的業務場景,數據量的大小,天天增量如何,數據的特色,會不會對歷史數據進行從新更新。數據存多久,是永久仍是有必定的週期。數據須要準實時呢仍是不須要準實時呢。因此清楚索引的構成和知道業務場景,纔可以結合起來作更好的設計。運維
因爲elasticsearch7.x不容許把索引級別的設置配置在elasticsearch.yml中,因此須要對每一個索引進行單獨的配置,這樣的話就比較麻煩,因此能夠把這些公共的配置配置在索引模板中,這樣就能夠在新建索引的時候能夠自動的設置到索引中,關於索引模板的操做能夠看考:聊聊elasticsearch7.8的模板和動態映射elasticsearch
接下來看看一些經常使用索引級別的配置ide
"number_of_replicas": 1, #推薦副本數爲1 "max_result_window": 100000, "refresh_interval": "30s", #這裏對實時性要求不高,能夠增長該值提升寫入性能 "index.search.slowlog.threshold.query.warn": 10s, "index.search.slowlog.threshold.query.info": 5s, "index.search.slowlog.threshold.query.debug": 2s, "index.search.slowlog.threshold.query.trace": 500ms, "index.search.slowlog.threshold.fetch.warn": 1s, "index.search.slowlog.threshold.fetch.info": 800ms, "index.search.slowlog.threshold.fetch.debug": 500ms, "index.search.slowlog.threshold.fetch.trace": 200ms, "index.indexing.slowlog.threshold.index.warn": 10s, "index.indexing.slowlog.threshold.index.info": 5s, "index.indexing.slowlog.threshold.index.debug": 2s, "index.indexing.slowlog.threshold.index.trace": 500ms "dynamic": false #是否關閉動態字段映射,默認爲true,這裏選擇我的選擇禁用
固然索引的配置還有不少其餘的,能夠根據實際狀況進行調整,這樣就能夠把須要配置公共索引配置設計成索引模板:post
PUT _index_template/template_index { "index_patterns": [ "index-*" ], "template": { "settings": { "number_of_replicas": 1, "max_result_window": 100000, "refresh_interval": "30s", "index.search.slowlog.threshold.query.warn": "10s", "index.search.slowlog.threshold.query.info": "5s", "index.search.slowlog.threshold.query.debug": "2s", "index.search.slowlog.threshold.query.trace": "500ms", "index.search.slowlog.threshold.fetch.warn": "1s", "index.search.slowlog.threshold.fetch.info": "800ms", "index.search.slowlog.threshold.fetch.debug": "500ms", "index.search.slowlog.threshold.fetch.trace": "200ms", "index.indexing.slowlog.threshold.index.warn": "10s", "index.indexing.slowlog.threshold.index.info": "5s", "index.indexing.slowlog.threshold.index.debug": "2s", "index.indexing.slowlog.threshold.index.trace": "500ms" }, "mappings": { "dynamic": false } }, "priority": 10 }
這樣新建index-開頭的索引的時候都會默認配置好如上的配置,這樣就是考慮到基本設置公共化性能
這部分主要說下索引命名規範,包括別名,經過別名可使得索引的操做變得更加靈活,一個索引能夠有多個別名,固然一個別名能夠配置多個索引,這樣的話就極大的增長了索引的的靈活性。在索引的命名上規定特殊字段開頭,一樣對其好進行權限控制,關於權限控制能夠參考:elasticsearch7.8權限控制和規劃測試
必須嚴格按照以下命名格式:(不然將沒法使用,由於這裏設置了相關權限);fetch
若是是索引拆分後(有多個索引),須要一個全局的讀的別名對全部拆分後的全部進行命名,和一個最新索引寫的別名(只對可更新的索引),若是這裏沒有描述清楚,請見2.5大索引的設計,兩個別名可規範以下:
mapping設置主要就是怎麼選擇數據類型,分詞等
中文分詞:推薦使用:"analyzer": "ik_max_word" ,這樣能夠更細粒度的進行中文分詞
設置字段的時候,務必過一下以下圖示的流程。根據實際業務須要,主要關注點:
核心參數的含義,梳理以下
這個很重要,直接影響到後期的管理和性能。
Elasticsearch中的數據組織成索引。每個索引由一個或多個分片組成。每一個分片是Luncene索引的一個實例,你能夠把實例理解成自管理的搜索引擎,用於在Elasticsearch集羣中對一部分數據進行索引和處理查詢。
分片設計原則
下面寫一個簡單的參考表(均可以根據實際狀況進行調整,只是我的的建議):
索引的大小 | 分片數量設置 |
0-20G | 2 |
20-100G | 8 |
100-400G | 15 |
400-900G | 30 |
900G-1.6T | 45 |
如上設置是基於15個數據節點進行配置的,基本都給增量預留了一些空間,最好是根據實際狀況進行設定,若是一個索引已經很大了,上面的配置不能知足了的話須要對對索引進行拆分了,使用索引模板+Rollover+索引生命週期進行自動滾動,拆分索引。見2.5節
當一個索引太大時就會有不少的風險,首先會影響性能,當分片數必定的狀況下,數據愈來愈多,一個分片就會愈來愈大,就會違背了上面的設計原則,其次就是一個索引出問題,很難恢復,而且影響範圍廣,那如何對很大的索引進行設計呢。可使用索引模板+Rollover+生命週期進行自動滾動建立索引,全部的索引都用一個別名進行讀,而且設置一個索引爲寫,這樣就可以很好的拆分索引。先看看這麼設計的原理圖。
上面有三個索引,經過index_all索引進行檢索,是用index_latest保證只寫入到一個最新的索引中,每次索引知足三個條件(文檔數,時間,索引大小)中的一個,就會自動的滾動生成新的索引。接下來作個實操,這樣更方面理解。
先來個官網,有興趣的能夠參考:https://www.elastic.co/guide/en/elasticsearch/reference/7.8/getting-started-index-lifecycle-management.html
主要分爲四個步驟:
首先建立生命週期的規則,對於索引的生命週期能夠參考:對Elasticsearch生命週期的思考,若是數據是按期存儲的,好比一些日誌,只保留最近30天,這樣的數據結合索引的生命週期能夠自動的進行清理。咱們首先建立一個策略policy_index,這裏是測試,因此把時間調至5分鐘,這些配置都應該根據實際狀況進行設置。
PUT _ilm/policy/policy_index { "policy": { "phases": { "hot": { "actions": { "rollover": { "max_size": "50GB", "max_age": "5m" } } } } } }
接下來設計索引模板,而且該策略應用進去。
PUT _index_template/policy_index_template { "index_patterns": [ "index-test-*" ], "template": { "settings": { "number_of_shards": 1, "number_of_replicas": 1, "index.lifecycle.name": "policy_index", #配置策略 "index.lifecycle.rollover_alias": "index-test-insert" }, "aliases": { "index-test-read": { "is_write_index": false #這個別名是用來讀的,不容許寫,不然會和寫的那個別名衝突 } } } }
這裏的模板只是爲了演示該小節的內容,實際狀況應該把基本配置以及mapping相關的設置好
接下來就是建立一個索引了
PUT index-test-000001
建立好以後,而後給索引添加別名index-test-insert,索引就自動有了兩個別名,read負責讀,insert負責寫
接下來,只要經過驗證便可:GET index-*/_ilm/explain
最後達到條件後就會自動生成新的索引,而後把index-test-insert別名切換到新的索引上面,就是這樣子的
大索引的設計就是拆分,不少都是根據時間進行切分索引的,若是記得沒錯的話,上面的000001這些能夠配置爲日期的。
參考博文: