此篇介绍一下Elasticsearch的使用场景及常见方法。
ES简介
Elasticsearch是一个基于Lucene的分布式搜索和分析引擎,它使用RESTful web接口提供服务。
概念
Lucene
简单说就是一个jar包,里面封装了各种建立倒排索引,以及进行搜索的算法代码,引入lucene.jar即可使用。
索引(Index)
- 索引是具有相似特征的文档的集合。
- 索引由名称标识(必须全部为小写,不能以下划线开头,不能包含逗号)。
- 在一个Elasticsearch集群中,可以定义任意数量的索引。
- 如果业务端对查询性能要求很高的话,还是建议使用单索引,也就是宽表化处理的方式,这样也可以比较好的应对聚合的需求。
类型(Type)
- 在Elasticsearch 6.0.0 或更高版本中创建的索引只能包含一个映射类型。
- 类型将在Elasticsearch 7.0.0的API中弃用,并在8.0.0中完全删除。
- 从Elasticsearch 6.x开始,只能一个Type对应一个Index。
文档(Document)
- 文档是可以建立索引的基本信息单位,以json表示。
- 可以把文档理解为MySQL表中的行级数据。
- 在索引(Index)中可以存储大量文档。
- 文档中有几个不可或缺的属性,分别如下:
_index:表示所在的index名。
_type:在6.x版本中只能指定一个类型,在6.4.0版本中默认为“doc”。
_id:文档的唯一标识,类似于MySQL数据库的主键id。
_source:文档数据以json形式保存在该字段内。
针对特定一个或者一类文档进行操作时,必须指定这些属性。
映射(Mapping)
- 模式映射(schema mapping)用于定义索引(Index)的元数据,指定要索引并存储文档的字段类型。
- Elasticsearch在Mapping中存储有关字段的信息。
- Mapping在文件中以json表示。
- 在实际的项目中,尽可能的自定义mapping,不要存储与搜索无关的数据。
字段(Field)
- Elasticsearch中的最小单元,相当于MySQL中的某个字段,类似于json里的一个键。
分片(Shards)
- 索引可能会存储大量数据,这些数据可能超过单个节点的硬件限制。
- 例如到了1TB可能就不再适合单个节点的磁盘,或者因为太慢无法满足来自单个节点的搜索请求。
- 每个分片(Shards)本身就是一个功能齐全且独立的Lucene“索引”,可以存储在Elasticsearch集群中的任何节点上,这就是分布式存储。
- 分片的好处:
(1)当你查询的索引在多个分片上时,Elasticsearch会把查询发送给每个相关的分片,并将结果合并在一起。所以,多个分片可以加快查询,提高吞吐量。
(2)通过将分片放在不同节点,可以存储超过单节点容量的数据。
副本(Replica)
- 当集群的某个节点宕机,为防止数据丢失,Elasticsearch还提供了副本(Replica)的概念。
- 副本分片(Replica Shards)是一个分片的精确复制,每个分片可以有零个或多个副本。
- 许多相同的分片,其中的一个被自动选择来更改索引操作,这种称为主分片(primary shards),其余的称为副本分片(replica shards)。
- 在主分片丢失时,集群则将副本分片提升为新的主分片。
- 副本(Replica)的好处:
(1)提高可用性。
(2)由于分片本身就是功能齐全且独立的索引,所以可以加快查询,提高吞吐量。
(3)增加副本分片,可以将数据存储到更多节点上,更好的处理并发请求。
节点(Node)
- 节点是一个运行着的Elasticsearch实例,或者就是个机器。
- 集群(Cluster)是一组具有相同cluster.name的节点集合,或者就是一组机器。它们协同工作,共享数据并提供故障转移和扩展功能,当然一个节点也可以组成一个集群。
- 在Elasticsearch集群中,节点分为Master、Data节点、Client节点等几种角色,任何一个节点都可以同时具备以上所有角色。
Master:主要管理集群信息、primary分片和replica分片信息、维护index信息。
Data:用来存储数据,维护倒排索引,提供数据检索等。
Client:只负责处理用户请求,实现请求转发,负载均衡等功能。
规划和技巧
- 可以在创建索引(Index)时定义主分片(Primary Shards)和副本分片(Replica Shards)的数量。
- 创建索引后,我们还可以动态更改副本数,但是要更改分片数就不那么轻松了。因此,预先规划正确的分片数量是最佳方法。
- 默认情况下,Elasticsearch中的每个索引分配有5个主分片和1个副本分片。这意味着如果集群中至少有两个节点,则索引将具有5个主分片和另外5个副本分片(1个完整副本),总计每个索引10个分片。
- Elasticsearch中的分片其实就是Lucene索引。
- 主分片和副本分片需要分配在不同的节点上,一是为了更好的负载均衡,二是发生故障时可以保障高可用,所以集群最好有2个节点或以上。
- 一个索引默认有5个主分片,每个主分片默认有1个副本分片,即创建一个索引默认会有10个分片。
- 读远大于写的场景,可以减少主分片个数,增加副本数,提高吞吐率。写远大于读的场景,最大程度分配主分片个数,一个机器一个,并最大程度减少副本数。
- 一般将平均分片的大小控制在几GB到几十GB之间。对于基于时间的数据使用场景来说,通常将分片大小控制在20GB到40GB之间。
- Elasticsearch推荐的最大JVM堆空间是30~32G,把分片容量限制为30GB,然后再对分片数量做合理估算。
特点
- 分布式存储,每个字段都可以被索引和搜索。
- 分布式的准实时分析搜索引擎。
- 可以扩展到上百台服务器,处理PB级结构化或非结构化数据。
跟一般数据库的区别
1. 通常的数据库侧重存储附带搜索,ES在存储之外侧重搜索。
2. 通常的数据库基于精确匹配,ES基于相关性匹配。
3. ES在搜索之外,还有分析。
4. 同MySQL一样,ES也提供了简单的聚合操作,avg,sum,min,max等。
5. 实时计算的一种常见方案,是数据产生后,通过消息队列(比如kafka)推给实时计算平台storm,计算后,再把数据存到ES。
6. 分析数据的能力,是建立在快速的查询上的。如果没有快速的查询能力,就谈不上分析。
实现
- 关系数据库,是将数据分成各个字段,存在数据库中,查询时再重新构造出对象;ES是文档存储,把对象直接放进去,查询时直接取出。
- MySQL基于B+树索引,来实现快速检索;ES基于倒排索引,对于文档检索来说,倒排索引在性能和空间上更有优势。