Spring Boot(九):整合elasticsearch並使用logstash同步數據

一到週末,就想在家裏躺屍,逛逛B站,看看直播,打打遊戲,美哉美哉。當然,作爲一名有自我修養的程序員,學習也是必不可少的。前段時間,我司的另一個項目組接手的項目中用到了elasticsearch,我就查了一下,原來是一個分佈式的搜索框架;所以,決定入門學習一下。

elasticsearch的背景

ElasticSearch是一個基於Lucene的搜索服務器。它提供了一個分佈式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java語言開發的,並作爲Apache許可條款下的開放源碼發佈,是一種流行的企業級搜索引擎。ElasticSearch用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。官方客戶端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和許多其他語言中都是可用的。根據DB-Engines的排名顯示,Elasticsearch是最受歡迎的企業搜索引擎,其次是Apache Solr,也是基於Lucene。

上面就是百度百科的介紹,基本上就是和Solr同源,都是基於Lucene來進行的封裝。想了解更多資料的讀者,請自行百度。本篇着重講解elasticsearch的使用。

elasticsearch的安裝

至於安裝,這裏博主提供兩種方法。
一:使用Docker安裝:
博主以前使用Docker安裝過elasticsearch,所以讀者可以看博主之前的文章。
https://blog.csdn.net/qq_32101993/article/details/100021002

二:在windows上安裝:
因爲用於本地測試,開發,就直接在windows上就好了。

下載安裝

首先去官網下載壓縮包:https://www.elastic.co/cn/downloads/past-releases

ps:這裏的版本需要根據自己的實際情況選擇,因爲博主會使用SpringBoot封裝的方法操作elasticsearch,而maven提供的最新版的 spring-data-elasticsearch 是 3.2,與之對應的elasticsearch版本是6.4.3 ,但是elasticsearch的最新版是7.4.0,所以,爲了方便,博主直接選擇歷史版本。

各位讀者根據需求下載所需版本即可。

elasticsearch壓縮包下載完成,解壓就行了,然後在bin目錄下雙擊elasticsearch或者在doc命令中敲命令也行。
啓動成功如下圖所示:

將elasticsearch加入系統服務

如果每個服務都使用doc命令來啓動,那麼電腦底下的任務欄會很亂,如果不小心關錯了,又要重新啓動一次,甚至需要殺掉進程,再次啓動。所以,直接將其添加爲系統服務,通過後臺服務的方式來啓動。

在bin目錄下的doc命令行中執行下面的命令

elasticsearch-service.bat install elasticsearch-6.4.3  # 最後是服務的名字,這裏可以自定義

執行上面的命令,當前服務就添加進了系統。然後可以通過任務管理器啓動了。
ps:通過任務管理器啓動elasticsearch服務,若是每次都顯示已停止,就證明此刻服務時有問題的。

需要對服務進行配置,在bin目錄下的doc命令行中輸入以下命令

elasticsearch-service.bat manager elasticsearch-6.4.3  # 後面跟的就是剛纔設置的服務名稱

然後,就會彈出一個管理界面。

根據圖上所示,之前是一個Java虛擬機的地址,現在選擇Use default,使用默認的,點擊確定。再次啓動服務,就可以看到服務啓動成功了。

通過PostMan工具,訪問地址:http://localhost:9200
看到了返回結果,當然,有讀者會問,爲什麼自己的name和cluster_name不一樣呢?這是因爲博主在啓動之前,對elasticsearch的默認配置進行了更改。

修改配置文件
# 集羣名稱
cluster.name: qfcwx

# 節點名稱
node.name: node-9006

# 配置是否跨域,方便head插件操作
http.cors.enabled: true
http.cors.allow-origin: "*"

博主就修改了上面的配置,其實還有很多配置,只是現在沒有接觸到。然後重啓服務,就可以看到自定義的集羣名稱和節點名稱了。

上面這些內容都是在說elasticsearch的安裝與啓動,下面就進行SpringBoot操作elasticsearch的環節。

SpringBoot整合elasticsearch

①、導入相應的約束。

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.2.0.RELEASE</version>
        </dependency>

這裏使用的是maven倉庫提供的最新版,依賴下載完,讀者可以點開依賴,查看elasticsearch的版本。因爲使用SpringBoot,所以其他包就不貼出來了,讀者根據項目需求導入。

②、修改配置文件

spring:
  data:
    elasticsearch:
      cluster-nodes: 127.0.0.1:9300
      cluster-name: qfcwx

③、編碼實戰
這裏就以檢索文章爲例,建立一個實體類。

package com.qfcwx.micro.search.pojo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

import java.io.Serializable;

/**
 * @ClassName: Article
 * @Author: 清風一陣吹我心
 * @Description: TODO  Elasticsearch需要的對象
 * @Date: 2019/10/19 16:11
 * @Version 1.0
 **/
@Data
@Document(indexName = "qfcwx_article", type = "article")
public class Article implements Serializable {

    @Id
    private String id;

    /**
     * 是否索引,看該域是否能被搜索
     * 是否分詞,表示搜索的時候是整體匹配還是單詞匹配
     * 是否存儲,是否在頁面上顯示
     */
    @Field(index = true, analyzer = "chinese", searchAnalyzer = "chinese")
    private String title;

    @Field(index = true, analyzer = "chinese", searchAnalyzer = "chinese")
    private String content;

    /**
     * 審批狀態
     */
    private String state;
}

@Data是lombook的註解,自動生成setter、getter等方法。
@Document這是elasticsearch的註解,indexName是索引的名字;type是類型。
@Field這個註解上面,類中也有相應的註解,表明當前屬性需要索引、分詞,存儲。

先說一下elasticsearch和MySQL的對應關係:

elasticsearch MySQL
索引 數據庫
類型
文檔

上面說的分詞,文章後面部分會做相應的說明。

實體類創建完畢,接着創建dao層。因爲使用spring-data的緣故,它將所有的關係型數據庫與非關係型數據庫的操作都封裝起來,提供一個統一的增刪改查方法,如果不通過配置和代碼,無法區分當前操作的是什麼數據庫。用的時間長了,感覺整個人都有點廢了的感覺,但是對於敏捷開發,真的是非常方便的。

public interface SearchRepository extends ElasticsearchRepository<Article, String> {

    /**
     * 自定義分頁查詢方法
     */
    Page<Article> findByTitleOrContentLike(String title, String content, Pageable pageable);
}

這裏寫了一個自定義方法,就像寫JPA一樣,根據方法名就能自動生成相應的查詢條件,不需要自己去寫sql。
然後寫service層。

@Service
@Transactional(rollbackFor = Exception.class)
public class SearchService {

    @Autowired
    private SearchRepository searchRepository;

    public void save(Article article) {
        article.setId(NumberUtil.getBitRandomNumber(6));
        searchRepository.save(article);
    }

    public PageResult<Article> findByKey(String key, Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page - 1, size);
        Page<Article> pageList = searchRepository.findByTitleOrContentLike(key, key, pageable);
        return new PageResult<Article>(pageList.getTotalElements(), pageList.getContent());
    }
}

這裏提供了兩個方法,一個是新增,一個是分頁查詢。
最後就是控制層了。

@RestController
@RequestMapping("/api/v1.0/article")
public class SearchController {

    @Autowired
    private SearchService searchService;

    @PostMapping
    public ResultBean<Boolean> save(@RequestBody Article article) {
        searchService.save(article);
        return new ResultBean<>(Boolean.TRUE);
    }

    @GetMapping(value = "/{key}/{page}/{size}")
    public ResultBean<PageResult<Article>> findByKey(@PathVariable String key, @PathVariable Integer page, @PathVariable Integer size) {
        return new ResultBean<>(searchService.findByKey(key, page, size));
    }
}

使用SpringBoot操作elasticsearch就是這麼簡單。

啓動項目,使用Postman工具進行測試。

可以看到返回結果,成功的插入了數據,接着多插入幾條數據。如何查看是否將數據存入了索引庫呢?此時,就可以使用第二個查詢接口了。

第一個參數是key,也就是通過什麼詞來搜索,後面兩個對應頁數和每頁的個數。

elasticsearch分詞器

通過上文知道了,操作elasticsearch是這麼簡單。SpringBoot大大簡化了操作關係型數據庫和非關係型數據庫的難度。但是,在開發中,還是有很多坑需要自己慢慢去踩,去解決的。

上面的Article實體類中說到了@Field這個註解,其中提到了分詞。那麼什麼是分詞呢?
其實理解起來很簡單。就是一句話分成幾個詞。下面就進行分詞的操作。
使用了elasticsearch原生的分詞器。
在Postman中輸入以下命令:

# elasticsearch 6.x和7.x
http://localhost:9200/_analyze/?pretty=true   並傳入json格式的數據:{ "analyzer": "chinese", "text": "我是程序員" }

# elasticsearch 5.x及以下
http://localhost:9200/_analyze?analyzer=chinese&pretty=true&text=我是程序員


結果反饋了,elasticsearch的默認分詞器,對中文並不友好。明明可以分成 我是、我、程序員等詞彙,連最基本的程序員詞彙都沒分出來,這真的是扎程序員的心啊。所以,爲了解決這種問題,就需要使用能夠支持中文的分詞器——ik分詞器。
至於ik分詞器是什麼,請各位自行查閱相關資料。

首先下載這個插件,和elasticsearch的版本對應。下載地址:
https://github.com/medcl/elasticsearch-analysis-ik/releases
下載完了,解壓放入elasticsearch文件夾裏面的plugin文件夾中即可。然後重啓服務。

修改analyzer的參數,重新發送請求。
ik_smart: 會將文本做最粗粒度的拆分,比如會將“我是程序員”,拆分爲:我、是、程序員。
ik_max_word: 會將文本做最細粒度的拆分,比如會將“我是程序員”,拆分爲:我、是、程序員、程序、員。

上面兩種分詞器,讀者根據開發需求選擇一個就可以了。
除了這些正規詞彙,還有一些詞,使用ik分詞器,也是無法正確分詞的。比如,博主經常在B站中看番。對於B站的粉絲肯定知道"阿偉死了"這個詞吧!如果使用這個詞來測試,會是什麼樣的結果呢?就來測試一下:

上面的分詞器還是將每個字分開了。這樣通過索引也無法找到正確的內容。那麼如何解決這個問題呢?“解鈴還須繫鈴人”,ik分詞器提供了自定義分詞策略。
進入我們剛纔解壓放入elasticsearch的plugin文件夾下的ik分詞器目錄,在config目錄中可以看到很多以.dic爲後綴的文件。

這些都是ik分詞器自帶的單詞與解釋的文件。以同樣的方式創建一個.dic的文件,名稱根據自己的喜好命名。然後用記事本打開,在裏面填入需要分詞的詞語。注意,這裏雖然創建了文件,但是分詞器並不知道自定義文件的名稱是什麼,所以,需要在 IKAnalyzer.cfg.xml文件中進行配置。

根據上面的提示,填入文件名稱及後綴就行,然後重啓服務,再用Postman測試。

通過圖片,可以看到,自定義的詞彙成功分詞了。如果以後還有其他分詞器沒有收錄的詞語,將其添加到文件中即可。關於ik分詞器的講解,到這裏就結束了。

Logstash同步數據

Logstash是一個開源的服務器端數據處理管道,可以同時從多個數據源獲取數據,並對其進行轉換,然後將其發送到你最喜歡的“存儲”。(當然,我們最喜歡的是Elasticsearch)

通過上面的話,可以知道Logstash可以將不同數據庫的數據同步到elasticsearch中。在實際開發中,不可能通過手動添加的方式將數據插入索引庫,所以需要藉助第三方工具,將數據庫的數據同步到索引庫。此時,Logstash出現了,它的使用方法也很簡單,下面講解一下,它是如何使用的。

首先下載對應版本的Logstash包,可以通過上面提供下載elasticsearch的地址進行下載,完成後解壓。

因爲解壓完的目錄和elasticsearch與MySQL沒有絲毫聯繫,這時就需要我們編寫配置文件了。根據官網和網上提供的配置文件,將其進行修改。其實就像Java連接數據庫,需要指明驅動、用戶名、密碼;操作elasticsearch,需要指明地址、集羣名稱等。這裏就是將elasticsearch與MySQ聯繫起來。熟悉JDBC操作的讀者,肯定知道這些配置如何填寫,這裏就不細說了。

先看一下上面配置中數據庫中的數據。

數據庫目前就添加了兩條測試數據。然後查看elasticsearch中索引庫中的文檔。
通過外部命令查看當前索引庫中的數據:

http://localhost:9200/qfcwx_article/article/_search


此時,索引庫中只有兩條數據,接下來就使用Logstash往索引庫中添加數據。

在Logstash的bin目錄下輸入命令:

logstash -f ../mysql/mysql.conf  # 後面跟的是文件地址,這是填的相對路徑

命令敲完,等一會就會看到紅色畫線部分提示啓動成功。因爲在配置文件中配置的同步時間是每分鐘同步一次,所以就等服務啓動完成之後的一分鐘後查看doc命令行的日誌輸出。

紅框部分顯示了配置文件中配置的sql,還有執行完的結果集。這時,再看看索引庫中的所有數據。

查詢結果表明,數據同步成功。
Logstash的基本用法就講完了。

elasticsearch-head插件的使用

在Docker安裝elasticsearch那篇博文中,已經提到了使用head插件來操作elasticsearch,所以這篇文章就簡短的提一下。
head插件是一個用來操作elasticsearch的圖形化界面工具,需要先下載,然後解壓啓動。但是Google提供了一款插件,和我們所要使用的插件是一模一樣的,只需在Google商店搜索並安裝即可。省去了在本地安裝下載的麻煩。

一切準備就緒就可以啓動elasticsearch服務,然後打開head插件進行連接了。

點擊菜單欄上的“索引”,可以新建索引。

保存,然後在數據瀏覽中可以看到索引中是否有數據。因爲剛建立索引,所以索引庫中還沒有數據。

接着就通過這個插件來添加幾條數據。

如上圖所示,右邊提示created就表明創建成功了。然後在查看索引庫中的數據。

此時就將剛纔添加的數據顯示出來了,如果數據看不完整,請刷新整個頁面。
當然,也能對已經存在的數據進行刪除。只需要根據數據的id進行下面的操作即可。

本篇關於elasticsearch的文章到這裏就接近尾聲了,上面提到的所有知識點,都只是一個入門,要想深入,還需要通過資料以及官方文檔進行學習。當然,如果文章中出現不足或者錯誤的地方也請各位讀者指出。程序員就是這樣一個特殊的羣體,讓學習永不止步。希望與各位讀者共同進步。

只有明白了人性的弱點,纔能有針對性的改變自己,適應環境,才能掌控自己的人生。

參考資料:
https://www.cnblogs.com/cjsblog/p/9459781.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章