Elasticsearch的基本概念

Elasticsearch是一个分布式文档存储,存储已序列化为JSON文档的复杂数据结构。当集群中有多个Elasticsearch节点时,存储的文档将分布在集群中,并且可以从任何节点立即访问。

Elasticsearch使用称为倒排索引的数据结构,该结构支持非常快速的全文本搜索。反向索引列出了出现在任何文档中的每个唯一单词,并标识了每个单词出现的所有文档。

Elasticsearch还具有无模式的能力,这意味着无需显式指定如何处理文档中可能出现的每个不同字段即可对文档建立索引。启用动态映射后,Elasticsearch自动检测并向索引添加新字段。此默认行为使索引和浏览数据变得容易-只需开始建立索引文档,Elasticsearch就会检测布尔值,浮点数和整数值,日期和字符串并将其映射到适当的Elasticsearch数据类型。

节点 Node

单个的Elasticsearch的服务实例被称为节点(node)。节点可以按用途分为3类:

  1. 数据节点:用来持有数据,提供对这些数据的搜索功能。
  2. 主节点:作为监督者负责控制其他节点的工作。一个集群中只有一个主节点。
  3. 部落节点: 可以像桥梁一样连接起多个集群,并允许我们在多个集群上执行几乎所有可以在单集群上执行的功能。

集群 Cluster

Elasticsearch是通过自然分布来实现的,可以将服务器(节点)添加到集群以增加容量,会自动在所有可用节点之间分配数据和查询负载。

Elasticsearch可以确保冗余,这既可以防止硬件故障,又可以在将节点添加到集群中时提高查询能力。随着集群的增长(或收缩),Elasticsearch会自动迁移shard以重新平衡集群。

分片 Shard

Elasticseach将数据散布到多个物理的Lucene索引上去。这些Lucene索引被称为分片(shard),而散步这些分片的过程叫做分片处理(sharding)。Elasticsearch会自动完成分片处理,并且让用户看起来这些分片更像是一个大索引。分片的数量在索引创建时就被配置好了,之后无法改变。除非创建一个新索引并重新索引全部数据。

副本 Replica

副本(Replica)解决了访问压力过大时单机无法处理所有请求的问题。思路很简单,为每个分片创建冗余副本,处理查询时可以把这些副本当作最初的主分片使用,以防止硬件故障并提高处理读取请求。可以在任意时间点添加或移除副本,可随时调整副本的数量。

创建索引时,索引中分片的数量是固定的,但是副本数量可以随时更改,而不会中断索引或查询操作。

在分片大小和为索引配置的主分片数量方面,存在许多性能方面的考虑和权衡取舍。分片越多,维护这些索引的开销就越大。分片越大,需要重新平衡集群时,移动分片所需的时间就越长。查询很多小的分片会使每个分片的处理速度更快,但是大量查询意味着更多的开销,因此查询较小数量的大分片可能会更快。

过滤器 Filter

过滤的唯一目的是用特定筛选条件来缩小结果范围。而查询不仅缩小结果范围,还会影响文档的得分。过滤不影响文档得分。

在使用过滤器时,过滤结果不依赖于查询,因此过滤结果可以被轻易地缓存起来供后续查询使用。

如果匹配结果数量极多,过滤器会执行得更快一点,因为不用重新计算文档的得分。某些时候,在使用后置过滤(post filter)时,Elasticsearch查询的执行速度没有我们期望的那么快。

经验法则告诉我们,开销最大的操作需要移动到查询处理链条的尾部。如果过滤器执行很快,开销很小,并且易于缓存,直接选择过滤器查询即可。相反,如果过滤器执行很慢,CPU开销大,并且难于缓存(比如有大量唯一值的情况),应选择使用后置过滤器。

查询 Query

  • match查询:适用于执行全文检索且需要对输入进行分析的场景。这种查询不需要进行查询语法解析,发生解析错误的概率极低,因此特别适合接收用户输入文本的场景。

  • term查询:一种简单的、无需对输入进行分析的查询方式,可以查询单个词语。这种查询方式的使用场景包括针对不分词字段进行检索。

  • bool查询:最常用的组合查询方式之一。能够把多个查询用布尔逻辑组织在一起,可以控制查询的某个字查询部分是必须匹配、可以匹配还是不应该匹配。要把匹配不同查询条件的查询组合在一起使用,bool查询就是一个很好的选择。

嵌套文档

当使用嵌套文档时,Elasticsearch实际上是为主对象创建了一个文档,并为内部对象创建额外的文档。普通查询中,这些额外文档被自动过滤掉,不会被搜索或展示出来,这在Apache Lucene中称为块连接。出于性能方面的考虑,额外的文档于主文档保存在一个索引块中。

这也是为什么嵌套文档必须要与主文档同时被索引。因为相互关联的两端文档的存储与索引是同时进行的。当文档都很小且主文档数据易于获取时,这种强关联关系并不会造成什么问题。如果这些文档很大,关联双方之一变化比较频繁,那么重建另外一部分文档变得不太现实了。另外就是如果一个嵌套文档属于多个文档时,问题就会变得非常棘手,但在父子关系功能面前就会迎刃而解。

父子关系文档

谈及父子关系功能,其最大的优势就是关系两端的文档时相互独立的,每端的文档都是独立索引的。这么做也是有代价的,会导致更复杂的查询及更慢的查询性能。第二个优势是这种关系适用于大型应用及多节点场景。

Elasticsearch总是将父文档相同的文档放置在同一个shard中,换句话说,子文档的routing参数值总是于其parent参数值相等。如果父文档有多个子文档,会导致文档在shard之间的不均匀分布,这会引发性能和存储问题。

results matching ""

    No results matching ""