Spring Boot(九):整合elasticsearch并使用logstash同步数据

一到周末,就想在家里躺尸,逛逛B站,看看直播,打打游戏,美哉美哉。当然,作为一名有自我修养的程序员,学习也是必不可少的。前段时间,我司的另一个项目组接手的项目中用到了elasticsearch,我就查了一下,原来是一个分布式的搜索框架;所以,决定入门学习一下。

ps:本文干货满满

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的对应关系:

elasticsearchMySQL
索引数据库
类型
文档

上面说的分词,文章后面部分会做相应的说明。

实体类创建完毕,接着创建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

只有明白了人性的弱点,才能有针对性的改变自己,适应环境,才能掌控自己的人生。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值