ElasticSearch 6.3.2 整合 Springboot 2.1.10.RELEASE 版本,使用 Logstash 导入 mysql 数据

 阅读完本文需要 5 分钟。”​

最近因为项目需要使用到 Elasticsearch,故而去学了一下,在此记录一下。

一、搭建基础环境和项目脚手架

打开 https://www.elastic.co/ 官网,下载 elasticSearch-6.3.2.zip 压缩包,下载 kibana-6.3.2.zip 和 logstash-6.3.2.zip ,解压缩到一个 elk 的文件夹下。idea 使用 spring.start.io 来创建一个springboot 项目,注意 elasticsearch 和 springboot 版本对应的关系, 这里选择的是 Springboot 2.1.10.RELEASE,具体版本可以打开 https://mvnrepository.com/ 搜索 spring-boot-starter-data-elasticsearch 查看相关依赖,确定适合本机安装的 es 版本。

 

二、关于 Elasticsearch 和 Kibana 以及 Logstash 基本介绍

Elasticsearch 用于全文搜索,使用了基于 Restful 的 API 交互方式访问,它是一个文档数据库,可以对存储的每个字段进行索引,可以将 mysql 中的数据同步至 es 集群中进行分词处理,可以和 mysql 进行对比,

最新版本 7.7 发生了一些变动:es7的java代码,只能使用 restclient。然后,个人综合了一下,对于 java 编程,建议采用 High-level-rest-client 的方式操作 ES 集群

。官方 在 es7 删除 type,并且 es6 时已经规定每一个index只能有一个 type。在 es7 中使用默认的_doc作为 type,官方说在 8.x 版本会彻底移除 type。
api 请求方式也发送变化,如获得某索引的某ID的文档:GET
index/_doc/id 其中 index 和 id 为具体的值。

es 的基本操作:

1、前提是必须安装了相应版本  jdk, 启动 bin\elasticsearch.bat,linux 环境下 bin\elasticsearch,访问 localhost:9200 出现一串 json 字符串表示启动成功;

2、启动完 elasticsearch 后 再启动 Kibana ,进入解压目录 .\bin\kibana.bat , linux 下 .\bin\kibana ,启动成功的话。浏览器中访问 localhost:5601 会出现操作界面,打开 dev-tools 页面,下面进行索引的操作都在该页面进行;

2、索引的基本操作: 

新建 IndexName 唯一,不然报错

PUT /blog{}

 

查询索引:

GET _search

{

  "query": {

    "match_all": {}

  }

}

 

条件查询:

POST blog/_search

{

  "query": {

    "bool": {

      "should": [

        {

          "match_phrase": {

            "problem_desp": " "

          }

        },

        {

          "match_phrase": {

            "cloud_id": "abcd"

          }

        }

      ]

    }

  }

}

 

删除索引慎操作会删除当前索引的所有数据(类似于 mysql 中 drop database 操作):

DELETE /blog{}

 

3、es 基本分词器 和 ik 分词器介绍

分词器介绍:

standard 支持中文,词汇单元转成小写形式,采用单字切分

simple 非字母分词器去掉

workspace 去掉空格不支持中文

language 不支持中文

POST _analyze

{

  "analyzer": "standard",

  "text": "我是中国人"

}

 

返回结果:

{

  "tokens": [

    {

      "token": "我",

      "start_offset": 1,

      "end_offset": 2,

      "type": "<IDEOGRAPHIC>",

      "position": 0

    },

    {

      "token": "是",

      "start_offset": 2,

      "end_offset": 3,

      "type": "<IDEOGRAPHIC>",

      "position": 1

    },

    {

      "token": "中",

      "start_offset": 3,

      "end_offset": 4,

      "type": "<IDEOGRAPHIC>",

      "position": 2

    },

    {

      "token": "国",

      "start_offset": 4,

      "end_offset": 5,

      "type": "<IDEOGRAPHIC>",

      "position": 3

    },

    {

      "token": "人",

      "start_offset": 5,

      "end_offset": 6,

      "type": "<IDEOGRAPHIC>",

      "position": 4

    }

  ]

}

 

它们对于中文的支持就好像一个老外讲中文的感觉,所以国内 es 大神开发了中文分词器 ik ,打开网址  https://github.com/medcl/elasticsearch-analysis-ik/releases 选择你的 es 版本和对应的文件格式,下载完成以后在 es 的压缩目录下 plugins 文件夹下新建 ik 文件夹然后将下载的文件解压出来全部复制到 ik 文件夹下,重启 es 使之生效;

POST _analyze

{

  "analyzer": "ik_smart",

  "text": "我是中国人"

}

 


结果很智能,我是中国人,分为三个词, 我、是、中国人

{

  "tokens": [

    {

      "token": "我",

      "start_offset": 0,

      "end_offset": 1,

      "type": "CN_CHAR",

      "position": 0

    },

    {

      "token": "是",

      "start_offset": 1,

      "end_offset": 2,

      "type": "CN_CHAR",

      "position": 1

    },

    {

      "token": "中国人",

      "start_offset": 2,

      "end_offset": 5,

      "type": "CN_WORD",

      "position": 2

    }

  ]

}

 


或者使用 ik_max_word 

POST _analyze

{

  "analyzer": "ik_max_word",

  "text": "我是中国人"

}

 

查询结果和 ik_smart 对比一下:

{

  "tokens": [

    {

      "token": "我",

      "start_offset": 0,

      "end_offset": 1,

      "type": "CN_CHAR",

      "position": 0

    },

    {

      "token": "是",

      "start_offset": 1,

      "end_offset": 2,

      "type": "CN_CHAR",

      "position": 1

    },

    {

      "token": "中国人",

      "start_offset": 2,

      "end_offset": 5,

      "type": "CN_WORD",

      "position": 2

    },

    {

      "token": "中国",

      "start_offset": 2,

      "end_offset": 4,

      "type": "CN_WORD",

      "position": 3

    },

    {

      "token": "国人",

      "start_offset": 3,

      "end_offset": 5,

      "type": "CN_WORD",

      "position": 4

    }

  ]

}



4、使用 Logstash 导入 mysql 数据到 es 中

导入数据的到 es 中的中间件有很多, 阿里巴巴出的 canal 、还有其他 go-elasticsearch 中间件,这里使用的是官方出的 Logstash ,logstash 的作用相当于一个管道用于流通数据。由于是 mysql 数据库,进入 mysql 官网下载 jar 包,这里有个配置问题,关于 es 6.3.2 配置

logstash.conf 文件 和最新版本 es-7.7.0,es-6.3.2 将下好的 jar 文件放入 es 安装目录下,而 es-7.7.0 则可以将 jar 文件放入 logstash-7.7.0\logstash-core\lib\jars  目录下,相应的 logstash.conf 配置文件发生改变

logstash-6.3.2 配置放在 bin 目录下:

4.1、  全量

    一次性把数据全部导入到 elasticsearch 中,例如初始化

4.2、  增量

包括三个方面:

  • 插入数据
  • 原有数据更新
  • 原有数据删除

input {

  jdbc {

    jdbc_connection_string => "jdbc:mysql://localhost:3306/demo"

# The user we wish to execute our statement as

    jdbc_user => "root"

    jdbc_password => "123456"

# The path to our downloaded jdbc driver

    jdbc_driver_library => "D:\\elk\\logstash-6.3.2\\logstash-6.3.2\\mysql-connector-java-5.1.47.jar"

    jdbc_driver_class => "com.mysql.jdbc.Driver"

# our query

    statement => "select * from tb_article where create_date < NOW() order by create_date DESC;"

    }

  }

output {

  stdout { codec => json_lines }

  elasticsearch {

"hosts" => "localhost:9200"

"index" => "blog"

  document_type => "_doc"

  document_id => "%{article_id}"

  }

}

前提是 jar 放入 logstash-7.7.0\logstash-core\lib\jars  ,logstash-7.7.0  配置放在 bin 目录下:

input {

  jdbc {

    jdbc_connection_string => "jdbc:mysql://localhost:3306/demo"

# The user we wish to execute our statement as

    jdbc_user => "root"

    jdbc_password => "123456"

# The path to our downloaded jdbc driver

    jdbc_driver_library => ""

    jdbc_driver_class => "com.mysql.jdbc.Driver"

# our query

    statement => "select * from tb_article where create_date > :sql_last_value and create_date < NOW() order by create_date DESC;"

    }

  }

output {

  stdout { codec => json_lines }

  elasticsearch {

"hosts" => "localhost:9200"

"index" => "blog"

  document_type => "_doc"

  document_id => "%{article_id}"

  }

}

最后进入 logstash\bin 目录执行,logstash -f logstash.conf ,如果配置正确会看到控制台打印出配置中的 sql 语句, sql 语句中的 :sql_last_value 指的是上次访问的数据,

导入成功后在 dev-tools 执行如下命令

GET /blog/_stats

POST /blog/_search{}​

 

三、es 集成 springboot 项目,项目地址 :https://github.com/blench/es_demo,具体代码不做过多解释,目前最新的 es-7.7 版本 springboot 还在更新不建议使用最新,项目中使用了 jpa 和 ElasticsearchRepository 来作为 mysql 和 es 访问,出现了几个小问题,

一是 es 查询无数据:es 实体类配置,type ="_doc" 必须加上;

二是 json 关于对象空值报错问题,加上 @JsonIgnore 或者 spring. jackson.serialization.fail-on-empty-beans = false

三是 springboot-2.3.3 使用 jpa 会报错导致服务无法启动,目前上网找了原因是 hiberate 的问题还没有解决 todo,放弃高版本选择低版本稳定的 springboot 版本。

 

spring:

    jackson:     

      date-format:  yyyy-MM-dd HH:mm:ss

        serialization:

          fail-on-empty-beans:  false

@Document(indexName = "blog", type = "_doc", useServerConfiguration = true, createIndex = false)

 

最后比较一下 es  和 mysql 的区别:

ElasticSearch

MySQL

Index

Database

Type

Table

Document

Row

Field

Column

Mapping

Schema

Everything is indexed

Index

Query

SQL

GET http://…

select * from …

POST http://…

update table set …

关于 elk 基本的使用就到这里了, 更多有趣的 java 知识、面试经验、leetcode 刷题欢迎关注我的微信公众号

 

 

参考资料:

https://www.imooc.com/learn/1161

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html

https://aijishu.com/a/1060000000015410

http://stackoverflow.com/

 



 

 

 

posted @ 2020-06-06 18:14  暗影游侠  阅读(1114)  评论(0编辑  收藏  举报