Elasticsearch究竟要设置多少分片数?

0、引言

本文翻译自Elasticsearch20170918热乎的官方博客,原做者:Christian Dahlqvist。 在构建Elasticsearch集群的初期若是集群分片设置不合理,可能在项目的中后期就会出现性能问题。缓存

Elasticsearch是一个很是通用的平台,支持各类各样的用例,而且为数据组织和复制策略提供了巨大灵活性。这种灵活性使得做为ELK新手的你将数据组织成索引和分片变得困难。虽然不必定会在首次启动时出现问题,但因为数据量随时间的推移,可能会致使性能问题。集群所拥有的数据越多,纠正问题就越困难,甚至有时可能须要从新索引大量数据。安全

当咱们遇到遭遇性能问题的用户时,能够追溯到关于数据索引的数据和群集数量的问题并不罕见。 对于涉及multi-tenancy或使用基于时间的索引的用户尤为如此。 在与用户讨论这个问题时(会议、论坛形式),引伸出的一些最多见的问题是:网络

1)“我应该有多少个分片?”
2)“个人分片应该有多大”?
  • 1
  • 2

这篇博客文章旨在帮助您回答这些问题,并为使用基于时间的索引的使用案例( 日志记录或安全分析 )提供实用的指导。数据结构

一、什么是分片?

在开始以前,让咱们约定文章中用到的一些概念和术语。 
Elasticsearch中的数据组织成索引。每个索引由一个或多个分片组成。每一个分片是Luncene索引的一个实例,你能够把实例理解成自管理的搜索引擎,用于在Elasticsearch集群中对一部分数据进行索引和处理查询。并发

【刷新】当数据写入分片时,它会按期地发布到磁盘上的新的不可变的Lucene段中,此时它可用于查询。——这被称为刷新。更详细的解读请参考: 
http://t.cn/R05e3YRide

【合并】随着分段数(segment)的增加,这些segment被按期地整合到较大的segments。 这个过程被称为合并(merging)。性能

因为全部段都是不可变的, 由于新的合并段须要建立,旧的分段将被删除 ,这意味着所使用的磁盘空间一般在索引时会波动。 合并可能资源至关密集,特别是在磁盘I/O方面。测试

分片是Elasticsearch在集群周围分发数据的单位。 Elasticsearch在从新平衡数据时 (例如 发生故障后) 移动分片的速度 取决于分片的大小和数量以及网络和磁盘性能。优化

提示:避免有很是大的分片,由于大的分片可能会对集群从故障中恢复的能力产生负面影响。 对于多大的分片没有固定的限制,可是分片大小为50GB一般被界定为适用于各类用例的限制。ui

二、索引有效期( retention period )

因为段是不可变的,更新文档须要Elasticsearch首先查找现有文档,而后将其标记为已删除,并添加更新的版本。删除文档还须要找到文档并将其标记为已删除。所以,删除的文档将继续占据磁盘空间和一些系统资源,直到它们被合并,这将消耗大量的系统资源。

Elasticsearch容许从文件系统直接删除完整索引,而没必要明确地必须单独删除全部记录。这是迄今为止从Elasticsearch删除数据的最有效的方式。

提示:尽量使用基于时间的索引来管理数据。根据保留期(retention period,能够理解成有效期)将数据分组。基于时间的索引还能够轻松地随时间改变主分片和副本分片的数量(觉得要生成的下一个索引进行更改)。这简化了适应不断变化的数据量和需求。

三、索引和分片不是空闲的?

【集群状态】对于每一个Elasticsearch索引,其映射和状态的信息都存储在集群状态。 这些集群状态信息保存在内存中以便快速访问。 所以,若是在集群中拥有大量索引,可能致使大的集群状态(特别是若是映射较大)。 全部更新集群状态操做为了在集群中保证一致性,须要经过单个线程完成,所以更新速度将变慢。

提示:为了减小索引数量并避免大的乃至很是庞大的映射,请考虑将相同索引结构的数据存储在相同的索引中,而不是基于数据的来源将数据分割成独立的索引。 在每一个索引的索引数量和映射大小之间找到一个很好的平衡很重要。**

每一个分片都有数据须要保存在内存中并使用堆空间。 这包括在分片级别保存信息的数据结构,也包括在段级别的数据结构,以便定义数据驻留在磁盘上的位置。 这些数据结构的大小不是固定的,而且将根据用例而有所不一样。

然而,段相关开销的一个重要特征是它与分段的大小不成正比。 这意味着与较小的段相比,较大的段的每一个数据量具备较少的开销,且这种差别很大。

【堆内存的重要性】为了可以每一个节点存储尽量多的数据,重要的是尽量多地管理堆内存使用量并减小其开销。 节点拥有的堆空间越多,它能够处理的数据和分片越多。

所以,索引和分片从集群的角度看待不是空闲的,由于每一个索引和分片都有必定程度的资源开销。

提示1:小分片会致使小分段(segment),从而增长开销。目的是保持平均分片大小在几GB和几十GB之间。对于具备基于时间的数据的用例,一般看到大小在20GB和40GB之间的分片。

提示2:因为每一个分片的开销取决于分段数和大小,经过强制操做迫使较小的段合并成较大的段能够减小开销并提升查询性能。一旦没有更多的数据被写入索引,这应该是理想的。请注意,这是一个消耗资源的(昂贵的)操做,较为理想的处理时段应该在非高峰时段执行。

提示3:您能够在集群节点上保存的分片数量与您可用的堆内存大小成正比,但这在Elasticsearch中没有的固定限制。 一个很好的经验法则是:确保每一个节点的分片数量保持在低于每1GB堆内存对应集群的分片在20-25之间。 所以,具备30GB堆内存的节点最多能够有600-750个分片,可是进一步低于此限制,您能够保持更好。 这一般会帮助群体保持处于健康状态。

四、分片的大小如何影响性能?

在Elasticsearch中,每一个查询在每一个分片的单个线程中执行。然而,能够并行处理多个分片,并能够在相同分片上执行多个查询和聚合。

【小分片的利弊】这意味着,在不涉及高速缓存时,最小查询延迟将取决于数据、查询的类型、分片的大小。查询大量小分片将使得每一个分片的处理速度更快,可是随着更多的任务须要按顺序排队和处理,它不必定要比查询较小数量的更大的分片更快。若是有多个并发查询,则有不少小碎片也会下降查询吞吐量。

提示:从查询性能角度肯定最大分片大小的最佳方法是使用逼真的数据和查询进行基准测试(真实数据而非模拟数据)。 始终使用查询和索引负载进行基准测试,表明节点在生产中须要处理的内容,由于单个查询的优化可能会产生误导性的结果。

五、如何管理分片大小?

当使用基于时间的索引时,每一个索引传统上都与固定的时间段相关联。 每日索引很是广泛,常常用于持有时间区间短或每日量大的数据。 这些容许数据期限期间以良好的粒度进行管理,而且能够方便地对天天更换调整volumes。

时间周期长的数据,特别是若是每日不保存天天的索引数据,则一般会使用每周或每个月的保存的碎片大小的增长。 这减小了随着时间的流逝须要存储在群集中的索引和碎片数量大小(直译有点费劲此处)。

提示:若是使用固按期限的时间索引数据,能够根据时间周期和预期数据量调整所涵盖的时间范围,以达到目标分片大小。

【均匀更新&快速变化的索引数据对比】具备固定时间间隔的基于时间的索引在数据量合理预测而且变化缓慢的状况下工做良好。 若是索引率能够快速变化,则很难保持均匀的目标分片大小。

为了可以更好地处理这种状况,推出了Rollover和S**hrink API**。 这些增长了如何管理索引和分片的灵活性,尤为适用于基于时间的索引。

此处省略了 Rollover和Shrink API的介绍。(建议查询官网补齐概念再深刻)

六、结论

这篇博客文章提供了有关如何在Elasticsearch中最好地管理数据的提示和实用指南。 若是您有兴趣了解更多,推荐阅读Google搜索 “Elasticsearch: the definitive guide” (有点旧,值得阅读)。

然而,关于如何最好地在索引和分片上分发数据的许多决策将取决于用例细节,有时可能难以肯定如何最佳地应用可用的建议。

文章说起的几个核心建议清单以下,以回答文章开头的提问。

1) “我应该有多少个分片?”
答: 每一个节点的分片数量保持在低于每1GB堆内存对应集群的分片在20-25之间。
2) “个人分片应该有多大”?
答:分片大小为50GB一般被界定为适用于各类用例的限制。
  • 1
  • 2
  • 3
  • 4

仍是读起来有点拗口,一些概念仍是不够深刻,不能很好的深刻浅出的讲解。 待我实践中更新吧。更多细节,欢迎讨论!

相关文章
相关标签/搜索