ElasticSearch

一、引言

1.1、ElasticSearch是什么?

The Elastic Stack, 包括 Elasticsearch、Kibana、Beats 和 Logstash(也稱為 ELK Stack)。能夠安全可靠地獲取任何來源、任何格式的數(shù)據(jù),然后實時地對數(shù)據(jù)進行搜索、分析和可視化。Elaticsearch,簡稱為 ES,ES 是一個開源的高擴展的分布式全文搜索引擎,是整個 Elastic Stack 技術(shù)棧的核心。它可以近乎實時的存儲、檢索數(shù)據(jù);本身擴展性很好,可以擴展到上百臺服務(wù)器,處理 PB 級別的數(shù)據(jù)。

1.2 全文搜索引擎

Google,百度類的網(wǎng)站搜索,它們都是根據(jù)網(wǎng)頁中的關(guān)鍵字生成索引,我們在搜索的時候輸入關(guān)鍵字,它們會將該關(guān)鍵字即索引匹配到的所有網(wǎng)頁返回;還有常見的項目中應用日志的搜索等等。對于這些非結(jié)構(gòu)化的數(shù)據(jù)文本,關(guān)系型數(shù)據(jù)庫搜索不是能很好的支持。一般傳統(tǒng)數(shù)據(jù)庫,全文檢索都實現(xiàn)的很雞肋,因為一般也沒人用數(shù)據(jù)庫存文本字段。進行全文檢索需要掃描整個表,如果數(shù)據(jù)量大的話即使對 SQL 的語法優(yōu)化,也收效甚微。建立了索引,但是維護起來也很麻煩,對于 insert 和 update 操作都會重新構(gòu)建索引。基于以上原因可以分析得出,在一些生產(chǎn)環(huán)境中,使用常規(guī)的搜索方式,性能是非常差的:

? 搜索的數(shù)據(jù)對象是大量的非結(jié)構(gòu)化的文本數(shù)據(jù)。
? 文件記錄量達到數(shù)十萬或數(shù)百萬個甚至更多。
? 支持大量基于交互式文本的查詢。
? 需求非常靈活的全文搜索查詢。
? 對高度相關(guān)的搜索結(jié)果的有特殊需求,但是沒有可用的關(guān)系數(shù)據(jù)庫可以滿足。
? 對不同記錄類型、非文本數(shù)據(jù)操作或安全事務(wù)處理的需求相對較少的情況。

為了解決結(jié)構(gòu)化數(shù)據(jù)搜索和非結(jié)構(gòu)化數(shù)據(jù)搜索性能問題,我們就需要專業(yè),健壯,強大的全文搜索引擎這里說到的全文搜索引擎指的是目前廣泛應用的主流搜索引擎。它的工作原理是計算機索引程序通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該詞在文章中出現(xiàn)的次數(shù)和位置,當用戶查詢時,檢索程序就根據(jù)事先建立的索引進行查找,并將查找的結(jié)果反饋給用戶的檢索方式。這個過程類似于通過字典中的檢索字表查字的過程。

1.3 Elasticsearch And Solr

Lucene 是 Apache 軟件基金會 Jakarta 項目組的一個子項目,提供了一個簡單卻強大的應用程式接口,能夠做全文索引和搜尋。在 Java 開發(fā)環(huán)境里 Lucene 是一個成熟的免費開源工具。就其本身而言,Lucene 是當前以及最近幾年最受歡迎的免費 Java 信息檢索程序庫。但 Lucene 只是一個提供全文搜索功能類庫的核心工具包,而真正使用它還需要一個完善的服務(wù)框架搭建起來進行應用。目前市面上流行的搜索引擎軟件,主流的就兩款:Elasticsearch 和 Solr,這兩款都是基于 Lucene 搭建的,可以獨立部署啟動的搜索引擎服務(wù)軟件。由于內(nèi)核相同,所以兩者除了服務(wù)器安裝、部署、管理、集群以外,對于數(shù)據(jù)的操作 修改、添加、保存、查詢等等都十分類似。在使用過程中,一般都會將 Elasticsearch 和 Solr 這兩個軟件對比,然后進行選型。這兩個搜索引擎都是流行的,先進的的開源搜索引擎。它們都是圍繞核心底層搜索庫 - Lucene構(gòu)建的 - 但它們又是不同的。像所有東西一樣,每個都有其優(yōu)點和缺點:

1.4 Elasticsearch Or Solr

1、 與 Solr 相比,Elasticsearch 易于安裝且非常輕巧。此外,你可以在幾分鐘內(nèi)安裝并運行Elasticsearch。但是,如果 Elasticsearch 管理不當,這種易于部署和使用可能會成為一個問題。基于 JSON 的配置很簡單,但如果要為文件中的每個配置指定注釋,那么它不適合您??偟膩碚f,如果你的應用使用的是JSON,那么 Elasticsearch 是一個更好的選擇。否則,請使用 Solr,因為它的 schema.xml 和 solrconfig.xml 都有很好的文檔記錄。
2、Solr 擁有更大,更成熟的用戶,開發(fā)者和貢獻者社區(qū)。ES 雖擁有的規(guī)模較小但活躍的用戶社區(qū)以及不斷增長的貢獻者社區(qū)。Solr 貢獻者和提交者來自許多不同的組織,而 Elasticsearch 提交者來自單個公司。
3、 Solr 更成熟,但 ES 增長迅速,更穩(wěn)定。
4、Solr 是一個非常有據(jù)可查的產(chǎn)品,具有清晰的示例和 API 用例場景。 Elasticsearch 的 文檔組織良好,但它缺乏好的示例和清晰的配置說明。
5、 Elasticsearch 易于使用,一個下載和一個命令就可以啟動一切。
6、 如果除了搜索文本之外還需要它來處理分析查詢,Elasticsearch 是更好的選擇
7、 如果需要分布式索引,則需要選擇 Elasticsearch。對于需要良好可伸縮性和以及性能分布式環(huán)境,Elasticsearch 是更好的選擇。
8、 Elasticsearch 在開源日志管理用例中占據(jù)主導地位,許多組織在 Elasticsearch 中索引它們的日志以使其可搜索。
9、如果你喜歡監(jiān)控和指標,那么請使用 Elasticsearch,因為相對于 Solr,Elasticsearch 暴露了更多的關(guān)鍵指標

二、Elasticsearch 入門

1、 Elasticsearch 安裝

Elasticsearch 的官方地址:https://www.elastic.co/cn/

Windows 版的 Elasticsearch 的安裝很簡單,解壓即安裝完畢。進入 bin 文件目錄,點擊 elasticsearch.bat 文件啟動 ES 服務(wù)
Linux版的安裝也很簡單,解壓后./Elasticsearch 就可以啟動。

注意:9300 端口為 Elasticsearch 集群間組件的通信端口,9200 端口為瀏覽器訪問的 http協(xié)議 RESTful 端口。打開瀏覽器(推薦使用谷歌瀏覽器),輸入地址:http://localhost:9200

測試結(jié)果

2、問題解決

Elasticsearch 是使用 java 開發(fā)的,且 7.8 版本的 ES 需要 JDK 版本 1.8 以上,默認安裝包帶有 jdk 環(huán)境,如果系統(tǒng)配置 JAVA_HOME,那么使用系統(tǒng)默認的 JDK,如果沒有配置使用自帶的 JDK,一般建議使用系統(tǒng)配置的 JDK。 如果雙擊啟動窗口閃退,通過路徑訪問追蹤錯誤,如果是“空間不足”,請修改config/jvm.options 配置文件

修改JVM配置

三、Elasticsearch 基本操作

1、RESTful

REST 指的是一組架構(gòu)約束條件和原則。滿足這些約束條件和原則的應用程序或設(shè)計就是 RESTful。Web 應用程序最重要的 REST 原則是,客戶端和服務(wù)器之間的交互在請求之間是無狀態(tài)的。從客戶端到服務(wù)器的每個請求都必須包含理解請求所必需的信息。如果服務(wù)器在請求之間的任何時間點重啟,客戶端不會得到通知。此外,無狀態(tài)請求可以由任何可用服務(wù)器回答,這十分適合云計算之類的環(huán)境??蛻舳丝梢跃彺鏀?shù)據(jù)以改進性能。
在服務(wù)器端,應用程序狀態(tài)和功能可以分為各種資源。資源是一個有趣的概念實體,它向客戶端公開。資源的例子有:應用程序?qū)ο?、?shù)據(jù)庫記錄、算法等等。每個資源都使用 URI (Universal Resource Identifier) 得到一個唯一的地址。所有資源都共享統(tǒng)一的接口,以便在客戶端和服務(wù)器之間傳輸狀態(tài)。使用的是標準的 HTTP 方法,比如 GET、PUT、POST 和
DELETE。
在 REST 樣式的 Web 服務(wù)中,每個資源都有一個地址。資源本身都是方法調(diào)用的目標,方法列表對所有資源都是一樣的。這些方法都是標準方法,包括 HTTP GET、POST、PUT、DELETE,還可能包括 HEAD 和 OPTIONS。簡單的理解就是,如果想要訪問互聯(lián)網(wǎng)上的資源,就必須向資源所在的服務(wù)器發(fā)出請求,請求體中必須包含資源的網(wǎng)絡(luò)路徑,以及對資源進行的操作(增刪改查)。

2、 數(shù)據(jù)格式

和Mysql數(shù)據(jù)庫做類比

ES 里的 Index 可以看做一個庫,而 Types 相當于表,Documents 則相當于表的行。這里 Types 的概念已經(jīng)被逐漸弱化,Elasticsearch 6.X 中,一個 index 下已經(jīng)只能包含一個type,Elasticsearch 7.X 中, Type 的概念已經(jīng)被刪除了。

3、HTTP 操作

3.1索引

3.1.1創(chuàng)建索引

對比關(guān)系型數(shù)據(jù)庫,創(chuàng)建索引就等同于創(chuàng)建數(shù)據(jù)庫,在 Postman 中,向 ES 服務(wù)器發(fā) PUT 請求 :http://127.0.0.1:9200/shopping,請求后,服務(wù)器返回響應,如果重復添加索引,會返回錯誤信息

{
"acknowledged"【響應結(jié)果】: true, # true 操作成功
 "shards_acknowledged"【分片結(jié)果】: true, # 分片操作成功
 "index"【索引名稱】: "shopping"
}

注意:創(chuàng)建索引庫的分片數(shù)默認 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默認 5 片

3.1.2查看所有索引

在 Postman 中,向 ES 服務(wù)器發(fā) GET 請求 :http://127.0.0.1:9200/_cat/indices?v
這里請求路徑中的_cat 表示查看的意思,indices 表示索引,所以整體含義就是查看當前 ES服務(wù)器中的所有索引,就好像 MySQL 中的 show tables 的感覺,服務(wù)器響應結(jié)果如下:

查看索引結(jié)果
image.png

3.1.3查看單個索引

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

查看索引向 ES 服務(wù)器發(fā)送的請求路徑和創(chuàng)建索引是一致的。但是 HTTP 方法不一致。這里是發(fā)送Get請求,可以體會一下 RESTful 的意義。

3.1.4刪除索引

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

3.2文檔

3.2.1 創(chuàng)建文檔

索引已經(jīng)創(chuàng)建好了,接下來我們來創(chuàng)建文檔,并添加數(shù)據(jù)。這里的文檔可以類比為關(guān)系型數(shù)據(jù)庫中的表數(shù)據(jù),添加的數(shù)據(jù)格式為 JSON 格式
在 Postman 中,此處發(fā)送請求的方式必須為 POST,不能是 PUT,否則會發(fā)生錯誤,向 ES 服務(wù)器發(fā) POST 請求 :http://127.0.0.1:9200/shopping/_doc
舉例說請求體內(nèi)容為:

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

返回結(jié)果如下:

{
 "_index"【索引】: "shopping",
 "_type"【類型-文檔】: "_doc",
 "_id"【唯一標識】: "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
}

上面的數(shù)據(jù)創(chuàng)建后,由于沒有指定數(shù)據(jù)唯一性標識(ID),默認情況下,ES 服務(wù)器會隨機生成一個。如果想要自定義唯一性標識,需要在創(chuàng)建時指定(例如指定id為1):http://127.0.0.1:9200/shopping/_doc/1

3.2.2 查看文檔

查看文檔時,需要指明文檔的唯一性標識,類似于 MySQL 中數(shù)據(jù)的主鍵查詢在 Postman 中,向 ES 服務(wù)器發(fā) GET 請求 :http://127.0.0.1:9200/shopping/_doc/1
查詢成功后,服務(wù)器響應結(jié)果:

{
 "_index"【索引】: "shopping",
 "_type"【文檔類型】: "_doc",
 "_id": "1",
 "_version": 2,
 "_seq_no": 2,
 "_primary_term": 2,
 "found"【查詢結(jié)果】: true, # true 表示查找到,false 表示未查找到
 "_source"【文檔源信息】: {
 "title": "華為手機",
 "category": "華為",
 "images": "http://www.gulixueyuan.com/hw.jpg",
 "price": 4999.00
 } 

3.2.3修改文檔

和新增文檔一樣,輸入相同的 URL 地址請求,如果請求體變化,會將原有的數(shù)據(jù)內(nèi)容覆蓋在 Postman 中,向 ES 服務(wù)器發(fā) POST 請求 :http://127.0.0.1:9200/shopping/_doc/1
請求體的內(nèi)容為:

{
 "title":"華為手機",
 "category":"華為",
 "images":"http://www.gulixueyuan.com/hw.jpg",
 "price":4999.00
}

修改成功后,服務(wù)器響應結(jié)果:

{
 "_index": "shopping",
 "_type": "_doc",
 "_id": "1",
 "_version"【版本】: 2,
 "result"【結(jié)果】: "updated", # updated 表示數(shù)據(jù)被更新
 "_shards": {
 "total": 2,
 "successful": 1,
 "failed": 0
 },
 "_seq_no": 2,
 "_primary_term": 2
}

修改后,如上版本會發(fā)生變化。

3.2.4修改字段

修改數(shù)據(jù)時,也可以只修改某一給條數(shù)據(jù)的局部信息,在 Postman 中,向 ES 服務(wù)器發(fā) POST 請求 :http://127.0.0.1:9200/shopping/_update/1
請求體內(nèi)容為:

{ 
 "doc": {
 "price":3000.00
 } 
}

1、倒排索引
2、IK分詞器可以自己添加關(guān)鍵詞,例如"西谷",不是個詞,但是如果想自己添加,可以自己添加一個dic文檔(第八集)


image.png

API學習

1、首先添加配置

/**
 * @author fuzq
 * @create
 */

@Configuration
public class esClientConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("localhost", 9200, "http")));
        return client;
    }
}

2、索引

//測試索引的創(chuàng)建
    @Test
    void createIndex() throws IOException {
        //創(chuàng)建請求
        CreateIndexRequest request = new CreateIndexRequest("xigu");
        //客戶端執(zhí)行請求,請求后獲得響應
        CreateIndexResponse createIndexResponse =
                restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);

        System.out.println(createIndexResponse);

    }
 //判斷索引是否存在
    @Test
    void getIndex() throws IOException {
        //創(chuàng)建請求
        GetIndexRequest getIndexRequest = new GetIndexRequest("xigu");
        boolean exists = restHighLevelClient.indices().exists(getIndexRequest,RequestOptions.DEFAULT);
        System.out.println(exists);


    }
//刪除索引
    @Test
    void deleteIndex() throws IOException{
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("傅志強傅志強。。。");
        AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        System.out.println(delete);
    }

3、文檔

image.png
image.png
image.png
image.png
image.png
image.png
image.png

部署EK+fileBeat
linux部署elasticsearch和kibana,在windows部署filebeat

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

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

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