Elasticsearch浅析
Elasticsearch简介
什么是Elasticsearch
Elasticsearch 是一个分布式的开源搜索和分析引擎(以下简称ES),适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。主要用于应用程序搜索、网站搜索、企业搜索、日志处理和分析、应用程序性能检测等。
为什么要用Elasticsearch
涉及到like的大数据量模糊查询,如果是直接对数据库进行查询的话,由于like模糊查询无法对数据列应用索引,所以需要一条条字符串进行全表扫描、比对查询,效率就非常低下。所以在Java中,解决大数据量的模糊查询,就会用到建立索引库,全文检索的查询技术,即ES。
Elasticsearch的倒排索引
Elasticsearch 使用的是一种名为倒排索引的数据结构,也叫反向索引(inverted index)。
通俗地来讲,正向索引是通过key找value,反向索引则是通过value找key。通过“关键词——文档”形式的一种映射结构,实现了通过物品属性信息对物品进行映射时,可以帮助用户快速定位到目标信息,从而极大降低了信息获取难度。
举个例子,如以下文档:
文档编号(id) | 文档内容 |
---|---|
1 | 我喜欢数学 |
2 | 我喜欢编程 |
3 | 我考试数学成绩很好 |
4 | 编程太难了 |
-
简单的倒排索引
编号 | 词元(token) | 倒排列表(list< id>) |
---|---|---|
1 | 我 | 1,2,3 |
2 | 喜欢 | 1,2 |
3 | 数学 | 1,3 |
4 | 编程 | 2,4 |
5 | 考试 | 3 |
6 | 成绩 | 3 |
7 | 很好 | 3 |
8 | 太难了 | 4 |
可以看到,文档被拆分成多个词元,分别对应各个词元编号。
比如,“编程”,其词元编号为4,倒排列表为(2,4),代表文档集合中编号为2和4的文档包含“编程”。
-
有单词频率信息(TF)的倒排索引
若一个词元在文档集合中出现多次,要如何标记呢?这就引入了带词频信息的倒排索引。
之所以要记录这个信息,是因为词频信息在搜索结果排序时,计算查询和文档相似度是很重要的一个计算因子,将其记录在倒排列表中,以方便后续排序时进行分值计算。
编号 | 词元(token) | 倒排列表(list< (id;TF)>) |
---|---|---|
1 | 我 | (1;1),(2;1),(3;1) |
2 | 喜欢 | (1;1),(2,1) |
3 | 数学 | (1;1),(3;1) |
4 | 编程 | (2;1),(4;1) |
5 | 考试 | (3;1) |
6 | 成绩 | (3;1) |
7 | 很好 | (3;1) |
8 | 太难了 | (4;1) |
比如,“编程”对应的倒排列表为(2;1),(4;1),代表编号为2和4文档中各出现了一次。
-
有词元频率和出现位置(pos)信息的倒排索引
若一个文档中某个词元出现多次,要如何标记呢?此时就要加上这个词元在文档中出现的位置。
编号 | 词元(token) | 倒排列表(list<(id;TF;< pos>)>) |
---|---|---|
1 | 我 | (1;1;<1>),(2;1;<1>,(3;1;<1>) |
2 | 喜欢 | (1;1;<2>),(2;1;<2>) |
3 | 数学 | (1;1;<3>),(3;1;<3>) |
4 | 编程 | (2;1;<3>),(4;1;<1>) |
5 | 考试 | (3;1;<3>) |
6 | 成绩 | (3;1;<4>) |
7 | 很好 | (3;1;<5>) |
8 | 太难了 | (4;1;<2>) |
比如,“编程”对应的倒排列表为(2;1;<3>),(4;1;<1>),代表整个文档集合中有两篇文档包含“编程”,分别是文档2和文档4,文档2“我喜欢编程”拆分为“我、喜欢、编程”三个词元,词元编号分别为1、2、3,因此“编程”在文档2中出现了1次,对应的词元编号(即出现的位置)为3;“编程”在文档4中出现了1次,对应的词元编号为1。
Elasticsearch分片和副本
在ES中,每个查询在每个分片的单个线程中执行。然而,可以并行处理多个分片,并可以在相同分片上执行多个查询和聚合。当分片所在的机器宕机,ES可以使用其副本进行恢复,从而避免数据丢失。
ES默认为一个索引创建5个主分片, 并分别为其创建一个副本分片。也就是说每个索引都由5个主分片成本, 而每个主分片都相应的有一个副本。
对于分布式搜索引擎来说,分片及副本的分配将是高可用及快速搜索响应的设计核心,主分片与副本都能处理查询请求, 它们的唯一区别在于只有主分片才能处理索引请求。
Elasticsearch 与 其他数据库的区别
Elasticsearch | 关系型数据库(如:MySQL) |
---|---|
索引(Index) | 数据库(Database) |
类型(type) (ES 8.X将弃用) | 表(Table) |
文档(Docment) | 行(Row) |
字段(Field) | 列(Columns) |
Elasticsearch 对比 Mongodb
与Mongodb类似,Elasticsearch是一种面向文档的数据库,也是以 JSON 文档的形式存储数据。
指标 | Elasticsearch | MongoDB |
---|---|---|
实现语言 | Java语言(restful) | C++语言(driver) |
分片方式 | hash | hash、range |
分布式 | 主副分片自动组合和配置 | 需要手动配置集群“路由+服务配置+sharding” |
内部存储 | 倒排索引 | B-Tree |
检索字段 | 全文检索,可用的检索插件较多 | 对索引字段个数有限制,全文检索效率低乃至不采用 |
时效性 | 非实时,有丢数据的风险 | 实时,理论上无丢数据的风险 |
Elasticsearch 对比 Redis
指标 | Redis | Elasticsearch |
---|---|---|
介绍 | Redis是内存中的数据结构存储,用作数据库,缓存和消息代理 | Elasticsearch是一个基于Apache Lucene的现代搜索和分析引擎 |
主数据库模型 | 键值存储 | 搜索引擎 |
实现语言 | C | Java |
二级索引 | 没有 | 是 |
API和其他访问方法 | 专有协议 | Java API RESTful HTTP / JSON API |
服务器端脚本 | Lua | 是 |
触发器 | 没有 | 是 |
分区方法 | 拆分 | 拆分 |
复制方法 | 主从复制 | 是 |
即:
-
对数据的读写要求极高,并且数据规模不大,也不需要长期存储,选redis;
-
数据规模较大,对数据的读性能要求很高,数据表的结构需要经常变,有时还需要做一些聚合查询,选MongoDB;
-
需要构造一个搜索引擎或者你想搞一个看着高大上的数据可视化平台,并且你的数据有一定的分析价值,选ElasticSearch&#