ES(elasticsearch) 是一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能
elastic stack 是elasticsearch为核心的技术栈,包括beats、logstash(用作数据收集)、kibana(负责图形展示)、elasticsearch(负责数据搜索,存储等核心功能)
Lucene 是Apache的开源搜索引擎类库,也就是一个jar包,提供了搜索引擎的核心API,elasticsearch就是基于它来做的二次开发
常见的分布式搜索的技术,如下
1、Elasticsearch: 开源的分布式搜索引擎
2、Splunk: 商业项目,收费
3、Solr: Apache的开源搜索引擎
一、倒排索引
传统数据库(例如MySQL)采用正向索引,例如给下表(tb_goods)中的id创建索引
elasticsearch采用倒排索引,例如给下表(tb_goods)中的id创建索引
以下是倒排索引的搜索过程
总结
1、正向索引: 基于文档id来创建索引。查询词条时必须先找到文档,而后判断是否包含词条
2、倒排索引: 对文档内容进行分词,对词条创建索引,并记录词条所在文档的信息。查询时先根据词条
去查询文档id,然后获取到文档
3. 正向索引是逐个遍历的方式去查询,效率低
二、elasticsearch对比mysql
elasticsearch
elasticsearch是面向文档存储的,可以是数据库中的一条商品数据,一个订单信息。注意elasticsearch的文档是以json形式存储的,也就是说,我们把数据(也叫文档)存储进elasticsearch时,这些文档数据就会自动被序列化为json格式,然后才存储进elasticsearch
elasticsearch的索引: 相同类型的文档的集合。索引和映射的概念,如下图
下面的表格是介绍elasticsearch中的各个概念以及含义,看的时候重点看第二、三列,第一列是为了让你更理解第二列的意思,所以在第一列拿MySQL的概念来做匹配。例如elasticsearch的Index表示索引也就是文档的集合,就相当于MySQL的Table(也就是表)
架构
MySQL:擅长事务擅长事务类型的操作,可以确保数据的安全和一致性。一般用于增删改
Elasticsearch: 擅长海量数据的搜索、分析、计算。一般用于查询
两者是互补的关系
总结
文档:一条数据就是一个文档,es中是json格式
字段:Json文档中的字段
索引:同类型文档的集合
映射:索引中文档的约束,比如字段名称、类型
elasticsearch与数据库的关系:
- 数据库负责事务类型操作
- elasticsearch负责海量数据的搜索、分析和计算
三、elasticsearch安装
elasticsearch、kibana、IK分词器,这三者通常是一起使用的
注意: 我们学习elasticsearch是基于docker容器来使用,需要你们提前准备好自己的docker容器以及掌握docker操作。elasticsearch一般都是搭配kibana(下节会学如何安装)来使用,kibana的作用是让我们非常方便的去编写elasticsearch中的DSL语句,从而去操作elasticsearch
首先安装es
第一步: 创建网络。因为我们还需要部署kibana容器,因此需要让es和kibana容器互联
systemctl start docker # 启动docker服务
docker network create es-net #创建一个网络,名字是es-net
第二步: 加载es镜像。采用elasticsearch的7.12.1版本的镜像,这个镜像体积有800多MB,所以需要在Windows上下载链接安装包,下载下来是一个es的镜像tar包,然后传到CentOS7的/root目录
es.tar下载: https://cowtransfer.com/s/c84ac851b9ba44
kibana.tar下载: https://cowtransfer.com/s/a76d8339d7ba4d
第三步: 把在CentOS7的/root目录的es镜像,导入到docker
docker load -i es.tar
docker load -i kibana.tar
第四步: 创建并运行es容器,容器名称就叫es。在docker(也叫Docker大容器、Docker主机、宿主机),根据es镜像来创建es容器
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”:内存大小,不能低于512
● -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请求端口,用于用户访问
● -p 9300:9300:端口映射配置,是es容器各个节点之间互相访问的端口,由于我们是单节点部署,所以用不到
● elasticsearch:7.12.1: 镜像名称,要把哪个镜像创建为容器,注意带版本号
浏览器访问http://192.168.229.129:9200
四、安装Kibana
第一步: 确保docker是启动的
systemctl start docker # 启动docker服务
第二步: 加载kibana镜像。这个镜像体积有1.04G,所以需要在Windows上下载链接安装包,下载下来是一个es的镜像tar包,然后传到CentOS7的/root目录(已下载)
第三步: 把在CentOS7的/root目录的kibana镜像,导入到docker
docker load -i kibana.tar
第四步: 创建并运行kibana容器,容器名称就叫kibana。在docker(也叫Docker大容器、Docker主机、宿主机),根据kibana镜像来创建kibana容器
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601 \
kibana:7.12.1
# --name: 指定容器的名字,例如kibana
# --network es-net: 加入一个名为es-net的网络中,与elasticsearch在同一个网络中
# -e ELASTICSEARCH_HOSTS: 由于kibana和es会被我们设置在同一个网络,所以这里的kibana可以通过容器名直接访问es,es的容器名我们在上一节设置的是es
# -e ELASTICSEARCH_HOSTS: 设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch
# -p 5601:5601: 端口映射配置,向外暴露的http请求端口,用于用户访问
浏览器输入http://192.168.229.129:5601
五、安装IK分词器
IK分词器官网: https://github.com/medcl/elasticsearch-analysis-ik。注意elasticsearch、kibana、IK分词器,这三者通常是一起使用的
es在创建倒排索引时,需要对文档进行分词。在搜索时,需要对用户输入的内容进行分词。但默认的分词规则不支持中文处理,默认是只支持对英文进行分词,但是在正常业务中,我们需要处理的文档大多是中文,所以我们需要对中文进行分词,所以就需要安装IK分词器
第一步: 我们在 ‘4. 安装elasticsearch’ 创建elasticsearch容器时,指定了数据卷目录,其中有个数据卷指定了自定义名称为es-plugins,表示存放插件的数据卷
我们使用inspect命令把es-plugins数据卷的路径信息查询出来
docker volume inspect es-plugins
第二步: 下载ik.zip压缩包到Windows,下载后解压出来是ik文件夹
根据上面查询出来的es-plugins数据卷的路径,把ik文件夹上传到CentOS7的 /var/lib/docker/volumes/es-plugins/_data 目录
https://cowtransfer.com/s/54a5fa3838d746
第三步: 重启elasticsearch容器,我们在 ‘. 安装elasticsearch’ 创建elasticsearch容器时,指定了自定义容器名称为es
# 重启elasticsearch容器
docker restart es
第四步: 查看elasticsearch容器的启动日志
docker logs -f es
第五步: 确保elasticsearch、kibana已正常运行
docker restart es #启动elasticsearch容器
docker restart kibana #启动kibana容器
第五步: 测试。在浏览器中输入:http://192.168.229.129:5601 即可看到elasticsearch的响应结果
IK分词器包含两种模式:
● ik_smart:最少切分,根据语义分词,正常分词
● ik_max_word:最细切分,也是根据语义分词,分的词语更多,更细
六、词典扩展和应用
Ik分词器的分词,底层是一个字典,在字典里面会有各种各样的词语,当ik分词器需要对分词文本进行分词时,ik分词器就会拿着这个文本(乱拆成多个词或词语),一个个去字典里面匹配,如果能匹配到,证明某个词(乱拆成多个词或词语)是词,就把这个证明后的词分出来,作为一个词
第一个问题: 字典的分词效果是有限的,只能对日常生活中常见的语义相关的词,进行分词,由于字典的词汇量少,所以我们需要对字典进行扩展。
第二个问题: 字典的分词效果往往存在违禁词,我们不希望IK分词器能匹配并成功把词典里的违禁词作为分词,解决: 禁用某些敏感词条
1、要拓展或禁用ik分词器的词库,只需要修改一个分词器目录中的config目录中的IKAnalyzer.cfg.xml文件,如下
cd /var/lib/docker/volumes/es-plugins/_data/ik/config
<?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>
2、在config目录新建myext.dic文件,写入自己想要的特定词,也就是扩展词。新建mystopword.dic文件,写入自己想要禁用的特定词,也就是不参与分词的词
3、重新启动elasticsearch、kibana
docker restart es #启动elasticsearch容器
docker restart kibana #启动kibana容器
4、测试。在浏览器中