前言
- 爲何es查詢和聚合都這麼快?底層是如何實現的?
- 數據在es集羣中如何存儲的?如何作到自動分佈式的?
- 爲何es的主分片數設置了以後就不能調整,而副本分片數能夠調整?
- 如何優化索引方式和查詢方式,有效利用緩存,提升查詢效率?
- 若是保證不停服的狀況下,平滑升級或擴容?
- 如何優化查詢效率?
相信看完Elasticsearch權威指南這本書,全部疑問都將獲得解答node
一. 基本概念
1. 分片
- 最小級別的工做單元,保存索引中一部分數據。是一個Lucene實例,自己就是一個完整的搜索引擎。可是應用程序不會直接與分片通信。
- 能夠想象成容器,節點間數據遷移以分片爲單位
- 分爲主分片和副分片(主分片的副本)
- 索引建立的時候,主分片的數量就固定了,可是副本分片數量可調整
- 默認一個索引分配5個主分片
- 主分片所在節點掛掉後,從新選舉主節點,並將副分片升級爲主分片
- 故障節點從新啓動後,會同步故障期間未同步到到數據
2. 文檔
- 根對象序列化成json對象
- 每次對文檔的操做(包括修改,刪除),_version都會加一
- 文檔是不可修改的。update是先刪除,再新建一個新的
- 刪除的文檔並不會被當即移除,只是標記爲刪除。以後後臺再清理
- 本身設置文檔的版本:添加version_type=external參數
3. 衝突解決
4. 文檔元數據
- _index 文檔存儲的地方
- _type 文檔表明的對象的類(7.x的版本將去掉_type)
- _id 文檔的惟一標識。可手動設置也可自動生成(22位長)
5. 集羣架構圖
兩個節點,三個主分片,一個副分片的效果圖 算法
擴展到三個節點到效果圖 sql
6. 集羣狀態
集羣狀態是一個數據結構,集羣狀態存在每一個客戶端中。保存如下信息
- 級別設置
- 集羣節點
- 索引以及相關的映射,別名等信息
- 索引的分片,以及分配的節點
集羣狀態-status
- green:全部主分片和副分片都已經分配
- yellow:全部主分片都已分配,至少有一個副本分片沒有分配
- red:至少一個主分片(或所有副分片)缺失
二. 集羣工做原理
1. 數據是如何在分佈式系統存儲的
2. 主分片和複製分片如何交互?
- 請求可以被髮送給任意節點
- 每一個節點都有能力處理任意請求
- 每一個節點都知道任意文檔所在節點(保存的集羣狀態),並轉發請求
- 發送請求時最好循環每一個節點以負載均衡
2.1 write操做(新建、刪除、索引)
順序步驟
- 客戶端發送請求(新建,刪除,索引)到node1節點
- 節點使用hash算法得出分片編號0,由於分片0在節點3,將請求轉發到節點3
- node3成功保存數據到主分片,若是成功,轉發請求到node1和node2到副節點
- 全部複製節點成功,發送成功回覆到請求節點1,節點1再返回給客戶端
可調的參數
2.2 read操做
- 客戶端發送get請求到node1
- 節點使用hash算法,獲得文檔所屬到主分片爲0分片
- 找到分片0的副分片所在節點爲node1,node2,node3
- 經過某種策略選定某個副分片節點,好比node2
- node2返回文檔給node1
- 而後node1返回給客戶端
2.3 update操做
順序步驟
- 客戶端給node1發送更新請求
- 經過哈希算法獲得主分片位置,轉發請求到node3
- node3檢索出文檔,修改_source字段到json文檔,而後重建索引。若是有其餘進程修改了文檔,它以retry_on_conflict設置的次數重複這一步,都未成功則放棄
- node3更新成功則發送整個新文檔(並非修改請求)到node1和node2的複製節點重建索引,都成功則返回給node1,再返回給客戶端
2.4 多文檔模式
mget 多文檔read
- 客戶端發送mget請求給node1
- node1爲每一個分片構建一個請求,並轉發到對應分片所在節點
- 當全部回覆被接收,node1組合這些響應,返回給客戶端
bulk 多文檔write
- 客戶端向node1發送請求
- node1爲每一個分片構建批量請求,而後轉發到這些主分片上
- 主分片按序執行,每個完成時,發送到副分片上
- 全部操做都完成後節點整理響應返回給客戶端
3. 索引是如何創建的
3.1 基本概念
- 映射(mapping):用於字段確認,每一個字段匹配爲確認的數據類型
- 分析(analysis):全文文本分詞,以創建倒排索引
- 倒排索引:由文檔中單詞的惟一列表和單詞在文檔中的位置組成,用於快速檢索結果而設計
3.2 分析(analysis)
分析的過程
- 分析由分析器(analyzer)完成
- 分析過程先標記一段文本爲單獨的詞(item)
- 而後標準化(好比所有轉爲小寫)item,以提升搜索性
- 分析的詳情可經過_analyze API查看
分析器包括的組件
es提供不少可用直接使用的組件,可自定義組合使用數據庫
- 字符過濾器(character filter):字符串先通過這作一些過濾操做
- 分詞器(tokenizer):將文本切分爲單詞,好比空格,逗號等。中文可用專門的分詞器
- 標記過濾器(token filter):修改詞語,好比轉小寫,去掉語氣詞,增長同義詞
內置的分析器
- 標準分析器:默認使用這個。標準切分,去掉大部分符號,最後轉爲小寫
- 空格分析器:按空格切分,不轉換爲小寫
- 語言分析器:根據特定語言的特性作分析
查詢方式
- 字段查詢:精確匹配,查詢前不會將被查詢的字符串分析
- 全文查詢:查詢前會先用分析器分析要查詢的字符串
手動指定分析器
- 當往es中加入字符串時,es會自動用標準分析器作分詞,可是可能某些字符就是普通的id,標籤等字段,不須要作分析,可手動指定映射
建立索引時查找分析器的順序
- mapping文件中指定字段的analyzer
- 文檔自己的_analyzer字段
- mapping文件中指定類型的默認analyzer
- mapping文件中全局默認的analyzer
- 節點級別默認的analyzer
- 標準analyzer
查找索引時查找分析器的順序
- 查詢參數中的analyzer
- mapping文件中指定字段的analyzer
- mapping文件中指定類型的analyzer
- mapping文件中全局默認的analyzer
- 節點級別默認的analyzer
- standard analyzer
3.3 映射
做用
定義字段類型,字段的數據類型以及被es處理的方式。json
支持的字段類型
類型 |
表示的數據類型 |
String |
string |
Whole Number |
byte short integer long |
Floating point |
float double |
Boolean |
boolean |
Date |
date |
新的字段若是沒有配置映射,es會自動猜想字段類型bootstrap
自定義字段映射可實現的功能
- 區分全文字符串(須要分詞)和精確字符串(不須要分詞)
- 使用特定語言的分析器
- 優化部分匹配字段
- 指定自定義日期格式
映射包含的參數
- properties:列出了可能包含的每一個字段的映射
- 元數據字段:_type, _id, _source
- dynamic:肯定字段添加時的策略(_source會一直保存)
- ture 自動添加
- false 忽略字段
- strict 拋出異常
- 設置項:如analyzer
- 其餘設置
自定義字段映射注意點
- 要映射的字段參數爲type, 除了string外,不多須要映射其餘type
- string字段的index字段,控制字符串以什麼方式被索引。
值 |
含義 |
analyzed |
分詞索引 |
not_analyzed |
不分詞索引 |
no |
不索引 |
- string字段選擇anlyzed爲index時,analyzer指定分析器。如:simple, english, whitespace
- 更新映射只能添加字段,不能修改已經被添加的字段。不然會致使出錯索引不到
文檔字段的屬性
- type
- index
- analyzer
- ip
- geo_point
- geo_shape
元數據_source字段
- 做用: 用於保存原始json字段
- 爲何須要
- 搜索結果能獲得完整文檔
- 缺乏它,部分更新請求不起做用
- 更新映射文件時,可直接取內容
- 更易排查錯誤
- 怎麼禁用:enabled:false
- 使用:搜索時能夠經過_source指定只返回哪些列
元數據_all字段
- 查詢不知道指定哪一個字段時,使用_all。也可禁用。使用_all時,會將其餘全部字段的值做爲一個大的字符串進行索引
動態模版
dynamic_templates 設置經過字段名或類型動態匹配不一樣的映射api
- match_mapping_type 模版使用的數據類型
- match 模版使用的字段名
- path 模版使用的字段全路徑(嵌套json)
三. 結構化查詢語言
1. 過濾
概述
文檔的字段是否包含特定值,比查詢更快,結果可緩存數組
原則上全文索引或者須要其餘相關性評分的使用查詢語句,其餘狀況都用過濾。緩存
重要的過濾語句
- term:精確匹配
- terms:多個條件的精確匹配
- range:範圍過濾
- exists:是否包含指定字段
- missing:沒有某個字段
- bool:合併多個過濾查詢結果
- must:and
- must_not:not
- shoud:or
過濾順序
- 過濾順序對性能有很大影響
- 更詳細的過濾條件應該放在最前,以便排除更多的文檔
- 被緩存的過濾應該放到不會緩存的過濾前面(緩存參考後面章節)
2. 查詢
簡述
每一個文檔的字段與特定字段的匹配程度如何,比過濾慢,結果不可緩存安全
重要的查詢語句
- math_all:查詢全部文檔
- match:標準查詢,全文和精確都支持
match指定多個值時,內部分詞後會執行多個match並放入bool查詢。默認爲or。可經過operator參數改成「and」
- multi_match:同時搜索多個字段,支持通配符
- bool:同bool過濾,多的是要計算_score
3. 相關性排序
排序方式
相關性簡介
類似度算法:TF/IDF(檢索詞詞頻/反向文檔頻率)
- TF: 詞頻,出如今當前文檔次數越多,相關性越大
- IDF:反轉文檔頻率,全部文檔數與出現這個詞的文件數百分比,詞出現頻率越大,IDF越小
- 因爲性能問題,每一個分片只會計算該分片內的IDF,而不是全部文檔
- boost參數能夠設置權重
4. 分佈式搜索的執行方式
概述
搜索包括查詢多個分片,並將多個分片元信息合併,而後再根據元數據獲取真正數據兩個步驟。
查詢多個索引和查詢一個索引徹底一致,無非是多查了幾個分片。擴展的時候,能夠不用將舊數據遷移到新索引,直接新建索引,而後查詢兩個索引,或者別名索引便可
查詢(query)
-
客戶端發送search給node3,建立一個from+size的空優先級隊列
-
廣播請求到每一個分片,每一個分片在本地執行查詢,並放到一個大小爲from+size的本地優先級隊列裏
-
每一個節點返回查詢結果(id和_score)給node3,node3將結果全局排序
- 多個請求會輪詢全部的分片副本以負載均衡,提升系統吞吐率
- 多索引的工做機制和單索引相似,只不過多了些分片
- 深度分頁會致使排序過程很是繁重,佔用巨大cpu和寬帶
取回(fetch)
- 協調節點辨別出哪些文檔須要取回,並向相應分片發送請求
- 每一個分片加載文檔,並作相關處理(好比高亮),而後返回給協調節點
- 協調節點將數據返回給客戶端
搜索選項(可選參數)
- preference:控制使用哪一個分片或節點處理請求
- timeout:協調節點等待多久就放棄其餘節點的結果
- routing:限制只搜索哪些分片,對於大規模系統頗有用
- search_type:query_then_fetch爲默認的搜索類型
- count:當不須要結果,只須要數量時
- query_and_fetch:查詢而且取回
- dfs_query_and_fetch,dfs_query_then_fetch
- scan:掃描,和scroll一塊兒使用。可高效取回大量數據。禁用排序實現
掃描和滾屏
scroll
相似傳統數據庫的遊標,搜索的是查詢時的索引快照,查詢結束以前的修改不會感知到
scan
不排序,只要有結果就返回
四. 分片內部原理
1. 索引動態更新原理
1.1 倒排索引-保證文檔可被搜索
1.2 倒排索引的內容是不可變的
1.3 不可變的同時動態添加段
查詢的時候,全部段依次查詢,而後聚合結果,經過這種方式,新文檔以最小代價加入文檔
- 新的文檔首先寫入內存區的索引緩存
- buffer中包括新的段包含的倒排索引,段名等
- buffer被提交
- 新段被打開,文檔可被索引
- 內存緩存被清除,等待新文檔
1.4 刪除和更新
由於段不可變,更新和刪除操做並非真的刪除,是經過新增.del文件和新建段文件,查詢返回前將標記爲del的文件從結果中刪除
1.5 近實時搜索
由於從buffer刷入磁盤代價很大。es容許一旦一個文件被緩存,就能夠設置段打開,文件能夠被搜索到
1.6 刷新
每一個分片默認每秒打開一個新段,因此新的改動須要1s後才能看到。能夠設置refresh_interval減小刷新的頻率
1.7 持久化變動
添加緩衝buffer的同時,經過添加事務日誌(默認512M),保證數據被完整持久化。每次flush(每30分鐘,或事務日誌過大)到磁盤時,段被所有提交,清空事務日誌
1.8 合併段
經過每秒自動刷新段,不用多久段數據就劇增。每一個段消耗計算機資源,且每次查詢都要依次檢查每一個段,段越多查詢越慢。es後臺合併段解決該問題。 合併大的段會消耗io和cpu資源。
1.9 Optimize API
強制合併段。對於數據再也不變更的索引頗有效,對數據還在動態增加的索引不要使用。
2. 緩存
概述
- 緩存針對過濾查詢
- 核心是一個字節集保存哪些文檔符合過濾條件
- 緩存的字節集是增量更新的
- 每一個過濾器都是獨立緩存的,且可複用
- 大部分枝葉過濾器(如term)會被緩存,而組合過濾器(如bool)不會被緩存
不可被緩存的狀況
- 腳本過濾器,腳本對es是不透明的
- Geo(地址)過濾器,不太會被重用
- 日期範圍精確到毫秒不會被緩存,整數會被緩存
過濾時間範圍的使用建議
- 對於時間精確到毫秒的查詢,可拆分爲日期+日期時間兩個過濾條件,前者會被緩存,且順序不要改變
五. 全文檢索
1. 全文檢索包括兩個方面
- 相關度(Relevance):TF/IDF,地理位置相近度,模糊類似度或其餘算法
- 分析(Analysis):分詞,建立倒排索引
2. 全文查詢分類
- 低級查詢:term查詢。沒有分析階段,會精確匹配特定短語
- 全文檢索:match,query_string等查詢。有分析階段。
- date,integer類型:精確查詢
- not_analyzed的string類型:分析查詢詞語(好比轉小寫),執行單個短語查詢
- analyzed的string類型:先解析查詢語句,生成短語列表。查詢後再合併查詢結果
六. 聚合
1. 基本概念
桶(buckets)
知足特定條件的文檔的集合。相似於sql裏面的group by
指標(metrics)
對桶內的文檔進行統計計算。相似sql裏面的count,sum,max等統計方法
2. 近似聚合
2.1 概述
- 分佈式算法三個因子模型同時只能選擇知足兩項:精確,實時,大數據
- ea選擇大數據和實時。會提供準確但不是100%精確的結果,以犧牲一點小的估算錯誤做爲代價,換來告訴的執行效率和極小的內存消耗
- 兩個近似算法:cardinality, percentiles
2.2 cardinality 基數度量
- 相似sql的distinct
- 是一個近似算法。基於HyperLogLot++(HLL)算法的。HLL先對輸入作哈希運算,根據hash運算的記過中的bits作機率估算獲得基數。HLL 論文
- 算法特性
- 可配置精度:參數爲precision_threshold (精度更高=跟多內存)
- precision_threshold範圍爲0-4000,數據結構使用內存爲:precision_threshold * 8
- 設置爲100時,可保證百萬級別的數據量偏差維持5%之內
- 小的數據集精度很是高
- 可配置使用的固定內存量
- 優化:預先計算hash值,不過性能的瓶頸由聚合時轉移到索引時(必須從新建索引,添加hash字段),須要根據業務場景來肯定。
2.3 percentiles 百分位數度量
- 展示了以某個具體百分比執行觀察到的數值,一般用於找出異常。
- 也是一個近似算法。使用TDigest算法
- 算法特性
- 極端百分比的狀況下,數據更準確。好比1%或99%。這由數據結構決定。
- 小數據集精度很是準確
3. significant_terms
- sigterms和其餘聚合不一樣,用於發現數據集中醫學異常指標
- 經過統計數據並對比正常數據找到可能有異常頻次的指標
4. 聚合的數據結構
4.1 Doc Values
-
聚合,排序使用Doc Values的數據結構
-
將文檔映射到他們包含的詞項
-
在索引時和倒排索引同時生成。基於segment且不可變。
-
Doc values數據存放到磁盤中,不是由jvm管理。
-
採用列式存儲,數據整齊排布,便於壓縮
-
不支持analyzed字段
-
除了analyzed的字符串,默認全部字段都開啓doc values。若是你永遠不會對某些字段進行聚合,排序操做,能夠禁用doc values。能夠節省磁盤空間和索引速度
4.2 Fielddata
- anaylzed的字符串,使用Fielddata這種數據結構支持聚合,fielddata存儲在內存堆中,舊版本沒有doc values時是用的fielddata
- anaylzed的過程會消耗極大內存,且生成大量token,對聚合很不友好
- fieldata會一直存在內存中,直到被驅逐或節點崩潰。注意觀察它的大小。
- dielddata不會在建索引時存在,是查詢時創建的
- indices.fielddata.cache.size:百分比或實際大小。 控制爲 fielddata 分配的堆空間大小。每次聚合查詢時,分析字段會加載到Fielddata中,若是查詢結果中 fielddata 大小超過了指定的大小 ,其餘的值將會被回收從而得到空間。
- 若是沒有足夠空間能夠將 fielddata 保留在內存中,Elasticsearch 就會時刻從磁盤重載數據,並回收其餘數據以得到更多空間。內存的回收機制會致使重度磁盤I/O,而且在內存中生成不少垃圾,這些垃圾必須在晚些時候被回收掉。
- 監控filddata: GET /_stats/fielddata?fields=*
5. 聚合優化
- 針對大量數據的嵌套聚合查詢,效率極低。默認的查詢方式爲深度優先。
- 可使用廣度優先處理聚合數量遠遠小於總組數的狀況。參數爲collect_mode: breadth_first
七. 地理位置
1. 設置字段類型爲地理位置
地理座標點不能被動態映射字段檢測,須要顯式申明對應字段類型(type參數)爲geo_point
2. geo_point格式
- 字符串: "40.715, -74.011", 維度在前,精度在後
- 數組: [40.715, -74.011], 維度在前,精度在後
- 對象: {"lat": 40.715, "lon": -74.011}
3. 過濾方式
- geo_bounding_box :: 落在指定矩形框中的座標點
- geo_distance :: 給定距離內的點
- geo_distance_range :: 距離範圍內的點
- geo_polygon :: 落在多邊形中的點
4. 使用注意
- 地理座標過濾器使用代價很高,它會將全部文檔的地理位置信息載入內存,而後計算。使用時謹慎,或放到過濾的最後
- bool過濾器默認會將地理信息過濾排到最後
- 默認是不被緩存的
- 每一個經緯度組合須要16本身的內存,可設置壓縮格式,減小精度,減小內存
- 合理設置精度:geohash_prefix和geohash_precision兩個參數。再結合geohash過濾器可高效查詢
5. geohash
- 把世界分爲4*8=32個單元的各自,每個格子用一個字母或數字標識。這些單元有被繼續分解成32個更小的單元,不斷重複
- 長度越長,精度越高
- 有同一前綴的geohash,位置靠的近,共同前綴越長,距離越近
- 恰好相鄰的位置也有可能geohash徹底不一樣
6. 地理位置聚合
- geo_distance 距離聚合:將文檔以指定中心店爲圓心的圓環分組
- geohash_grid網格聚合:將文檔按geohash單元分組,以便在地圖上呈現
- geo_bounds: 邊界聚合:包含座標點的矩形框
7. 地理形狀(geo_shape)
八. 數據建模
1. 關聯關係
關聯關係的處理,使用扁平化的存儲,將數據冗餘到同一個索引,提升查詢效率
2. 嵌套對象
設計
內部存儲
普通對json含有數組時,內部存儲會被扁平化,致使邏輯關係丟失。需改成nested關係,而不是默認的object。嵌套對象內部會被索引爲分離的隱藏文檔
查詢
使用特殊的nested查詢或nested過濾
排序
3. 父子關係
原理
- 和nested差很少,區別是nested是存儲在同一個文檔中,而父子關係是徹底不一樣的文檔
- 父子文檔需存儲在同一個分片中
- 父子關係映射存儲在doc-values的數據結構中,徹底存在內存
- 適合父文檔少,子文檔多的狀況
優點
- 更新父文檔時,不用更新子文檔索引
- 建立刪除修改子文檔時,不影響父文檔和其餘文檔
劣勢
- 查詢速度比嵌套類型慢5-10倍
- 不適合父文檔多的狀況
設計父子關係
- 指定某一文檔type爲另外一文檔type的parent
- 建立父文檔時,和普通文檔沒區別
- 建立子文檔時,必須經過parent指定父文檔id。做用是建立關聯關係並保證分配到同一個分片(使用父文檔id作hash計算)
- 儘可能少使用父子關係,僅父文檔比較少的時候
4. 擴容設計
擴容思路
- 首先查看是否有低效率的查詢能夠優化
- 是否缺乏足夠的內存
- 是否開啓了swap
- 已經創建好的索引,不可修改分片數,可經過從新索引,將舊數據遷移到新索引中
- 搜索性能取決於最慢節點的響應時間,合理設置分片使之負載均衡
- 由於單索引和多索引沒有區別,可經過設置多索引以擴容
分片數量設置
- 基於現有的數據量和按期的增加量,預估數據總量
- 基於現有的硬件信息,設置單個分片,0個副本,找到單個分片在當前硬件條件下能支持的最大文檔數
- 用總數量/單個分片的最大數,大體可估算出分片數
基於時間的數據流場景優化
- 按時間切分索引
- 舊數據不會被改變,使用optimize api進行段合併。
- 大多數索引會有大概 50–150 個段,哪怕它們存有 TB 級別的數十億條文檔。段數量過大代表合併出現了問題(好比,合併速度跟不上段的建立)
- 不過段合併消耗掉你節點上所有的I/O資源,從而有可能使集羣失去響應。 若是你想要對索引執行
optimize
,你須要先把索引移到一個安全的節點,再執行。
- 爲了避免影響正常索引,段合併後臺限制磁盤讀寫速率爲20MB/s,可根據實際狀況調整,好比SSD盤,參數爲indices.store.throttle.max_bytes_per_sec。甚至在沒有查詢時,設置爲none,即沒有限制,合併完再改回去。
- 而且,對還在寫數據的索引進行優化(Optimize)操做將會是一個糟糕的想法, 由於優化操做將消耗節點上大量 I/O 並對現有索引形成衝擊
- 咱們能夠臨時移除副本分片,進行優化,而後再恢復副本分片
- 去除副本以前,可經過snapshot restore api備份數據
- 更舊的不會被使用的數據,關閉索引。關閉後除了磁盤,不會佔用其餘資源。flush(清空事務日誌)->close(關閉索引)
- 數據歸檔:snapshot restore api將數據存儲到hdfs或其餘地方
基於用戶的數據流場景
- 指定路由:保證同類數據會分發到同一分片。查詢時也傳入路由參數,確保只查詢特定的分片,多分片查詢帶來的性能損耗
- 使用別名,指定特定的名字對應特定的路由值和過濾器。以達到多個名稱共享一個索引的效果。看起來像多個索引同樣。
- 當某個分片數據量劇增到須要單獨建索引時,使用_alias操做:指定action的remove和add參數,實現平滑遷移。
九. 管理,監控
1. 重要的參數配置
- cluster.name
- node.name
- path.data
- path.logs
- path.plugins
- discovery.zen.minum_master_nodes: 最小主節點數,防止腦裂(多個主節點)
- discover.zen.ping.unicast.hosts: 集羣單播列表
- gateway.recover_after_nodes 至少多少個節點,集羣纔可用
- gateway.expected_node 集羣期待有多少個節點
- gateway.recover_fater_time 等待多久才進行數據恢復
- logger.discovery 日誌級別
- index.search.slowlog.threshold.query.warn : "10s" 查詢慢與10s的輸出warn日誌
- index.search.slowlog.threshold.fetch.debug: "500ms" 查詢慢與500ms的輸出debug日誌
- index.indexing.slowlog.threshold.index.info: "5s 查詢慢與5s的輸出info日誌
- index.unassigned.node_left.delayed_timeout 修改延時分片時間
- cluster.routing.allocation.enable" : "none" 禁止分片分配
2. 不要修改的配置
- 不要更改垃圾回收器,默認使用CMS。不要更換爲新一代的G1
- 線程數量,默認爲cpu核數。IO操做是由Lucene線程完成,不是es。
3. 堆內存的配置
- 默認爲1G,實際生產環境必須修改
- 保證Xms和Xmx同樣,防止運行時改變堆內存大小,這很是消耗資源
- 內存分片不要超過本機內存的一半。由於Lucene自己也會須要內存和緩存。
- 若是不須要對分詞作聚合運算,可下降堆內存。堆內存越小,Elasticsearch(更快的 GC)和 Lucene(更多的內存用於緩存)的性能越好。
- 內存不要超過32G。每一個對象的指針都變長了,就會使用更多的 CPU 內存帶寬,也就是說你實際上失去了更多的內存。果你想保證其安全可靠,設置堆內存爲 31 GB 是一個安全的選擇
- 若是內存很大,能夠考慮給一個機器分配多個es實例,但總的堆內存仍是不要超過一半。同時配置cluster.routing.allocation.same_shard.host: true。防止同一個分片(主副)在一個機器上
- 設置bootstrap.mlockall: true,鎖住內存,不讓發生內存swapping
4. 運維及優化
- 日誌文件默認存放在安裝目錄下的logs文件裏,"logger.discovery" : "DEBUG"可設置日誌級別
- 能夠設置輸出慢查詢日誌
- 若是不須要實時準確,把index.refresh_interval改到30s,作大批量倒入時,把這個值設爲-1,倒入完畢後從新設置回來
- 大批量倒入時,index.number_of_replicas設爲0,關閉副本,提升效率
- 儘可能使用es自動生成的id,避免版本查找影響效率。若是使用本身的id,使用壓縮性能良好的,避免使用太過隨機的id
- 延遲分片:防止節點掉線而後又重啓致使的大量數據遷移問題。由於掉線的節點上的數據可能會由於失效而所有被刪除,而後從新複製。參數爲index.unassigned.node_left.delayed_timeout
5. 滾動重啓
- 保證不停集羣功能的狀況下逐一對每一個節點進行升級或維護
- 先中止索引新的數據
- 禁止分片分配。cluster.routing.allocation.enable" : "none"
- 關閉單個節點,並執行升級維護
- 啓動節點,並等待加入集羣
- 重啓分片分配。cluster.routing.allocation.enable" : "all"
- 對其餘節點重複以上步驟
- 恢復索引更新數據