Featured image of post 【微服务】11、ElasticSearch

【微服务】11、ElasticSearch

初识elasticsearch

什么是elasticsearch

elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容。

elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)(是以elasticsearch为核心的技术栈,包括beats、Logstash、kibana、elasticsearch)。被广泛应用在日志数据分析、实时监控等领域。

elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。

elasticsearch的发展

Lucene是一个Java语言的搜索引擎类库,是Apache公司的顶级项目,由DougCutting1999年研发。官网地址:https://lucene.apache.org/

Lucene的优势:

:::danger 易扩展

高性能(基于倒排索引)

:::

Lucene的缺点:

:::color4 只限于Java语言开发

学习曲线陡峭

不支持水平扩展

:::

2004Shay Banon基于Lucene开发了Compass

2010Shay Banon重写了Compass,取名为Elasticsearch

官网地址: https://www.elastic.co/cn/

相比与luceneelasticsearch具备下列优势:

:::success 支持分布式,可水平扩展

提供Restful接口,可被任何语言调用

:::

正向索引和倒排索引

传统数据库(如MySQL)采用正向索引,例如给下表(tb_goods)中的id创建索引:

elasticsearch采用倒排索引:

:::success 文档(document):每条数据就是一个文档

词条(term):文档按照语义分成的词语

:::

总结:

什么是文档和词条?

:::success 每一条数据就是一个文档

对文档中的内容分词,得到的词语就是词条

:::

什么是正向索引?

:::warning 基于文档id创建索引。查询词条时必须先找到文档,而后判断是否包含词条

:::

什么是倒排索引?

:::color1 对文档内容分词,对词条创建索引,并记录词条所在文档的信息。查询时先根据词条查询到文档id,而后获取到文档

:::

elasticsearch是面向文档存储的,可以是数据库中的一条商品数据,一个订单信息。

文档数据会被序列化为json格式后存储在elasticsearch中。

mysql和elasticsearch概念对比

MySQL Elasticsearch 说明
Table Index 索引(index),就是文档的集合,类似数据库的表(table)
Row Document 文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式
Column Field 字段(Field),就是JSON文档中的字段,类似数据库中的列(Column
Schema Mapping Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema
SQL DSL DSLelasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

Mysql:擅长事务类型操作,可以确保数据的安全和一致性

Elasticsearch:擅长海量数据的搜索、分析、计算

总结:

文档:一条数据就是一个文档,es中是Json格式

字段:Json文档中的字段

索引:同类型文档的集合

映射:索引中文档的约束,比如字段名称、类型

elasticsearch与数据库的关系:

数据库负责事务类型操作

elasticsearch负责海量数据的搜索、分析、计算

安装elasticsearch、kibana、IK分词器

采用docker安装它们

部署单点es

创建网络

因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络:

1
docker network create es-net

运行docker命令,部署单点es:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
docker run -d \
	--name es \
    -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
    -e "discovery.type=single-node" \
    -v es-data:/usr/share/elasticsearch/data \
    -v es-plugins:/usr/share/elasticsearch/plugins \
    --privileged \
    --network es-net \
    -p 9200:9200 \
    -p 9300:9300 \
elasticsearch:7.12.1

命令解释:

  • -e "cluster.name=es-docker-cluster":设置集群名称
  • -e "http.host=0.0.0.0":监听的地址,可以外网访问
  • -e "ES_JAVA_OPTS=-Xms512m -Xmx512m":内存大小
  • -e "discovery.type=single-node":非集群模式
  • -v es-data:/usr/share/elasticsearch/data:挂载逻辑卷,绑定es的数据目录
  • -v es-logs:/usr/share/elasticsearch/logs:挂载逻辑卷,绑定es的日志目录
  • -v es-plugins:/usr/share/elasticsearch/plugins:挂载逻辑卷,绑定es的插件目录
  • --privileged:授予逻辑卷访问权
  • --network es-net :加入一个名为es-net的网络中
  • -p 9200:9200:端口映射配置

在浏览器中输入:http://虚拟机ip:9200 即可看到elasticsearch的响应结果:

部署kibana

kibana可以给我们提供一个elasticsearch的可视化界面,便于我们学习。

运行docker命令,部署kibana:

1
2
3
4
5
6
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601  \
kibana:7.12.1

kibana启动一般比较慢,需要多等待一会,可以通过命令:

1
docker logs -f kibana |grep 5601

查看运行日志,当查看到下面的日志,说明成功:

此时,在浏览器输入地址访问:http://虚拟机ip:5601,即可看到结果

安装IK分词器

在线安装:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 进入容器内部
docker exec -it es /bin/bash

# 在线下载并安装
./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip

#退出
exit

#重启容器
docker restart es

IK分词器包含两种模式:

  • ik_smart:最少切分,粒度较粗

  • ik_max_word:最细切分,粒度细

进入es的Dev Tools

扩展词典和停用词典

随着互联网的发展,“造词运动”也越发的频繁。出现了很多新的词语,在原有的词汇列表中并不存在。比如:“奥力给”,“传智播客” 等。

所以我们的词汇也需要不断的更新,IK分词器提供了扩展词汇的功能。

1)打开IK分词器config目录:

2)在IKAnalyzer.cfg.xml配置文件内容添加:

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
  <comment>IK Analyzer 扩展配置</comment>
  <!--用户可以在这里配置自己的扩展字典 *** 添加扩展词典-->
  <entry key="ext_dict">ext.dic</entry>
</properties>

3)新建一个 ext.dic,可以参考config目录下复制一个配置文件进行修改

1
2
传智播客
奥力给

4)重启elasticsearch

1
2
3
4
docker restart es

# 查看 日志
docker logs -f elasticsearch

日志中已经成功加载ext.dic配置文件

停用词典:

在互联网项目中,在网络间传输的速度很快,所以很多语言是不允许在网络上传递的,如:关于宗教、政治等敏感词语,那么我们在搜索时也应该忽略当前词汇。

IK分词器也提供了强大的停用词功能,让我们在索引时就直接忽略当前的停用词汇表中的内容。

1)IKAnalyzer.cfg.xml配置文件内容添加:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
  <comment>IK Analyzer 扩展配置</comment>
  <!--用户可以在这里配置自己的扩展字典-->
  <entry key="ext_dict">ext.dic</entry>
  <!--用户可以在这里配置自己的扩展停止词字典  *** 添加停用词词典-->
  <entry key="ext_stopwords">stopword.dic</entry>
</properties>

3)在 stopword.dic 添加停用词

1
习大大

4)重启elasticsearch

1
2
3
4
5
6
# 重启服务
docker restart es
docker restart kibana

# 查看 日志
docker logs -f es

日志中已经成功加载stopword.dic配置文件

注意当前文件的编码必须是 UTF-8 格式,严禁使用Windows记事本编辑

总结:

分词器的作用是什么?

:::warning 创建倒排索引时对文档分词

用户搜索时,对输入的内容分词

:::

IK分词器有几种模式?

:::color1 ik_smart:智能切分,粗粒度

ik_max_word:最细切分,细粒度

:::

IK分词器如何拓展词条?如何停用词条?

:::danger 利用config目录的IkAnalyzer.cfg.xml文件添加拓展词典和停用词典

在词典中添加拓展词条或者停用词条

:::

数据同步

elasticsearch中的酒店数据来自于mysql数据库,因此mysql数据发生改变时,elasticsearch也必须跟着改变,这个就是elasticsearch与mysql之间的数据同步

总结:

方式一:同步调用

:::info 优点:实现简单,粗暴

缺点:业务耦合度高

:::

方式二:异步通知

:::color2 优点:低耦合,实现难度一般

缺点:依赖mq的可靠性

:::

方式三:监听binlog

:::color3 优点:完全解除服务间耦合

缺点:开启binlog增加数据库负担、实现复杂度高

:::

使用 Hugo 构建
主题 StackJimmy 设计