Elasticsearch之引言

2020-08-25  本文已影响0人  冰河winner

1、Elasticsearch是什么

Elasticsearch 是一个分布式的开源搜索和分析引擎,在 Apache Lucene 的基础上开发而成。

Lucene 是开源的搜索引擎工具包,Elasticsearch 充分利用Lucene,并对其进行了扩展,使存储、索引、搜索都变得更快、更容易, 而最重要的是, 正如名字中的“ elastic ”所示, 一切都是灵活、有弹性的。而且,应用代码也不是必须用Java 书写才可以和Elasticsearc兼容,完全可以通过JSON 格式的HTTP 请求来进行索引、搜索和管理Elasticsearch 集群。

如果你已经听说过Lucene ,那么可能你也听说了Solr ,它也是开源的基于Lucene 的分布式搜索引擎,跟Elasticsearch有很多相似之处。

1.png

但是Solr 诞生于2004 年,而Elasticsearch诞生于2010,Elasticsearch凭借后发优势和更活跃的社区、更完备的生态系统,迅速反超Solr,成为搜索市场的第二代霸主。

Elasticsearch具有以下优势:

2、逻辑结构

2.1 Document

Elasticsearch 是面向文档的,这意味着索引和搜索数据的最小单位是文档

一个文档通常是以JSON 的数据格式来表示的。例如,一项技术大会的活动可以通过如下文档表达:

{
    "name":"Elasticsearch技术峰会",
    "organizer":"冰河",
    "location ":"中国, 浙江,杭州"
}

一个Document中有很多Field,一个Field就是一个数据字段。

文档可以是包含若干取值的一行。但是这样的比较不够精准,它们还是有所差别。一个区别是,和行有所不同,文档可以是层次型的。例如,位置可以包含地址和邮编:

{
    "name":"Elasticsearch技术峰会",
    "organizer":"冰河",
    "location ":{
        "address":"中国, 浙江,杭州",
        "postcode":"310000"
    }
}

一篇单独的文档也可以包含一组数值,例如:

{
    "name":"Elasticsearch技术峰会",
    "organizer":"冰河",
    "member":[
        "洪七公",
        "黄药师",
        "欧阳锋",
        "一灯"
    ]
}

2.2 Type

类型,是文档的逻辑容器,类似于表格是行的容器。在不同的类型中,最好放入不同结构的文档。

每个类型中字段(Field)的定义称为映射(Mapping)。例如, 一个人的姓名可以映射为string,年龄可以映射为int。

映射包含某个类型中当前索引的所有文档的所有字段,但是不是所有的文档必须要有所有的宇段。同样,如果一篇新近索引的文档拥有一个映射中尚不存在的字段, Elasticsearch 会自动地将新字段加入映射。为了添加这个字段Elasticsearch 不得不确定它是什么类型,于是Elasticsearch 会进行猜测。例如, 如果值是7,Elasticsearch 会假设字段是长整型。

这种新字段的自动检测也有缺点,因为Elasticsearch 可能猜得不对。例如,在索引了值7之后,你可能想再索引hello world ,这时由于它是string 而不是long ,索引就会失败。对于线上环境,一般在索引数据之前,都会定义好所需的映射,不允许动态添加字段。

2.3 Index

索引,是类型的容器。一个Elasticsearch 索引非常像关系型世界的数据库,是独立的大量文档集合。每个索引存储在磁盘上的同组文件中,索引存储了所有映射类型的字段,还有一些设置。

2.4 与关系数据库的类比

ES 关系数据库
Field Column
Document Row
Type Table
Mapping Schema
Index Database

需要特别注意的是:ES 6以前每个Index可以有多个Type,在ES 6中一个Index仅能包含一个Type,而在ES 7将完全移除Type

为什么要移除Type呢?

我们一直拿ES与关系数据库作类比,说"索引"和关系数据库的“库”是相似的,“类型”和“表”是对等的。实际上这是一个不太准确的对比。在关系型数据库里,"表"是相互独立的,一个“表”里的列和另外一个“表”的同名列没有关系,互不影响。但在ES的中不是这样的。

在同一个Index下,不管有多少个Type,底层共用一个Lucene实例,也就是说,所有Type的同名字段在内部使用的是同一个Lucene字段存储,这就要求同名字段必须属于同一种数据类型。这可能导致一些问题,例如同一个索引下,有两个结构不同的Type,都拥有一个名为"deleted"字段,但是如果期望的在一个Type里是存储日期值,在另外一个Type里存储布尔值,是做不到的。

还有一个更重要的原因,在同一个索引中,存储仅有小部分字段相同或者全部字段都不相同的文档,会导致数据稀疏,影响Lucene有效压缩数据的能力。

3、物理结构

3.1 Node

一个节点是一个ES的实例,在服务器上启动ES之后,就拥有了一个节点,如果在另一个服务器上启动ES,这就是另一个节点。甚至可以在一台服务器上启动多个ES进程,在一台服务器上拥有多个节点。多个节点可以加入同一个集群。

当ElasticSearch的节点启动后,它会利用多播(multicast)(或者单播,如果用户更改了配置)寻找集群中的其它节点,并与之建立连接。这个过程如下图所示:

2.png

节点主要有以下几种角色:

3.2 Shard

一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。

为了解决这个问题,ES提供了将索引划分成多份的能力,这些份就叫做分片。当创建一个索引的时候,可以指定想要的分片的数量。每个分片本身也是一个功能完善并且独立的Lucene“索引”,这个“索引”可以被放置到集群中的任何节点上。

基于分片可以进行分布式的、并行的操作,进而提高性能/吞吐量。至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由ES管理的,对于用户来说这些都是透明的。

在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了。这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。

为此目的,ES允许创建分片的一份或多份拷贝。一旦有了拷贝,每个索引就有了主分片(Primary Shard)和复制分片(Replica Shard)之别。

复制之所以重要,主要有两方面的原因:

在索引创建之后,可以在任何时候动态地改变复制分片的数量,但是不能改变主分片的数量

默认情况下,ES中的每个索引被分片5个主分片和1个复制,这意味着,如果集群中至少有两个节点,索引将会有5个主分片和另外5个复制分片,这样的话每个索引总共就有10个分片。一个索引的多个分片可以存放在集群中的一台主机上,也可以存放在多台主机上,这取决于集群机器数量。主分片和复制分片的具体位置是由ES内在的策略所决定的。

下图是一个有3 个节点的集群是示意图:

3.png

默认情况下,当索引一篇文档的时候,系统首先根据文档ID 的散列值选择一个主分片,并将文档发送到该主分片。这份主分片可能位于另一个节点,就像上图节点2 上的主分片,不过对于应用程序这一点是透明的。

然后文档被发送到该主分片的所有副本分片进行索引。这使得副本分片和主分片之间保持数据的同步。数据同步使得副本分片可以服务于搜索请求,并在原有主分片无法访问时自动升级为主分片。

4.png

当搜索一个索引时, Elasticsearch 需要在该索引的完整分片集合中进行查找。这些分片可以是主分片,也可以是副本分片,原因是对应的主分片和副本分片通常包含一样的文档。Elasticsearch 在索引的主分片和l副本分片中进行搜索请求的负载均衡,使得副本分片对于搜索性能和容错都有所帮助。

3.3 Cluster

集群由若干节点组成,这些节点在同一个网络内,cluster-name相同。

Elasticsearch 的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是集群健康, 它在 status 字段中展示为 greenyellow 或者 red

上一篇 下一篇

猜你喜欢

热点阅读