文章目录
- ElasticSearch简介
- 正向索引和倒排索引
- 正向索引
- 倒排索引
- ElasticSearch和MySQL的区别
ElasticSearch简介
-
什么是ElasticSearch?
ElasticSearch 是一款非常强大的开源搜索引擎,可以帮助我们从海量的数据中快速找到需要的内容。 -
什么是ELK?
ElasticSearch 结合 Kibana、Logstash、Beats,被成为 Elastic Stack(ELK,Elastic 技术栈)。ELK 被广泛应用在 日志数据分析、实时监控等领域。
其中,ElasticSearch 是 Elastic Stack 的核心,主要负责存储、搜索和分析数据。
ElasticSearch 的底层是 Lucene。而 Lucene 是Apache的开源搜索引擎类库,提供了搜索引擎的核心API,由 DougCutting 于 1999年研发。
Lucene的优点:
- 易扩展
- 高性能(基于倒排索引)
Lucene的缺点:
- 只限于Java语言开发
- 学习曲线陡峭
- 不支持水平扩展
而 ElasticSearch 相比 Lucene,具有下列优势:
- 支持分布式,可水平扩展
- 提供
Restful
接口,可被任何语言调用。
正向索引和倒排索引
倒排索引 的概念是基于MySQL这样的 正向索引 而言的。
为了更好的说明什么是正向索引,什么是倒排索引,下面我们直接举一个实例。
假设现在我们有以下的数据表:
他的主键是id
,即通过 id 查询我们是走索引的,其他的 title 等字段我们并未为其创建索引。
正向索引
现在,使用 Mysql 进行搜索,如果是根据id
查询,那么直接走索引,查询速度非常快。但是如果我们使用的是 title
进行查询,那么 Mysql 将会逐行扫描数据,在数据量足够大的情况下,搜索的速度会变得非常非常慢。
流程大致如下:
1)用户搜索数据,条件是title符合"%手机%"
2)逐行获取数据,比如id为1的数据
3)判断数据中的title是否符合用户搜索条件
4)如果符合则放入结果集,不符合则丢弃。回到步骤1
倒排索引
倒排索引中有两个非常重要的概念:
- 文档(
Document
):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息 - 词条(
Term
):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。例如:我是中国人,就可以分为:我、是、中国人、中国、国人这样的几个词条
创建倒排索引是对正向索引的一种特殊处理,流程如下:
- 将每一个文档的数据利用算法分词,得到一个个词条
- 创建表,每行数据包括词条、词条所在文档id、位置等信息
- 因为词条唯一性,可以给词条创建索引,例如hash表结构索引
举个简单的例子,以我们上面的表为例,建立倒排索引后,将会多出这么一个表格:
这个表格是怎么来的呢?他存的又是什么鬼东西呢?首先吧,这个表格的词条就是我们从刚才的 title 里面抽取,或者说分离出来的词。而文档 id 对应的就是该词条对应的能被用来索引的键(id)。
倒排索引的搜索流程如下(以搜索"华为手机"为例):
1)用户输入条件"华为手机"
进行搜索。
2)对用户输入内容分词,得到词条:华为
、手机
。
3)拿着词条在倒排索引中查找,可以得到包含词条的文档id:1、2、3。
4)拿着文档id到正向索引中查找具体文档。
虽然要先查询倒排索引,再通过索引去查询数据表,但是无论是词条、还是文档id都建立了索引,查询速度非常快!无需全表扫描。
ElasticSearch和MySQL的区别
elasticsearch是面向 文档(Document) 存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为 json格式
后存储在 elasticsearch
中:
下图左边对应的是MySQL的存储,右边对应的是ElasticSearch的存储。
可以看到,我们的 Json文档
就相当于MySQL中的行,或者专业点,我们叫一条记录
。
而每个Json文档中包含很多的字段
,类似于数据库中的列
。
在MySQL中,我们会有很多张表(例如,用户表,学生表,成绩表),每张表存储的是数据,我称之为记录
。而在ElasticSearch中,我们会有很多个索引(用户索引,学生索引,成绩索引),每个索引存储的数据,我们称之为文档
。
数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有映射(mapping),是索引中文档的字段约束信息,类似表的结构约束。
针对MySQL和ElasticSearch的概念做一下对比的话,大致如下:
MySQL | Elasticsearch | 说明 |
---|---|---|
Table | Index | 索引(index),就是文档的集合,类似数据库的表(table) |
Row | Document | 文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式 |
Column | Field | 字段(Field),就是JSON文档中的字段,类似数据库中的列(Column) |
Schema | Mapping | Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema) |
SQL | DSL | DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD |
注意:ElasticSearch 和 MySQL 是互补关系,不是替代关系。
-
Mysql:擅长事务类型操作,可以确保数据的安全和一致性
-
Elasticsearch:擅长海量数据的搜索、分析、计算
因此在企业中,往往是两者结合使用:
- 对安全性要求较高的写操作,使用
mysql
实现 - 对查询性能要求较高的搜索需求,使用
elasticsearch
实现 - 两者再基于某种方式,实现数据的同步,保证一致性