随着企业对近实时搜索的迫切需求,Elasticsearch 受到越来越多的关注。
Elasticsearch官方文档:https://www.elastic.co/cn/what-is/elasticsearch.
一、Elasticsearch简介
1.1 什么是 Elasticsearch?
Elasticsearch 是一个分布式的开源搜索和分析引擎 ,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。简单来说只要涉及搜索和分析相关的, ES 都可以做。
1.2 Elasticsearch 的用途?
Elasticsearch 在速度和可扩展性方面都表现出色,而且还能够索引多种类型的内容,这意味着其可用于多种用例:
- 比如一个在线网上商店,您可以在其中允许客户搜索您出售的产品。在这种情况下,您可以使用Elasticsearch存储整个产品目录和库存,并为它们提供搜索和自动完成建议。
- 比如收集日志或交易数据,并且要分析和挖掘此数据以查找趋势,统计信息,摘要或异常。在这种情况下,您可以使用 Logstash(Elasticsearch / Logstash / Kibana堆栈的一部分)来收集,聚合和解析数据,然后让 Logstash 将这些数据提供给 Elasticsearch。数据放入 Elasticsearch 后,您可以运行搜索和聚合以挖掘您感兴趣的任何信息。
1.3 Elasticsearch 的工作原理?
Elasticsearch 是在 Lucene 基础上构建而成的。ES 在 Lucence 上做了很多增强。
Lucene 是apache软件基金会 4 的 jakarta 项目组的一个子项目,是一个开放源代码 的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎 (英文与德文两种西方语言)。
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
1)Elasticsearch 的原始数据从哪里来?
原始数据从多个来源 ( 包括日志、系统指标和网络应用程序 ) 输入到 Elasticsearch 中。
2)Elasticsearch 的数据是怎么采集的?
数据采集指在 Elasticsearch 中进行索引之前解析、标准化并充实这些原始数据的过程。这些数据在 Elasticsearch 中索引完成之后,用户便可针对他们的数据运行复杂的查询,并使用聚合来检索自身数据的复杂汇总。这里用到了 Logstash 。
3)怎么可视化查看想要检索的数据?
这里就要用到 Kibana 了,用户可以基于自己的数据进行搜索、查看数据视图等。
1.4 Elasticsearch 索引是什么?
Elasticsearch 索引指相互关联的文档集合 。Elasticsearch 会以 JSON 文档的形式存储数据。每个文档都会在一组键 ( 字段或属性的名称 ) 和它们对应的值 ( 字符串、数字、布尔值、日期、数值组、地理位置或其他类型的数据 ) 之间建立联系。
Elasticsearch 使用的是一种名为倒排索引 的数据结构,这一结构的设计可以允许十分快速地进行全文本搜索。倒排索引会列出在所有文档中出现的每个特有词汇,并且可以找到包含每个词汇的全部文档。
在索引过程中,Elasticsearch 会存储文档并构建倒排索引 ,这样用户便可以近实时地对文档数据进行搜索。索引过程是在索引 API 中启动的 ,通过此 API 您既可向特定索引中添加 JSON 文档,也可更改特定索引中的 JSON 文档。
1.5 Logstash 的用途是什么?
Logstash 就是 ELK 中的 L 。
Logstash 是 Elastic Stack 的核心产品之一,可用来对数据进行聚合和处理,并将数据发送到 Elasticsearch 。Logstash 是一个开源的服务器端数据处理管道,允许您在将数据索引到 Elasticsearch 之前同时从多个来源采集数据,并对数据进行充实和转换。
1.6 Kibana 的用途是什么?
Kibana 是一款适用于 Elasticsearch 的数据可视化和管理工具,可以提供实时的直方图、线性图 等。
1.7 为什么使用 Elasticsearch
- ES 很快,近实时的搜索平台。
- ES 具有分布式的本质特质。
- ES 包含一系列广泛的功能,比如数据汇总和索引生命周期管理。
二、ES 基本概念
2.1 Index ( 索引 )
动词:相当于 Mysql 中的 insert
名词:相当于 Mysql 中的 database
与 mysql 的对比
2.2 倒排索引
我们传统的检索方式是通过遍历整篇文章,逐个比对找到对应的关键词位置,而倒排索引是通过分词策略,形成词和文章的关系映射表 ,这种词典+映射表 的方式就是倒排索引,有点类似于我们以前使用的新华字典。倒排索引可极大的提高查询效率。
倒排索引:相当于一篇文章包含了哪些词,它从词出发,记载了这个词在哪些文档出现过,有两部分组成——词典 + 映射表
倒排索引的底层实现是基于 FST(Finite State Transducer) 数据结构。
举例:
假如数据库有如下电影记录:
- 1-大话西游
- 2-大话西游外传
- 3-解析大话西游
- 4-西游降魔外传
- 5-梦幻西游独家解析
分词:将整句分拆为单词
检索:独家大话西游
将 独家大话西游 解析拆分成 独家 、大话 、西游
ES 中 A、B、G 记录 都有这三个词的其中一种, 所以 1,2, 3,4, 5 号记录都有相关的词被命中。
1 号记录命中 2 次, A、B 中都有 ( 命中 2 次 ) ,而且 1 号记录有 2 个词,相关性得分:2 次/2 个词=1
2 号记录命中 2 个词 A、B 中的都有 ( 命中 2 次 ) ,而且 2 号记录有 2 个词,相关性得分:2 次/3 个词= 0.67
3 号记录命中 2 个词 A、B 中的都有 ( 命中 2 次 ) ,而且 3 号记录有 2 个词,相关性得分:2 次/3 个词= 0.67
4 号记录命中 2 个词 A 中有 ( 命中 1 次 ) ,而且 4 号记录有 3 个词,相关性得分:1 次/3 个词= 0.33
5 号记录命中 2 个词 A 中有 ( 命中 2 次 ) ,而且 4 号记录有 4 个词,相关性得分:2 次/4 个词= 0.5
所以检索出来的记录顺序如下:
- ? 1-大话西游 ( 相关性得分:1 )
- ? 2-大话西游外传 ( 相关性得分:0.67 )
- ? 3-解析大话西游 ( 相关性得分:0.67 )
- ? 5-梦幻西游独家解析 ( 相关性得分:0.5 )
- ? 4-西游降魔 ( 相关性得分:0.33 )
三、Docker 搭建环境
3.1. 搭建 Elasticsearch 环境
1 ) 下载镜像文件
docker pull elasticsearch:7.4.2
2 ) 创建实例
配置映射文件夹
mkdir -p /mydata/elasticsearch/config
配置映射文件夹
mkdir -p /mydata/elasticsearch/data
设置文件夹权限任何用户可读可写
chmod 777 /mydata/elasticsearch -R
配置 http.host
echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type"="single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
访问:http://192.168.56.10:9200
访问:http://192.168.56.10:9200/_cat 访问节点信息
3.2. 搭建 Kibana 环境
docker pull kibana:7.4.2
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 -d kibana:7.4.2
四、中文分词
ES 内置了很多种分词器,但是对中文分词不友好,所以我们需要借助第三方中文分词工具包。
4.1 ES 中的分词的原理
4.1.1 ES 的分词器概念
ES 的一个分词器 ( tokenizer ) 接收一个字符流 ,将其分割为独立的词元 ( tokens ) ,然后输出词元流 。
ES 提供了很多内置的分词器,可以用来构建自定义分词器 ( custom ananlyzers )
4.1.2 标准分词器原理
比如 stadard tokenizer 标准分词器,遇到空格 进行分词。该分词器还负责记录各个词条 ( term ) 的顺序或 position 位置 ( 用于 phrase 短语和 word proximity 词近邻查询 ) 。每个单词的字符偏移量 ( 用于高亮显示搜索的内容 ) 。
4.1.3 英文和标点符号分词示例
查询示例如下:
POST _analyze
{
"analyzer": "standard",
"text": "Do you know why I want to study ELK? 2 3 33..."
}
查询结果:
do, you, know, why, i, want, to, study, elk, 2,3,33
从查询结果可以看到:
(1)标点符号没有分词。
(2)数字会进行分词。
4.1.4 中文分词示例
但是这种分词器对中文的分词支持不友好,会将词语分词为单独的汉字。
我们可以安装 ik 分词器 来更加友好的支持中文分词。
4.2 安装 ik 分词器
4.2.1 ik 分词器地址
ik 分词器地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
先检查 ES 版本,安装的版本是 7.4.2,所以安装 ik 分词器的版本也选择 7.4.2
4.2.2 安装 ik 分词器的方式
方式一:容器内安装 ik 分词器
docker exec -it <容器 id> /bin/bash
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
unzip 压缩包
rm -rf *.zip
方式二:映射文件安装 ik 分词器
cd /mydata/elasticsearch/plugins
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
unzip 压缩包
rm -rf *.zip
4.3 解压 ik 分词器到容器中
- 如果没有安装 unzip 解压工具,则安装 unzip 解压工具。
apt install unzip
命令格式:unzip <ik 分词器压缩包>
实例:unzip ELK-IKv7.4.2.zip -d ./ik
chmod -R 777 ik/
rm ELK-IKv7.4.2.zip
4.4 检查 ik 分词器安装
docker exec -it <容器 id> /bin/bash
elasticsearch-plugin list
- 结果如下,说明 ik 分词器安装好了。是不是很简单。
ik
- 然后退出 Elasticsearch 容器,并重启 Elasticsearch 容器
exit
docker restart elasticsearch
4.5 使用 ik 中文分词器
ik 分词器有两种模式
- 智能分词模式 ( ik_smart )
- 最大组合分词模式 ( ik_max_word )
我们先看下 智能分词 模式的效果。比如对于 一颗小星星 进行中文分词,得到的两个词语:一颗 、小星星
我们在 Dev Tools Console 输入如下查询
POST _analyze
{
"analyzer": "ik_smart",
"text": "一颗小星星"
}
再来看下 最大组合分词模式 。输入如下查询语句。
POST _analyze
{
"analyzer": "ik_max_word",
"text": "一颗小星星"
}
一颗小星星 被分成了 6 个词语:一颗、一、颗、小星星、小星、星星。
4.6 自定义分词词库
ik 分词器的配置文件在容器中的路径:
/usr/share/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml。
修改这个文件可以通过修改映射文件,文件路径:
/mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml
编辑配置文件:
vim /mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml
配置文件内容如下所示:
<?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">custom/mydict.dic;custom/single_word_low_freq.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">custom/ext_stopword.dic</entry>
<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">location</entry>
<!--用户可以在这里配置远程扩展停止词字典-->
<entry key="remote_ext_stopwords">http://xxx.com/xxx.dic</entry>
</properties>
修改配置 remote_ext_dict 的属性值,指定一个 远程网站文件的路径,比如 http://www.xxx.com/ikwords.text。
参考:
Elasticsearch面试题总结
14.Elasticsearch原理
|