中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

成都模板建站代理seo站長工具下載

成都模板建站代理,seo站長工具下載,可信網(wǎng)站 認(rèn)證規(guī)則,圖片設(shè)計制作哪個軟件好手機前言 elastic表示可伸縮,search表示查詢。所以es的核心即為查詢。通常情況下,我們的數(shù)據(jù)可以分為三類:結(jié)構(gòu)化數(shù)據(jù)、非結(jié)構(gòu)化數(shù)據(jù)、半結(jié)構(gòu)化數(shù)據(jù)。 結(jié)構(gòu)化數(shù)據(jù):一般會用特定的結(jié)構(gòu)來組織和管理數(shù)據(jù),表現(xiàn)為二維表結(jié)構(gòu)。…

前言

elastic表示可伸縮,search表示查詢。所以es的核心即為查詢。通常情況下,我們的數(shù)據(jù)可以分為三類:結(jié)構(gòu)化數(shù)據(jù)、非結(jié)構(gòu)化數(shù)據(jù)、半結(jié)構(gòu)化數(shù)據(jù)。
結(jié)構(gòu)化數(shù)據(jù):一般會用特定的結(jié)構(gòu)來組織和管理數(shù)據(jù),表現(xiàn)為二維表結(jié)構(gòu)。這些數(shù)據(jù)信息一般是有關(guān)系的,所以可以保存到關(guān)系型數(shù)據(jù)庫如MySQL、Oracle中,并可以通過SQL語句來查詢。
– 優(yōu)點:方便管理、方便查詢。
– 缺點:擴展結(jié)構(gòu)較為困難。
非結(jié)構(gòu)化數(shù)據(jù):無法用二維表結(jié)構(gòu)來表現(xiàn)的數(shù)據(jù)。如日志、文檔、報表、圖片、視頻等。這種數(shù)據(jù)維度廣、數(shù)據(jù)量大,所以存儲和查詢的成本較大。一般會將這種數(shù)據(jù)保存到noSQL數(shù)據(jù)庫當(dāng)中,如redis、mongoDB、HBase。這種數(shù)據(jù)庫一般以 K-V 結(jié)構(gòu)保存,通過key來查詢數(shù)據(jù),相對較快。
半結(jié)構(gòu)化數(shù)據(jù):將數(shù)據(jù)的結(jié)構(gòu)和內(nèi)容混在一起,沒有明確的區(qū)分。如XML,一般保存在redis、mongoDB、HBase中。
– 缺點:不容易查詢內(nèi)容。
但是生活中很多情況下數(shù)據(jù)并非關(guān)系型結(jié)構(gòu)化的數(shù)據(jù),無法模糊查詢、也無法遍歷匹配。為了解決這種問題,于是有了es。

一、ElasticSearch概述

The Elastic Stack包括ElasticSearch、Kibana、Beats和Logstash。能夠安全可靠的獲取任何來源、任何格式的數(shù)據(jù),然后實時地對數(shù)據(jù)進行搜索、分析和可視化。ElasticSearch簡稱ES,是一個開源的高擴展的分布式全文搜索引擎,是整個Elastic Stack技術(shù)棧的核心。它可以近乎實時的存儲、檢索數(shù)據(jù)。

全文搜索引擎:

可以理解為全棧搜索。如在csdn中,用戶可以寫一些文章, 其他用戶根據(jù)內(nèi)容詞匯、關(guān)鍵字等進行搜索,查詢網(wǎng)站內(nèi)所有匹配的文章,并以列表的形式展現(xiàn)結(jié)果。傳統(tǒng)的數(shù)據(jù)庫進行這樣的檢索時效率較低。即使進行SQL的優(yōu)化,效果也不會有顯著變化。所以在生產(chǎn)環(huán)境中,這種常規(guī)的搜索方式效果較差。
這就需要我們采用專門用于全文搜索的搜索引擎。至于具體使用那種搜索引擎,需要考慮如下幾點進行分析:

  • 除了搜索文本之外,還需要服務(wù)器來處理分析查詢
  • 搜索服務(wù)器也需要是集群,而且可擴展
  • 對數(shù)據(jù)進行大量的分析,統(tǒng)計出不同的指標(biāo)

二、ElasticSearch使用

Windows版本的ES安裝很簡單,解壓即安裝完畢。解壓后,進入/bin目錄,點擊elasticsearch.bat文件啟動es服務(wù)。
在這里插入圖片描述

9300 端口為 ElasticSearch 集群間組件的通信端口
9200 端口為瀏覽器訪問的http協(xié)議 RESTful 端口

如果直接通過瀏覽器向 ElasticSearch 發(fā)送請求,那么需要在發(fā)送的請求中包含 HTTP 標(biāo)準(zhǔn)的方法,而 HTTP 的大部分特性僅支持GETPOST方法。為了方便的進行客戶端的訪問,可以使用Postman軟件。
Postman能夠發(fā)送任何類型的 HTTP 請求(GET, HEAD, POST, PUT…)不僅能夠表單提交,也可以附帶任何類型請求體。
在這里插入圖片描述

2.1 RESTful

es支持分布式、RESTful 風(fēng)格的搜索和分析,這就表示es允許采用RESTful風(fēng)格的方式發(fā)請求進行軟件訪問。RESTful(Representational State Transfer 資源狀態(tài)轉(zhuǎn)換)是一種軟件架構(gòu)風(fēng)格,比如 HTTP 就遵循了REST原則:
如在web中資源的唯一標(biāo)識是 URI(統(tǒng)一資源路徑)http://localhost:9200/test/test.txt 路徑中不包含對資源的操作,如增加、修改不應(yīng)該存在在路徑中。RESTful風(fēng)格架構(gòu)就要求遵循統(tǒng)一的接口原則,包含一組受限制的預(yù)定義操作,不論什么樣的資源都應(yīng)該通過使用相同的接口對資源進行訪問。這里的接口應(yīng)該符合標(biāo)準(zhǔn)HTTP方法,比如 GETPOST、PUTDELETE、HEAD等請求。
路徑是對資源的定位,方法是對資源的操作。按照HTTP的方法暴露資源,那資源將具有安全性冪等性的特性。如 GET、HEAD都是安全的,無論訪問多少次,都不會改變資源的狀態(tài)。PUT、DELETE都是冪等性的,無論對資源操作多少次,結(jié)果都是一樣的,后面的請求不會比第一回請求產(chǎn)生更多的影響。
所以當(dāng)我們采用RESTful風(fēng)格向es發(fā)出請求之后,es會返回相應(yīng),返回相應(yīng)的數(shù)據(jù)格式是JSON格式。我們可以在請求體中發(fā)送JSON格式的字符串給服務(wù)器,服務(wù)器拿到后做相應(yīng)的處理。所以es中數(shù)據(jù)的發(fā)送和數(shù)據(jù)的處理都是以JSON為標(biāo)準(zhǔn)格式的。
為什么采用JSON格式:因為JSON格式更容易轉(zhuǎn)換成字符串在網(wǎng)絡(luò)中傳遞,而且識別會更加容易。

2.2 客戶端 Postman

如果直接通過瀏覽器向ES服務(wù)器發(fā)送請求,那么需要在發(fā)送的請求中包含HTTP標(biāo)準(zhǔn)的方法,而HTTP的大部分特性僅支持 GETPOST 方法。所以為了能夠方便的進行客戶端的訪問,可以使用Postman軟件。Postman是一款網(wǎng)頁調(diào)試工具,能夠發(fā)送任何類型的HTTP請求(GET、HEAD、PSOT、PUT…)不僅能夠表單提交,且可以附帶任何類型請求體。

2.3 數(shù)據(jù)格式

ElasticSearch 是面向文檔型數(shù)據(jù)庫,一條數(shù)據(jù)就是一個文檔。ElasticSearch 里存儲文檔數(shù)據(jù)和關(guān)系型數(shù)據(jù)庫MySQL存儲數(shù)據(jù)的概念類比如下:
在這里插入圖片描述
在關(guān)系型數(shù)據(jù)庫中,索引是為了優(yōu)化查詢設(shè)計的數(shù)據(jù)庫對象。沒有索引也能進行檢索,只是速度會有所降低。而ES軟件專門用于全文檢索數(shù)據(jù),所以索引是整個搜索引擎中的關(guān)鍵。ES為了做到快速準(zhǔn)確的查詢,使用了一個特殊的概念來進行數(shù)據(jù)的存儲和查詢。我們稱之為倒排索引。

正排(正向)索引
在這里插入圖片描述

通過文章編號快速查詢到文章內(nèi)容。我們將文章編號設(shè)置為主鍵,同時生成主鍵索引。通過主鍵索引快速關(guān)聯(lián)到對應(yīng)信息。
在正排索引中,如果想要查詢文章中包含哪些熱門詞匯,會比較麻煩。我們需要做模糊查詢,而且對每條數(shù)據(jù)都需要進行遍歷,效率明顯下降。且查詢內(nèi)容的大小寫、時態(tài)等因素都會影響準(zhǔn)確率。此時需要換種方式來將索引和數(shù)據(jù)關(guān)聯(lián)。

倒排索引
在這里插入圖片描述
與以往的查詢方式相反(通過主鍵ID關(guān)聯(lián)文件內(nèi)容,再查詢關(guān)鍵字)。倒排索引是通過關(guān)鍵字查詢主鍵ID,再關(guān)聯(lián)文章內(nèi)容,查詢效率較快。
倒排索引中,強調(diào)關(guān)鍵字文檔編號的關(guān)聯(lián),表的作用反而不那么明顯。所以在 ES7.x 中,Type的概念被刪除。

2.2 HTTP操作

2.2.1 索引操作

1)創(chuàng)建索引

對比關(guān)系型數(shù)據(jù)庫,創(chuàng)建索引就等同于創(chuàng)建數(shù)據(jù)庫。在MySQL中對數(shù)據(jù)進行操作,需要知道連接的數(shù)據(jù)庫database和對應(yīng)的表,在es中叫Index索引

在 Postman 中,向ES服務(wù)器發(fā) PUT 請求:http://127.0.0.1:9200/shopping
在這里插入圖片描述
acknowledge:true 響應(yīng)成功
index:shopping 當(dāng)前索引為shopping
PUT具有冪等性,所以發(fā)出同樣的請求,結(jié)果是一樣的。而POST不具有冪等性,兩次操作的結(jié)果可能不一樣。

PUT 和 PUSH 的區(qū)別:
PUT
PUT請求用于在Elasticsearch中創(chuàng)建或更新一個文檔。當(dāng)使用PUT請求時,需要指定文檔的唯一標(biāo)識符(ID),然后提供文檔的內(nèi)容。如果指定的文檔ID已存在,Elasticsearch將更新該文檔;如果文檔ID不存在,它將創(chuàng)建一個新的文檔。
PUSH
Push是一種與索引或更新具有一定關(guān)聯(lián)的操作無關(guān)的API。它允許向特定字段添加新的元素。該API用于數(shù)組類型的字段,例如nested字段或array字段。使用Push可以向現(xiàn)有文檔字段添加新的元素,而不必使用GET和PUT來檢索和創(chuàng)建整個文檔。

2)查看所有索引

GET 獲取索引的相關(guān)信息
在這里插入圖片描述

在Postman中,向ES服務(wù)器發(fā)GET請求: http://127.0.0.1:9200/_cat/indices?v

3)查看單個索引

在Postman中,向服務(wù)器發(fā)GET請求:http://127.0.0.1:9200/shopping

{"shopping"【索引名】: { "aliases"【別名】: {},"mappings"【映射】: {},"settings"【設(shè)置】: {"index"【設(shè)置 - 索引】: {"creation_date"【設(shè)置 - 索引 - 創(chuàng)建時間】: "1614265373911","number_of_shards"【設(shè)置 - 索引 - 主分片數(shù)量】: "1","number_of_replicas"【設(shè)置 - 索引 - 副分片數(shù)量】: "1","uuid"【設(shè)置 - 索引 - 唯一標(biāo)識】: "eI5wemRERTumxGCc1bAk2A","version"【設(shè)置 - 索引 - 版本】: {"created": "7080099"},"provided_name"【設(shè)置 - 索引 - 名稱】: "shopping"}}}
}

4)刪除索引

在Postman中,向ES服務(wù)器發(fā)DELETE請求:http://127.0.0.1:9200/shopping
重新訪問索引時,服務(wù)器返回響應(yīng):索引不存在。

2.2.2 文檔操作

1)創(chuàng)建文檔

在Postman中,向ES服務(wù)器發(fā)POST請求:http://127.0.0.1:9200/shopping/_doc
注意,此處發(fā)送請求的方式必須是POST,不能是PUT,不然會發(fā)生錯誤。這是由于數(shù)據(jù)創(chuàng)建成功之后,會返回一個 id ,可以認(rèn)為是剛剛創(chuàng)建數(shù)據(jù)的標(biāo)識,由es軟件隨機生成。所以同樣的請求多次執(zhí)行之后,返回的結(jié)果不一樣。
所以 POST 不是冪等性,但 PUT 操作必須是冪等性的,所以不能使用 PUT 操作。

{"title":"小米手機","category":"小米","images":"http://www.gulixueyuan.com/xm.jpg","price":3999.00
}

服務(wù)器相應(yīng)結(jié)果如下:

{"_index"【索引】: "shopping","_type"【類型-文檔】: "_doc","_id"【唯一標(biāo)識】: "Xhsa2ncBlvF_7lxyCE9G", #可以類比為 MySQL 中的主鍵,隨機生成"_version"【版本】: 1,"result"【結(jié)果】: "created", #這里的 create 表示創(chuàng)建成功"_shards"【分片】: {"total"【分片 - 總數(shù)】: 2,"successful"【分片 - 成功】: 1,"failed"【分片 - 失敗】: 0},"_seq_no": 0,"_primary_term": 1
}

自定義id:http://127.0.0.1:9200/shopping/_doc/1001
如果采用上面的方式提交兩次 PUSH 請求操作,那么該操作也是冪等性的,相當(dāng)于 PUT 操作。也就是說,如果增加數(shù)據(jù)時明確數(shù)據(jù)主鍵,那么請求方式也可以是PUT
或者,為了明確當(dāng)前的操作是新增,可以把_doc改為 _createhttp://127.0.0.1:9200/shopping/_create/1002

2)查看文檔

<1> 主鍵查詢

可以用 GET 的方式發(fā)送一條新的請求即可:http://127.0.0.1:9200/shopping/_doc/1001

<2> 全量查詢

上面的查詢語句中,1001類似主鍵,結(jié)果就類似于主鍵查詢的結(jié)果。
一個主鍵id只能獲取一條數(shù)據(jù)。如果想要查詢索引下面的所有數(shù)據(jù),可以采用:http://127.0.0.1:9200/shopping/_search

3)修改文檔

完全覆蓋性的修改,具有冪等性,可以使用PUT方法進行操作。http://127.0.0.1:9200/shopping/_doc
在這里插入圖片描述

{"title":"小米手機","category":"小米","images":"http://www.gulixueyuan.com/xm.jpg","price":4999.00
}

4)修改字段

局部數(shù)據(jù)需要更新時,由于每次更新的結(jié)果不一樣,所以不是冪等性,不能用PUT方式,只能用POST方式。http://127.0.0.1:9200/shopping/_update/1001

{"doc":{"title":"華為手機"}
}

在命令行中需要明確對誰進行修改,所以需要使用命令_update,如果使用_doc,可能會被認(rèn)為是新增。

5)刪除文檔(字段)

使用DELETE方法,http://127.0.0.1:9200/shopping/_doc/1001

2.2.3 映射操作

有的查詢可以分詞查詢,有的不能,必須全部匹配。在MySQL中,一個表的字段、類型、長度信息都屬于表的結(jié)構(gòu)信息,在es中也有類似概念,稱為映射。
創(chuàng)建映射PUThttp://127.0.0.1:9200/user/_mapping

{"properties" : {"name" : {"type" : "text",	// 可以分詞"index" : "true"	// 可以被索引},"sex" : {"type" : "keyword",	// 不能分詞,必須完整匹配"index" : "true"},"tel" : {"type" : "keyword","index" : "false"	// 不能被索引},}
}

2.2.4 高級查詢

1)條件查詢

請求路徑:GEThttp://127.0.0.1:9200/shopping/_search?q=category:小米
請求體:GEThttp://127.0.0.1:9200/shopping/_search
【Body -> row -> JSON】

// 條件查詢
{"query" : {"match" : {"category" : "小米"}}
}// 全量查詢
{"query" : {"match_all" : {}}
}// 分頁查詢
{"query" : {"match" : {"category" : "小米"},"from" : 0,"size" : 2	//每頁查詢的數(shù)據(jù)2條}
}// 指定查詢字段
{"query" : {"match" : {"category" : "小米"},"from" : 0,"size" : 2,"_source" : ["title"]	// 指定title字段}
}// 查詢排序
{"query" : {"match" : {"category" : "小米"},"from" : 0,"size" : 2,"_source" : ["title"],"sort" : {"price" : {"order" : "desc"}}}
}// 多條件查詢 邏輯與&& = must,邏輯或|| = should
// 小米手機,且價格=1999
{"query" : {"bool" : {"must" : [{"match" : {"catatory" : "小米"}},{"match" : {"price" : "1999.00"}}]}
}
// 小米或華為手機
{"query" : {"bool" : {"should" : [{"match" : {"catatory" : "小米"}},{"match" : {"catatory" : "華為"}}]}
}// 范圍查詢
{"query" : {"bool" : {"should" : [{"match" : {"catatory" : "小米"}},{"match" : {"catatory" : "華為"}},"filter" : {"range" : {"price" : {"gt" : 5000	// 價格大于5000}}}]}
}// 模糊查詢(全文檢索)
// 文字即使不正確,也能查詢出數(shù)據(jù)。保存文檔數(shù)據(jù)時,es會對文檔進行分詞拆解,并將拆解后的數(shù)據(jù)保存到倒排索引中。所以即使使用文字的一部分,也能檢索到數(shù)據(jù)。這種檢索方式就稱為全文檢索。
{"query" : {"match" : {"category" : "米"}}
}// 完全匹配
{"query" : {"match_phrase" : {"category" : "米"}}
}// 高亮顯示
{"query" : {"match_phrase" : {"category" : "米"}},"highliaht" : {"fields" : {"cayegory" : {}}}
}

在這里插入圖片描述

2)聚合查詢

// 聚合查詢
{"aggs" : {"price_group" : {	// 名稱,隨意起名"terms" : {	// 分組"field" : "price"	// 分組字段}}},"size" : 0	// 只返回聚合結(jié)果而不返回具體的文檔數(shù)據(jù)
}

這里的terms是一個聚合類型(aggregation type),用于對指定字段進行分組。比如價格為“1999”的商品數(shù)量為1,價格為“2999”的商品數(shù)量為3。

terms可以換成其他聚合類型,如: “sum” (求和聚合):用于對指定字段的值進行求和操作。它會計算指定字段值的總和。
"avg"(平均值聚合):用于對指定字段的值進行平均值計算。它會計算指定字段值的平均值。
"max"(最大值聚合):用于查找指定字段的最大值。它會返回指定字段中的最大值。
"min"(最小值聚合):用于查找指定字段的最小值。它會返回指定字段中的最小值。
"count"(計數(shù)聚合):用于計算文檔數(shù)量。它會返回匹配指定條件的文檔數(shù)量。
"date_histogram"(日期直方圖聚合):用于按時間范圍對文檔進行分組,并統(tǒng)計每個時間范圍內(nèi)的文檔數(shù)量。

2.2.5 Java API操作

準(zhǔn)備操作

pom依賴

<dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!-- elasticsearch 的客戶端 --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.8.0</version></dependency><!-- elasticsearch 依賴 2.x 的 log4j --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.8.2</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.8.2</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.9</version></dependency><!-- junit 單元測試 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
</dependencies>

創(chuàng)建ES客戶端

// 創(chuàng)建客戶端對象
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
...
// 關(guān)閉客戶端連接
client.close();

注意:9200 端口為 Elasticsearch 的 Web 通信端口,localhost 為啟動 ES 服務(wù)的主機名

1)索引

1. 創(chuàng)建索引
// 創(chuàng)建索引 - 請求對象
CreateIndexRequest request = new CreateIndexRequest("user");// 發(fā)送請求,獲取響應(yīng)
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
boolean acknowledged = response.isAcknowledged();// 響應(yīng)狀態(tài)
System.out.println("操作狀態(tài) = " + acknowledged);
2. 查詢索引
// 查詢索引 - 請求對象
GetIndexRequest request = new GetIndexRequest("user");// 發(fā)送請求,獲取響應(yīng)
GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
System.out.println("aliases:"+response.getAliases());
System.out.println("mappings:"+response.getMappings());	// 查看索引結(jié)構(gòu)
System.out.println("settings:"+response.getSettings());	// 查看配置
3. 刪除索引
// 刪除索引 - 請求對象
DeleteIndexRequest request = new DeleteIndexRequest("user");
// 發(fā)送請求,獲取響應(yīng)
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
// 操作結(jié)果
System.out.println("操作結(jié)果 : " + response.isAcknowledged());

2)文檔

1. 新增 / 批量新增
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http"))
);// 新增文檔 - 請求對象
IndexRequest request = new IndexRequest();
// 設(shè)置索引及唯一性標(biāo)識
request.index("user").id("1001");// 創(chuàng)建數(shù)據(jù)對象
User user = new User();
user.setName("zhangsan");
user.setAge(30);
user.setSex("男");// 向ES插入數(shù)據(jù),必須將數(shù)據(jù)轉(zhuǎn)換成JSON格式
ObjectMapper mapper = new ObjectMapper();
String userJson = mapper.writeValueAsString(user);
// 添加文檔數(shù)據(jù),數(shù)據(jù)格式為 JSON 格式
request.source(userJson, XContentType.JSON);
// 客戶端發(fā)送請求,獲取響應(yīng)對象
IndexResponse reponse = client.index(request, RequestOptions.DEFAULT);// 打印結(jié)果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());client.close();

批量新增

RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http"))
);// 批量新增數(shù)據(jù)
BulkRequest request = new BulkRequest();
request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "zhangsan"));
request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "lisi"));// 客戶端發(fā)送請求,獲取響應(yīng)對象
BulkResponse responses = client.bult(request, RequestOptions.DEFAULT);//打印結(jié)果信息
System.out.println("took:" + responses.getTook());
System.out.println("items:" + responses.getItems());client.close();
2. 修改
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http"))
);// 新增文檔 - 請求對象
UpdateRequest request = new UpdatRequest();
// 設(shè)置索引及唯一性標(biāo)識
request.index("user").id("1001");
request.dox(XContentType.JSON, "sex", "女");// 客戶端發(fā)騷那個請求,獲取響應(yīng)對象
UpdatResponse reponse = client.update(request, RequestOptions.DEFAULT);// 打印結(jié)果信息
System.out.println("_result:" + response.getResult());client.close();
3. 查詢
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http"))
);//1.創(chuàng)建請求對象
GetRequest request = new GetRequest().index("user").id("1001");//2.客戶端發(fā)送請求,獲取響應(yīng)對象
GetResponse response = client.get(request, RequestOptions.DEFAULT);//3.打印結(jié)果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_type:" + response.getType());
System.out.println("_id:" + response.getId());
System.out.println("source:" + response.getSourceAsString());client.close();
4. 刪除 / 批量刪除
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http"))
);//1.創(chuàng)建請求對象
DeleteRequest request = new DeleteRequest().index("user").id("1001");//2.客戶端發(fā)送請求,獲取響應(yīng)對象
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);//3.打印結(jié)果信息
System.out.println("source:" + response.toString());client.close();

批量刪除

RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http"))
);// 批量刪除數(shù)據(jù)
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest().index("user").id("1001"));
request.add(new DeleteRequest().index("user").id("1002"));// 客戶端發(fā)送請求,獲取響應(yīng)對象
BulkResponse responses = client.bult(request, RequestOptions.DEFAULT);//打印結(jié)果信息
System.out.println("took:" + responses.getTook());
System.out.println("items:" + responses.getItems());client.close();
5. 高級查詢
全量查詢
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http"))
);// 1. 全量查詢:matchAllQuery
SearchRequest request = new SearchRequest();
request.indices("user");request.source(new SearchSourceBuilder.query(QueryBuilders.matchAllQuery()));SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 2. 條件查詢:termQuery
SearchRequest request = new SearchRequest();
request.indices("user");request.source(new SearchSourceBuilder.query(QueryBuilders.termQuery("age", 30)));SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 3. 分頁查詢
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder.query(QueryBuilders.matchAllQuery());
builder.from(0);
builder.size(2);
request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 4. 查詢排序
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder.query(QueryBuilders.matchAllQuery());
builder.sort("age", SortOrder.DESC);
request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 5. 過濾字段
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder.query(QueryBuilders.matchAllQuery());
String excludes = {"age"};
String indludes = {"name"}
builder.fetchSource(indludes, excludes );
request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 6. 組合查詢
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));
boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "男"));builder.query(boolQueryBuilder);request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 7. 范圍查詢
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder();
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");rangeQueryBuilder.gte(30)
rangeQueryBuilder.lte(40);builder.query(rangeQueryBuilder);request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 8. 模糊查詢
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.fuzzyQuery("name","wangwu").fuzziness(Fuzziness.ONE));request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 9. 高亮查詢
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder();
TermsQueryBuilders termsQueryBuilder = QueryBuilders.termQuery("name", "zhangsan");HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font color='red'>");
highlightBuilder.postTags("<font color='red'>");
highlightBuilder.field("name");
// 設(shè)置高亮構(gòu)建對象
builder.highlighter(highlightBuilder);
builder.query(termsQueryBuilder);request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 10. 聚合查詢
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder();AggregationBuilder aggregationBuilder = AggregationBuilders.max("max_age").filed("age");
builder.aggregation(aggregationBuilder );builder.query(termsQueryBuilder);request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}// 11. 分組查詢
SearchRequest request = new SearchRequest();
request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder();AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").filed("age");
builder.aggregation(aggregationBuilder );builder.query(termsQueryBuilder);request.source(builder);
SearchResponse response= client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();System.out.println("source:" + response.getHits());for( SearchHit hit : hits ) {System.out.println(hit.getSourceAsString());
}client.close();

三、進階

3.1 概念

1. 索引(Index)

一個索引就是一個擁有幾分相似特征的文檔的集合。比如說,你可以有一個客戶數(shù)據(jù)的索引,另一個產(chǎn)品目錄的索引,還有一個訂單數(shù)據(jù)的索引。一個索引由一個名字來標(biāo)識(必須全部是小寫字母),并且當(dāng)我們要對這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字。在一個集群中,可以定義任意多的索引。
能搜索的數(shù)據(jù)必須索引,這樣的好處是可以提高查詢速度,比如:新華字典前面的目錄就是索引的意思,目錄可以提高查詢速度。

Elasticsearch 索引的精髓:一切設(shè)計都是為了提高搜索的性能。

2. 類型(Type)

7.x 之后默認(rèn)不再支持自定義索引類型(默認(rèn)類型為:_doc)

3. 文檔(Document)

一個文檔是一個可被索引的基礎(chǔ)信息單元,也就是一條數(shù)據(jù)。
比如:你可以擁有某一個客戶的文檔,某一個產(chǎn)品的一個文檔,當(dāng)然,也可以擁有某個訂單的一個文檔。文檔以 JSON(Javascript Object Notation)格式來表示,而 JSON 是一個到處存在的互聯(lián)網(wǎng)數(shù)據(jù)交互格式。
在一個 index/type 里面,可以存儲任意多的文檔。

4. 字段(Filed)

相當(dāng)于是數(shù)據(jù)表的字段,對文檔數(shù)據(jù)根據(jù)不同屬性進行的分類標(biāo)識。

5. 映射(Mapping)

mapping 是處理數(shù)據(jù)的方式和規(guī)則方面做一些限制,如:某個字段的數(shù)據(jù)類型、默認(rèn)值、分析器、是否被索引等等。這些都是映射里面可以設(shè)置的,其它就是處理 ES 里面數(shù)據(jù)的一些使用規(guī)則設(shè)置也叫做映射,按著最優(yōu)規(guī)則處理數(shù)據(jù)對性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能對性能更好。

6. 分片(Shards)

可以理解成MySQL數(shù)據(jù)庫中的分表。
一個索引可以存儲超出單個節(jié)點硬件限制的大量數(shù)據(jù)。比如,一個具有 10 億文檔數(shù)據(jù)的索引占據(jù) 1TB 的磁盤空間,而任一節(jié)點都可能沒有這樣大的磁盤空間?;蛘邌蝹€節(jié)點處理搜索請求,響應(yīng)太慢。為了解決這個問題,Elasticsearch 提供了將索引劃分成多份的能力,每一份就稱之為分片。當(dāng)你創(chuàng)建一個索引的時候,你可以指定你想要的分片的數(shù)量。每個分片本身也是一個功能完善并且獨立的“索引”,這個“索引”可以被放置到集群中的任何節(jié)點上。

分片很重要,主要有兩方面的原因:
1)允許你水平分割 / 擴展你的內(nèi)容容量。
2)允許你在分片之上進行分布式的、并行的操作,進而提高性能/吞吐量。
至于一個分片怎樣分布,它的文檔怎樣聚合和搜索請求,是完全由 Elasticsearch 管理的,對于作為用戶來說,這些都是透明的,無需過分關(guān)心。

7. 副本(Replicas)

在一個網(wǎng)絡(luò) / 云的環(huán)境里,失敗隨時都可能發(fā)生,在某個分片/節(jié)點不知怎么的就處于離線狀態(tài),或者由于任何原因消失了,這種情況下,有一個故障轉(zhuǎn)移機制是非常有用并且是強烈推薦的。為此目的,Elasticsearch 允許你創(chuàng)建分片的一份或多份拷貝,這些拷貝叫做復(fù)制分片(副本)。

復(fù)制分片之所以重要,有兩個主要原因:
在分片/節(jié)點失敗的情況下,提供了高可用性。因為這個原因,注意到復(fù)制分片從不與原/主要(original/primary)分片置于同一節(jié)點上是非常重要的。
擴展你的搜索量/吞吐量,因為搜索可以在所有的副本上并行運行。

分配分片和副本

{"settings" : {"number_of_shards" : 3,"number_of_replicas" : 1}
}

8. 分配(Allocation)

將分片分配給某個節(jié)點的過程,包括分配主分片或者副本。如果是副本,還包含從主分片復(fù)制數(shù)據(jù)的過程。這個過程是由 master 節(jié)點完成的。

3.2 系統(tǒng)框架

在這里插入圖片描述
一個運行中的 Elasticsearch 實例稱為一個節(jié)點,而集群是由一個或者多個擁有相同cluster.name 配置的節(jié)點組成, 它們共同承擔(dān)數(shù)據(jù)和負(fù)載的壓力。當(dāng)有節(jié)點加入集群中或者從集群中移除節(jié)點時,集群將會重新平均分布所有的數(shù)據(jù)。
作為用戶,我們可以將請求發(fā)送到集群中的任何節(jié)點 ,包括主節(jié)點。 每個節(jié)點都知道任意文檔所處的位置,并且能夠?qū)⑽覀兊恼埱笾苯愚D(zhuǎn)發(fā)到存儲我們所需文檔的節(jié)點。 無論我們將請求發(fā)送到哪個節(jié)點,它都能負(fù)責(zé)從各個包含我們所需文檔的節(jié)點收集回數(shù)據(jù),并將最終結(jié)果返回給客戶端。 Elasticsearch 當(dāng)一個節(jié)點被選舉成為主節(jié)點時, 它將負(fù)責(zé)管理集群范圍內(nèi)的所有變更,例如增加、刪除索引,或者增加、刪除節(jié)點等。 而主節(jié)點并不需要涉及到文檔級別的變更和搜索等操作,所以當(dāng)集群只擁有一個主節(jié)點的情況下,即使流量的增加它也不會成為瓶頸。 任何節(jié)點都可以成為主節(jié)點。我們的示例集群就只有一個節(jié)點,所以它同時也成為了主節(jié)點。對這一切的管理都是透明的。

寫流程

新建、索引和刪除 請求都是 操作, 必須在主分片上面完成之后才能被復(fù)制到相關(guān)的副本分片。
在這里插入圖片描述

參數(shù):consistency
含義:consistency,即一致性。在默認(rèn)設(shè)置下,即使僅僅是在試圖執(zhí)行一個_寫_操作之前,主分片都會要求 必須要有 規(guī)定數(shù)量(quorum)(或者換種說法,也即必須要有大多數(shù))的分片副本處于活躍可用狀態(tài),才會去執(zhí)行_寫_操作(其中分片副本可以是主分片或者副本分片)。這是為了避免在發(fā)生網(wǎng)絡(luò)分區(qū)故障(network partition)的時候進行_寫_操作,進而導(dǎo)致數(shù)據(jù)不一致。_規(guī)定數(shù)量_即:
int( (primary + number_of_replicas) / 2 ) + 1
consistency 參數(shù)的值可以設(shè)為 one (只要主分片狀態(tài) ok 就允許執(zhí)行_寫_操作),all(必須要主分片和所有副本分片的狀態(tài)沒問題才允許執(zhí)行_寫_操作), 或quorum 。默認(rèn)值為 quorum , 即大多數(shù)的分片副本狀態(tài)沒問題就允許執(zhí)行_寫_操作。
注意,規(guī)定數(shù)量 的計算公式中 number_of_replicas 指的是在索引設(shè)置中的設(shè)定副本分片數(shù),而不是指當(dāng)前處理活動狀態(tài)的副本分片數(shù)。如果你的索引設(shè)置中指
定了當(dāng)前索引擁有三個副本分片,那規(guī)定數(shù)量的計算結(jié)果即:
int( (primary + 3 replicas) / 2 ) + 1 = 3
如果此時你只啟動兩個節(jié)點,那么處于活躍狀態(tài)的分片副本數(shù)量就達不到規(guī)定數(shù)量,也因此您將無法索引和刪除任何文檔。

參數(shù):timeout
含義:如果沒有足夠的副本分片會發(fā)生什么? Elasticsearch 會等待,希望更多的分片出現(xiàn)。默認(rèn)情況下,它最多等待 1 分鐘。 如果你需要,你可以使用 timeout 參數(shù)使它更早終止: 100 100 毫秒,30s 是 30 秒。

讀流程在這里插入圖片描述

更新流程

部分更新一個文檔結(jié)合了先前說明的讀取和寫入流程,步驟如下:
在這里插入圖片描述

  1. 客戶端向 Node 1 發(fā)送更新請求。
  2. 它將請求轉(zhuǎn)發(fā)到主分片所在的 Node 3 。
  3. Node 3 從主分片檢索文檔,修改 _source 字段中的 JSON ,并且嘗試重新索引主分片的文檔。如果文檔已經(jīng)被另一個進程修改,它會重試步驟 3 ,超過 retry_on_conflict 次后放棄。
  4. 如果 Node 3 成功地更新文檔,它將新版本的文檔并行轉(zhuǎn)發(fā)到 Node 1 和 Node 2 上的副本分片,重新建立索引。一旦所有副本分片都返回成功, Node 3 向協(xié)調(diào)節(jié)點也返回成功,協(xié)調(diào)節(jié)點向客戶端返回成功。

分片原理

傳統(tǒng)的數(shù)據(jù)庫每個字段存儲單個值,但這對全文檢索并不夠。文本字段中的每個單詞需
要被搜索,對數(shù)據(jù)庫意味著需要單個字段有索引多值的能力。最好的支持是一個字段多個值
需求的數(shù)據(jù)結(jié)構(gòu)是倒排索引。

倒排索引

Elasticsearch 使用一種稱為倒排索引的結(jié)構(gòu),它適用于快速的全文搜索。
所謂的正向索引,就是搜索引擎會將待搜索的文件都對應(yīng)一個文件 ID,搜索時將這個ID 和搜索關(guān)鍵字進行對應(yīng),形成 K-V 對,然后對關(guān)鍵字進行統(tǒng)計計數(shù)。
在這里插入圖片描述

但是互聯(lián)網(wǎng)上收錄在搜索引擎中的文檔的數(shù)目是個天文數(shù)字,這樣的索引結(jié)構(gòu)根本無法滿足實時返回排名結(jié)果的要求。所以,搜索引擎會將正向索引重新構(gòu)建為倒排索引,即把文件ID對應(yīng)到關(guān)鍵詞的映射轉(zhuǎn)換為關(guān)鍵詞到文件ID的映射,每個關(guān)鍵詞都對應(yīng)著一系列的文件,這些文件中都出現(xiàn)這個關(guān)鍵詞。一個倒排索引由文檔中所有不重復(fù)詞的列表構(gòu)成,對于其中每個詞,有一個包含它的文檔列表。
在這里插入圖片描述

文檔搜索

早期的全文檢索會為整個文檔集合建立一個很大的倒排索引并將其寫入到磁盤。 一旦新的索引就緒,舊的就會被其替換,這樣最近的變化便可以被檢索到。
倒排索引被寫入磁盤后是 不可改變 的:它永遠不會修改。

動態(tài)更新索引

如何在保留不變性的前提下實現(xiàn)倒排索引的更新?答案是: 用更多的索引。通過增加新的補充索引來反映新近的修改,而不是直接重寫整個倒排索引。每一個倒排索引都會被輪流查詢到,從最早的開始查詢完后再對結(jié)果進行合并。

文檔分析

首先我們通過 Postman 發(fā)送 GET 請求查詢分詞效果

# GET http://localhost:9200/_analyze
{"text":"測試單詞"
}

ES 的默認(rèn)分詞器無法識別中文中測試、單詞這樣的詞匯,而是簡單的將每個字拆完分為一個詞。這樣的結(jié)果顯然不符合我們的使用要求,所以我們需要下載 ES 對應(yīng)版本的中文分詞器。我們這里采用 IK 中文分詞器,下載地址為:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.8.0
將解壓后的后的文件夾放入 ES 根目錄下的 plugins 目錄下,重啟 ES 即可使用。我們這次加入新的查詢參數(shù)"analyzer":"ik_max_word

# GET http://localhost:9200/_analyze
{"text":"測試單詞","analyzer":"ik_max_word"
}// ik_max_word:會將文本做最細粒度的拆分
// ik_smart:會將文本做最粗粒度的拆分

ES 中也可以進行擴展詞匯,首先進入 ES 根目錄中的 plugins 文件夾下的 ik 文件夾,進入 config 目錄,創(chuàng)建 custom.dic文件,寫入 單詞 。同時打開 IKAnalyzer.cfg.xml 文件,將新建的 custom.dic 配置其中,重啟 ES 服務(wù)器。
在這里插入圖片描述

自定義分析器

# PUT http://localhost:9200/my_index
{"settings": {"analysis": {"char_filter": {"&_to_and": {"type": "mapping","mappings": [ "&=> and "]}},"filter": {"my_stopwords": {"type": "stop","stopwords": [ "the", "a" ]}},"analyzer": {"my_analyzer": {"type": "custom","char_filter": [ "html_strip", "&_to_and" ],"tokenizer": "standard","filter": [ "lowercase", "my_stopwords" ]}}
}}}

結(jié)果展示:

{"tokens": [{"token": "quick","start_offset": 4,"end_offset": 9,"type": "<ALPHANUM>","position": 1},{"token": "and","start_offset": 10,"end_offset": 11,"type": "<ALPHANUM>","position": 2},{"token": "brown","start_offset": 12,"end_offset": 17,"type": "<ALPHANUM>","position": 3},{"token": "fox","start_offset": 18,"end_offset": 21,"type": "<ALPHANUM>","position": 4}]
}

文檔處理

當(dāng)我們使用 index API 更新文檔 ,可以一次性讀取原始文檔,做我們的修改,然后重新索引 整個文檔 。 最近的索引請求將獲勝:無論最后哪一個文檔被索引,都將被唯一存儲在 Elasticsearch 中。如果其他人同時更改這個文檔,他們的更改將丟失。在數(shù)據(jù)庫領(lǐng)域中,有兩種方法通常被用來確保并發(fā)更新時變更不會丟失:悲觀并發(fā)控制、樂觀并發(fā)控制

樂觀并發(fā)控制
當(dāng)我們之前討論 index ,GET 和 delete 請求時,我們指出每個文檔都有一個_version(版本)號,當(dāng)文檔被修改時版本號遞增。 Elasticsearch 使用這個 version 號來確保變更以正確順序得到執(zhí)行。如果舊版本的文檔在新版本之后到達,它可以被簡單的忽略。我們可以利用 version 號來確保應(yīng)用中相互沖突的變更不會導(dǎo)致數(shù)據(jù)丟失。我們通過指定想要修改文檔的 version 號來達到這個目的。 如果該版本不是當(dāng)前版本號,我們的請求將會失敗。
老的版本 es 使用 version,但是新版本不支持了,會報下面的錯誤,提示我們用 if_seq_noif_primary_term。
POST: http://127.0.0.1:9200/shopping/_doc/1001?if_seq_no=0&if_primary_term=0

外部系統(tǒng)版本控制
如果你的主數(shù)據(jù)庫已經(jīng)有了版本號 — 或一個能作為版本號的字段值比如 timestamp?—那么你就可以在 Elasticsearch 中通過增加 version_type=external 到查詢字符串的方式重用這些相同的版本號, 版本號必須是大于零的整數(shù), 且小于 9.2E+18?— 一個 Java 中 long類型的正值。
外部版本號的處理方式和我們之前討論的內(nèi)部版本號的處理方式有些不同,Elasticsearch 不是檢查當(dāng)前 _version 和請求中指定的版本號是否相同, 而是檢查當(dāng)前_version 是否 小于 指定的版本號。 如果請求成功,外部的版本號作為文檔的新 _version 進行存儲。
POST: http://127.0.0.1:9200/shopping/_doc/1001?version=3&version_type=external

四、框架集成

Spring Data 框架基礎(chǔ)

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.6.RELEASE</version><relativePath/></parent><groupId>com.atguigu.es</groupId><artifactId>springdata-elasticsearch</artifactId><version>1.0</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-test</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId></dependency></dependencies>
</project>

增加配置文件

在 resources 目錄中增加 application.properties 文件

# es 服務(wù)地址
elasticsearch.host=127.0.0.1
# es 服務(wù)端口
elasticsearch.port=9200
# 配置日志級別,開啟 debug 日志
logging.level.com.atguigu.es=debug

SpringBoot 主程序

package com.atguigu.es;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringDataElasticSearchMainApplication {public static void main(String[] args) {SpringApplication.run(SpringDataElasticSearchMainApplication.class,args);}
}

數(shù)據(jù)實體類

package com.atguigu.es;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Document(indexName = "product", shards = 3, replicas = 1)
public class Product {@Idprivate Long id;//商品唯一標(biāo)識@Filed(type = FieldType.Text)private String title;//商品名稱@Filed(type = FieldType.Keyword)private String category;//分類名稱@Filed(type = FieldType.Keyword)private Double price;//商品價格@Filed(type = FieldType.Keyword, index = false)	// 不做索引關(guān)聯(lián)private String images;//圖片地址
}

配置類

package com.atguigu.es;import lombok.Data;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
// 關(guān)聯(lián)配置文件
@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
@Data
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {private String host ;private Integer port ;//重寫父類方法@Overridepublic RestHighLevelClient elasticsearchClient() {RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);return restHighLevelClient;}
}

DAO 數(shù)據(jù)訪問對象

package com.atguigu.es;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductDao extends ElasticsearchRepository<Product,Long> {
}

索引操作

package com.atguigu.es;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringDataESIndexTest {//注入 ElasticsearchRestTemplate@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;//創(chuàng)建索引并增加映射配置@Testpublic void createIndex(){//創(chuàng)建索引,系統(tǒng)初始化會自動創(chuàng)建索引System.out.println("創(chuàng)建索引");}@Testpublic void deleteIndex(){//創(chuàng)建索引,系統(tǒng)初始化會自動創(chuàng)建索引boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class);System.out.println("刪除索引 = " + flg);}
}

文檔操作

package com.atguigu.es;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;import java.util.ArrayList;
import java.util.List;@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringDataESProductDaoTest {@Autowiredprivate ProductDao productDao;/*** 新增*/@Testpublic void save(){Product product = new Product();product.setId(2L);product.setTitle("華為手機");product.setCategory("手機");product.setPrice(2999.0);product.setImages("http://www.atguigu/hw.jpg");productDao.save(product);}//修改@Testpublic void update(){Product product = new Product();product.setId(1L);product.setTitle("小米 2 手機");product.setCategory("手機");product.setPrice(9999.0);product.setImages("http://www.atguigu/xm.jpg");productDao.save(product);}//根據(jù) id 查詢@Testpublic void findById(){Product product = productDao.findById(1L).get();System.out.println(product);}//查詢所有@Testpublic void findAll(){Iterable<Product> products = productDao.findAll();for (Product product : products) {System.out.println(product);}}//刪除@Testpublic void delete(){Product product = new Product();product.setId(1L);productDao.delete(product);}//批量新增@Testpublic void saveAll(){List<Product> productList = new ArrayList<>();for (int i = 0; i < 10; i++) {Product product = new Product();product.setId(Long.valueOf(i));product.setTitle("["+i+"]小米手機");product.setCategory("手機");product.setPrice(1999.0+i);product.setImages("http://www.atguigu/xm.jpg");productList.add(product);}productDao.saveAll(productList);}//分頁查詢@Testpublic void findByPageable(){//設(shè)置排序(排序方式,正序還是倒序,排序的 id)Sort sort = Sort.by(Sort.Direction.DESC,"id");int currentPage=0;//當(dāng)前頁,第一頁從 0 開始,1 表示第二頁int pageSize = 5;//每頁顯示多少條//設(shè)置查詢分頁PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);//分頁查詢Page<Product> productPage = productDao.findAll(pageRequest);for (Product Product : productPage.getContent()) {System.out.println(Product);}}
}

文檔搜索

package com.atguigu.es;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringDataESSearchTest {@Autowiredprivate ProductDao productDao;/*** term 查詢* search(termQueryBuilder) 調(diào)用搜索方法,參數(shù)查詢構(gòu)建器對象*/@Testpublic void termQuery(){TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米");Iterable<Product> products = productDao.search(termQueryBuilder);for (Product product : products) {System.out.println(product);}}/*** term 查詢加分頁*/@Testpublic void termQueryByPage(){int currentPage= 0 ;int pageSize = 5;//設(shè)置查詢分頁PageRequest pageRequest = PageRequest.of(currentPage, pageSize);TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米");Iterable<Product> products = productDao.search(termQueryBuilder,pageRequest);for (Product product : products) {System.out.println(product);}}
}

Spark Streaming - 集成

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.atguigu.es</groupId><artifactId>sparkstreaming-elasticsearch</artifactId><version>1.0</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.12</artifactId><version>3.0.0</version></dependency><dependency><groupId>org.apache.spark</groupId><artifactId>spark-streaming_2.12</artifactId><version>3.0.0</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!-- elasticsearch 的客戶端 --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.8.0</version></dependency><!-- elasticsearch 依賴 2.x 的 log4j --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.8.2</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.8.2</version></dependency>
<!-- <dependency>-->
<!-- <groupId>com.fasterxml.jackson.core</groupId>-->
<!-- <artifactId>jackson-databind</artifactId>-->
<!-- <version>2.11.1</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; junit 單元測試 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>junit</groupId>-->
<!-- <artifactId>junit</artifactId>-->
<!-- <version>4.12</version>-->
<!-- </dependency>--></dependencies>
</project>

功能實現(xiàn)

package com.atguigu.esimport org.apache.http.HttpHost
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.ReceiverInputDStream
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.elasticsearch.action.index.IndexRequest
import org.elasticsearch.client.indices.CreateIndexRequest
import org.elasticsearch.client.{RequestOptions, RestClient, RestHighLevelClient}
import org.elasticsearch.common.xcontent.XContentTypeimport java.util.Date
object SparkStreamingESTest {def main(args: Array[String]): Unit = {val sparkConf = new SparkConf().setMaster("local[*]").setAppName("ESTest")val ssc = new StreamingContext(sparkConf, Seconds(3))val ds: ReceiverInputDStream[String] = ssc.socketTextStream("localhost", 9999)ds.foreachRDD(rdd => {data => {new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200)))// 設(shè)置索引及唯一性標(biāo)識val ss = data.split(" ")// 新增文檔 - 請求對象val request = new IndexRequest()request.index("product").id(ss(0))val json = s"""| { "data" : "${ss(1)}"}|""".stripMargin// 添加文檔數(shù)據(jù),數(shù)據(jù)格式為 JSON 格式request.source(json, XContentType.JSON)// 客戶端發(fā)送請求,獲取響應(yīng)對象val response = client.index(request, RequestOptions.DEFAULT)System.out.println("_index:" + response.getIndex());System.out.println("_id:" + response.getId());System.out.println("_result:" + response.getResult());client.close()}})ssc.start()ssc.awaitTermination()}
}

Flink - 集成

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.atguigu.es</groupId><artifactId>flink-elasticsearch</artifactId><version>1.0</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.apache.flink</groupId><artifactId>flink-scala_2.12</artifactId><version>1.12.0</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-streaming-scala_2.12</artifactId><version>1.12.0</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-clients_2.12</artifactId><version>1.12.0</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-elasticsearch7_2.11</artifactId><version>1.12.0</version></dependency><!-- jackson --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.11.1</version></dependency></dependencies>
</project>

功能實現(xiàn)

package com.atguigu.es;
import org.apache.flink.api.common.functions.RuntimeContext;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.connectors.elasticsearch.ElasticsearchSinkFunction;
import org.apache.flink.streaming.connectors.elasticsearch.RequestIndexer;
import org.apache.flink.streaming.connectors.elasticsearch7.ElasticsearchSink;
import org.apache.http.HttpHost;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.Requests;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class FlinkElasticsearchSinkTest {public static void main(String[] args) throws Exception {// 構(gòu)建Flink環(huán)境對象StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();// Source:數(shù)據(jù)的輸入DataStreamSource<String> source = env.socketTextStream("localhost", 9999);// 使用ESBuilder構(gòu)建輸出List<HttpHost> hosts = new ArrayList<>();hosts.add(new HttpHost("localhost", 9200, "http"));ElasticsearchSink.Builder<String> esBuilder = new ElasticsearchSink.Builder<>(hosts, new ElasticsearchSinkFunction<String>() {@Overridepublic void process(String s, RuntimeContext runtimeContext, RequestIndexer requestIndexer){Map<String, String> jsonMap = new HashMao<>();jsonMap.put("data", s);IndexRequest indexRequest = Requests.indexRequest();indexRequest.index("flink-index");indexRequest.id("9001");indexRequest.source(jsonMap);requestIndexer.add(indexRequest);}})// Sink:數(shù)據(jù)的輸出esBuilder.setBuilFlushMaxActions(1);source.addSink(esSinkBuilder.build());env.execute("flink-es");}
}

五、優(yōu)化

5.1 硬件選擇

ES重度使用磁盤,磁盤能處理的吞吐量越大,節(jié)點久越穩(wěn)定。優(yōu)化磁盤I/O的技巧:

使用SSD。SSD(Solid State Drive 固態(tài)硬盤)相對于傳統(tǒng)的機械硬盤(HDD),SSD采用閃存存儲技術(shù),沒有機械部件,因此速度更快、耐用性更高。
使用RAID 0。RAID(Redundant Array of Independent Disks)是一種數(shù)據(jù)存儲技術(shù),用于將多個物理硬盤組合成一個邏輯卷,以提高數(shù)據(jù)的性能、容錯能力或同時兼具兩者。RAID 0,也被稱為條帶化(striping),是RAID級別中的一種。它通過將數(shù)據(jù)分散存儲在多個硬盤上,以提高讀寫性能。在RAID 0中,數(shù)據(jù)被分成多個固定大小的塊,并按順序分配到各個硬盤上。因此,當(dāng)讀取或?qū)懭霐?shù)據(jù)時,可以同時從多個硬盤中讀取或?qū)懭?#xff0c;大大提高了數(shù)據(jù)傳輸速度。
使用多塊硬盤,并允許ES通過多個path.data目錄配置把數(shù)據(jù)條帶化分配到他們上面。
不要使用遠程掛載的存儲。遠程掛載的存儲是指通過網(wǎng)絡(luò)連接將遠程存儲設(shè)備(通常是網(wǎng)絡(luò)存儲設(shè)備)連接到本地計算機,并將其作為本地計算機的一個目錄或驅(qū)動器來使用。比如 NFS 或者 SMB/CIFS。

5.2 分片策略

分片和副本的設(shè)計為 ES 提供了支持分布式和故障轉(zhuǎn)移的特性,但分片和副本不是可以無限分配的。分片在設(shè)置好之后是不能修改的,由于路由計算規(guī)則,數(shù)據(jù)的存儲位置是可以通過計算得到的,一旦分片動態(tài)變化,可能會導(dǎo)致數(shù)據(jù)查詢不到。所以分片一定是在創(chuàng)建索引時久設(shè)定好的。

合理設(shè)置分片數(shù)

設(shè)計原則:
每個分片占用的硬盤容量不超過 ES 的最大 JVM 的堆空間設(shè)置(一般設(shè)置不超過 32G,參考下文
的 JVM 設(shè)置原則),因此,如果索引的總?cè)萘吭?500G 左右,那分片大小在 16 個左右即可;當(dāng)然,
最好同時考慮原則 2。
考慮一下 node 數(shù)量,一般一個節(jié)點有時候就是一臺物理機,如果分片數(shù)過多,大大超過了節(jié)點數(shù),
很可能會導(dǎo)致一個節(jié)點上存在多個分片,一旦該節(jié)點故障,即使保持了 1 個以上的副本,同樣有可能
會導(dǎo)致數(shù)據(jù)丟失,集群無法恢復(fù)。所以, 一般都設(shè)置分片數(shù)不超過節(jié)點數(shù)的 3 倍。
主分片,副本和節(jié)點最大數(shù)之間數(shù)量,我們分配的時候可以參考以下關(guān)系:
節(jié)點數(shù)<=主分片數(shù)(副本數(shù)+1)*

推遲分片策略

對于節(jié)點瞬時中斷的問題,默認(rèn)情況,集群會等待一分鐘來查看節(jié)點是否會重新加入,如果這個節(jié)點在此期間重新加入,重新加入的節(jié)點會保持其現(xiàn)有的分片數(shù)據(jù),不會觸發(fā)新的分片分配。這樣就可以減少 ES 在自動再平衡可用分片時所帶來的極大開銷。
通過修改參數(shù) delayed_timeout ,可以延長再均衡的時間,可以全局設(shè)置也可以在索引級別進行修改:

PUT /_all/_settings 
{"settings": {"index.unassigned.node_left.delayed_timeout": "5m" }
}

5.3 路由選擇

當(dāng)我們查詢文檔的時候,Elasticsearch 如何知道一個文檔應(yīng)該存放到哪個分片中呢?它其實是通過下面這個公式來計算出來:
shard = hash(routing) % number_of_primary_shards
routing 默認(rèn)值是文檔的 id,也可以采用自定義值,比如用戶 id。

5.4 寫入速度優(yōu)化

針對于搜索性能要求不高,但是對寫入要求較高的場景,我們需要盡可能的選擇恰當(dāng)寫優(yōu)化策略。綜合來說,可以考慮以下幾個方面來提升寫索引的性能:

加大 Translog Flush ,目的是降低 Iops、Writeblock。
增加 Index Refresh 間隔,目的是減少 Segment Merge 的次數(shù)。
調(diào)整 Bulk 線程池和隊列。
優(yōu)化節(jié)點間的任務(wù)分布。
優(yōu)化 Lucene 層的索引建立,目的是降低 CPU 及 IO。

批量數(shù)據(jù)提交

ES 提供了 Bulk API 支持批量操作,當(dāng)我們有大量的寫任務(wù)時,可以使用 Bulk 來進行批量寫入。
通用的策略如下:Bulk 默認(rèn)設(shè)置批量提交的數(shù)據(jù)量不能超過 100M。數(shù)據(jù)條數(shù)一般是根據(jù)文檔的大小和服務(wù)器性能而定的,但是單次批處理的數(shù)據(jù)大小應(yīng)從 5MB~15MB 逐漸增加,當(dāng)性能沒有提升時,把這個數(shù)據(jù)量作為最大值。

優(yōu)化存儲設(shè)備

ES 是一種密集使用磁盤的應(yīng)用,在段合并的時候會頻繁操作磁盤,所以對磁盤要求較高,當(dāng)磁盤速度提升之后,集群的整體性能會大幅度提高。

合理使用合并

Lucene 以段的形式存儲數(shù)據(jù)。當(dāng)有新的數(shù)據(jù)寫入索引時,Lucene 就會自動創(chuàng)建一個新的段。
隨著數(shù)據(jù)量的變化,段的數(shù)量會越來越多,消耗的多文件句柄數(shù)及 CPU 就越多,查詢效率就會下降。
由于 Lucene 段合并的計算量龐大,會消耗大量的 I/O,所以 ES 默認(rèn)采用較保守的策略,讓后臺定期進行段合并。

減少refresh的次數(shù)

Lucene 在新增數(shù)據(jù)時,采用了延遲寫入的策略,默認(rèn)情況下索引的 refresh_interval 為1 秒。
Lucene 將待寫入的數(shù)據(jù)先寫到內(nèi)存中,超過 1 秒(默認(rèn))時就會觸發(fā)一次 Refresh,然后 Refresh 會把內(nèi)存中的的數(shù)據(jù)刷新到操作系統(tǒng)的文件緩存系統(tǒng)中。
如果我們對搜索的實效性要求不高,可以將 Refresh 周期延長,例如 30 秒。
這樣還可以有效地減少段刷新次數(shù),但這同時意味著需要消耗更多的 Heap 內(nèi)存。

加大 Flush 設(shè)置

Flush 的主要目的是把文件緩存系統(tǒng)中的段持久化到硬盤,當(dāng) Translog 的數(shù)據(jù)量達到512MB 或者 30 分鐘時,會觸發(fā)一次 Flush。
index.translog.flush_threshold_size 參數(shù)的默認(rèn)值是 512MB,我們進行修改。
增加參數(shù)值意味著文件緩存系統(tǒng)中可能需要存儲更多的數(shù)據(jù),所以我們需要為操作系統(tǒng)的文件緩存系統(tǒng)留下足夠的空間。

減少副本的數(shù)量

ES 為了保證集群的可用性,提供了 Replicas(副本)支持,然而每個副本也會執(zhí)行分析、索引及可能的合并過程,所以 Replicas 的數(shù)量會嚴(yán)重影響寫索引的效率。
當(dāng)寫索引時,需要把寫入的數(shù)據(jù)都同步到副本節(jié)點,副本節(jié)點越多,寫索引的效率就越慢。
如果我們需要大批量進行寫入操作,可以先禁止Replica復(fù)制,設(shè)置index.number_of_replicas: 0 關(guān)閉副本。在寫入完成后,Replica 修改回正常的狀態(tài)。

5.5 內(nèi)存設(shè)置

如果有一個 64G 內(nèi)存的機器, ES 堆內(nèi)存的分配需要滿足以下兩個原則:

1. 不要超過物理內(nèi)存的 50%:Lucene 的設(shè)計目的是把底層 OS 里的數(shù)據(jù)緩存到內(nèi)存中。
Lucene 的段是分別存儲到單個文件中的,這些文件都是不會變化的,所以很利于緩存,同時操作系統(tǒng)也會把這些段文件緩存起來,以便更快的訪問。
如果我們設(shè)置的堆內(nèi)存過大,Lucene 可用的內(nèi)存將會減少,就會嚴(yán)重影響降低 Lucene 的全文本查詢性能。
2.堆內(nèi)存的大小最好不要超過 32GB:在 Java 中,所有對象都分配在堆上,然后有一個 Klass Pointer 指針指向它的類元數(shù)據(jù)。
這個指針在 64 位的操作系統(tǒng)上為 64 位,64 位的操作系統(tǒng)可以使用更多的內(nèi)存(2^ 64)。在 32 位的系統(tǒng)上為 32 位,32 位的操作系統(tǒng)的最大尋址空間為 4GB(2^32)。
但是 64 位的指針意味著更大的浪費,因為你的指針本身大了。浪費內(nèi)存不算,更糟糕的是,更大的指針在主內(nèi)存和緩存器(例如 LLC, L1 等)之間移動數(shù)據(jù)的時候,會占用更多的帶寬。

最終我們都會采用 31 G 設(shè)置:-Xms 31g,-Xmx 31g

5.6 重要配置

參數(shù)名參數(shù)值說明
cluster.nameelasticsearch配置 ES 的集群名稱,默認(rèn)值是 ES,建議改成與所存數(shù)據(jù)相關(guān)的名稱,ES 會自動發(fā)現(xiàn)在同一網(wǎng)段下的集群名稱相同的節(jié)點
node.namenode-1集群中的節(jié)點名,在同一個集群中不能重復(fù)。節(jié)點的名稱一旦設(shè)置,就不能再改變了。當(dāng)然,也可以設(shè) 置 成 服 務(wù) 器 的 主 機 名 稱 , 例 如node.name:${HOSTNAME}。
node.mastertrue指定該節(jié)點是否有資格被選舉成為 Master 節(jié)點,默認(rèn)是 True,如果被設(shè)置為 True,則只是有資格成為Master 節(jié)點,具體能否成為 Master 節(jié)點,需要通過選舉產(chǎn)生。
node.datatrue指定該節(jié)點是否存儲索引數(shù)據(jù),默認(rèn)為 True。數(shù)據(jù)的增、刪、改、查都是在 Data 節(jié)點完成的。
index.number_of_shards1設(shè)置都索引分片個數(shù),默認(rèn)是 1 片。也可以在創(chuàng)建索引時設(shè)置該值,具體設(shè)置為多大都值要根據(jù)數(shù)據(jù)量的大小來定。如果數(shù)據(jù)量不大,則設(shè)置成 1 時效率最高
index.number_of_replicas1設(shè)置默認(rèn)的索引副本個數(shù),默認(rèn)為 1 個。副本數(shù)越多,集群的可用性越好,但是寫索引時需要同步的數(shù)據(jù)越多。
transport.tcp.compress1設(shè)置在節(jié)點間傳輸數(shù)據(jù)時是否壓縮,默認(rèn)為 False,不壓縮
discovery.zen.minimum_master_nodestrue設(shè)置在選舉 Master 節(jié)點時需要參與的最少的候選主節(jié)點數(shù),默認(rèn)為 1。如果使用默認(rèn)值,則當(dāng)網(wǎng)絡(luò)不穩(wěn)定時有可能會出現(xiàn)腦裂。合理的數(shù)值為 (master_eligible_nodes/2)+1 ,其中
master_eligible_nodes 表示集群中的候選主節(jié)點數(shù)
discovery.zen.ping.timeout1設(shè)置在集群中自動發(fā)現(xiàn)其他節(jié)點時 Ping 連接的超時時間,默認(rèn)為 3 秒。在較差的網(wǎng)絡(luò)環(huán)境下需要設(shè)置得大一點,防止因誤判該節(jié)點的存活狀態(tài)而導(dǎo)致分片的轉(zhuǎn)移
http://www.risenshineclean.com/news/29753.html

相關(guān)文章:

  • 木工支模價格明細表搜索引擎優(yōu)化的流程是什么
  • 自己做網(wǎng)站哪種好做搜索引擎優(yōu)化的策略主要有
  • 網(wǎng)站建設(shè)江門游戲代理加盟
  • 河南平臺網(wǎng)站建設(shè)價位百度網(wǎng)站網(wǎng)址是多少
  • 深圳定制網(wǎng)站制作費用百度智能建站系統(tǒng)
  • 網(wǎng)站開發(fā)技術(shù)實驗教程seo推廣優(yōu)化的方法
  • 漢中門戶網(wǎng)工程招標(biāo)杭州seo網(wǎng)站哪家好
  • 高端網(wǎng)站建設(shè)費用深圳網(wǎng)絡(luò)推廣公司哪家好
  • 個人接做網(wǎng)站多少錢app優(yōu)化方案
  • 汕頭有建網(wǎng)站公司嗎seo案例
  • 公司和網(wǎng)站備案查詢密碼網(wǎng)絡(luò)營銷和傳統(tǒng)營銷的區(qū)別有哪些
  • 宣傳片視頻西安seo排名
  • wordpress采集網(wǎng)頁文章安卓優(yōu)化大師app下載
  • 工作總結(jié)ppt模板免費寧波優(yōu)化推廣選哪家
  • 桂林做網(wǎng)站的公司seo是哪里
  • 購物網(wǎng)站開發(fā)技術(shù)河北網(wǎng)站優(yōu)化公司
  • 網(wǎng)站風(fēng)格類型百度流量統(tǒng)計
  • 為什么做電子商務(wù)網(wǎng)站的原因中國建設(shè)網(wǎng)官方網(wǎng)站
  • 制作一個買股票的網(wǎng)站怎么做seo比較好的公司
  • 網(wǎng)站畢業(yè)設(shè)計怎么做網(wǎng)絡(luò)營銷推廣活動有哪些
  • 合伙做網(wǎng)站怎么分配股權(quán)各地疫情最新消息
  • 大連小型網(wǎng)站建設(shè)關(guān)鍵的近義詞
  • 做本地團購網(wǎng)站游戲網(wǎng)站交換友情鏈接
  • 合肥網(wǎng)站建設(shè)找佳達百度seo服務(wù)方案
  • 廣西網(wǎng)站建設(shè)開發(fā)外包市場營銷方案范文5篇
  • 泗陽做網(wǎng)站公司競價托管就選微競價
  • 網(wǎng)站logo用什么做百度網(wǎng)站打不開
  • 網(wǎng)站批量做httpsseo優(yōu)化實訓(xùn)報告
  • 深圳租房建設(shè)局網(wǎng)站天天外鏈官網(wǎng)
  • 淮安建設(shè)工程協(xié)會網(wǎng)站查詢站長之家 seo查詢