Elasticsearch 集群分配多少分片合理

https://www.jianshu.com/p/297e13045605

Elasticsearch 是一个非常通用的平台,支持各种用户实例,并为组织数据和复制策略提供了极大的灵活性。但是,这种灵活性有时会使我们很难在早期确定如何很好地将数据组织成索引和分片,尤其是不熟悉 Elastic Stack。虽然不一定会在首次启动时引起问题,但随着数据量的增长,它们可能会导致性能问题。群集拥有的数据越多,纠正问题也越困难,因为有时可能需要重新索引大量数据。
     因此,当我们遇到性能问题时,往往可以追溯到索引方式以及集群中分片的数量。那么就会遇到问题,我们应该有多少分片以及我的分片应该有多大。

一、什么是分片?

假如我们的集群的架构如下图:

image.png

集群(cluster): 由一个或多个节点组成, 并通过集群名称与其他集群进行区分

节点(node): 单个 ElasticSearch 实例. 通常一个节点运行在一个隔离的容器或虚拟机中

索引(index): 在 ES 中, 索引是一组文档的集合

分片(shard): 因为 ES 是个分布式的搜索引擎, 所以索引通常都会分解成不同部分, 而这些分布在不同节点的数据就是分片. ES自动管理和组织分片, 并在必要的时候对分片数据进行再平衡分配, 所以用户基本上不用担心分片的处理细节.

副本(replica): ES 默认为一个索引创建 5 个主分片, 并分别为其创建一个副本分片. 也就是说每个索引都由 5 个主分片成本, 而每个主分片都相应的有一个 copy。对于分布式搜索引擎来说, 分片及副本的分配将是高可用及快速搜索响应的设计核心.主分片与副本都能处理查询请求,它们的唯一区别在于只有主分片才能处理索引请求.副本对搜索性能非常重要,同时用户也可在任何时候添加或删除副本。额外的副本能给带来更大的容量, 更高的呑吐能力及更强的故障恢复能力。

如上图,有集群两个节点,并使用了默认的分片配置. ES自动把这5个主分片分配到2个节点上, 而它们分别对应的副本则在完全不同的节点上。其中 node1 有某个索引的分片1、2、3和副本分片4、5,node2 有该索引的分片4、5和副本分片1、2、3。

当数据被写入分片时,它会定期发布到磁盘上的不可变的 Lucene 分段中用于查询。随着分段数量的增长,这些分段会定期合并为更大的分段。 此过程称为合并。 由于所有分段都是不可变的,这意味着所使用的磁盘空间通常会在索引期间波动,因为需要在删除替换分段之前创建新的合并分段。 合并可能非常耗费资源,特别是在磁盘I / O方面。

分片是 Elasticsearch 集群分发数据的单元。 Elasticsearch 在重新平衡数据时可以移动分片的速度,例如发生故障后,将取决于分片的大小和数量以及网络和磁盘性能。

注1:避免使用非常大的分片,因为这会对群集从故障中恢复的能力产生负面影响。 对分片的大小没有固定的限制,但是通常情况下很多场景限制在 50GB 的分片大小以内。

注2:当在ElasticSearch集群中配置好你的索引后, 你要明白在集群运行中你无法调整分片设置. 既便以后你发现需要调整分片数量, 你也只能新建创建并对数据进行重新索引(reindex)(虽然reindex会比较耗时, 但至少能保证你不会停机).
    主分片的配置与硬盘分区很类似, 在对一块空的硬盘空间进行分区时, 会要求用户先进行数据备份, 然后配置新的分区, 最后把数据写到新的分区上。

注3:尽可能使用基于时间的索引来管理数据保留期。 根据保留期将数据分组到索引中。 基于时间的索引还可以轻松地随时间改变主分片和副本的数量,因为可以更改下一个要生成的索引。

二、索引和分片是否是空闲的

对于每个 Elasticsearch 索引,有关映射和状态的信息都存储在集群状态中。它保存在内存中以便快速访问。 因此,在群集中具有大量索引可能导致较大的群集状态,尤其是在映射较大的情况下。 这可能会变得很慢,因为所有更新都需要通过单个线程完成,以便在更改集群中分布之前保证一致性。
    每个分片都有需要保存在内存中的数据并使用堆空间。 这包括在分片级别保存信息的数据结构,但也包括在分段级别的数据结构,以便定义数据驻留在磁盘上的位置。 这些数据结构的大小不固定,并且会根据使用场景不同而有所不同。然而,分段相关开销的一个重要特征是它与分段的大小不严格成比例。 这意味着与较小的分段相比,较大的分段每个数据量的开销较小。 差异可能很大。为了能够为每个节点存储尽可能多的数据,管理堆的使用并尽可能减少开销变得很重要。 节点拥有的堆空间越多,它可以处理的数据和分片就越多。
    因此,索引和分片在集群视角下不是空闲的,因为每个索引和分片都存在一定程度的资源开销。

分配的每个分片都是有额外的成本的:

  • 每个分片本质上就是一个Lucene索引, 因此会消耗相应的文件句柄, 内存和CPU资源
  • 每个搜索请求会调度到索引的每个分片中. 如果分片分散在不同的节点倒是问题不太. 但当分片开始竞争相同的硬件资源时, 性能便会逐步下降
  • ES 使用词频统计来计算相关性. 当然这些统计也会分配到各个分片上。如果在大量分片上只维护了很少的数据, 则将导致最终的文档相关性较差。

注1:小的分片会造成小的分段,从而会增加开销。我们的目的是将平均分片大小控制在几 GB 到几十 GB 之间。对于基于时间的数据的使用场景来说,通常将分片大小控制在 20GB 到 40GB 之间。
    注2:由于每个分片的开销取决于分段的数量和大小,因此通过 forcemerge 操作强制将较小的分段合并为较大的分段,这样可以减少开销并提高查询性能。 理想情况下,一旦不再向索引写入数据,就应该这样做。 请注意,这是一项比较耗费性能和开销的操作,因此应该在非高峰时段执行。
    注3:我们可以在节点上保留的分片数量与可用的堆内存成正比,但 Elasticsearch 没有强制的固定限制。 一个好的经验法则是确保每个节点的分片数量低于每GB堆内存配置20到25个分片。 因此,具有30GB堆内存的节点应该具有最多600-750个分片,但是低于该限制可以使其保持更好。 这通常有助于集群保持健康。
    注4:如果担心数据的快速增长, 建议根据这条限制: ElasticSearch推荐的最大JVM堆空间 是 30~32G, 所以把分片最大容量限制为 30GB, 然后再对分片数量做合理估算。例如, 如果的数据能达到 200GB, 则最多分配7到8个分片。
    注5:如果是基于日期的索引需求, 并且对索引数据的搜索场景非常少. 也许这些索引量将达到成百上千, 但每个索引的数据量只有1GB甚至更小. 对于这种类似场景, 建议是只需要为索引分配1个分片。如果使用ES的默认配置(5个分片), 并且使用 Logstash 按天生成索引, 那么 6 个月下来, 拥有的分片数将达到 890 个. 再多的话, 你的集群将难以工作--除非提供了更多(例如15个或更多)的节点。想一下, 大部分的 Logstash 用户并不会频繁的进行搜索, 甚至每分钟都不会有一次查询. 所以这种场景, 推荐更为经济使用的设置. 在这种场景下, 搜索性能并不是第一要素, 所以并不需要很多副本。 维护单个副本用于数据冗余已经足够。不过数据被不断载入到内存的比例相应也会变高。如果索引只需要一个分片, 那么使用 Logstash 的配置可以在 3 节点的集群中维持运行 6 个月。当然你至少需要使用 4GB 的内存, 不过建议使用 8GB, 因为在多数据云平台中使用 8GB 内存会有明显的网速以及更少的资源共享.

三、分片大小如何影响性能

在Elasticsearch中,每个查询在每个分片的单个线程中执行。 但是,可以并行处理多个分片,对同一分片也可以进行多个查询和聚合。
    这意味着,如果不涉及缓存,则最小查询延迟将取决于数据、查询类型以及分片的大小。 查询大量小的分片将使每个分片的处理速度更快,但是需要按顺序排队和处理更多的任务,它不一定比查询较少数量的较大分片更快。 如果存在多个并发查询,则拥有大量小分片也会降低查询吞吐量。
    从查询性能角度确定最大分片大小的最佳方法是使用实际数据和查询进行基准测试。 始终以查询和加载索引的节点在生产中需要处理的内容基准,因为优化单个查询可能会产生误导性结果。

四、如何管理分片大小

当使用基于时间的索引时,通常每个索引都与固定的时间段相关联。 每天的索引非常常见,通常用于保存保留期短的或每日量大的数据。 这些允许以合适的粒度管理保留期,并且可以轻松调整日常基础量。 具有较长保留期的数据,特别是如果每日的量不能保证使用每天的索引,通常使用每周或每月的索引以保证分片大小。 这减少了随着时间的推移需要存储在集群中的索引和分片的数量。
    :如果使用基于时间的索引,这个时间是某个固定的时间段,那么需要根据数据的保留期限和预期的数据量来调整每个索引所覆盖的时间段,以达到目标分片的大小。也就是说,如果我们要确定最终分片的大小,则需要根据我们的数据保存的期限以及预估预期的数据量来调整我们索引需要按照天还是周还是月的时间来进行评估。
    当数据量可以合理预测并且变化缓慢时,具有固定时间间隔的基于时间的索引很有效。 如果索引快速变化,则很难保持统一的目标分片大小。为了能够更好地处理这种类型的场景,引入了 Rollover and Shrink API (https://www.jianshu.com/writer#/notebooks/27738831/notes/31623194) 。 这些为索引和分片的管理方式增加了很多灵活性,特别是对于基于时间的索引。
     Rollover and Shrink API 可以指定应包含的文档和索引的数量和/或应该向其写入最大期限的文档。 一旦超出其中一个标准,Elasticsearch 就可以触发创建新索引,无需停机即可完成写入。 可以切换到特定大小的新索引,而不是让每个索引覆盖特定的时间段,这使得可以更容易地为所有索引实现均匀的分片大小。如果需要更新数据,在使用此API时,事件的时间戳与其所处的索引之间不再存在明显的链接,这可能会使更新效率大大降低,因为每次更新都需要在搜索之前进行。
    :如果我们有基于时间的不可变数据,其中数据量可能会随时间发生显著变化,就可以考虑使用 Rollover API,通过动态更改每个索引所涵盖的时间段来实现最佳目标分片大小。 这提供了极大的灵活性,并且可以帮助避免在数据量不可预测时具有太大或太小的分片。
     Shrink API 允许我们将现有索引缩小为具有较少主分片的新索引。 如果在索引期间需要跨节点均匀扩展分片,但这会导致分片太小,一旦索引不再被索引,此 API 可用于减少主分片的数量。 这将生成更大的分片,更适合长期存储数据。
     如果需要让每个索引覆盖特定的时间段,并且希望能够在大量节点上扩展索引,请考虑使用 Shrink API 在索引不再编入索引时减少主分片的数量。 如果最初配置了太多分片,此 API 还可用于减少分片数量。

五、总结

关于如何在索引和分片之间最佳地分布数据,这将取决于所使用的场景的细节,有时很难确定如何最好地应用可用的建议。
    数据分片也是要有相应资源消耗,并且需要持续投入。当索引拥有较多分片时, 为了组装查询结果, ES 必须单独查询每个分片(当然并行的方式)并对结果进行合并。所以高性能 IO 设备(SSDs)和多核处理器无疑对分片性能会有巨大帮助。尽管如此, 还是要多关心数据本身的大小,更新频率以及未来的状态。在分片分配上并没有绝对的答案。

参考:
https://www.elastic.co/cn/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster
https://segmentfault.com/a/1190000008868585

作者:zpei0411
链接:https://www.jianshu.com/p/297e13045605
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

原文地址:https://www.cnblogs.com/shijingxiang/p/11286959.html

时间: 2024-11-09 02:34:05

Elasticsearch 集群分配多少分片合理的相关文章

elasticsearch 集群indices 分片状态INITIALIZING

elasticsearch 集群indices 分片状态INITIALIZING,集群状态为: yellow 故障现象 GET /_cat/shards/7a_cool 7a_cool 5 r STARTED 4583018 759.4mb 10.2.4.21 pt01-pte-10-2-4-21 7a_cool 17 r INITIALIZING 10.2.4.22 pt01-pte-10-2-4-22 <==异常分片 解决办法 1:关闭异常分片主机es 服务: 登陆pt01-pte-10-2

Elasticsearch集群知识笔记

Elasticsearch集群知识笔记 Elasticsearch内部提供了一个rest接口用于查看集群内部的健康状况: curl -XGET http://localhost:9200/_cluster/health response结果: { "cluster_name": "format-es", "status": "green", ... } 这里的status有3种状态,分别是green(所有主分片和复制分片都可用

剖析Elasticsearch集群系列第一篇 Elasticsearch的存储模型和读写操作

剖析Elasticsearch集群系列涵盖了当今最流行的分布式搜索引擎Elasticsearch的底层架构和原型实例. 本文是这个系列的第一篇,在本文中,我们将讨论的Elasticsearch的底层存储模型及CRUD(创建.读取.更新和删除)操作的工作原理. Elasticsearch是当今最流行的分布式搜索引擎,GitHub. SalesforceIQ.Netflix等公司将其用于全文检索和分析应用.在Insight,我们用到了Elasticsearch的诸多不同功能,比如: 全文检索 比如找

【ELK】03、ElasticSearch集群

上一篇主要学习了ES及其插件的安装,这一篇主要学习ES集群及其节点管理 一.ES集群概述 1.ES集群简介 ES就是为高可用和可扩展而生的,服务器的扩展可以通过购置性能更强的服务器(垂直扩展或者向上扩展,Vertical Scale/Scaling Up),亦或是通过购置更多的服务器(水平扩展或者向外扩展,Horizontal Scale/Scaling Out)来完成.尽管ES能够利用更强劲的硬件,垂直扩展毕竟还是有它的极限.真正的可扩展性来自于水平扩展 - 通过向集群中添加更多的节点来分布负

ElasticSearch集群配置

elasticsearch集群搭建,可以把索引进行分片存储,一个索引可以分成若干个片,分别存储到集群里面,而对于集群里面的负载均衡,副本分配,索引动态均衡(根据节点的增加或者减少)都是elasticsearch自己内部完成的,一有情况就会重新进行分配. 下面先是介绍几个关于elasticsearch的几个名词 1.cluster 代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的.es的一个概念就是去中心化,字面上理解就是无中心节点,

elasticsearch 集群

elasticsearch 集群 搭建elasticsearch的集群 现在假设我们有3台es机器,想要把他们搭建成为一个集群 基本配置 每个节点都要进行这样的配置: cluster.name: baichebao-cluster 这个是配置集群的名字,为了能进行自动查找 node.name: "baichebao-node-1" 这个是配置当前节点的名字,当然每个节点的名字都应该是唯一的 node.master: false node.data: true 这两个配置有4种配置方法,

ES2:ElasticSearch 集群配置

ElasticSearch共有两个配置文件,都位于config目录下,分别是elasticsearch.yml和logging.yml,其中,elasticsearch.yml 是全局配置文件,用于在服务器级别对ElasticSearch进行配置.ElasticSearch的配置选项分为静态设置和动态设置两种,静态设置必须在结点级别(node-level)设置,或配置在elasticsearch.yml配置文件中,或配置在环境变量中,或配置在命令行中,在结点启动之后,静态设置不能修改.集群的名字

elasticsearch集群介绍及优化【转】

elasticsearch用于构建高可用和可扩展的系统.扩展的方式可以是购买更好的服务器(纵向扩展)或者购买更多的服务器(横向扩展),Elasticsearch能从更强大的硬件中获得更好的性能,但是纵向扩展也有一定的局限性.真正的扩展应该是横向的,它通过增加节点来传播负载和增加可靠性.对于大多数数据库而言,横向扩展意味着你的程序将做非常大的改动来利用这些新添加的设备.对比来说,Elasticsearch天生是分布式的:它知道如何管理节点来提供高扩展和高可用.这意味着你的程序不需要关心这些.对于大

Elasticsearch集群中处理大型日志流的几个常用概念

之前对于CDN的日志处理模型是从logstash agent==>>redis==>>logstash index==>>elasticsearch==>>kibana3,对于elasticsearch集群搭建,可以把索引进行分片存储,一个索引可以分成若干个片,分别存储到集群里面,而对于集群里面的负载均衡,副本分配,索引动态均衡(根据节点的增加或者减少)都是elasticsearch自己内部完成的,一有情况就会重新进行分配.下面先是介绍几个关于elastic