打开淘宝, 搜索 狂飙 会出现各种价格有关狂飙的书籍, 当然也有高启强同款的孙子兵法!!! 如下图所示:
那么面对海量的数据, 如何快速且准确的找到我们想要的内容呢? 淘宝界面已经可以按照综合排序 / 销量 / 信用 / 价格等进行筛选, 是如何做到的呢?
ElasticSearch 1
- 1 ElasticSearch 的概念
- 1.1 基本概念
- 1.2 ELK 技术栈
- 1.3 ElasticSearch 与 Lucene
- 1.4 ElasticSearch 与 MySQL
- 2 正向索引及倒排索引
- 2.1 正向索引
- 2.2 倒排索引
- 2.3 总结
- 3 部署 ElasticSearch
- 4 部署 Kibana
- 5 安装 IK 分词器
1 ElasticSearch 的概念
1.1 基本概念
ElasticSearch 是一款非常强大的开源搜索引擎, 那么其功能也就是帮助我们在海量的数据中找到想要的数据内容, 如上面我们在淘宝界面搜索狂飙展现出的内容, 如我们敲代码遇到 BUG 复制到百度看到的内容.
ElasticSearch 是面向文档 (Document) 存储的, 可以是数据库中的一条商品数据或者是一个订单信息, 文档数据会被序列化为 json 格式后存储在 ElasticSearch 中;
1.2 ELK 技术栈
在学习分布式搜索引擎之前, 先来了解一下 ELK 技术栈的概念, Elasticsearch / Logstash( / Beats) 和 Kibana 这三个技术就是常说的 ELK 技术栈, 这三个技术的结合是大数据领域中一个很巧妙的设计, 当然这也是一种经典的 MVC 模型思想.
- Logstash 担任控制层的角色, 负责数据的搜集及过滤;
- Elasticsearch 担任数据持久层的角色, 负责数据的存储;
- Kibana 则是一个开源的分析与可视化平台, 设计的初衷也是用来搭配 ElasticSearch 的使用, 可以用 Kibana 搜索和查看存放在 ElasticSearch 中的数据, Kibana 与 Elasticsearch 的交互方式是各种不同的图表 / 表格 / 地图等,直观的展示数据,从而达到高级的数据分析与可视化的目的。
通过上面的概念可知 ElasticSearch 是 ELK 技术栈的核心, 毕竟其主要工作便是 存储 / 搜索 / 分析数据.
1.3 ElasticSearch 与 Lucene
Lucene 是 Java 语言的搜索引擎类库, 为 Apache 公司的项目, 而 ElasticSearch 的底层就是基于 Lucene 来实现的, 两者的优缺点如下: Lucene: * 易扩展 / 高性能; * 只限于 Java 语言开发 / 不支持水平扩展;
ElasticSearch:
- 支持分布式, 可水平扩展;
- 提供了 Restful 接口, 可被任何语言调用.
1.4 ElasticSearch 与 MySQL
MySQL 更擅长事务类型的操作, 可以确保数据的安全性和一致性;
ElasticSearch 更擅长海量数据的搜索 / 分析 / 计算.
因此, 在企业中往往两种结合在一起使用, 场景如下:
- 对查询性能要求较高的搜索需求使用 ElasticSearch 实现;
- 对安全性要求较高的写操作往往使用 MySQL 实现.
2 正向索引及倒排索引
关于索引和映射之间的区别:
- 索引就是相同类型的文档的集合, 如所有商品的文档可以放在一块进行组织, 成为商品的索引; 如所有的用户都放在一起进行组织就称之为用户的索引;
- 因为数据库中各个表中的数据基本都是相同类型, 因此数据库中的表可以称之为是索引;
- 因为数据库中的表会有约束信息, 用来定义表的结构 / 字段的名称或者类型等信息, 因此索引库中就有映射 (mapping), 关于映射的概念可以理解为索引中文档的字段约束信息, 类似于表结构的约束.
2.1 正向索引
在学习倒排索引之前, 先了解正向索引的概念, 如下图 MySQL 表;
如果是根据 id 进行查询可以直接 select * from gen_table where table_id=93
, 但是如果在此表中进行模糊搜索 “信息” 这两个字眼, 只能逐行进行搜索, select * from gen_table where table_comment like '%信息%'
, 步骤如下:
1 用户根据 table_comment 这个条件进行搜索数据;
2 逐行获取数据, 从 id 为 93 这一行开始;
3 判断数据中的 table_comment 是否符合用户的搜索条件;
4 如果符合, 则放入结果集, 否则就丢弃, 回到步骤 1 进行重复.
如果表中的数据比较少, 还可以这样进行查询, 但是如果数据量巨大, 全表搜索查询效率将会非常低, 你能忍受搜索数据等待个小时为单位的时间么?
2.2 倒排索引
倒排索引的两个比较重要的概念:
- 文档(Document): 用来搜索的数据, 其中的每一条数据就是一个文档, 如一个网页或者是一件商品信息;
- 词条(Term): 对文档数据或用户搜索数据, 利用某种算法分词, 得到的具备含义的词语就是词条, 如 “狂飙这部剧真好看” 就可以分为: "狂, 狂飙, 这, 部, 剧, 真, 好看"这样的词条.
主要流程:
创建倒排索引是对正向索引的一种特殊处理, 如下:
- 将每一个文档的数据利用算法进行分词, 得到多个词条;
- 创建表, 每行数据包含词条 / 词条所在文档的 id 及位置等信息;
- 因为词条的唯一性, 因此可以给词条创建索引, 如 hash 表结构索引.
例如: 使用倒排索引搜索 “阿迪篮球鞋” 流程如下:
- 我们输入 “阿迪篮球鞋” 进行搜索;
- 对输入的内容进行分词, 得到两个词条: 阿迪, 篮球鞋;
- 根据这两个词条在倒排索引中进行查找, 可以得到包含词条的文档 id 为: 1, 2;
- 拿着文档 id 在正向索引中查找到具体的文档.
2.3 总结
- 正向索引
-
- 优点:
-
-
- 可以为多个字段创建索引;
-
-
-
- 根据索引字段进行搜索, 速度比较快;
-
-
- 缺点:
-
-
- 根据非索引字段或者索引字段中的部分词条查找时, 只能全表扫描;
-
- 倒排索引
-
- 优点:
-
-
- 根据词条搜索或者模糊搜索时, 速度非常快;
-
-
- 缺点:
-
-
- 只能给词条创建索引, 而不是字段;
-
-
-
- 无法根据字段进行排序.
-
3 部署 ElasticSearch
在安装 ElasticSearch 时遇到了很多 “坑”, 如果有在安装的过程中报错, 请点击此链接来查看解决办法: 【Debug】Centos 7 下部署 ElasticSearch 及 Kibana 时踩过的坑;
声明此安装是在 Centos 7 环境下的安装.
步骤一: 创建网络;
因为我们需要部署 Kibana 容器, 因此需要让 ElasticSearch 和 Kibana 容器进行关联, 因此需要创建一个网络: docker network create es-net
;
步骤二: 加载镜像;
这里需要注意 ElasticSearch 的版本和 Kibana 的版本一致, 主要方式有两种, 如下:
- 自己在官网下载包, 官网下载点击此处, 然后上传到虚拟机中, 运行
docker load -i elasticsearch.tar
执行加载即可; 大部分的电脑这种操作还是没问题的, 但是我的电脑这种方式不妥, 其实最保险的方式还是下面这种方式; - 在 docker 镜像仓库查找指令, 网站为: Docker 镜像仓库, 这里我选的是 7.17.7 版本,
docker pull elasticsearch:7.17.7
, 如下图所示:
步骤三: 运行并部署 ElasticSearch, 指令如下:
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.17.7
指令解析:
4 部署 Kibana
步骤一: 建议直接拉去, 指令: docker pull kibana:7.17.7
;
步骤二: 运行并部署;
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601 \
kibana:7.17.7
指令解析:
步骤三: 浏览器输入 http://172.16.00.99:5601 (去看自己虚拟机的 ip) 查看是否出现界面;
5 安装 IK 分词器
步骤一: 进入容器内部, 执行指令: docker exec -it es /bin/bash
, es 为我的容器名称, 这里写自己命名的 ElasticSearch 容器的名称;
将指令 ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.17.7/elasticsearch-analysis-ik-7.17.7.zip
复制进去回车;因为我的电脑已经安装过, 所以报错已存在;
步骤二: 执行 exit
指令并重启 ElasticSearch 容器: docker restart es
;
步骤三: 测试;
总结:
1 分词器的作用:
- 创建倒排索引时对文档分词;
- 用户搜索时对输入的内容进行分词.
2 IK 分词器的两种模式:
- ik_smart: 智能切分, 粗粒度;
- ik_max_word: 最细切分, 细粒度.