浅谈Lucene到ElasticSearch介绍
1.1.数据库搜索的问题
要实现类似百度的复杂搜索,或者京东的商品搜索,如果使用传统的数据库存储数据,那么会存在一系列的问题:
- 性能瓶颈:当数据量越来越大时,数据库搜索的性能会有明显下降。虽然可以通过分库分表来解决存储问题,但是性能问题并不能彻底解决,而且系统复杂度会提高、可用性下降。
- 复杂业务:百度或京东的搜索往往需要复杂的查询功能,例如:拼音搜索、错字的模糊搜索等。这些功能用数据库搜索难以实现,或者实现复杂度较高
- 并发能力:数据库是磁盘存储,虽然也有缓存方案,但是并不实用。因此数据库的读写并发能力较差,难以应对高并发场景
但是,并不是说数据库就一无是处。在一些对业务有强数据一致性需求,事物需求的情况下,数据库是不可替代的。
只是在海量数据的搜索方面,需要有新的技术来解决,就是我们今天要学习的 倒排索引 技术。
1.2.倒排索引
倒排索引是一种特殊的数据索引方式,虽然与数据库存储的数据结构没有太大差别,但是在检索方式上却大不一样。
1.2.1.基本概念
先来看两个概念:
- 文档(Document):用来检索的海量数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息
- 词条(Term):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。
例如,数据库中有下面的数据:
|
id |
title |
url |
|
10 |
谷歌地图之父跳槽FaceBook |
http://www.sizengxiangshi.cn/10.html |
|
20 |
谷歌地图之父加盟FaceBook |
http://www.sizengxiangshi.cn/10.html |
|
30 |
谷歌地图创始人拉斯离开谷歌加盟Facebook |
http://www.sizengxiangshi.cn/10.html |
|
40 |
谷歌地图之父跳槽Facebook与Wave项目取消有关 |
http://www.sizengxiangshi.cn/10.html |
|
50 |
谷歌地图之父拉斯加盟社交网站Facebook |
http://www.sizengxiangshi.cn/10.html |
那么这里的每一行数据就是一条文档,如:
|
id |
title |
url |
|
10 |
谷歌地图之父跳槽FaceBook |
http://www.sizengxiangshi.cn/10.html |
把标题字段分词,可以得到词语如: 谷歌 就是一个词条
现在,假设用户要搜索 "谷歌创始人跳槽" ,来看看倒排索引的传统查找在检索时的区别:
1.2.1.传统查找流程
因为复杂搜索往往是模糊地查找,因此数据库索引基本都会失效,只能逐条数据判断。基本流程如下:
1)用户搜索数据,条件是title符合 "谷歌创始人跳槽"
2)逐行获取数据,比如id为10的数据
3)判断数据中的title是否符合用户搜索条件
4)如果符合则放入结果集,不符合则丢弃。回到步骤1

如果有5条数据,则需要遍历并判断5次。如果有100万数据,则需要循环遍历和判断100万次。线性查找和判断,效率极差,一个10mb的硬盘文件,遍历一遍需要3秒。
1.2.2.倒排索引流程
倒排索引的数据存储方式与数据库类似,但检索方式不同。
1.2.2.1.数据存储方式
先看看倒排索引如何处理数据。
文档列表 :
首先,倒排索引需要把文档数据逐个编号(从0递增),存储到文档表中。并且给每一个编号创建索引,这样根据编号检索文档的速度会非常快。

词条列表(Term Dictionary):
然后,对文档中的数据按照算法做分词,得到一个个的词条,记录词条和词条出现的文档的编号、位置、频率信息,如图:

然后给词条创建索引,这样根据词条匹配和检索的速度就非常快
1.2.2.2.检索数据过程
倒排索引的检索流程如下:
1)用户输入条件 "谷歌创始人跳槽" 进行搜索。
2)对用户输入内容分词,得到词条: 谷歌 、 创始人 、 跳槽 。
3)拿着词条到词条列表中查找,可以得到包含词条的文档编号:0、1、2、3、4。
4)拿着词条的编号到文档列表中查找具体文档。
如图:

虽然搜索会在两张表进行,但是每次都是根据索引查找,因此速度比传统搜索时的全表扫描速度要快得多。
1.3.Lucene
在java语言中,对倒排索引的实现中最广为人知的就是Lucene了,目前主流的java搜索框架都是依赖Lucene来实现的。
- Lucene是一套用于全文检索和搜寻的开源程序库,由Apache软件基金会支持和提供
- Lucene提供了一个简单却强大的应用程序接口(API),能够做全文索引和搜寻,在Java开发环境里Lucene是一个成熟的免费开放源代码工具
- Lucene并不是现成的搜索引擎产品,但可以用来制作搜索引擎产品,比较知名的搜索产品有:Solr、ElasticSearch
- 官网:http://lucene.apache.org/
企业生产中一般都会使用成熟的搜索产品,例如:Solr或者Elasticsearch,不过从性能来看Elasticsearch略胜一筹,因此我们今天的分享目标就是elasticsearch。
2.ElasticSearch介绍和安装
如果把Lucene比喻成一台发动机,那么Solr就是一台家用汽车,而Elasticsearch就是一台c超级跑车。
2.1.简介
Elastic官网:https://www.elastic.co/cn/
Elastic是一系列产品的集合,比较知名的是ELK技术栈,其核心就是ElasticSearch:
Elasticsearch官网:https://www.elastic.co/cn/products/elasticsearch

Elasticsearch是一个基于Lucene的搜索 web服务 ,对外提供了一系列的Rest风格的API接口。因此任何语言的客户端都可以 通过发送Http请求来实现ElasticSearch的操作 。
ES的主要优势特点如下:
- 速度快 :Elasticsearch 很快,快到不可思议。我们通过有限状态转换器实现了用于全文检索的倒排索引,实现了用于存储数值数据和地理位置数据的 BKD 树,以及用于分析的列存储。而且由于每个数据都被编入了索引,因此您再也不用因为某些数据没有索引而烦心。您可以用快到令人惊叹的速度使用和访问您的所有数据。实现 近实时搜索 ,海量数据更新在Elasticsearch中几乎是完全同步的。
- 扩展性高 :可以在笔记本电脑上运行,也可以在承载了 PB 级数据的成百上千台服务器上运行。原型环境和生产环境可无缝切换;无论 Elasticsearch 是在一个节点上运行,还是在一个包含 300 个节点的集群上运行,您都能够以相同的方式与 Elasticsearch 进行通信。它能够 水平扩展 ,每秒钟可处理海量事件,同时能够自动管理索引和查询在集群中的分布方式,以实现极其流畅的操作。天生的分布式设计,很容易搭建大型的 分布式集群 (solr使用Zookeeper作为注册中心来实现分布式集群)
- 强大的查询和分析 :通过 Elasticsearch,您能够执行及合并多种类型的搜索(结构化数据、非结构化数据、地理位置、指标),搜索方式随心而变。先从一个简单的问题出发,试试看能够从中发现些什么。找到与查询最匹配的 10 个文档是一回事。但如果面对的是十亿行日志,又该如何解读呢?Elasticsearch 聚合让您能够从大处着眼,探索数据的趋势和模式。如全文检索,同义词处理,相关度排名,复杂数据分析。
- 操作简单 :客户端API支持Restful风格,简单容易上手。
目前Elasticsearch最新的版本是7.x.x,我就使用7.4.2版本,官网*载下**安装:

需要JDK1.8及以上(在7.0以后的版本中,自带了jdk)
如果要自己*载下**

2.2.安装
我们选择在windows下安装。
安装ES的步骤非常简单:
- 解压:绿色版软件,解压即可使用
- 配置:修改ES的配置文件中部分属性
- 启动:运行启动脚本即可启动
1)解压
把*载下**的文件解压到某个目录即可,最好不要有中文:
2.2.安装
我们选择在windows下安装。
安装ES的步骤非常简单:
- 解压:绿色版软件,解压即可使用
- 配置:修改ES的配置文件中部分属性
- 启动:运行启动脚本即可启动
1)解压
把*载下**文件解压到某个目录即可,最好不要有中文:

2)修改配置
进入config目录,有下面的配置:

核心是两个配置:

我们打开jvm.options,修改JVM内存参数:
Elasticsearch基于Lucene的,而Lucene底层是java实现,因此我们需要配置jvm参数
默认配置如下:
-Xms1g
-Xmx1g
内存占用太多了,我们调小一些:
-Xms512m
-Xmx512m
3)启动
进入安装目录的bin目录:

双击elasticsearch.bat文件即可启动。可以看到日志中的IP和端口信息:

在浏览器中访问:http://127.0.0.1:9200

2.3.Kibana
ElasticSearch是一个web服务,但是没有提供图形化界面来操作
2.3.1.什么是Kibana?
Kibana是一个基于Node.js的Elasticsearch索引库数据统计工具,可以利用Elasticsearch的聚合功能,生成各种图表,如柱形图,线状图,饼图等。
而且还提供了操作Elasticsearch索引数据的控制台,并且提供了一定的API提示,非常有利于我们学习Elasticsearch的语法。
2.3.2.安装NodeJS
因为Kibana依赖于node,需要在windows下先安装Node.js

一路下一步即可安装成功,然后在任意黑窗口输入名:
node -v
可以查看到node版本,如下:

如果安装后,命令没有反应,可以重启电脑再试。
2.3.3.安装Kibana

目录结构:

2)运行
进入bin目录:

双击kibana.bat文件即可
双击运行:
发现kibana的监听端口是5601
我们访问:http://127.0.0.1:5601

3)控制台
Kibana提供了开发工具(devTools)方便我们操作ES,点击左侧菜单即可找到

在控制台中,可以方便地向ES发起Http请求:

说明:
- GET :代表是发送了一个 GET 方式的http请求
- _search :是请求的URL路径,前面省略了 localhost:9200
- {"query": { "match_all": {} } } :是JSON风格的请求参数,这里代表查询所有数据