什么是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两种分词类型
测试一下