Elasticsearch學習筆記

前言

  • 爲何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. 數據是如何在分佈式系統存儲的

  • 文檔經過路由存放到分片
  • 經過如下算法得出該文檔存儲時的分片編號
    shard = hash(routing) % number_of_primary_shards
    複製代碼
  • routing是任意字符串,默認是_id
  • 主分片的數量不可改變,不然以前的路由失效,文檔就找不到了
  • 自定義路由能夠保證有關聯性的文檔被保存在同一個分片

2. 主分片和複製分片如何交互?

  • 請求可以被髮送給任意節點
  • 每一個節點都有能力處理任意請求
  • 每一個節點都知道任意文檔所在節點(保存的集羣狀態),並轉發請求
  • 發送請求時最好循環每一個節點以負載均衡

2.1 write操做(新建、刪除、索引)

順序步驟

  • 客戶端發送請求(新建,刪除,索引)到node1節點
  • 節點使用hash算法得出分片編號0,由於分片0在節點3,將請求轉發到節點3
  • node3成功保存數據到主分片,若是成功,轉發請求到node1和node2到副節點
  • 全部複製節點成功,發送成功回覆到請求節點1,節點1再返回給客戶端
可調的參數
  • replication:默認爲sync,主分片獲得複製分片成功響應才返回。async表示請求在主分片執行成功就返回,依舊轉發請求到副分片,不過不知道成功與否
  • consistency:主分片嘗試寫入時,須要規定數量(quorum)或過半的分片可用。可爲one,all,quorum(默認)。quorum只有在number_of_replicas大於1時才生效
    int((primary[老是1] + number_of_replicas) /2 + 1)
    複製代碼
  • timeout:分片不足時,等待時間。默認1min

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. 相關性排序

排序方式

  • _score:默認排序方式,默認倒序

  • 字段排序:_score不須要計算,默認正序

  • 多級排序:可指定多個字段。先用第一個字段排序,第一個相同時排第二個

  • 字符串參數排序:

    被分析的字段進行強制排序會消耗大量內存

相關性簡介

類似度算法: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)

  • 地理形狀是經過一個個geohash單元畫出來的

八. 數據建模

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"
  • 對其餘節點重複以上步驟
  • 恢復索引更新數據
相關文章
相關標籤/搜索