Elasticsearch集群搭建、优化及实践
文章目錄
- 一、Elasticsearch集群
- 1、Elasticsearch集群概念
- 2、Elasticsearch集群安裝
- 3、安裝Kibana
- 4、測試集群狀態
- 二、Elasticsearch優化
- 1、磁盤選擇
- 2、分片策略
- 3、內存設置
- 三、Elasticsearch實踐
- 1、ES自動補全
- 2、創建索引
- 3、安裝logstash導入數據
- 4、項目搭建
- 5、自動補全功能
- 6、高亮搜索關鍵字功能
- 7、頁面展示
- 總結:
一、Elasticsearch集群
1、Elasticsearch集群概念
2)集群(cluster):一組節點組織在一起稱為一個集群,它們共同持有整個的數據,并一起提供索引和搜索功能。
3)分片(shards):ES可以把完整的索引分成多個分片,分別存儲在不同的節點上。
4)副本(replicas):ES可以為每個分片創建副本,提高查詢效率,保證在分片數據丟失后的恢復。
分片數量只能在索引創建時指定,索引創建后不能再更改分片數量,但可以改變副本的數量。
2、Elasticsearch集群安裝
下載Elasticsearch7.17.7版本:https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.7-linux-x86_64.tar.gz
因為8.6.2版本,與springboot整合ES的版本不一致無法解析響應正文,而且7.17.7也是比較新的
將該壓縮包通過Mobax終端上傳到目錄/中,進入到目錄/中,然后解壓到目錄/usr/local/中:tar -zxvf elasticsearch-7.17.7-linux-x86_64.tar.gz -C /usr/local/
安裝ik分詞器到該ES服務中:
1)下載IKAnalyzer:https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.17.7/elasticsearch-analysis-ik-7.17.7.zip
2)通過mobax上傳至虛擬機的目錄/,進入到目錄/中,然后進行解壓縮:unzip elasticsearch-analysis-ik-7.17.7.zip -d /usr/local/elasticsearch-7.17.7/plugins/analysis-ik
安裝拼音分詞器到該ES服務中:
1)下載拼音分詞器:https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v7.17.7/elasticsearch-analysis-pinyin-7.17.7.zip
2)通過mobax上傳到虛擬機的/目錄,進入到目錄/中,解壓到elasticsearch的plugins/analysis-pinyin目錄下:unzip elasticsearch-analysis-pinyin-7.17.7.zip -d /usr/local/elasticsearch-7.17.7/plugins/analysis-pinyin
給es用取得該文件件的權限:chown -R es:es /usr/local/elasticsearch-7.17.7
修改配置文件:vim /usr/local/elasticsearch-7.17.7/config/elasticsearch.yml,添加如下
#集群名稱,保證唯一 cluster.name: my_elasticsearch #節點名稱,必須不一樣 node.name: node1 #可以訪問該節點的ip地址 network.host: 0.0.0.0 #該節點服務端口號 http.port: 9200 #集群間通信端口號 transport.tcp.port: 9300 #候選主節點的設備地址 discovery.seed_hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"] #候選主節點的節點名 cluster.initial_master_nodes: ["node1","node2","node3"] #關閉安全認證,才能訪問es xpack.security.enabled: false xpack.security.http.ssl:enabled: false將elasticsearch-7.17.7文件夾修改名字為myes1:mv /usr/local/elasticsearch-7.17.7/ /usr/local/myes1
切換為es用戶:su es
后臺啟動第一個ES節點:ES_JAVA_OPTS="-Xms512m -Xmx512m" /usr/local/myes1/bin/elasticsearch -d,默認占用4G,只是為了搭建集群而搭建集群,所以設置512m的內存。
測試ES服務是否正常啟動:curl 127.0.0.1:9200
切換為root用戶:su root
進入到目錄/中,然后將ES壓縮包解壓到目錄/usr/local/中:tar -zxvf elasticsearch-7.17.7-linux-x86_64.tar.gz -C /usr/local/
進入到目錄/中,然后將ik分詞器壓縮包進行解壓縮:unzip elasticsearch-analysis-ik-7.17.7.zip -d /usr/local/elasticsearch-7.17.7/plugins/analysis-ik
進入到目錄/中,然后將pinyin分詞器解壓到elasticsearch的plugins/analysis-pinyin目錄下:unzip elasticsearch-analysis-pinyin-7.17.7.zip -d /usr/local/elasticsearch-7.17.7/plugins/analysis-pinyin
給es用取得該文件件的權限:chown -R es:es /usr/local/elasticsearch-7.17.7
修改配置文件:vim /usr/local/elasticsearch-7.17.7/config/elasticsearch.yml,添加如下
#集群名稱,保證唯一 cluster.name: my_elasticsearch #節點名稱,必須不一樣 node.name: node2 #可以訪問該節點的ip地址 network.host: 0.0.0.0 #該節點服務端口號 http.port: 9201 #集群間通信端口號 transport.tcp.port: 9301 #候選主節點的設備地址 discovery.seed_hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"] #候選主節點的節點名 cluster.initial_master_nodes: ["node1","node2","node3"] #關閉安全認證,才能訪問es xpack.security.enabled: false xpack.security.http.ssl:enabled: false將elasticsearch-7.17.7文件夾修改名字為myes2:mv /usr/local/elasticsearch-7.17.7/ /usr/local/myes2
進入到目錄/中,然后將ES壓縮包解壓到目錄/usr/local/中:tar -zxvf elasticsearch-7.17.7-linux-x86_64.tar.gz -C /usr/local/
進入到目錄/中,然后將ik分詞器壓縮包進行解壓縮:unzip elasticsearch-analysis-ik-7.17.7.zip -d /usr/local/elasticsearch-7.17.7/plugins/analysis-ik
進入到目錄/中,然后將pinyin分詞器解壓到elasticsearch的plugins/analysis-pinyin目錄下:unzip elasticsearch-analysis-pinyin-7.17.7.zip -d /usr/local/elasticsearch-7.17.7/plugins/analysis-pinyin
給es用取得該文件件的權限:chown -R es:es /usr/local/elasticsearch-7.17.7
修改配置文件:vim /usr/local/elasticsearch-7.17.7/config/elasticsearch.yml,添加如下
#集群名稱,保證唯一 cluster.name: my_elasticsearch #節點名稱,必須不一樣 node.name: node3 #可以訪問該節點的ip地址 network.host: 0.0.0.0 #該節點服務端口號 http.port: 9202 #集群間通信端口號 transport.tcp.port: 9302 #候選主節點的設備地址 discovery.seed_hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"] #候選主節點的節點名 cluster.initial_master_nodes: ["node1","node2","node3"] #關閉安全認證,才能訪問es xpack.security.enabled: false xpack.security.http.ssl:enabled: false將elasticsearch-7.17.7文件夾修改名字為myes3:mv /usr/local/elasticsearch-7.17.7/ /usr/local/myes3
切換為es用戶:su es
后臺啟動第二個ES節點:ES_JAVA_OPTS="-Xms512m -Xmx512m" /usr/local/myes2/bin/elasticsearch -d
后臺啟動第三個ES節點:ES_JAVA_OPTS="-Xms512m -Xmx512m" /usr/local/myes3/bin/elasticsearch -d
查看集群是否搭建成功,訪問瀏覽器:http://192.168.126.24:9200/_cat/nodes
查看集群的狀態:curl -uelastic:pwd -XGET "http://127.0.0.1:9200/_cluster/health?pretty"
3、安裝Kibana
1)進入到config目錄下:cd /usr/local/kibana-7.17.7-linux-x86_64/config
2)修改配置文件:vim kibana.yml
3)添加kibana主機ip:server.host: "192.168.126.24"
添加Elasticsearch路徑:elasticsearch.hosts: ["http://127.0.0.1:9200","http://127.0.0.1:9201","http://127.0.0.1:9202"]
4、測試集群狀態
創建product索引
PUT /product {"settings": {"number_of_shards": 5,"number_of_replicas": 1},"mappings": {"properties": {"id": {"type": "integer","store": true,"index": true},"productName": {"type": "text","store": true,"index": true},"productDesc": {"type": "text","store": true,"index": true}}} }“number_of_shards”: 5,即設置該索引的分片數量為5,“number_of_replicas”: 1,每個分片的副本數為1。
查看集群健康狀態:GET /_cat/health?v
查看索引狀態:GET /_cat/indices?v
查看分片狀態:GET /_cat/shards?v
ES集群可以自動進行故障應對,即可以自動進行水平擴容。
改變每個分片的副本數
PUT /product/_settings {"number_of_replicas": 2 }分片數不能改變,但是分片的副本數可以改變。
二、Elasticsearch優化
1、磁盤選擇
1)使用SSD(固態硬盤)。
2)使用RAID0模式,即將連續的數據分散到多個硬盤存儲,這樣可以并行進行IO操作。代價是一塊硬盤發生故障就會引發系統故障。
3)不要使用遠程掛載的存儲。即在ES服務器中,而非ES服務器之外的存儲。
2、分片策略
每個分片的底層都是一個Lucene索引,會消耗一定的系統資源。搜索請求需要命中索引中的所有分片,分片過多會降低搜索的性能。
分片原則:
1)每個分片占用的磁盤容量不超過ES的JVM的最大堆空間設置(一般設置不超過32G)。
2)分片數一般不超過節點數的三倍。
3)推遲分片分配:節點中斷后集群會重新分配分片。但默認集群會等待一分鐘來查看節點是否重新加入??梢栽O置等待的時長,減少分配的次數。
3、內存設置
2)Xmx和Xms的大小設置為相同時,可以減輕伸縮堆大小帶來的壓力。
3)Xmx和Xms不要超過物理內存的50%,因為ES內部的Lucene也要占據一部分物理內存。
4)Xmx和Xms不要超過32G,由于JAVA語言的特性,堆內存超過32G會浪費大量系統資源,所以在內存足夠的情況下,最終都會采用設置為31G。
三、Elasticsearch實踐
1、ES自動補全
自動補全對性能要求極高,ES不是通過倒排索引來實現的,所以需要將對應的查詢字段類型設置為completion。
創建索引,添加自動補全字段
PUT /product2 {"mappings": {"properties": {"id": {"type": "integer","store": true,"index": true},"productName": {"type": "completion","store": true,"index": true},"productDesc": {"type": "text","store": true,"index": true}}} } POST /product2/_doc {"id":1,"productName":"elasticsearch1","productDesc":"elasticsearch1 is a good search engine" } POST /product2/_doc {"id":2,"productName":"elasticsearch2","productDesc":"elasticsearch2 is a good search engine" }測試自動補全功能
GET /product2/_search {"suggest": {"prefix_suggestion": {"prefix": "elastic","completion": {"field": "productName","skip_duplicates": true,"size": 10 }}} }2、創建索引
創建news索引
PUT /news {"settings": {"number_of_shards": 5,"number_of_replicas": 1,"analysis": {"analyzer": {"ik_pinyin": {"tokenizer": "ik_smart","filter": "pinyin_filter"},"tag_pinyin": {"tokenizer": "keyword","filter": "pinyin_filter"}},"filter": {"pinyin_filter": {"type": "pinyin","keep_joined_full_pinyin":true,"keep_original": true,"remove_duplicated_term": true}}}},"mappings": {"properties": {"id": {"type": "integer","index": true},"title": {"type": "text","index": true,"analyzer": "ik_pinyin","search_analyzer": "ik_smart"},"content": {"type": "text","index": true,"analyzer": "ik_pinyin","search_analyzer": "ik_smart"},"url": {"type": "keyword","index": true},"tags": {"type": "completion","analyzer": "tag_pinyin"}}} }3、安裝logstash導入數據
通過命令行進入mysql中導入SQL文件:source 絕對路徑/xxx.sql;
下載logstash:https://artifacts.elastic.co/downloads/logstash/logstash-7.17.7-windows-x86_64.zip
將logstash壓縮包進行解壓,在/logstash-7.17.7/config/目中下創建mysql.conf文件。寫入以下腳本:
input {jdbc {jdbc_driver_library => "F:\SoftWare\mysql\mysql-connector-java-8.0.27.jar"jdbc_driver_class => "com.mysql.jdbc.Driver"jdbc_connection_string => "jdbc:mysql:///news"jdbc_user => "root"jdbc_password => "root"schedule => "* * * * *"jdbc_default_timezone => "Asia/Shanghai"statement => "SELECT * FROM news;"} }filter {mutate {split => {"tags" => ","}} }output {elasticsearch {hosts => ["192.168.126.24:9200","192.168.126.24:9201","192.168.126.24:9202"]index => "news"document_id => "%{id}"} }在解壓路徑/logstash-7.17.7下,打開cmd窗口,運行命令:bin\logstash -f config\mysql.conf
測試自動補齊功能
GET /news/_search {"suggest": {"YOUR_SUGGESTION": {"prefix": "zhu", //需要補全的關鍵詞"completion": {"field": "tags","skip_duplicates": true,//去重復值"size": 10}}} }4、項目搭建
在resources目錄下,創建配置文件application.yml,添加如下配置:
spring:elasticsearch:uris: http://192.168.126.24:9200,http://192.168.126.24:9201,http://192.168.126.24:9202logging:pattern:console: '%d{HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n'創建com.zzx.escase.document包,在包下創建實體類News
package com.zzx.escase.document;import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Transient; import org.springframework.data.elasticsearch.annotations.CompletionField; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.suggest.Completion;@Document(indexName = "news") @Data public class News {@Idprivate Integer id;@Fieldprivate String title;@Fieldprivate String content;@Fieldprivate String url;@CompletionField@Transientprivate Completion tags; }創建com.zzx.escase.repository包,在包下創建接口Repository
package com.zzx.escase.repository;import com.zzx.escase.document.News; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;public interface NewsRepository extends ElasticsearchRepository<News,Integer> { }5、自動補全功能
創建com.zzx.escase.service包,在包下創建類NewsService
package com.zzx.escase.service;import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.text.Text; import org.elasticsearch.search.suggest.Suggest; import org.elasticsearch.search.suggest.SuggestBuilder; import org.elasticsearch.search.suggest.SuggestBuilders; import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.stereotype.Service;import java.util.List; import java.util.stream.Collectors;@Service public class NewsService {@Autowiredprivate ElasticsearchRestTemplate template;//自動補齊public List<String> autoSuggest(String keyword){// 1.創建補齊請求SuggestBuilder suggestBuilder = new SuggestBuilder();// 2.構建補齊條件CompletionSuggestionBuilder suggestionBuilder = SuggestBuilders.completionSuggestion("tags").prefix(keyword).skipDuplicates(true).size(10);suggestBuilder.addSuggestion("prefix_suggestion",suggestionBuilder);// 3.發送請求SearchResponse response = template.suggest(suggestBuilder, IndexCoordinates.of("news"));// 4.處理結果List<String> result = response.getSuggest().getSuggestion("prefix_suggestion").getEntries().get(0).getOptions().stream().map(Suggest.Suggestion.Entry.Option::getText).map(Text::toString).collect(Collectors.toList());return result;} }在Test根目錄下,創建com.zzx.escase.service包,在包下創建NewsServiceTest測試類
package com.zzx.escase.service;import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTest public class NewsServiceTest {@Autowiredprivate NewsService newsService;@Testpublic void testAutoSuggest(){List<String> list = newsService.autoSuggest("zhu");list.forEach(System.out::println);}}即打印出tags域中自動補齊的10個關鍵詞
6、高亮搜索關鍵字功能
在com.zzx.escase.repository的接口Repository下,添加高亮搜索關鍵字方法
@Highlight(fields = {@HighlightField(name = "title"),@HighlightField(name="content")}) List<SearchHit<News>> findByTitleMatchesOrContentMatches(String title, String content);在com.zzx.escase.service的接口NewsService下,添加高亮搜索關鍵字方法
//查詢關鍵字 public List<News> highLightSearch(String keyword){List<SearchHit<News>> result = newsRepository.findByTitleMatchesOrContentMatches(keyword, keyword);//處理結果,封裝News類型的集合ArrayList<News> newsList = new ArrayList();for (SearchHit<News> newsSearchHit : result) {News news = newsSearchHit.getContent();//高亮字段Map<String, List<String>> highlightFields = newsSearchHit.getHighlightFields();if(highlightFields.get("title") != null){news.setTitle(highlightFields.get("title").get(0));}if(highlightFields.get("content") != null){news.setTitle(highlightFields.get("content").get(0));}newsList.add(news);}return newsList; }將elasticsearch內部的處理高亮的結果封裝到News實體類中,然后返回
在Test根目錄下的com.zzx.escase.service包的NewsServiceTest測試類中添加高亮測試方法
@Test public void testHighLightSearch(){List<News> newsList = newsService.highLightSearch("演員");newsList.forEach(System.out::println); }此時每個演員的關鍵字都會被套上em的標簽,再由前端對em標簽進行渲染。
創建com.zzx.escase.controller包,在包下創建類NewsController
package com.zzx.escase.controller;import com.zzx.escase.document.News; import com.zzx.escase.service.NewsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController public class NewsController {@Autowiredprivate NewsService newsService;@GetMapping("/autoSuggest")public List<String> autoSuggest(String term){return newsService.autoSuggest(term);}@GetMapping("/highLightSearch")public List<News> highLightSearch(String term){return newsService.highLightSearch(term);} }啟動該springboot項目,然后在瀏覽器中查看:http://localhost:8080/autoSuggest?term="zhu"
以及http://localhost:8080/highLightSearch?term="演員"
7、頁面展示
前端頁面代碼:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>結果</title><link rel="stylesheet" type="text/css" href="css/jquery-ui.min.css"/><link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/><script src="js/jquery-2.1.1.min.js"></script><script src="js/jquery-ui.min.js"></script><style>body {padding-left: 14px;padding-top: 14px;}ul, li {list-style: none;padding: 0;}li {padding-bottom: 16px;}a, a:link, a:visited, a:hover, a:active {text-decoration: none;}em {color: red;font-style: normal;}</style> </head> <body> <div><input id="newsTag" class="form-control" style="display: inline; width: 50%;" name="keyword"><button class="btn btn-primary" onclick="search()">搜索一下</button> </div> <hr> <div><ul id="news"></ul> </div> </body> <script>$("#newsTag").autocomplete({source: "/autoSuggest", // 請求路徑delay: 100, //請求延遲minLength: 1 //最少輸入多少字符像服務器發送請求})function search() {var term = $("#newsTag").val();$.get("/highLightSearch", {term: term}, function (data) {var str = "";for (var i = 0; i < data.length; i++) {var document = data[i];str += "<li>" +" <h4>" +" <a href='" + document.url + "' target='_blank'>" + document.title + "</a>" +" </h4> " +" <p>" + document.content + "</p>" +" </li>";}$("#news").html(str);})} </script> </html>給輸入文本框綁定自動補齊autocomplete函數,以及給搜索按鈕綁定search函數,用以展示數據。
總結:
安裝Kibana需要修改Kibana的配置文件kiabana.yml,配置集群的連接即可。
在創建索引時,可以指定索引的分片數和分片的副本數,創建后只能修改分片的副本數。
1)優化磁盤,就是選擇SSD或者使用RAID0模式;
2)分片策略,就是每個分片占用的磁盤容量一般不超過32G。
分片數一般不超過節點數的三倍。
推遲分片分配。
減少副本數量,以及大批量寫入時,副本先設置為0,寫完再復原。
3)內存設置,就是Xmx和Xms的大小設置為相同。
Xmx和Xms不要超過物理內存的50%。
Xmx和Xms不要超過32G。
總結
以上是生活随笔為你收集整理的Elasticsearch集群搭建、优化及实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 清华大学自动化系和计算机系,清华大学自动
- 下一篇: 继电器电路图分析