优化 Elasticsearch 每个索引应该有多少个分片?
关于副本
====
副本主要是为了提高搜索性能,用户可以随时添加或删除副本。它们为您提供了额外的容量、更高的吞吐量和更强的故障切换能力。我们始终建议生产群集有两个副本用于故障转移。
谨慎分配你的分片
========
当在 ElasticSearch 集群中配置好你的索引后, 你要明白在集群运行中你无法调整分片设置. 如果以后你发现需要调整分片数量, 那么您需要重新索引所有源文档-reindex(虽然重建索引比较耗时,但可以在没有停机的情况下完成).
主分片配置非常类似于硬盘分区,其中原始磁盘空间的重新分区需要用户备份,配置新分区以及将数据重写到新分区
2~3GB 的小型静态数据集
=============
分
配分片时主要考虑的你的数据集的增长趋势.
我们也经常会看到一些不必要的过度分片场景. 从 ES 社区用户对这个热门主题(分片配置)的分享数据来看, 用户可能认为过度分配是个绝对安全的策略(这里讲的过度分配是指对特定数据集, 为每个索引分配了超出当前数据量(文档数)所需要的分片数).
Elastic 在早期确实鼓吹过这种做法, 然后很多用户做的更为极端--例如分配 1000 个分片. 事实上, Elastic 目前对此持有更谨慎的态度.
稍有富余是好的, 但过度分配分片却是大错特错. 具体定义多少分片很难有定论, 取决于用户的数据量和使用方式.一百个很少使用的碎片可能没问题;而两个使用量很大的碎片可能太多了.
要知道, 你分配的每个分片都是有额外的成本的:
每个分片本质上就是一个 Lucene 索引, 因此会消耗相应的文件句柄, 内存和 CPU 资源
每个搜索请求会调度到索引的每个分片中. 如果分片分散在不同的节点倒是问题不太. 但当分片开始竞争相同的硬件资源时, 性能便会逐步下降
ES 使用词频统计来计算相关性. 当然这些统计也会分配到各个分片上. 如果在大量分片上只维护了很少的数据, 则将导致最终的文档相关性较差
我们的客户通常认为随着业务的增长, 他们的数据量也会相应的增加, 所以很有必要为此做长期规划. 很多用户相信他们将会遇到暴发性增长(尽管大多数甚至都没有遇到过峰值), 当然也希望避免重新分片并减少可能的停机时间.
如果你真的担心数据的快速增长, 我们建议你多关心这条限制: ElasticSearch 推荐的最大 JVM 堆空间是 30~32G, 所以把你的分片最大容量限制为 30GB, 然后再对分片数量做合理估算. 例如, 你认为你的数据能达到 200GB, 我们推荐你最多分配 7 到 8 个分片.
总之, 不要现在就为你可能在三年后才能达到的 10TB 数据做过多分配. 如果真到那一天, 你也会很早感知到性能变化的.
尽管本部分并未详细讨论副本分片, 但我们推荐你保持适度的副本数并随时可做相应的增加. 如果你正在部署一个新的环境, 也许你可以参考我们的基于副本的集群的设计.这个集群有三个节点组成, 每个分片只分配了副本. 不过随着需求变化, 你可以轻易地调整副本数量.
大规模以及日益增长的数据场景
==============
对大数据集, 我们非常鼓励你为索引多分配些分片--当然也要在合理范围内. 上面讲到的每个分片最好不超过 30GB 的原则依然使用.
不过, 你最好还是能描述出每个节点上只放一个索引分片的必要性. 在开始阶段, 一个好的方案是根据你的节点数量按照 1.5~3 倍的原则来创建分片. 例如,如果你有 3 个节点, 则推荐你创建的分片数最多不超过 9(3x3)个.
随着数据量的增加,如果你通过集群状态 API 发现了问题,或者遭遇了性能退化,则只需要增加额外的节点即可. ES 会自动帮你完成分片在不同节点上的分布平衡.
再强调一次, 虽然这里我们暂未涉及副本节点的介绍, 但上面的指导原则依然使用: 是否有必要在每个节点上只分配一个索引的分片. 另外, 如果给每个分片分配 1 个副本, 你所需的节点数将加倍. 如果需要为每个分片分配 2 个副本, 则需要 3 倍的节点数. 更多详情可以参考基于副本的集群.
Logstash
========
不知道你是否有基于日期的索引需求, 并且对索引数据的搜索场景非常少. 也许这些索引量将达到成百上千, 但每个索引的数据量只有 1GB 甚至更小. 对于这种类似场景, 我建议你只需要为索引分配 1 个分片.
如果使用 ES 的默认配置(5 个分片), 并且使用 Logstash 按天生成索引, 那么 6 个月下来, 你拥有的分片数将达到 890 个. 再多的话, 你的集群将难以工作--除非你提供了更多(例如 15 个或更多)的节点.
想一下, 大部分的 Logstash 用户并不会频繁的进行搜索, 甚至每分钟都不会有一次查询. 所以这种场景, 推荐更为经济使用的设置. 在这种场景下, 搜索性能并不是第一要素, 所以并不需要很多副本. 维护单个副本用于数据冗余已经足够. 不过数据被不断载入到内存的比例相应也会变高.
如果你的索引只需要一个分片, 那么使用 Logstash 的配置可以在 3 节点的集群中维持运行 6 个月. 当然你至少需要使用 4GB 的内存, 不过建议使用 8GB, 因为在多数据云平台中使用 8GB 内存会有明显的网速以及更少的资源共享.
总结
再次声明, 数据分片也是要有相应资源消耗,并且需要持续投入.
评论