首頁技術(shù)文章正文

ElasticSearch入門教程[java培訓(xùn)]

更新時(shí)間:2020-04-10 來源:黑馬程序員 瀏覽量:

ElasticSearch 是一個(gè)高可用開源全文檢索和分析組件。提供存儲(chǔ)服務(wù),搜索服務(wù),大數(shù)據(jù)準(zhǔn)實(shí)時(shí)分析等。一般用于提供一些提供復(fù)雜搜索的應(yīng)用。


ElasticSearch 提供了一套基于restful風(fēng)格的全文檢索服務(wù)組件。前身是compass,直到2010被一家公司接管進(jìn)行維護(hù),開始商業(yè)化,并提供了ElasticSearch 一些相關(guān)的產(chǎn)品,包括大家比較熟悉的 kibana、logstash 以及 ElasticSearch 的一些組件,比如 安全組件shield 。當(dāng)前最新的ElasticSearch 版本為 5.1.1 ,比較應(yīng)用廣泛的為 2.X,直到 2016年12月推出了5.x 版本,將版本號(hào)調(diào)為 5.X 。這是為了和 kibana 和 logstash 等產(chǎn)品版本號(hào)進(jìn)行統(tǒng)一 ElasticSearch 。我們將從以下幾個(gè)問題快速了解一些ElasticSearch索引服務(wù)器。推薦了解黑馬程序員Java培訓(xùn)課程。


一、ES是如何產(chǎn)生背景


1、大規(guī)模數(shù)據(jù)如何檢索?

當(dāng)系統(tǒng)數(shù)據(jù)量上了10億、100億條的時(shí)候,我們?cè)谧鱿到y(tǒng)架構(gòu)的時(shí)候通常會(huì)從以下角度去考慮問題:


1)用什么數(shù)據(jù)庫好?(mysql、sybase、oracle、達(dá)夢(mèng)、神通、mongodb、hbase…)

2)如何解決單點(diǎn)故障; (lvs、F5、A10、Zookeep、MQ)

3)如何保證數(shù)據(jù)安全性;(熱備、冷備、異地多活)

4)如何解決檢索難題;(數(shù)據(jù)庫代理中間件:mysql-proxy、Cobar、MaxScale等;)

5)如何解決統(tǒng)計(jì)分析問題;(離線、近實(shí)時(shí))


2、傳統(tǒng)數(shù)據(jù)庫的應(yīng)對(duì)解決方案

對(duì)于關(guān)系型數(shù)據(jù),我們通常采用以下或類似架構(gòu)去解決查詢瓶頸和寫入瓶頸:

1)通過主從備份解決數(shù)據(jù)安全性問題;

2)通過數(shù)據(jù)庫代理中間件心跳監(jiān)測(cè),解決單點(diǎn)故障問題;

3)通過代理中間件將查詢語句分發(fā)到各個(gè)slave節(jié)點(diǎn)進(jìn)行查詢,并匯總結(jié)果

1586486810697_es快速入門01.png


3、非關(guān)系型數(shù)據(jù)庫的解決方案

對(duì)于Nosql數(shù)據(jù)庫,基本原理類似:

1)通過副本備份保證數(shù)據(jù)安全性;

2)通過節(jié)點(diǎn)競(jìng)選機(jī)制解決單點(diǎn)問題;

3)先從配置庫檢索分片信息,然后將請(qǐng)求分發(fā)到各個(gè)節(jié)點(diǎn),最后由路由節(jié)點(diǎn)合并匯總結(jié)果

es快速入門02


4、另辟蹊徑完全把數(shù)據(jù)放入內(nèi)存怎么樣?

我們知道,完全把數(shù)據(jù)放在內(nèi)存中是不可靠的,實(shí)際上也不太現(xiàn)實(shí),當(dāng)我們的數(shù)據(jù)達(dá)到PB級(jí)別時(shí),按照每個(gè)節(jié)點(diǎn) 96G內(nèi)存計(jì)算,在內(nèi)存完全裝滿的數(shù)據(jù)情況下,我們需要的機(jī)器是:1PB=1024T=1048576G 節(jié)點(diǎn)數(shù) =1048576/96=10922個(gè) 實(shí)際上,考慮到數(shù)據(jù)備份,節(jié)點(diǎn)數(shù)往往在2.5萬臺(tái)左右。成本巨大決定了其不現(xiàn)實(shí)!

從前面討論我們了解到,把數(shù)據(jù)放在內(nèi)存也好,不放在內(nèi)存也好,都不能完完全全解決問題。 全部放在內(nèi)存速度問題是解決了,但成本問題上來了。 為解決以上問題,從源頭著手分析,通常會(huì)從以下方式來尋找方法:

1、存儲(chǔ)數(shù)據(jù)時(shí)按有序存儲(chǔ);

2、將數(shù)據(jù)和索引分離;

3、壓縮數(shù)據(jù); 這就引出了Elasticsearch

二、ES基礎(chǔ)知識(shí)

1、ES主要解決問題

1)檢索相關(guān)數(shù)據(jù);

2)返回統(tǒng)計(jì)結(jié)果;

3)速度要快;

2、Lucene與ES關(guān)系

1)Lucene只是一個(gè)庫。想要使用它,你必須使用Java來作為開發(fā)語言并將其直接集成到你的應(yīng)用中,更糟糕的是,Lucene非常復(fù)雜,你需要深入了解檢索的相關(guān)知識(shí)來理解它是如何工作的。

2)Elasticsearch也使用Java開發(fā)并使用Lucene作為其核心來實(shí)現(xiàn)所有索引和搜索的功能,但是它的目的是通過簡單的RESTful API來隱藏Lucene的復(fù)雜性,從而讓全文搜索變得簡單。

3、ES工作原理
當(dāng)ElasticSearch的節(jié)點(diǎn)啟動(dòng)后,它會(huì)利用多播(multicast)(或者單播,如果用戶更改了配置)尋找集群中的其它節(jié)點(diǎn),并與之建立連接。這個(gè)過程如下圖所示:

es快速入門03


4、ES的基本概念

1)近實(shí)時(shí)查詢(Near RealTime)
Elasticsearch 是一個(gè)能提供近實(shí)時(shí)查詢的搜索服務(wù)引擎,這意味著從索引文檔到真正可搜索之間會(huì)有一個(gè)輕微的延遲(大概在一秒內(nèi))。

2)節(jié)點(diǎn)和集群
節(jié)點(diǎn)(node)是一個(gè)運(yùn)行著的 Elasticsearch 實(shí)例,你可以認(rèn)為是單個(gè)服務(wù)器。集群(cluster)是一個(gè)或多個(gè)節(jié)點(diǎn)的集合,他們協(xié)同工作,共享數(shù)據(jù)并提供故障轉(zhuǎn)移和擴(kuò)展功能。集群由唯一名稱標(biāo)識(shí),如 .NET Core 中的環(huán)境名稱,推薦在不同的環(huán)境中使用諸如
Development,Production 之類的名稱部署開發(fā)。其實(shí)節(jié)點(diǎn)和集群就是 web 開發(fā)中的常見概念而已,大家注意區(qū)分即可。

3)文檔
文檔是可索引信息的基本單元,以JSON表示。你可以用其來定義單個(gè)產(chǎn)品信息或是員工信息。我們可以把文檔理解為數(shù)據(jù)庫文檔中的行列數(shù)據(jù)。在索引/類型中,您可以存儲(chǔ)任意數(shù)量的文檔。文檔有幾個(gè)共同不可缺的屬性,分別為 _index, _type, _id, 針對(duì)特定一個(gè)或一類文檔進(jìn)行操作時(shí),必須指定這些屬性。 最后要提醒大家的是,雖然文檔物理上是駐留在索引中,但實(shí)際上文檔必須索引/分配給索引中的類型。

4)索引
索引是具有某些相似特征的文檔的集合,它和數(shù)據(jù)庫中的索引概念并不十分相同。我們可以把索引理解為數(shù)據(jù)庫文檔中的數(shù)據(jù)庫。事實(shí)上,我們的數(shù)據(jù)被存儲(chǔ)和索引在分片(shards)中,索引只是一個(gè)把一個(gè)或多個(gè)分片分組在一起的邏輯空間。然而,這只是一些內(nèi)部細(xì)節(jié)——我們的程序完全不用關(guān)心分片。

5)類型

在索引中,我們可以定義一個(gè)或多個(gè)類型。類型是索引的邏輯類別/分區(qū),其語義完全由開發(fā)者決定。通常,為具有一組公共字段的文檔定義類型。例如,假設(shè)開發(fā)者運(yùn)行博客平臺(tái)并將所有數(shù)據(jù)存儲(chǔ)在一個(gè)索引中。在此索引中,我們可以為用戶數(shù)據(jù)定義類型,為博客數(shù)據(jù)定義另一種類型,并為注釋數(shù)據(jù)定義另一種類型。我們可以把索引理解成數(shù)據(jù)庫文檔中的表。

6)分片和復(fù)制理

論上,索引可以存儲(chǔ)盡可能多的數(shù)據(jù),但是這種情況下性能往往不太樂觀,或者常見的磁盤容量限制也不能允許。所以 Elasticsearch 提供了類似于 MongoDB 中的分片功能,該功能能將索引細(xì)分為多個(gè)分片。每個(gè)分片本身是一個(gè)功能完全和獨(dú)立的“索引”,可以托管在集群中的任何節(jié)點(diǎn)上。

同樣的,有分片技術(shù)來處理數(shù)據(jù)量增長快速的問題,就意味著需要復(fù)制技術(shù)來應(yīng)對(duì)這種過程中(其實(shí)不只是該過程,任何情況下都應(yīng)該有安全意識(shí))數(shù)據(jù)安全的問題。Elasticsearch 允許您將索引分片的一個(gè)或多個(gè)副本轉(zhuǎn)換為所謂的副本分片。復(fù)制技術(shù)為我們提供了數(shù)據(jù)的高可用性和搜索吞吐的擴(kuò)展性。不過需要注意的是,副本分片從不分配在與從其復(fù)制的原始/主分片相同的節(jié)點(diǎn)上。

總而言之,每個(gè)索引可以拆分為多個(gè)分片。索引也可以復(fù)制為零(意味著沒有副本)或更多次。一旦復(fù)制,每個(gè)索引將具有主分片(從索引復(fù)制的原始分片)和副本分片(主分片的副本)。開發(fā)者可以在創(chuàng)建索引時(shí)就為每個(gè)索引定義分片和副本的數(shù)量。創(chuàng)建索引后,可以隨時(shí)動(dòng)態(tài)更改副本數(shù),但不能在此過程后隨即更改分片數(shù)。


三、ES的安裝與服務(wù)啟動(dòng)


1、下載ES的壓縮包


官網(wǎng)地址: https://www.elastic.co/products/elasticsearch


Window 系統(tǒng)下載 zip 版本,linux 系統(tǒng)下載 tar 版本將下載的zip解壓到指定的磁盤上


2、ES服務(wù)的目錄結(jié)構(gòu)

es快速入門04

bin 存放 elasticSearch 運(yùn)行命令 config 存放配置文件 lib 存放 elasticSearch 運(yùn)行依賴 jar 包 modules 存放 elasticSearch 模塊 plugins 存放插件。



3、ES服務(wù)的啟動(dòng)


指定ES安裝目錄下的bin下的elasticsearch.bat

es快速入門05


啟動(dòng)日志信息如下:

es快速入門06


4、訪問ES服務(wù)

es快速入門07


四、通過java去訪問ES服務(wù)


1、搭建環(huán)境

創(chuàng)建Maven工廠,添加ES的客戶端坐標(biāo)


<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>cn.itcast.maven</groupId>

  <artifactId>elasticsearch_helloworld</artifactId>

  <version>0.0.1‐SNAPSHOT</version>

  <name>elasticsearch_helloworld</name>

  <dependencies>

    <dependency>

        <groupId>org.elasticsearch</groupId>

        <artifactId>elasticsearch</artifactId>

        <version>2.4.0</version>

    </dependency>

    <dependency>

        <groupId>junit</groupId>

        <artifactId>junit</artifactId>

        <version>4.12</version>

    </dependency>

    <dependency>

        <groupId>com.fasterxml.jackson.core</groupId>

        <artifactId>jackson‐core</artifactId>

        <version>2.8.1</version>

    </dependency>

    <dependency>

        <groupId>com.fasterxml.jackson.core</groupId>

        <artifactId>jackson‐databind</artifactId>

        <version>2.8.1</version>

    </dependency>

    <dependency>

        <groupId>com.fasterxml.jackson.core</groupId>

        <artifactId>jackson‐annotations</artifactId>

        <version>2.8.1</version>

    </dependency>

  </dependencies>

</project>


2、創(chuàng)建索引


@Test

// 直接在ElasticSearch中建立文檔,自動(dòng)創(chuàng)建索引

public void demo1() throws IOException {

  // 創(chuàng)建連接搜索服務(wù)器對(duì)象

  Client client = TransportClient

    .builder()

 .build()

    .addTransportAddress(

    new InetSocketTransportAddress(InetAddress

                                   .getByName("127.0.0.1"), 9300));

  // 描述json 數(shù)據(jù)

  /*

         * {id:xxx, title:xxx, content:xxx}

         */

  XContentBuilder builder = XContentFactory

    .jsonBuilder()

    .startObject()

    .field("id", 1)

    .field("title", "ElasticSearch是一個(gè)基于Lucene的搜索服務(wù)器")

    .field("content",

           "它提供了一個(gè)分布式多用戶能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java開發(fā)

的,并作為Apache許可條款下的開放源碼發(fā)布,是當(dāng)前流行的企業(yè)級(jí)搜索引擎。設(shè)計(jì)用于云計(jì)算中,能夠達(dá)到實(shí)時(shí)搜

索,穩(wěn)定,可靠,快速,安裝使用方便。")

    .endObject();

  // 建立文檔對(duì)象

  client.prepareIndex("blog1", "article", "1").setSource(builder).get();

  // 關(guān)閉連接

  client.close();

}


3、查詢索引


@Test

// 各種查詢使用

public void demo3() throws IOException {

  // 創(chuàng)建連接搜索服務(wù)器對(duì)象

  Client client = TransportClient

    .builder()

    .build()

    .addTransportAddress(

    new InetSocketTransportAddress(InetAddress

                                   .getByName("127.0.0.1"), 9300));

  // 搜索數(shù)據(jù)

  // get() === execute().actionGet()

  // SearchResponse searchResponse = client.prepareSearch("blog1")

  // .setTypes("article")

  // .setQuery(QueryBuilders.queryStringQuery("全面")).get();

  // SearchResponse searchResponse = client.prepareSearch("blog1")

  // .setTypes("article")

  // .setQuery(QueryBuilders.wildcardQuery("content", "*全文*")).get();

  SearchResponse searchResponse = client.prepareSearch("blog2")

    .setTypes("article")

    .setQuery(QueryBuilders.termQuery("content", "搜索")).get();

  printSearchResponse(searchResponse);

  // 關(guān)閉連接

  client.close();

}


猜你喜歡:

如何理解并實(shí)現(xiàn)HashMap?

Java中級(jí)程序員學(xué)習(xí)線路圖



分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!