补充章节
正如前文提到的,这就是第个补充的章节,这里会介绍 Elasticsearch 如何在分布式环境中运行。 本章解释了经常使用术语,好比 集群 (cluster), 节点 (node) 以及 分片 (shard),以及如何横向扩展主机,如何处理硬件故障。node
尽管这一章不是必读章节 —— 你能够彻底不用理会分片,复制以及故障恢复就能长时间使用 Elasticsearch。你能够先跳过这一章节,而后在你须要的时候再回来。数据库
你能够随时根据你的须要扩展 Elasticsearch。你能够购买配置更好的主机 (vertical scale or scaling up) 或者购买更多的主机 (horizontal scale or scaling out) 来达到扩展的目的。安全
硬件越强大,Elasticsearch 运行的也就越快,可是垂直扩展 (vertical scale) 方式也有它的局限性。真正的扩展来自于横向扩展 (horizontal scale) 方式,在集群中添加更多的节点,这样能在节点之间分配负载。elasticsearch
对于大多数数据库来讲,横向扩展意味着你的程序每每须要大改,以充分使用这些新添加的设备。相比而言,Elasticsearch 自带 分布式功能:他知道如何管理多个节点并提供高可用性。这也就意味着你的程序根本不须要为扩展作任何事情。分布式
在这一章节,咱们将要探索如何根据你的须要建立你的 集群,节点 以及 分片,并保障硬件故障后,你的数据依旧的安全。性能
若是咱们启用一个既没有数据,也没有索引的单一节点,那咱们的集群看起来就像是这样 学习
节点 是 Elasticsearch 运行中的实例,而 集群 则包含一个或多个具备相同 cluster.name
的节点,它们协同工做,共享数据,并共同分担工做负荷。因为节点是从属集群的,集群会自我重组来均匀地分发数据。测试
集群中的一个节点会被选为 master 节点,它将负责管理集群范畴的变动,例如建立或删除索引,添加节点到集群或从集群删除节点。master 节点无需参与文档层面的变动和搜索,这意味着仅有一个 master 节点并不会因流量增加而成为瓶颈。任意一个节点均可以成为 master 节点。咱们例举的集群只有一个节点,所以它会扮演 master 节点的角色。搜索引擎
做为用户,咱们能够访问包括 master 节点在内的集群中的任一节点。每一个节点都知道各个文档的位置,并可以将咱们的请求直接转发到拥有咱们想要的数据的节点。不管咱们访问的是哪一个节点,它都会控制从拥有数据的节点收集响应的过程,并返回给客户端最终的结果。这一切都是由 Elasticsearch 透明管理的。spa
在 Elasticsearch 集群中能够监控统计不少信息,其中最重要的就是:集群健康(cluster health)。它的status
有 green
、yellow
、red
三种;
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
是咱们最应该关注的字段。status
能够告诉咱们当前集群是否处于一个可用的状态。三种颜色分别表明:
状态 | 意义 |
---|---|
green |
全部主分片和从分片均可用 |
yellow |
全部主分片可用,但存在不可用的从分片 |
red |
存在不可用的主要分片 |
在接下来的章节,咱们将学习一下什么是主要分片(primary shard) 和 从分片(replica shard),并说明这些状态在实际环境中的意义。
为了将数据添加到 Elasticsearch,咱们须要 索引(index) —— 存储关联数据的地方。实际上,索引只是一个逻辑命名空间(logical namespace),它指向一个或多个 分片(shards)。
分片(shard) 是 工做单元(worker unit) 底层的一员,它只负责保存索引中全部数据的一小片。在接下来的《深刻分片》一章中,咱们还将深刻学习分片是如何运做的,可是如今你只要知道分片是一个独立的Lucene实例既可,而且它自身也是一个完整的搜索引擎。咱们的文档存储而且被索引在分片中,可是咱们的程序并不会直接与它们通讯。取而代之,它们直接与索引进行通讯的。
在 elasticsearch 中,分片用来分配集群中的数据。把分片想象成一个数据的容器。数据被存储在分片中,而后分片又被分配在集群的节点上。当你的集群扩展或者缩小时,elasticsearch 会自动的在节点之间迁移分配分片,以便集群保持均衡。
分片分为 主分片(primary shard) 以及 从分片(replica 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> }
status
为 yellow
.集群的健康情况 yellow
意味着全部的 主分片(primary shards) 启动而且运行了,这时集群已经能够成功的处理任意请求,可是 从分片(replica shards) 没有彻底被激活。事实上,当前这三个从分片都处于unassigned
(未分配)的状态,它们还未被分配到节点上。在同一个节点上保存相同的数据副本是没有必要的,若是这个节点故障了,就等同于全部的数据副本也丢失了。
如今咱们的集群已经可用了,可是依旧存在因硬件故障而致使数据丢失的风险。
在单一节点上运行意味着有单点故障的风险,没有数据冗余备份。幸运的是,咱们能够启用另外一个节点来保护咱们的数据。
启动第二个节点
为了测试在增长第二个节点后发生了什么,你可使用与第一个节点相同的方式启动第二个节点(你能够参考 入门-》安装-》运行 Elasticsearch 一章),并且在同一个目录——多个节点能够分享同一个目录。
只要第二个节点与第一个节点的 cluster.name
相同(参见./config/elasticsearch.yml
文件中的配置),它就能自动发现并加入到第一个节点的集群中。若是没有,请结合日志找出问题所在。这多是多播(multicast)被禁用,或者防火墙阻止了节点间的通讯。
若是咱们启动了第二个节点,这个集群应该叫作 双节点集群(cluster-two-nodes)
双节点集群——全部的主分片和从分片都被分配:
当第二个节点加入后,就产生了三个 从分片(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 }
status
是 green
.咱们的集群不只功能齐全的,而且具备高可用性。
随着应用需求的增加,咱们该如何扩展?若是咱们启动第三个节点,集群内会自动重组,这时便成为了三节点集群(cluster-three-nodes)
分片已经被从新分配以平衡负载:
在 Node 1
和 Node 2
中分别会有一个分片被移动到 Node 3
上,这样一来,每一个节点上就都只有两个分片了。这意味着每一个节点的硬件资源(CPU、RAM、I/O)被更少的分片共享,因此每一个分片就会有更好的性能表现。
分片自己就是一个很是成熟的搜索引擎,它可使用单个节点的全部资源。咱们一共有6个分片(3个主分片和3个从分片),所以最多能够扩展到6个节点,每一个节点上有一个分片,这样每一个分片均可以使用到所在节点100%的资源了。
可是若是咱们想要扩展到六个节点以上应该怎么办?
主分片的数量在索引建立的时候就已经指定了,实际上,这个数字定义了能存储到索引中的数据最大量(具体的数量取决于你的数据,硬件的使用状况)。例如,读请求——搜索或者文档恢复就能够由主分片或者从分片来执行,因此当你拥有更多份数据的时候,你就拥有了更大的吞吐量。
从分片的数量能够在运行的集群中动态的调整,这样咱们就能够根据实际需求扩展或者缩小规模。接下来,咱们来增长一下从分片组的数量:
PUT /blogs/_settings
{
"number_of_replicas" : 2 }
增长number_of_replicas
到2:
从图中能够看出,如今 blogs
的索引总共有9个分片:3个主分片和6个从分片。也就是说,如今咱们就能够将总节点数扩展到9个,就又会变成一个节点一个分片的状态了。最终咱们获得了三倍搜索性能的三节点集群。
提示
固然,仅仅是在一样数量的节点上增长从分片的数量是根本不能提升性能的,由于每一个分片都有访问系统资源的权限。你须要升级硬件配置以提升吞吐量。
不过更多的从分片意味着咱们有更多的冗余:经过上文的配置,咱们能够承受两个节点的故障而不会丢失数据。
前文咱们已经提到过 Elasticsearch 能够应对节点故障。让咱们来尝试一下。若是咱们把第一个节点杀掉,咱们的集群就会以下图所示:
被杀掉的节点是主节点。而为了集群的正常工做必须须要一个主节点,因此首先进行的进程就是从各节点中选择了一个新的主节点:Node 2
。
主分片 1
和 2
在咱们杀掉 Node 1
后就丢失了,咱们的索引在丢失主节点的时候是不能正常工做的。若是咱们在这个时候检查集群健康状态,将会显示 red
:存在不可用的主节点!
幸运的是,丢失的两个主分片的完整拷贝在存在于其余的节点上,因此新的主节点所完成的第一件事情就是将这些在 Node 2
和 Node 3
上的从分片提高为主分片,而后集群的健康状态就变回至 yellow
。这个提高的进程是瞬间完成了,就好像按了一下开关。
那么为何集群健康状态依然是是 yellow
而不是 green
呢?是由于如今咱们有3个主分片,可是咱们以前设定了1个主分片有2个从分片,可是如今却只有1份从分片,因此状态没法变为 green
,不过咱们能够不用太担忧这里:当咱们再次杀掉 Node 2
的时候,咱们的程序依旧能够在没有丢失任何数据的状况下运行,由于Node 3
中依旧拥有每一个分片的备份。
若是咱们重启 Node 1
,集群就可以从新分配丢失的从分片,这样结果就会与三节点两从集群一致。若是Node 1
依旧还有旧节点的内容,系统会尝试从新利用他们,并只会复制在故障期间的变动数据。
到目前为止,咱们已经清晰地了解了 Elasticsearch 的横向扩展以及数据安全的相关内容。接下来,咱们将要继续讨论分片的生命周期等更多细节。