ElasticSearch的基本概念

ElasticSearch具有几个核心概念。从一开始就理解这些概念将大大有助于简化学习过程。

Near Realtime (NRT)

ElasticSearch是一种接近实时的搜索平台。这就意味着,从你索引一个文档直到它能够搜索之间,会有一个细微的延迟时间(通常是1秒)。

Cluster

集群是一个或多个节点(服务器)的集合,它们共同保存全部的数据,并且在所有节点上提供联合的索引和搜索功能。集群由一个唯一的名称所标识,默认值为“elasticsearch”。这个名称非常重要,因为只有当一个节点的集群名称和一个集群的名称相同时,这个节点才能够加入这个集群。

请确保你不会在不同的环境中重用相同的相同的集群名称,否则节点就有可能加入错误的集群。例如,在开发环境、预生产环境和生产环境中,你可以分别使用logging-devlogging-stagelogging-prod作为集群名称。

注意,即使某个集群只有一个节点,这个集群也是有效的,也可以非常好的工作。此外,你还可以拥有多个独立的集群,每个集群都有自己唯一的集群名称。

Node

节点是一台单个的服务器,是集群的组成部分,负责存储数据,并且实现集群的索引和搜索功能。节点就像集群一样,也是通过名称来标识的,这个名称默认是一个随机的通用唯一标识符(UUID),集群启动时便会为节点分配一个名称。如果你不想使用默认名称,那么你可以定义任意的节点名称。节点名称对于集群管理非常重要,你可以通过节点名称确定网络服务器和ElasticSearch集群节点之间的对应关系。

你可以将节点配置为通过集群名称加入一个特定的集群。在默认情况下,每个结点启动之后都会加入一个名为elasticsearch的集群。这就意味着,如果在网络上启动多个节点,并且假设它们能够互相发现,那么它们都会自动形成和加入一个名为elasticsearch的集群。

在单个集群之中,可以包含任意多个节点。此外,如果网络中没有任何ElasticSearch节点正在运行,那么在你启动一个节点之后,它将会形成一个名为elasticsearch的单节点集群。

Index

索引是具有相似特性的文档集合。例如,你可以为客户数据建立一个索引,为产品目录建立另一个索引,以及为订单数据再建立另一个索引。索引由一个名称(必须为小写)标识,在对其文档执行索引、搜索、更新和删除操作时,可以通过这个名称来引用索引。

在单个集群中,你可以根据需要定义多个索引。

Type

在索引中,你可以定义一个或多个类型。类型是索引的一种逻辑分类/分区,它的语义完全由你决定。一般来说,你可以为具有一组公共字段的文档定义一个类型。例如,假设你正在运营一个博客平台,并且将所有数据存储在一个索引之中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,以及为评论数据再定义另一个类型。

Document

文档是可以索引的信息的基本单位。例如,你可以为单个客户建立一个文档,为单个产品建立另一个文档,以及为单个订单再建立一个文档。这些文档是以JSON(JavaScript Object Notation)格式表示的,这是一种无处不在的互联网数据交换格式。

在一个索引/类型中,你可以根据需要存储尽可能多的文档。注意,尽管文档物理上存储在一个索引之中,但实际上必须将文档分配至索引的某个类型之中。

Shards & Replicas

索引可以存储大量的数据,这些数据可能会超过单个节点的硬件限制。例如,某个索引具有十亿个文档,需要占用大约1TB的磁盘空间,但是单个节点可能没有这么大的磁盘空间,并且单个节点独自处理搜索请求的速度可能会很慢。

为了解决这个问题,ElasticSearch能够将你的索引分割为若干分块,这些分块称为分片(shard)。当你创建索引时,你可以简单地定义所需的分片数量。每个分片本身是一个全功能的、独立的“索引”,可以将其托管在集群中的任何节点。

分片非常重要,主要由于以下两个原因:

  • 它使得你能够水平分割/扩展你的存储卷;
  • 它使得你能够将搜索操作分配给各个分片(可能在多个节点上),从而实现并行操作,因此可以提高性能/吞吐量。

搜索请求是如何分配给分片的?搜索请求是如何聚合结果文档的?这些技术细节都是完全由ElasticSearch自己管理的,对于普通用户来说是透明的。

在一个网络/云环境中,可以预见任何时候都有可能发生故障。因此,强烈建议使用一种故障转移机制,以便于应对某个分片/节点莫名其妙地离线或失踪的情况。为此,ElasticSearch允许你为索引分片创建一个或多个拷贝,我们将这些拷贝称为复制分片,简称为复制(replica)。

复制非常重要,主要由于以下两个原因:

  • 当某个分片/节点发生故障时,它能够提供高可用功能。因此,需要注意的是,一个复制分片不能和原始/主分片分配在相同的节点上。
  • 它使得你能够扩大搜索量/吞吐量,因为搜索可以并行地在所有的复制上执行。

总之,每个索引都可以分割成多个分片。索引也可以有零个或多个复制。一旦创建了复制,每个索引都将有一个主分片(复制的原始分片)和一个复制分片(主分片的拷贝)。在创建索引时,可以为每个索引定义分片和复制的数量。创建索引之后,你可以随时动态地修改复制的数量,但是你不能在事后修改分片的数量。

在默认情况下,ElasticSearch会为每个分片分配5个主分片和1个复制。这就意味着,如果你的集群至少有两个节点,那么你的索引将会有5个主分片和另外5个复制分片(1个完整的复制),每个索引总共会有10个分片。

注意:
每个ElasticSearch分片都是一个Lucene索引。你可以在单个Lucene索引中包含大量的文档。正如LUCENE-5843所述,文档数量的上限为2,147,483,519(等于Integer.MAX_VALUE – 128)。你可以使用_cat/shards的API来监控分片的大小。

既然如此,让我们开始学习真正有趣的部分吧!