Administrator
发布于 2023-05-12 / 16 阅读
0
0

微服务(十二)——elasticsearch

什么是elasticsearch

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

elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在海量数据搜索、日志统计分析、实时监控等领域。

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

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

Lucene的优势:

  • 易扩展
  • 高性能(基于倒排索引)

Lucene的缺点:

  • 只限于Java语言开发
  • 学习曲线陡峭
  • 不支持水平扩展

而elasticsearch正是基于Lucene开发的搜索引擎,官网地址:https://www.elastic.co/cn/

相比Lucene,elasticsearch具备以下优势

  • 支持分布式,可水平扩展
  • 提供Restful接口,可被任何语言调用

倒排索引

学习elasticsearch,首先需要了解下什么是倒排索引。

我们先通过例子来看下正向索引。

在mysql中,对于%开头的模糊查询,是不会走索引的,而是会逐条检索。如果有百万条数据,那么就要逐条检索百万次,搜索效率会很低。

那么我们来看下倒排索引是怎么做的

elasticsearch每一条数据就是一个文档,它会对文档中的内容分词,得到的词语就是词条。在查询数据时,将搜索内容分成词条,根据词条去词条表中查询到文档id并合并。最后根据文档id查询并返回文档数据结果集。

可以看到,正向索引和倒排索引的区别:

  • 正向索引:基于文档id创建索引。查询词条时必须先找到文档,而后判断是否包含词条
  • 倒排索引:对文档内容分词,对词条创建索引,并记录词条所在文档的信息。查询时限根据词条查询到文档id,而后获取到文档。比较适用于内容搜索

elasticsearch概念

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

文档数据会被序列化为json格式后存储在elasticsearch中。MongoDB就属于文档型数据库。

索引(Index):相同类型的文档的集合。概念类似于数据库的表

elasticsearch和mysql中的概念对比:

使用场景上来看,mysql擅长事务类型操作,可以确保数据的安全和一致性,而elasticsearch更擅长海量数据的分析、搜索、计算。很多时候两者会配合使用,而中间需要做数据同步。

es安装

创建网络

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

docker network create es-net

拉取镜像

拉取镜像

docker pull elasticsearch

运行es

docker run -d \
    --name elasticsearch \
    -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 \
    --net es-net \
    -p 9200:9200 \
    -p 9300:9300 \
    elasticsearch

参数解释:

  • -d:后台运行
  • --name:容器名称
  • -e:ES_JAVA_OPTS-设置es可用内存大小,默认1G
  • -e:discovery.type-运行模式,此处非集群模式
  • -v:挂载逻辑卷,绑定es的数据目录
  • -v:挂载逻辑卷,绑定es的插件
  • --privileged:授予逻辑卷访问权
  • --net:加入自建网络
  • -p:端口映射,9200-暴露的http端口,供用户访问;9300-es容器中各个节点互联的端口,可以不暴露

查看容器运行

浏览器访问,端口9200,出现如下json串返回代表es容器运行成功。

安装kibana

拉取镜像

docker pull kibana

运行kibana

docker run -d \
    --name kibana \
    -e ELASTICSEARCH_HOSTS=http://elasticsearch:9200 \
    --network es-net \
    -p 5601:5601 \
    kibana

上面注意,因为我们使用了同一网络es-net,es和kibana在一个网络中,所以kibana可以通过容器名elasticsearch访问es服务。

浏览器访问,端口5601

这里重点看下Dev Tools,这是一个DSL控制台,可以执行DSL语句,查看返回结果,类似于mysql客户端工具Navicat、SQLyog的sql语句控制台。

安装分词器IK

es在创建倒排索引时需要对文档分词。在搜索时,需要对用户输入内容分词。但默认的分词规则对中文处理并不友好。

我们再kibana的Dev Tools控制台测试下

POST /_analyze
{
  "analyzer": "standard",
  "text": "气温舒适,very good!"
}

语法说明:

  • POST:请求方式
  • /_analyze:请求路径,这里省略了http://111.229.191.140:9200,有kibana帮我们补充
  • 请求参数,json风格
  • -analyzer:分词器类型,这里是默认的standard分词器,还有chinese、english等
  • -text:要分词的内容

先测试下es是否正常连接,返回右侧json串代表正常

测试分词

可以看到,es自带的分词器对中文分词效果比较差,无法按词义如“气温”、“舒适”分词。

而处理中文分词,我们一般会使用IK分词器。

安装步骤

#进入容器内部
docker exec -it elasticsearch bash

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

#退出
exit

#重启容器
docker restart elasticsearch

我们es版本是5.6.12,IK分词器版本要和es版本匹配,具体对应关系如下

执行安装

打开kibana控制台,如果出现下面错误

错因:index_closed_exception 异常因为 .kibana 索引被关闭

curl -X POST "localhost:9200/.kibana/_open"

执行如下命令

刷新控制台

在github官方文档中,IK分词器有ik_smart和ik_max_word两种分词类型

测试一下

 


评论