ElasticSearch學(xué)習(xí)文檔

@author Gandalf

介紹

ES是什么

Elasticsearch實(shí)時(shí)的分布式全文搜索分析引擎,內(nèi)部使用Lucene做索引與搜索,開(kāi)發(fā)語(yǔ)言為Java

全文:對(duì)全部的文本內(nèi)容進(jìn)行分析,建立索引,使之可以被搜索

實(shí)時(shí):新增到 ES 中的數(shù)據(jù)在1秒后就可以被檢索到,這種新增數(shù)據(jù)對(duì)搜索的可見(jiàn)性稱為“準(zhǔn)實(shí)時(shí)/近實(shí)時(shí)搜索”。

分布式:可以動(dòng)態(tài)調(diào)整集群規(guī)模,彈性擴(kuò)容

Github:https://github.com/elastic/elasticsearch

可以做什么

  • 搜索:搭建搜索引擎(類(lèi)似百度、谷歌、知乎等可搜索功能的實(shí)現(xiàn))、日志收集分析系統(tǒng)
  • 聚合分析:進(jìn)行數(shù)據(jù)分析、統(tǒng)計(jì),生成指標(biāo)數(shù)據(jù)。
  • 適用場(chǎng)景:適合用于中等規(guī)模數(shù)據(jù)的應(yīng)用場(chǎng)景,據(jù)官方描述,集群規(guī)模支持“上百”個(gè)節(jié)點(diǎn),ES適合中等數(shù)據(jù)量的業(yè)務(wù),不適合海量數(shù)據(jù)存儲(chǔ)

優(yōu)缺點(diǎn)

  • 迭代快速,目前每2周左右就會(huì)發(fā)布新版本

  • 社區(qū)活躍且生態(tài)豐富

  • 語(yǔ)法與關(guān)系型數(shù)據(jù)庫(kù)迥異,語(yǔ)法學(xué)習(xí)成本高

基本概念

ES是面向文檔的。各種文本內(nèi)容以文檔(document)的形式存儲(chǔ)到ES中,文檔可以是一封郵件、一條日志,一條關(guān)系型數(shù)據(jù)庫(kù)的記錄,或者一個(gè)網(wǎng)頁(yè)的內(nèi)容。使用 JSON 作為文檔的序列化格式,文檔可以有很多字段,創(chuàng)建索引的時(shí)候,同關(guān)系型數(shù)據(jù)庫(kù)創(chuàng)建表約束一樣,可指定各字段的數(shù)據(jù)類(lèi)型(也可不指定,動(dòng)態(tài)生成文檔),可指定不同字段不同的分詞器,指定字段是否被搜索到。

索引結(jié)構(gòu)

存儲(chǔ)結(jié)構(gòu)上,由_index、_type_id標(biāo)識(shí)一個(gè)文檔

  • _index:為指向一個(gè)或多個(gè)分片的物理存儲(chǔ)命名,存儲(chǔ)某一類(lèi)型文檔的集合

  • _type:用于區(qū)分一個(gè)_index中的不同細(xì)分,多個(gè)_type的數(shù)據(jù)結(jié)構(gòu)應(yīng)是相似的,如建立一個(gè)訂單類(lèi)的索引,有不同_type類(lèi)型的訂單:物流訂單、采購(gòu)訂單、出庫(kù)訂單...,索引中的多個(gè)type,實(shí)際上是存放在一起的,一個(gè)index下,不能有多個(gè)字段重名但type不一致

  • _id:文檔唯一標(biāo)識(shí),可自行指定,ES自動(dòng)生成的id,長(zhǎng)度為20個(gè)字符,URL安全,base64編碼,GUID,分布式環(huán)境也不會(huì)發(fā)生沖突

分片

分片(Shard): ES利用分片解決單機(jī)無(wú)法存儲(chǔ)規(guī)模巨大的問(wèn)題,將數(shù)據(jù)分為多個(gè)分片,分片就是一個(gè)lucene實(shí)例,會(huì)自動(dòng)創(chuàng)建索引和處理請(qǐng)求,不同分片可存儲(chǔ)在不同的機(jī)器上,通過(guò)路由策略找到分片所在的位置;分布式存儲(chǔ)中還會(huì)把分片復(fù)制成多個(gè)副本,實(shí)現(xiàn)水平擴(kuò)展能力以及高可用(HA),同時(shí)副本還可以執(zhí)行讀請(qǐng)求,分擔(dān)集群壓力,ES將數(shù)據(jù)副本分為主從兩部分,即主分片primary hard和副分片replica shard,主數(shù)據(jù)作為權(quán)威數(shù)據(jù),寫(xiě)過(guò)程中先寫(xiě)主分片,成功后再寫(xiě)副分片,當(dāng)集群規(guī)模擴(kuò)大或縮小時(shí),ES 會(huì)自動(dòng)在各節(jié)點(diǎn)中遷移分片,使數(shù)據(jù)仍然均勻分布在集群里

primary shard不能和自己replica shad在同一節(jié)點(diǎn),單節(jié)點(diǎn)創(chuàng)建primary shard和replica shard在同一臺(tái)機(jī)器上時(shí),是不會(huì)分配給replica shard的。

Tip :分片一旦指定久可以修改,所以一開(kāi)始就盡量規(guī)劃好主分片數(shù)量,先依據(jù)硬件情況定好單個(gè)分片容量,然后依據(jù)業(yè)務(wù)場(chǎng)景預(yù)估數(shù)據(jù)量和增長(zhǎng)量,再除以單個(gè)分片容量。

文檔結(jié)構(gòu)

_mapping:自動(dòng)或者手動(dòng)為ES中index的typet建立的一種數(shù)據(jù)結(jié)構(gòu)和相關(guān)配置

_all:ES會(huì)自動(dòng)將多個(gè)field的值用串聯(lián)的方式鏈接起來(lái),變成一個(gè)長(zhǎng)的字符串,作為_(kāi)all field的值,同時(shí)建立索引,在搜索的時(shí)候,沒(méi)有指定field的值時(shí)候,就默認(rèn)搜索_all

倒排索引

建立倒排索引的時(shí)候,會(huì)執(zhí)行一個(gè)操作,對(duì)各個(gè)拆分的各個(gè)單詞進(jìn)行相應(yīng)的處理(noralization)歸一化,搜索的時(shí)候也要進(jìn)行分詞并歸一化,提升搜索命中文檔的概率 likes-->like Tom-->tom

如不提前指定索引及類(lèi)型,es會(huì)自動(dòng)建立index和type,不需要提前創(chuàng)建,會(huì)默認(rèn)對(duì)每個(gè)field建立倒排索引,讓其可以被搜索

各節(jié)點(diǎn)說(shuō)明

  • master節(jié)點(diǎn):管理ES的元數(shù)據(jù),管理索引的創(chuàng)建和刪除,結(jié)點(diǎn)增加和移除,默認(rèn)會(huì)選出一臺(tái)做master,不會(huì)處理所有的請(qǐng)求,通過(guò)配置 node.master: true(默認(rèn)),使節(jié)點(diǎn)具有被選舉為 Master 的資格,主結(jié)點(diǎn)也可做數(shù)據(jù)節(jié)點(diǎn),生產(chǎn)環(huán)境盡量分離主節(jié)點(diǎn)與數(shù)據(jù)節(jié)點(diǎn)
  • 數(shù)據(jù)節(jié)點(diǎn)(Data node):保存數(shù)據(jù)、執(zhí)行數(shù)據(jù)相關(guān)操作:CRUD、搜索、聚合等。數(shù)據(jù)節(jié)點(diǎn)對(duì)CPU、內(nèi)存、I/O要求較高
  • 預(yù)處理節(jié)點(diǎn)(Ingest node):在索引文檔之前,即寫(xiě)入數(shù)據(jù)之前,通過(guò)定義好的一系列的processors(處理器)和pipeline(管道),對(duì)數(shù)據(jù)進(jìn)行某種轉(zhuǎn)換。processors和pipeline攔截bulk和index請(qǐng)求
  • 協(xié)調(diào)節(jié)點(diǎn)(Coordinateing node):處理客戶端請(qǐng)求的節(jié)點(diǎn),并將請(qǐng)求轉(zhuǎn)發(fā)給文檔所在的位置,在收集各節(jié)點(diǎn)的處理請(qǐng)求后,合并數(shù)據(jù)并轉(zhuǎn)換為客戶端,每個(gè)節(jié)點(diǎn)都可以作為協(xié)調(diào)節(jié)點(diǎn)
集群狀態(tài)示意圖

ES讀請(qǐng)求與寫(xiě)請(qǐng)求都是首先通過(guò)協(xié)調(diào)節(jié)點(diǎn),由協(xié)調(diào)節(jié)點(diǎn)進(jìn)行請(qǐng)求分發(fā)到對(duì)應(yīng)的shard以及對(duì)應(yīng)的node,各node處理完后回復(fù)協(xié)調(diào)節(jié)點(diǎn)再向客戶端做響應(yīng)

分詞

IK 分詞器簡(jiǎn)介:ik有兩種分詞模式,ik_max_word,和ik_smart模式;

ik_max_word: 會(huì)將文本做最細(xì)粒度的拆分,比如會(huì)將“中華人民共和國(guó)國(guó)歌”拆分為“中華人民共和國(guó),中華人民,中華,華人,人民共和國(guó),人民,人,民,共和國(guó),共和,和,國(guó)國(guó),國(guó)歌”,會(huì)窮盡各種可能的組合;
ik_smart: 會(huì)做最粗粒度的拆分,比如會(huì)將“中華人民共和國(guó)國(guó)歌”拆分為“中華人民共和國(guó),國(guó)歌”。

進(jìn)階知識(shí)

集群健康狀態(tài)

從數(shù)據(jù)完整性的角度劃分,集群健康狀態(tài)分為三種:

  • Green:所有的主分片和副分片都正常運(yùn)行。

  • Yellow:所有的主分片都正常運(yùn)行,但不是所有的副分片都正常運(yùn)行。這意味著存在單點(diǎn)故障風(fēng)險(xiǎn)

  • Red:有主分片沒(méi)能正常運(yùn)行,不是所有的主分片都是active狀態(tài)。

集群狀態(tài)是全局信息,包括內(nèi)容路由信息、配置信息,描述了“哪個(gè)分片位于哪個(gè)節(jié)點(diǎn)”這種信息,

集群狀態(tài)發(fā)布流程:集群狀態(tài)由主節(jié)點(diǎn)負(fù)責(zé)維護(hù),主節(jié)點(diǎn)更新后廣播到其它節(jié)點(diǎn) ,該操作是一個(gè)不完全分布事務(wù),分為兩階段,commit與apply階段, master變更集群信息后,廣播變更信息到各個(gè)子節(jié)點(diǎn),多數(shù)節(jié)點(diǎn)確認(rèn)后,集群狀態(tài)發(fā)布成功

主節(jié)點(diǎn)主分片選舉過(guò)程

當(dāng)master節(jié)點(diǎn)掛掉后,會(huì)自動(dòng)選舉一個(gè)node成為新的maste,基于Bully算法,每個(gè)節(jié)點(diǎn)個(gè)ID,選出各節(jié)點(diǎn)認(rèn)為ID值最小的作為主節(jié)點(diǎn)

新主節(jié)點(diǎn)將丟失掉的primary shard的某個(gè)replica shard提升為primary shard, 此時(shí)cluster status會(huì)變?yōu)閥ellow,因?yàn)閜rimary全都變成active了,但少了一個(gè)replica shard

重啟故障的node,主節(jié)點(diǎn)會(huì)將缺失的副本都cpy到該node上,而且該node會(huì)用之前已有的shard數(shù)據(jù),只是同步一下掛掉后發(fā)生過(guò)的修改

之后cluster status狀態(tài)就變?yōu)間reen,因?yàn)閜rimary shard和replica shard都屬于可用狀態(tài)

ES節(jié)點(diǎn)內(nèi)部通信與數(shù)據(jù)傳輸都是基于TCP,基于netty,包括REST接口也是基于netty進(jìn)行封裝路由

ES數(shù)據(jù)可被搜索流程

段合并

默認(rèn)情況下索引的refresh_interval為1秒,

ES并發(fā)控制

通過(guò)樂(lè)觀鎖實(shí)現(xiàn)并發(fā)控制,通過(guò)版本號(hào)的方式控制,每次更新之前先拿到版本號(hào)與ES中的版本號(hào)對(duì)比,如果不一致,則過(guò)去當(dāng)前版本號(hào)中的最新數(shù)據(jù),再修改

悲觀鎖:每次獲取數(shù)據(jù)都會(huì)加鎖,悲觀的認(rèn)為別人會(huì)修改數(shù)據(jù),其余線程想獲取數(shù)據(jù)必須等到該鎖被釋放后才能獲取到,悲觀適用于多寫(xiě),樂(lè)觀適用于多讀,樂(lè)觀鎖存在ABA問(wèn)題

悲觀鎖可通過(guò)版本號(hào)與CAS實(shí)現(xiàn),如Java中的原子類(lèi);

寫(xiě)數(shù)據(jù)流程

image-20210121112939821
  1. 客戶端向NODE1發(fā)送寫(xiě)請(qǐng)求。
  2. NODE1使用文檔ID來(lái)確定文檔屬于分片0,通過(guò)集群狀態(tài)中的內(nèi)容路由表信息獲知分片0的主分片位于NODE3,因此請(qǐng)求被轉(zhuǎn)發(fā)到NODE3上。
  3. NODE3上的主分片執(zhí)行寫(xiě)操作。如果寫(xiě)入成功,則它將請(qǐng)求并行轉(zhuǎn)發(fā)到 NODE1和NODE2的副分片上,等待返回結(jié)果。當(dāng)所有的副分片都報(bào)告成功,NODE3將向協(xié)調(diào)節(jié)點(diǎn)報(bào)告成功,協(xié)調(diào)節(jié)點(diǎn)再向客戶端報(bào)告成功
詳細(xì)流程
image-20210121113357715

在客戶端收到成功響應(yīng)時(shí),意味著寫(xiě)操作已經(jīng)在主分片和所有副分片都執(zhí)行完成

建立索引流程
image

讀數(shù)據(jù)流程

查詢分為兩階段:QUERY_THEN_FETCH查詢與獲取,Query階段知道了要取哪些數(shù)據(jù),但是并沒(méi)有取具體的數(shù)據(jù),F(xiàn)etch階段獲取具體的數(shù)據(jù)

Query階段
query階段

QUERY_THEN_FETCH搜索類(lèi)型的查詢階段步驟如下:
(1)客戶端發(fā)送search請(qǐng)求到NODE 3。
(2)Node 3將查詢請(qǐng)求轉(zhuǎn)發(fā)到索引的每個(gè)主分片或副分片中。
(3)每個(gè)分片在本地執(zhí)行查詢,并使用本地的Term/DocumentFrequency信息進(jìn)行打分,添加結(jié)果到大小為from + size的本地有序優(yōu)先隊(duì)列中。
(4)每個(gè)分片返回各自優(yōu)先隊(duì)列中所有文檔的ID和排序值給協(xié)調(diào)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn)合并這些值到自己的優(yōu)先隊(duì)列中,產(chǎn)生一個(gè)全局排序后的列表。

Fetch階段
image-20210121114352581

Fetch階段由以下步驟構(gòu)成:
(1)協(xié)調(diào)節(jié)點(diǎn)向相關(guān)NODE發(fā)送GET請(qǐng)求。
(2)分片所在節(jié)點(diǎn)向協(xié)調(diào)節(jié)點(diǎn)返回?cái)?shù)據(jù)。
(3)協(xié)調(diào)節(jié)點(diǎn)等待所有文檔被取得,然后返回給客戶端。

分布式系統(tǒng)搜索執(zhí)行流程
image

刪數(shù)據(jù)流程

刪除方式為標(biāo)記刪除,只會(huì)對(duì)文檔進(jìn)行標(biāo)記為delete,不會(huì)真正物理刪除,等es存儲(chǔ)達(dá)到一定閾值時(shí),才會(huì)自動(dòng)刪除標(biāo)記為delete的文檔,查詢時(shí)會(huì)過(guò)濾掉被標(biāo)記為刪除的數(shù)據(jù),或者lucene段合并時(shí)才會(huì)清除標(biāo)記為刪除的數(shù)據(jù)

修改數(shù)據(jù)流程

ES配置

節(jié)點(diǎn)配置

創(chuàng)建獨(dú)立主節(jié)點(diǎn)的配置:

node.master: true
node.data: false

數(shù)據(jù)節(jié)點(diǎn)配置

node.master: false
node.data: true
node.ingest: false

預(yù)處理節(jié)點(diǎn)配置

node.master: false
node.data: false
node.ingest: true

協(xié)調(diào)節(jié)點(diǎn)配置

node.master: false
node.data: false
node.ingest: false

ES模板配置

{
    "template": "*",
    "order" : 0,
    "settings": 
    {
        "index.merge.policy.max_merged_segment" : "2gb",
        "index.merge.policy.segments_per_tier" : "24",
        "index.number_of_replicas" : "1",
        "index.number_of_shards" : "24",
        "index.optimize_auto_generated_id" : "true",
        "index.refresh_interval" : "120s",
        "index.translog.durability" : "async",
        "index.translog.flush_threshold_size" : "1000mb",
        "index.translog.sync_interval" : "120s",
        "index.unassigned.node_left.delayed_timeout" : "5d"
    }
}

配置修改

重要配置修改

https://www.elastic.co/guide/cn/elasticsearch/guide/current/important-configuration-changes.html

設(shè)置es堆內(nèi)存

https://www.elastic.co/guide/cn/elasticsearch/guide/current/heap-sizing.html

時(shí)間類(lèi)型存儲(chǔ):往 ES 寫(xiě)入時(shí)間類(lèi)型的數(shù)據(jù)的時(shí)候,可以寫(xiě)入不同的時(shí)間格式的值,最終在 ES 中都會(huì)轉(zhuǎn)化成 long 類(lèi)型用于查詢和排序。

ES使用

安裝使用

下載 https://www.elastic.co/cn/downloads/elasticsearch

java環(huán)境:確保服務(wù)器的jvm和運(yùn)行程序的jvm的版本是完全一致的

  1. 啟動(dòng)
/usr/java/jdk1.8.0_144/bin/java -Xms24g -Xmx24g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+AlwaysPreTouch -server -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -Djdk.io.permissionsUseCanonicalPath=true -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j.skipJansi=true -XX:+Hepath.home=/usr/elasticsearch-5.5.2 -cp /usr/elasticsearch-5.5.2/lib/* org.elasticsearch.bootstrap.Elasticsearch -d
  1. 訪問(wèn)

啟動(dòng)成功后,ES提供REST接口,http端口為9200,Java默認(rèn)訪問(wèn)端口為9300

集群運(yùn)維管理

查詢集群狀態(tài)

-- 默認(rèn)請(qǐng)求到主節(jié)點(diǎn)
curl -X GET "localhost:9200/_cluster/state  
-- 接收請(qǐng)求的節(jié)點(diǎn)執(zhí)行,可用于驗(yàn)證當(dāng)前節(jié)點(diǎn)的集群狀態(tài)是否為最新
curl -X GET "localhost:9200/_cluster/state?local=true 

查詢集群健康狀態(tài)

curl -X GET localhost:9200/_cat/health?v
curl -X GET localhost:9200/_cluster/health?pretty

集群節(jié)點(diǎn)信息

curl http://127.0.0.1:9200/_cat/nodes?v
圖片

查詢索引列表

curl -X GET "localhost:9200/_cat/indices?v"

節(jié)點(diǎn)監(jiān)控

-- 可以全面的查看集群各個(gè)節(jié)點(diǎn)的各種性能指標(biāo)情況
curl -X GET "localhost:9200/_nodes/stats?pretty"

查詢節(jié)點(diǎn)信息

curl -X GET "localhost:9200/_nodes?pretty"

集群磁盤(pán)分布情況

curl http://127.0.0.1:9200/_cat/allocation?v

修改索引允許動(dòng)態(tài)映射

-- 修改后插入文檔時(shí)索引遇到默認(rèn)字段會(huì)自動(dòng)修改mapping(表接口)
curl -XPUT "http://localhost:9200/index_name/type_name/_mapping" -H 'Content-Type: application/json' -d '{
    "dynamic": true
}'

修改索引為一個(gè)副本

curl -XPUT  "http://localhost:9200/index_name/_settings" -H 'Content-Type: application/json' -d '{"number_of_replicas":1}'

ES正在執(zhí)行的任務(wù)

curl -X GET 'localhost:9200/_tasks?pretty'
-- 取消正在執(zhí)行的任務(wù)
curl -X POST 'localhost:9200/_tasks/node_id:task_id/_cancel'
-- 過(guò)濾出正在執(zhí)行的查詢?nèi)蝿?wù)
curl -X GET 'localhost:9200/_tasks?actions=cluster:*&pretty'
curl -X GET 'localhost:9200/_tasks?actions=*&detailed&pretty'

任務(wù)管理API

分片狀態(tài)及管理

索引恢復(fù)進(jìn)度

curl localhost:9200/_cat/recovery?pretty&v
-- 查詢某個(gè)具體索引的恢復(fù)過(guò)程
curl localhost:9200/index_name/_recovery?pretty&v

節(jié)點(diǎn)自動(dòng)分配

查看是否自動(dòng)副本分配
-- 如修改副本數(shù)量后,索引為自動(dòng)均衡,可通過(guò)用此配置查詢
curl -XGET 'localhost:9200/_cluster/settings?pretty' -d '{
    "persistent": {},
    "transient": {
        "cluster": {
            "routing": {
                "allocation": {
                    "enable": "all"
                }
            }
        }
    }
}'
設(shè)置自動(dòng)分配分片
curl -XPUT 'localhost:9200/_cluster/settings' -d'{
    "transient": {
        "cluster.routing.allocation.enable": "all"
    }
}'

分片分布情況

curl localhost:9200/_cat/shards

索引分片同步列表

curl 'localhost:9200/_cluster/state?filter_path=metadata.indices.index_name.in_sync_allocations.*,routing_table.indices.index_name.*&pretty'

問(wèn)題定位

熱點(diǎn)線程查詢

curl -X GET "localhost:9200/_nodes/node_name1,node_name2/hot_threads"

查詢未分配索引的詳細(xì)解釋

curl localhost:9200/_cluster/allocation/explain

查詢節(jié)點(diǎn)線程池使用

curl -X GET "http://localhost:9200/_cat/thread_pool"

常用語(yǔ)法

ES查詢語(yǔ)法:QueryDSL

DSL:Domain specified language:特定領(lǐng)域的語(yǔ)言,使用http構(gòu)建復(fù)雜的請(qǐng)求體進(jìn)行查詢

查詢返回語(yǔ)法解釋

GET /index_name/type_name/_search
took 耗費(fèi)了多少毫秒
time_out 是否超時(shí)
_shards:數(shù)據(jù)拆分成了5個(gè)分片
hists.total:查詢結(jié)果的數(shù)量
hist.max_score:score的含義,就是document對(duì)于一個(gè)search的相關(guān)度的匹配分?jǐn)?shù),分?jǐn)?shù)越高,相關(guān)度越高
hits.hits:包含了匹配搜索的數(shù)據(jù)

查詢排序

-- 查詢index_name索引,按時(shí)間排序,默認(rèn)取前20條
curl -i -XGET 'http://localhost:9200/index_name/_search?sort=createTime:asc?pretty'

批量查詢 mget

 查詢不同index下的不同document
 GET /_mget 
 {
   "docs"  :[
     {
       "_index":"index_name",
       "_type":"type_name",
       "_id":1
     },{
       "_index":"index_name2",
       "_type":"type_name",
       "_id":2
     }
   ]
 }
 --查詢同一個(gè)index下的不同document
  GET /index_name/_mget
 {
   "docs"  :[
     {
       "_type":"type_name",
       "_id":1
     },{
       "_type":"type_name",
       "_id":2
     }
   ]
 }

bool查詢

bool查詢,組合查詢
復(fù)合子句可以合并多種子句為一個(gè)單一的查詢,無(wú)論是葉子子句還是其他的復(fù)合子句。
合并多子句
http://192.168.41.11:9200/index_name/type_name/_search
{
    "query":{
        "bool":{
            "must":{"match":{"type":"1"} },
            "must_not":{"match":{ "blockCode":"5201030003"}},
            "should":{"match":{ "doorName":"Openai大模型"} }
        }
    }
}

分頁(yè)查詢

{
    "query":{
        "bool":{
            "must":[
                {
                    "match":{"blockCode":"5201030003"}
                },
                {
                    "match":{"type":"23"}
                }
            ]
        }
    },
    "size":"2",
    "from":"0",
    "sort":{
        "createdDate":{
            "order":"desc"
        }
    }
}

ES分頁(yè)from默認(rèn)從0開(kāi)始,size默認(rèn)為10

深分頁(yè)問(wèn)題

deep paging:當(dāng)集群節(jié)點(diǎn)眾多,且分頁(yè)查詢的頁(yè)數(shù)過(guò)大時(shí),會(huì)很消耗服務(wù)器資源,如分頁(yè)from1000,size10 的分頁(yè)請(qǐng)求過(guò)來(lái)后,會(huì)將請(qǐng)求打到各個(gè)shard或者replica節(jié)點(diǎn)上,去取每個(gè)節(jié)點(diǎn)去10010條數(shù)據(jù)到coordinate結(jié)點(diǎn)上,10個(gè)節(jié)點(diǎn)共100100條進(jìn)行排序選出10條。

超時(shí)查詢

返回在指定超時(shí)時(shí)間內(nèi)查詢到的數(shù)據(jù),有可能數(shù)據(jù)沒(méi)有查詢完畢

curl localhost:9200/index_name/index_name/_search?timeout=1s

精確值查詢

term過(guò)濾:term主要用于精確匹配哪些值,比如數(shù)字,日期,布爾值或 not_analyzed的字符串,允許使用多個(gè)匹配條件

----條件查詢并排序
http://localhost:9200/index_name/type_name/_search
{
  "query":{
    :"match":{
      "residentId":"1234123"
    }
  },
  "sort":[{
    "createdDate":"desc"
  }]
}
-----全文檢索
http://localhost:9200/index_name/type_name/_search
{
    "query": {
        "match":{"photoLargeUuid":"84cb5b32 a195229e0a7d"}
    }
}
全文搜索會(huì)將查詢條件分割進(jìn)行組合查詢按權(quán)重排序
---phrase 查詢
短語(yǔ)全詞匹配

復(fù)合查詢

GET /item/_search
{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "brand": {
                            "query": "小米"
                        }
                    }
                },
                {
                    "term": {
                        "title": {
                            "value": "小米"
                        }
                    }
                }
            ]
        }
    }
}

更新語(yǔ)法

post /index_name/type_name/1/update
{
"doc":{
"residentId":"341234123412"
  }
 }

刪除語(yǔ)法

-- delete  post 刪除ID為796098575183802的記錄
curl -x delete http://localhost:9200/index_name/type_name/796098575183802
--delete post  刪除該索引index_name,謹(jǐn)慎執(zhí)行

curl -X DELETE "localhost:9200/index_name?pretty"

統(tǒng)計(jì)語(yǔ)法

統(tǒng)計(jì)索引條數(shù)

curl 'localhost:9200/index_name/_count?pretty'
curl 'localhost:9200/face_picture_index/_count?pretty'
curl 'localhost:9200/index_name/_count?pretty'

聚合統(tǒng)計(jì)

按類(lèi)型進(jìn)行統(tǒng)計(jì)

http://localhost:9200/index_name/type_name/_search
{
    "size":0,
    "aggs": {
        "group_by_type": {
            "terms": {
                "field": "type"
            }
        }
    }
}
-----聚合統(tǒng)計(jì),按月分段,以開(kāi)門(mén)方式為維度進(jìn)行統(tǒng)計(jì)
{
    "size":0,
    "aggs":{
        "group_by_date":{
            "range":{
                "field":"createdDate",
                "ranges":[
                    {"from":1555261319001,
                     "to":1557853319000
                    },{
                    "from":1552582919001,
                    "to":1555261319000
                    },{
                    "from":1550163719000,
                    "to":1552582919000}
                    ]
            },
            "aggs":{
                "group_by_type":{
                    "terms":{
                        "field":"type"
                    }
                }
            }
        }
    }
}

ES優(yōu)化

1. 慢查詢配置

curl -XPUT "http://localhost:9200/index_name/_settings" -H 'Content-Type: application/json' -d'{
    "index.search.slowlog.threshold.fetch.debug": "5s",
    "index.search.slowlog.threshold.query.warn": "5s",
    "index.indexing.slowlog.threshold.index.info": "5s",
    "index.indexing.slowlog.threshold.index.warn": "10s"
}'

配置慢查詢?nèi)罩?,將索引中的慢查詢,慢索引打印出?lái)

2. 索引配置優(yōu)化

數(shù)據(jù)量大的情況下:基于日期輪詢的索引可以每天生成一個(gè)索引,然后用別名關(guān)聯(lián),或者使用索引通配符匹配

3. 系統(tǒng)層面優(yōu)化

  1. 關(guān)閉swap,調(diào)整max open files
  2. http://dockone.io/article/505
  3. 調(diào)整shard數(shù),replica數(shù)
  4. elasticsearch三個(gè)重要的優(yōu)化 https://zhaoyanblog.com/archives/319.html

4. 結(jié)構(gòu)優(yōu)化

不需要排序聚合,不需要在腳本中訪問(wèn)的字段可以禁用doc_valus字段節(jié)省存儲(chǔ)空間

建議周期性的建立新索引

5. 寫(xiě)入速度優(yōu)化

  1. 加大 Translog Flush ,目的是降低 Iops(每秒讀寫(xiě)數(shù))、Writeblock。但是會(huì)降低實(shí)時(shí)性,需要接受一定概率的數(shù)據(jù)丟失(服務(wù)器斷電)
  2. 增加 Index Refresh 間隔,目的是減少 Segment Merge 的次數(shù)。
  3. 增長(zhǎng)索引刷新時(shí)間,默認(rèn)為1s,index_refresh_interval:120s
  4. 調(diào)整 Bulk 線程池和隊(duì)列。
  5. 優(yōu)化節(jié)點(diǎn)間的任務(wù)分布。

6. 定位cup過(guò)高

查看節(jié)點(diǎn)hot_threads

curl -X GET "localhost:9200/_cat/thread_pool"
curl -X GET "localhost:9200/_nodes/node-241/hot_threads"
curl -X GET "localhost:9200/_nodes/node-241,node-131/hot_threads"

active:當(dāng)前正在執(zhí)行任務(wù)的線程數(shù)量,queue:隊(duì)列中等待處理的請(qǐng)求數(shù)量,rejected:隊(duì)列已滿,請(qǐng)求被拒絕的次數(shù)。

7. ES寫(xiě)入數(shù)據(jù)過(guò)慢原因

  1. 隨著寫(xiě)入索引數(shù)據(jù)增多,單個(gè)shard數(shù)據(jù)量太大(超過(guò)50GB),導(dǎo)致寫(xiě)入速度變慢

  2. 隨著數(shù)據(jù)寫(xiě)入,segment合并變得頻繁,es節(jié)點(diǎn)負(fù)載變高

8.存儲(chǔ)優(yōu)化

強(qiáng)制段合并

elasticsearch刪除數(shù)據(jù)并未真正從磁盤(pán)進(jìn)行刪除已,而是將數(shù)據(jù)標(biāo)記為刪除,等到段合并時(shí)才會(huì)清楚標(biāo)記為刪除的數(shù)據(jù),強(qiáng)制Elasticsearch進(jìn)行段合并segment merging,Segment merging要消耗CPU,以及大量的I/O資源,所以一定要在你的ElasticSearch集群處于維護(hù)窗口期間,并且有足夠的I/O空間的

curl -XPOST 'http://localhost:9200/索引名稱/_forcemerge?only_expunge_deletes=true'

9. 節(jié)點(diǎn)內(nèi)存使用率過(guò)高原因

分段內(nèi)存一個(gè)Lucene分段就是一個(gè)完整的倒排索引,倒排索引由單詞詞典和倒排列表組成。在 Lucene 中,單詞詞典中的 FST 結(jié)構(gòu)會(huì)被加載到內(nèi)存。因此每個(gè)分段都會(huì)占用一定的內(nèi)存空間??梢酝ㄟ^(guò)下面的

API來(lái)查看所有節(jié)點(diǎn)上的所有分段占用的內(nèi)存總量:
curl -X GET "localhost:9200/_cat/nodes?v&h=segments.memory"

也可以單獨(dú)查看每個(gè)分段的內(nèi)存占用量:

curl  -X  GET  "localhost:9200/_cat/segments?v&h=index,shard,segment,size.memory"

查詢分片緩存請(qǐng)求大小, 默認(rèn)為堆1%大小

curl -X GET "localhost:9200/_stats/request_cache?pretty"

查詢節(jié)點(diǎn)查詢緩存占用大小,默認(rèn)為堆10%大小

curl -X GET "localhost:9200/_cat/nodes?v&h=query_cache.memory_size"

故障處理

1. 如何安全重啟elasticsearch?

https://www.elastic.co/guide/cn/elasticsearch/guide/current/_rolling_restarts.html

2. 重啟節(jié)點(diǎn)后有部分索引分片未能恢復(fù)

生產(chǎn)環(huán)境中有兩臺(tái)節(jié)點(diǎn),將主節(jié)點(diǎn)增加查詢最大限制數(shù)后重啟

indices.query.bool.max_clause_count: 10240

直接docker restart elasticsearch 后,重啟elasticsearch后,有一個(gè)索引長(zhǎng)期yellow,有兩個(gè)分片長(zhǎng)期處于未分配狀態(tài),es日志出現(xiàn)以下關(guān)鍵錯(cuò)誤日志

primary shard with sync id but number of docs differ: 7728586 (node-205-1, primary) vs 7728583(node-149-1) 

直接重啟節(jié)點(diǎn)后出現(xiàn)兩個(gè)節(jié)點(diǎn)的某個(gè)分片的數(shù)據(jù)不一致
解決:

將這個(gè)有問(wèn)題的索引修改副本數(shù)為0,再修改為1,待分配完后即可恢復(fù)

索引恢復(fù)(indices.recovery)是ES數(shù)據(jù)恢復(fù)過(guò)程,是集群?jiǎn)?dòng)過(guò)程中最緩慢的過(guò)程。集群完全重啟,或者M(jìn)aster節(jié)點(diǎn)掛掉后,新選出的Master也有可能執(zhí)行索引恢復(fù)過(guò)程。
待恢復(fù)的是哪些數(shù)據(jù)?是客戶端寫(xiě)入成功,但是未執(zhí)行刷盤(pán)(flush)的Lucene分段。
索引恢復(fù)有哪些好處?
保持?jǐn)?shù)據(jù)完整性:當(dāng)節(jié)點(diǎn)異常重啟時(shí),寫(xiě)入磁盤(pán)的數(shù)據(jù)先到文件系統(tǒng)的緩沖,未必來(lái)得及刷盤(pán)。如果不通過(guò)某種方式將未進(jìn)行刷盤(pán)的數(shù)據(jù)找回,則會(huì)丟失一些數(shù)據(jù)。
數(shù)據(jù)副本一致性:由于寫(xiě)入操作在多個(gè)分片副本上沒(méi)有來(lái)得及全部執(zhí)行,副分片需要同步成和主分片完全一致。

3. 生產(chǎn)環(huán)境某臺(tái)ES節(jié)點(diǎn)負(fù)載高原因:

未找到

4. profile定位查詢緩慢原因

curl -X GET "http://localhost:9200/index_name/type_name/_search?pretty" -d'{
"profile":true,
"query":{
     "match":{
        "blockCode":"5203210005"
        }
    }
}'

fielddata=true,以便通過(guò)取消倒排索引將fielddata加載到內(nèi)存中

ES官方解釋為在es5.x以后,聚合排序這種操作需使用指定數(shù)據(jù)結(jié)構(gòu)fieldData進(jìn)行單獨(dú)操作,需要單獨(dú)開(kāi)啟,ES排序field的類(lèi)型只支持text類(lèi)型

解決辦法如下兩步:

第二:mapping修改

PUT my_index/_mapping
{
  "properties": {
    "createTime": { 
      "type":     "text",
      "fielddata": true
    }
  }
}

5. 索引有多個(gè)副本但副本分片未自動(dòng)分配

問(wèn)題描述:新建索引時(shí)設(shè)置了0個(gè)副本,后來(lái)設(shè)置為1個(gè),但是集群沒(méi)有自動(dòng)分配分片,索引長(zhǎng)期為yellow

解決:查看集群設(shè)置是否自動(dòng)分配,是否為未設(shè)置自動(dòng)分配,設(shè)置為自動(dòng)分配

參考及推薦

ES中文使用向?qū)?/a>

Elasticsearch學(xué)習(xí)之集群常見(jiàn)狀況處理(干貨)

elasticsearch 百億級(jí)數(shù)據(jù)檢索案例與原理

Elasticsearch 集群內(nèi)應(yīng)該設(shè)置多少個(gè)分片

《Elasticsearch 源碼解析與優(yōu)化實(shí)戰(zhàn)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容