elasticsearch(三)---分布式集群

Elasticsearch用于构建高可用和可扩展的系统。扩展的方式能够是购买更好的服务器(纵向扩展(vertical scale or scaling up))或者购买更多的服务器(横向扩展(horizontal scale or scaling out))。html

Elasticsearch虽然能从更强大的硬件中得到更好的性能,可是纵向扩展有它的局限性。真正的扩展应该是横向的,它经过增长节点来均摊负载和增长可靠性。node

对于大多数数据库而言,横向扩展意味着你的程序将作很是大的改动才能利用这些新添加的设备。对比来讲,Elasticsearch天生就是分布式的:它知道如何管理节点来提供高扩展和高可用。这意味着你的程序不须要关心这些。 在这章咱们将探索如何建立你的集群(cluster)、节点(node)和分片(shards),使其按照你的需求进行扩展,并保证在硬件故障时数据依旧安全。数据库

空集群

若是咱们启动一个单独的节点,它尚未数据和索引,这个集群看起来就像图1。安全

图1:只有一个空节点的集群服务器

一个节点(node)就是一个Elasticsearch实例,而一个集群(cluster)由一个或多个节点组成,它们具备相同的cluster.name,它们协同工做,分享数据和负载。当加入新的节点或者删除一个节点时,集群就会感知到并平衡数据。网络

集群中一个节点会被选举为主节点(master),它将临时管理集群级别的一些变动,例如新建或删除索引、增长或移除节点等。主节点不参与文档级别的变动或搜索,这意味着在流量增加的时候,该主节点不会成为集群的瓶颈。任何节点均可以成为主节点。咱们例子中的集群只有一个节点,因此它会充当主节点的角色。并发

作为用户,咱们可以与集群中的任何节点通讯,包括主节点。每个节点都知道文档存在于哪一个节点上,它们能够转发请求到相应的节点上。咱们访问的节点负责收集各节点返回的数据,最后一块儿返回给客户端。这一切都由Elasticsearch处理。elasticsearch

集群健康

在Elasticsearch集群中能够监控统计不少信息,可是只有一个是最重要的:集群健康(cluster health)。集群健康有三种状态:greenyellowred分布式

GET /_cluster/health
复制代码

在一个没有索引的空集群中运行如上查询,将返回这些信息:性能

{
   "cluster_name":          "elasticsearch",
   "status":                "green", <1>
   "timed_out":             false,
   "number_of_nodes":       1,
   "number_of_data_nodes":  1,
   "active_primary_shards": 0,
   "active_shards":         0,
   "relocating_shards":     0,
   "initializing_shards":   0,
   "unassigned_shards":     0
}
复制代码

status字段提供一个综合的指标来表示集群的的服务情况。三种颜色各自的含义:

在接下来的章节,咱们将说明什么是主要分片(primary shard)和复制分片(replica shard),并说明这些颜色(状态)在实际环境中的意义。

添加索引

为了将数据添加到Elasticsearch,咱们须要索引(index)——一个存储关联数据的地方。实际上,索引只是一个用来指向一个或多个分片(shards)的“逻辑命名空间(logical namespace)”.

一个分片(shard)是一个最小级别“工做单元(worker unit)”,它只是保存了索引中全部数据的一部分。在接下来的《深刻分片》一章,咱们将详细说明分片的工做原理,可是如今咱们只要知道分片就是一个Lucene实例,而且它自己就是一个完整的搜索引擎。咱们的文档存储在分片中,而且在分片中被索引,可是咱们的应用程序不会直接与它们通讯,取而代之的是,直接与索引通讯。

分片是Elasticsearch在集群中分发数据的关键。把分片想象成数据的容器。文档存储在分片中,而后分片分配到你集群中的节点上。当你的集群扩容或缩小,Elasticsearch将会自动在你的节点间迁移分片,以使集群保持平衡。

分片能够是主分片(primary shard)或者是复制分片(replica shard)。你索引中的每一个文档属于一个单独的主分片,因此主分片的数量决定了索引最多能存储多少数据。

理论上主分片能存储的数据大小是没有限制的,限制取决于你实际的使用状况。分片的最大容量彻底取决于你的使用情况:硬件存储的大小、文档的大小和复杂度、如何索引和查询你的文档,以及你指望的响应时间。
复制代码

复制分片只是主分片的一个副本,它能够防止硬件故障致使的数据丢失,同时能够提供读请求,好比搜索或者从别的shard取回文档。

当索引建立完成的时候,主分片的数量就固定了,可是复制分片的数量能够随时调整。

让咱们在集群中惟一一个空节点上建立一个叫作blogs的索引。默认状况下,一个索引被分配5个主分片,可是为了演示的目的,咱们只分配3个主分片和一个复制分片(每一个主分片都有一个复制分片):

PUT /blogs
{
   "settings" : {
      "number_of_shards" : 3,
      "number_of_replicas" : 1
   }
}
复制代码

附带索引的单一节点集群:

咱们的集群如今看起来就像上图——三个主分片都被分配到Node 1。若是咱们如今检查集群健康(cluster-health),咱们将见到如下信息:

{
   "cluster_name":          "elasticsearch",
   "status":                "yellow", <1>
   "timed_out":             false,
   "number_of_nodes":       1,
   "number_of_data_nodes":  1,
   "active_primary_shards": 3,
   "active_shards":         3,
   "relocating_shards":     0,
   "initializing_shards":   0,
   "unassigned_shards":     3 <2>
}
复制代码

<1> 集群的状态如今是 yellow

<2> 咱们的三个复制分片尚未被分配到节点上

集群的健康状态yellow表示全部的主分片(primary shards)启动而且正常运行了——集群已经能够正常处理任何请求——可是复制分片(replica shards)尚未所有可用。事实上全部的三个复制分片如今都是unassigned状态——它们还未被分配给节点。在同一个节点上保存相同的数据副本是没有必要的,若是这个节点故障了,那全部的数据副本也会丢失。

如今咱们的集群已经功能完备,可是依旧存在因硬件故障而致使数据丢失的风险。

故障转移

在单一节点上运行意味着有单点故障的风险——没有数据备份。幸运的是,要防止单点故障,咱们惟一须要作的就是启动另外一个节点。

启动第二个节点
为了测试在增长第二个节点后发生了什么,你可使用与第一个节点相同的方式启动第二个节点,并且命令行在同一个目录——一个节点能够启动多个Elasticsearch实例。
只要第二个节点与第一个节点有相同的cluster.name(请看./config/elasticsearch.yml文件),它就能自动发现并加入第一个节点所在的集群。若是没有,检查日志找出哪里出了问题。这多是网络广播被禁用,或者防火墙阻止了节点通讯。
复制代码

若是咱们启动了第二个节点,这个集群看起来就像下图。 双节点集群——全部的主分片和复制分片都已分配:

第二个节点已经加入集群,三个复制分片(replica shards)也已经被分配了——分别对应三个主分片,这意味着在丢失任意一个节点的状况下依旧能够保证数据的完整性。

文档的索引将首先被存储在主分片中,而后并发复制到对应的复制节点上。这能够确保咱们的数据在主节点和复制节点上均可以被检索。

cluster-health如今的状态是green,这意味着全部的6个分片(三个主分片和三个复制分片)都已可用:

{
   "cluster_name":          "elasticsearch",
   "status":                "green", <1>
   "timed_out":             false,
   "number_of_nodes":       2,
   "number_of_data_nodes":  2,
   "active_primary_shards": 3,
   "active_shards":         6,
   "relocating_shards":     0,
   "initializing_shards":   0,
   "unassigned_shards":     0
}
复制代码

咱们的集群不只是功能完备的,并且是高可用的。

横向扩展

随着应用需求的增加,咱们该如何扩展?若是咱们启动第三个节点,咱们的集群会从新组织本身,就像图4:

图4:包含3个节点的集群——分片已经被从新分配以平衡负载:

Node3包含了分别来自Node 1和Node 2的一个分片,这样每一个节点就有两个分片,和以前相比少了一个,这意味着每一个节点上的分片将得到更多的硬件资源(CPU、RAM、I/O)。

分片自己就是一个完整的搜索引擎,它可使用单一节点的全部资源。咱们拥有6个分片(3个主分片和三个复制分片),最多能够扩展到6个节点,每一个节点上有一个分片,每一个分片能够100%使用这个节点的资源。

继续扩展

若是咱们要扩展到6个以上的节点,要怎么作?

主分片的数量在建立索引时已经肯定。实际上,这个数量定义了能存储到索引里数据的最大数量(实际的数量取决于你的数据、硬件和应用场景)。然而,主分片或者复制分片均可以处理读请求——搜索或文档检索,因此数据的冗余越多,咱们能处理的搜索吞吐量就越大。

复制分片的数量能够在运行中的集群中动态地变动,这容许咱们能够根据需求扩大或者缩小规模。让咱们把复制分片的数量从原来的1增长到2:

PUT /blogs/_settings
{
   "number_of_replicas" : 2
}
复制代码

图5:增长number_of_replicas到2:

从图中能够看出,blogs索引如今有9个分片:3个主分片和6个复制分片。这意味着咱们可以扩展到9个节点,再次变成每一个节点一个分片。这样使咱们的搜索性能相比原始的三节点集群增长三倍。

固然,在一样数量的节点上增长更多的复制分片并不能提升性能,由于这样作的话平均每一个分片的所占有的硬件资源就减小了(译者注:大部分请求都汇集到了分片少的节点,致使一个节点吞吐量太大,反而下降性能),你须要增长硬件来提升吞吐量。

不过这些额外的复制节点使咱们有更多的冗余:经过以上对节点的设置,咱们可以承受两个节点故障而不丢失数据。
复制代码

应对故障

咱们已经说过Elasticsearch能够应对节点失效,因此让咱们继续尝试。若是咱们杀掉第一个节点的进程(如下简称杀掉节点),咱们的集群看起来就像这样:

图5:杀掉第一个节点后的集群

咱们杀掉的节点是一个主节点。一个集群必需要有一个主节点才能使其功能正常,因此集群作的第一件事就是各节点选举了一个新的主节点:Node 2。

主分片1和2在咱们杀掉Node 1时已经丢失,咱们的索引在丢失主分片时不能正常工做。若是此时咱们检查集群健康,咱们将看到状态red:不是全部主分片均可用!

幸运的是丢失的两个主分片的完整拷贝存在于其余节点上,因此新主节点作的第一件事是把这些在Node 2和Node 3上的复制分片升级为主分片,这时集群健康回到yellow状态。这个提高是瞬间完成的,就好像按了一下开关。

为何集群健康状态是yellow而不是green?咱们有三个主分片,可是咱们指定了每一个主分片对应两个复制分片,当前却只有一个复制分片被分配,这就是集群状态没法达到green的缘由,不过不用太担忧这个:当咱们杀掉Node 2,咱们的程序依然能够在没有丢失数据的状况下继续运行,由于Node 3还有每一个分片的拷贝。

若是咱们重启Node 1,集群将可以从新分配丢失的复制分片,集群情况与上一节的 图5:增长number_of_replicas到2 相似。若是Node 1依旧有旧分片的拷贝,它将会尝试再利用它们,它只会从主分片上复制在故障期间有数据变动的那一部分。

如今你应该对分片如何使Elasticsearch能够水平扩展并保证数据安全有了一个清晰的认识。接下来咱们将会讨论分片生命周期的更多细节。

参考:es官方文档

相关文章
相关标签/搜索