0、引言

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

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

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

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

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

1、什么是分片?

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

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

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

由于所有段都是不可变的, 因为新的合并段需要创建,旧的分段将被删除 ,这意味着所使用的磁盘空间通常在索引时会波动。 合并可能资源相当密集,特别是在磁盘I/O方面。

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

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

2、索引有效期( retention period )

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

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

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

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

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

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

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

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

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

因此,索引和分片从集群的角度看待不是空闲的,因为每个索引和分片都有一定程度的资源开销。

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

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

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

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

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

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

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

5、如何管理分片大小?

当使用基于时间的索引时,每个索引传统上都与固定的时间段相关联。 每日索引非常普遍,经常用于持有时间区间短或每日量大的数据。 这些允许数据期限期间以良好的粒度进行管理,并且可以方便地对每天更换调整volumes。

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

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

【均匀更新&快速变化的索引数据对比】具有固定时间间隔的基于时间的索引在数据量合理预测并且变化缓慢的情况下工作良好。 如果索引率可以快速变化,则很难保持均匀的目标分片大小。

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

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

6、结论

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

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

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

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

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

Elasticsearch究竟要设置多少分片数?的更多相关文章

  1. elasticsearch6设置默认分片数和副本数

    elasticsearch6设置索引的默认分片数和副本数已经不是在elasticsearch.yml文件中了,而是使用了一个索引模板的东西 curl -XPUT 'http://10.27.12.16 ...

  2. 1 集群状态、增删改查、全量替换、强制创建、设置单个index的分片数副本数

    检查集群健康状态,可以看集群颜色.(黄色:primary shard都正常,replica不正常) GET /_cat/health?v 列出集群所有index GET /_cat/indices?v ...

  3. JAVA之工作线程数究竟要设置多少

    一.需求缘起 Web-Server通常有个配置,最大工作线程数,后端服务一般也有个配置,工作线程池的线程数量,这个线程数的配置不同的业务架构师有不同的经验值,有些业务设置为CPU核数的2倍,有些业务设 ...

  4. Elasticsearch 集群分配多少分片合理

    Elasticsearch 是一个非常通用的平台,支持各种用户实例,并为组织数据和复制策略提供了极大的灵活性.但是,这种灵活性有时会使我们很难在早期确定如何很好地将数据组织成索引和分片,尤其是不熟悉 ...

  5. 【翻译自mos文章】使用dbua升级时,须要手工设置CLUSTER_DATABASE參数么?

    使用dbua升级时,须要手工设置CLUSTER_DATABASE參数么? 来源于: Is Manual Setting Of CLUSTER_DATABASE Parameter Required F ...

  6. vertica 设置最大会话数

    默认会话数最大值55,如果超过了,就会报如下错误: com.vertica.support.exceptions.NonTransientConnectionException: [Vertica][ ...

  7. LODOP设置打印份数及是否逐份输出

    LODOP中通过SET_PRINT_COPIES可以设置打印份数,例如:LODOP.SET_PRINT_COPIES(2);//指定份数为2份 如果一个任务里有多页,打印份数的时候,有两种输出方式,一 ...

  8. #pragma pack() -----设置默认对齐数

    #pragma pack()  -----设置默认对齐数 预处理命令#pragma:程序如下 则根据修改的对齐数来算:则需要占据内存的大小是14 如果不进行设置,则按照编译器默认的对齐数来算:则需要占 ...

  9. es分片数相关知识

    分片数量 总分片数=主分片数 *(副分片数+1) 如下创建索引配置表示,总分片数=1 *(1+4),表示总共5个分片. "settings": { "number_of_ ...

随机推荐

  1. CTF之常见的两种关于word的信息隐藏技术

    一.利用word本身自带的文字隐藏功能 1.在word中输入文字 2.选中文字,单击右键,选择字体选项 3.单击字体选项后,单击隐藏,确定 查找隐藏信息 1.单击左上角WPS文字后,选择选项按钮单击 ...

  2. map和jsonObject 这2中数据结构之间转换

    前台写json直接是:var array = [ ] ; 调用方法:array[index],若是对象,再[“key”] var obj = {''a'':123 , "b":&q ...

  3. google play apk 下载

    https://apps.evozi.com/apk-downloader/?id=com.sgiggle.production

  4. hasura graphql-engine v1.0.0-alpha25 的几个方便功能

    hasura graphql-engine 是一个很不错的graphql 引擎,但是我们的数据模型经常可能会有变动, 但是以前的版本对于这些的处理,官方的方式是删除元数据,重启server,都不是很好 ...

  5. restheart 基本使用

    restheart 是一个方便基于mongodb的restapi 开发框架 参考项目 https://github.com/rongfengliang/restheart-docker-compose ...

  6. bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3611 https://www.luogu.org/problemnew/show/P4103 ...

  7. NOI2002银河英雄传说——带权并查集

    题目:https://www.luogu.org/problemnew/show/P1196 关键点在于存下每个点的位置. 自己糊涂的地方:位置是相对于谁的位置? 因为每次给一个原来是fa的点赋位置时 ...

  8. Eclipse设置相同变量背景色高亮显示

    在Eclipse中,鼠标选中或者光标移动到java类的变量名时,相同变量会被标识显示(设置背景色高亮), 并且侧边滚动条会标出变量的位置, 查找变量十分方便. 1.相同变量标识高亮显示: Window ...

  9. Java之优先队列

    PriorityQueue属于Java Collections Framework.PriorityQueue基于优先级堆,它是Queue接口的实现.当我们需要一个Queue实现时,可以使用这种数据结 ...

  10. 设计模式初学者笔记:Abstract Factory模式

    首先啰嗦下创建迷宫所用的Room类.这个类并不直接保存Room四周的构造,而是通过MapSite* _sides[4]这个私有数组成员指向Room四周的构造.那么什么时候将四周构造直接放在Room中, ...