管理 Elasticsearch 内存并进行故障排除

原创
05/18 15:04
阅读数 60

导语



随着 Elastic 扩展我们的 Elasticsearch Service Cloud 产品和自动上线,我们已经将 Elastic Stack 的受众范围从完整的运营团队扩展到了数据工程师,安全团队和顾问。作为 Elastic 支持团队的代表,我喜欢与更多用户背景甚至更广泛的用例进行交互。


在更广泛的听众中,我看到了更多有关管理资源分配的问题,尤其是神秘的 shard 堆比率和避免使用熔断器(circuit breaker)的问题。我完全理解!当我开始使用 Elastic Stack 时,我遇到了同样的问题。这是我关于 Java 堆和时间序列数据库分片以及扩展自己的基础结构的第一个介绍。


当我加入 Elastic 团队时,我很喜欢文档之外的内容,我们有博客和教程,因此我可以很快上手。但是后来我在第一个月就非常费劲地使我的理论知识与用户通过我的问题队列发送的错误相关联。最终,我发现像其他支持团队成员一样,许多报告的错误仅是分配问题的征兆,而相同的七个链接(在下面的理论部分可以看到)会带给用户加快成功管理其资源分配的速度。


作为支持团队的代表,在以下各节中,我将遍历我们向用户发送的最重要的分配管理理论链接,我们看到的最重要的症状以及我们指导用户更新其配置以解决其资源分配问题的地方。


理论


作为 Java 应用程序,Elasticsearch 需要从系统的物理内存中分配一些逻辑内存(堆)。这应该最多是物理 RAM 的一半,上限为 32GB。设置更高的堆使用率通常是为了响应昂贵的查询和更大的数据存储。 父级熔断器默认为95%,但是一旦持续达到85%,我们建议你扩展资源。

Elasticsearch包 含多个熔断器,这些熔断器用于防止操作引起 OutOfMemoryError。每个断路器都指定了可以使用多少内存的限制。此外,还有一个父级熔断器,用于指定可在所有断路器上使用的内存总量。


我强烈建议我们的团队提供这些概述文章,以获取更多信息:

  • 堆问题

  • 堆:大小调整和交换

  • 我的 Elasticsearch 集群中应该有多少个碎片?


配置


开箱即用,Elasticsearch 的默认设置会根据节点角色和总内存自动调整 JVM 堆的大小。但是,根据需要,你可以通过以下三种方式直接对其进行配置:


1.直接在本地 Elasticsearch 文件的 config > jvm.options 文件中

## JVM configuration ################################################################ ## IMPORTANT: JVM heap size ################################################################ # Xms represents the initial size of total heap space # Xmx represents the maximum size of total heap space -Xms4g-Xmx4g


2. 作为 docker-compose 中的 Elasticsearch 环境变量

version: '2.2'services:  es01:    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.0    environment:      - node.name=es01      - cluster.name=es      - bootstrap.memory_lock=true      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"      - discovery.type=single-node    ulimits:      memlock:        soft: -1        hard: -1    ports:      - 9200:9200


3.通过我们的 Elasticsearch Service > Deployment > Edit view。注意:滑动条分配物理内存,大约一半将分配给堆。


故障排除


如果您的群集当前遇到性能问题,则很可能归咎于通常的怀疑

  • 配置问题:分片,没有 ILM 策略

  • 引入的高体量:高请求速度/负载,重叠昂贵的查询/写入


所有以下所有 cURL / API请求都可以在 Elasticsearch Service > API 控制台中作为 Elasticsearch API 的 cURL 发出,或者在 Kibana> Dev Tools 下进行。


过度分片


数据索引存储在 sub-shards 中,这些 sub-shards 使用堆进行维护以及在搜索/写入请求期间使用。shard 大小应限制为 50GB,数量应限制为通过以下公式确定的值:

shards <= sum(nodes.max_heap) * 20


以上面的 Elasticsearch Service 为例,在两个区域中具有 8GB 的物理内存(这将总共分配两个节点)

# node.max_heap 8GB of physical memory / 2 = 4GB of heap  # sum(nodes.max_heap) 4GB of heap * 2 nodes = 8GB # max shards 8GB * 20 160


然后将其与 _cat /allocation 进行交叉比较

GET /_cat/allocation?v=true&h=shards,nodeshards node    41 instance-0000000001    41 instance-0000000000


或者使用 _cluster/health

GET /_cluster/health?filter_path=status,*_shards{  "status": "green",  "unassigned_shards": 0,  "initializing_shards": 0,  "active_primary_shards": 41,  "relocating_shards": 0,  "active_shards": 82,  "delayed_unassigned_shards": 0}


因此,此部署具有最多160个建议的82个分片。如果计数高于建议值,则可能在接下来的两个部分中出现症状(请参阅下文)。


如果有任何 shard 报告(除 active_shards 或 active_primary_shards)之外的数字 > 0,则表明你已确定导致性能问题的主要原因。


最常见的情况是,如果报告了问题,则其值为 unassigned_shards > 0。如果这些 shard 是主要分片,则群集将报告为状态:红色;如果仅副本,它将报告为状态:黄色。(这就是在索引上设置副本很重要的原因,这样,如果群集遇到问题,它可以恢复而不是遭受数据丢失。)


假设我们有一个状态:黄色,带有一个未分配的分片。为了进行调查,我们将通过 _cat /shards 来查看哪个索引分片遇到问题

GET _cat/shards?v=true&s=stateindex                                     shard prirep state        docs   store ip           nodelogs                                      0     p      STARTED         2  10.1kb 10.42.255.40 instance-0000000001logs                                      0     r      UNASSIGNEDkibana_sample_data_logs                   0     p      STARTED     14074  10.6mb 10.42.255.40 instance-0000000001.kibana_1                                 0     p      STARTED      2261   3.8mb 10.42.255.40 instance-0000000001


因此,这将用于我们的非系统索引日志,该日志具有未分配的副本分片。让我们看看通过运行_cluster/allocation/explain 是什么造成这个原因(专业提示:当你向我们发送问题以提供支持时,这正是我们的工作)

GET _cluster/allocation/explain?pretty&filter_path=index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*{ "index": "logs",  "node_allocation_decisions": [{      "node_name": "instance-0000000005",      "deciders": [{          "decider": "data_tier",          "decision": "NO",          "explanation": "node does not match any index setting


此错误消息指向 data_hot,它是索引生命周期管理(ILM)策略的一部分,并指示我们的 ILM 策略与我们当前的索引设置不一致。在这种情况下,此错误的原因是由于没有指定 hot-warm 节点而设置了 hot-warm ILM 策略。


仅供参考,如果你在没有任何 unsigned shards 的情况下运行此命令,则会出现 400 错误,提示找不到任何未分配的分片进行解释,因为没有错误要报告。


如果你遇到非逻辑原因(例如,临时网络错误,例如分配期间节点离开群集),则可以使用 Elastic 方便的 _cluster/reroute。

POST /_cluster/reroute


无需定制的此请求将启动一个异步后台进程,该进程尝试分配所有当前状态:UNASSIGNED shards。 


熔断器


最大化堆分配会导致对集群的请求超时或错误,并且经常会导致集群遇到熔断器异常。熔断器会导致类似的 elasticsearch.log 事件:

Caused by: org.elasticsearch.common.breaker.CircuitBreakingException: [parent] Data too large, data for [<transport_request>] would be [num/numGB], which is larger than the limit of [num/numGB], usages [request=0/0b, fielddata=num/numKB, in_flight_requests=num/numGB, accounting=num/numGB]


要进行调查,请查看你的 heap.percent,方法是查看 _cat/nodes:

GET /_cat/nodes?v=true&h=name,node*,heap*# heap = JVM (logical memory reserved for heap)# ram  = physical memoryname                                node.role heap.current heap.percent heap.maxtiebreaker-0000000002 mv             119.8mb           23    508mbinstance-0000000001   himrst           1.8gb           48    3.9gbinstance-0000000000   himrst           2.8gb           73    3.9gb


或者,如果你先前已启用它,请导航至 Kibana > Stack Monitoring。


如果你确定正被击中内存熔断器,则可以考虑暂时增加堆容量,为自己腾出空间进行调查。在调查根本原因时,请通过群集代理日志或 elasticsearch.log 查找先前的连续事件。你将寻找


昂贵的查询,尤其是:

  • 高桶聚合

    • 当我发现搜索在根据搜索大小或存储桶尺寸运行查询之前临时分配堆的某个端口时,我感到非常傻,因此设置 10,000,000 确实让我的运营团队感到非常沮丧。

  • 非优化映射

    • 感到愚蠢的第二个原因是,当我认为进行分层报告会比扁平化的数据更好(不是)。

  • 请求量/速度:通常是批量或异步查询


是时间该扩容


如果这不是你第一次接触熔断器,或者你怀疑这将是一个持续存在的问题(例如,持续击中85%,那么该是时候考虑扩展资源了),那么你需要仔细研究一下 JVM 内存压力作为你的长期堆指标。你可以在 Elasticsearch Service > Deployment 中进行检查


或者你可以根据 _nodes/stats 信息进行计算:

GET /_nodes/stats?filter_path=nodes.*.jvm.mem.pools.old{"nodes": { "node_id": { "jvm": { "mem": { "pools": { "old": {  "max_in_bytes": 532676608,  "peak_max_in_bytes": 532676608,  "peak_used_in_bytes": 104465408,  "used_in_bytes": 104465408}}}}}}}


这里:

JVM Memory Pressure = used_in_bytes / max_in_bytes


潜在的症状是 elasticsearch.log 中的垃圾收集器(gc)事件发生的频率高且持续时间长

[timestamp_short_interval_from_last][INFO ][o.e.m.j.JvmGcMonitorService] [node_id] [gc][number] overhead, spent [21s] collecting in the last [40s]


如果你确认了这种情况,则需要研究扩展集群或减少达到集群的需求。你需要调查/考虑:

  • 增加堆资源(堆/节点,节点数)

  • 减少分片(删除不必要的/旧的数据,使用 ILM 将数据放入温/冷存储中,以便你可以缩小数据,关闭不需要的数据的副本,以防丢失)


结论


喔!从我在 Elastic Support 中看到的情况来看,这是最常见的用户问题的缩影:未分配的分片 (unassigned shards),不平衡的分片堆,熔断器,大量垃圾收集和分配错误。所有这些都是核心资源分配管理对话的症状。希望你现在也了解理论和解决步骤。


不过,如果你现在仍无法解决问题,请随时与我们联系。我们在这里,乐意为你服务!你可以通过Elastic Discuss,Elastic Community Slack 咨询,培训和支持与我们联系。


为我们将 Elastic Stack 的资源分配作为非运维(也喜欢运维)进行自管的能力感到高兴!


参考:

【1】https://www.elastic.co/blog/managing-and-troubleshooting-elasticsearch-memory


正文完



 作者:Stef Nestor

本文编辑:喝咖啡的猫



嗨,互动起来吧!

喜欢这篇文章么?

欢迎留下你想说的,留言 100% 精选哦!

Elastic 社区公众号长期征稿,如果您有 Elastic  技术的相关文章,也欢迎投稿至本公众号,一起进步! 投稿请添加微信:medcl123



招聘信息

Job board


大数据研发Elasticsearch高级/资深/技术专家—好未来集团技术中台


薪资范围20k-50K(根据面评定)


BASE: 北京 中关村科贸电子城


简历投递邮箱:yangsongbai@tal.com

岗位职责 :

1. 负责好未来elassearch体系建设,中间件建设,on k8s建设,混合云建设

2. 负责好未来存储体系建设

3. 负责全集团es组件建设,提升搜索能力

岗位要求:

1. 本科以上学历,计算机及相关专业;五年以上开发经验,3年以上ES优化经验

2. 编程能力扎实,熟悉Java/golang中的一种,具有良好的数据结构、算法、操作系统等计算机基本知识;

3. 熟悉Lucene的原理和程序结构,能够基于Elasticsearch编写复杂的查询语句,对ES源码有较深入研究,可以进行定制优化

4. 熟悉倒排索引、中文分词排序等相关技术,并能根据需求完善开源的分词器

5. 精通搜索引擎相关知识,如:建模、分词、索引、关联词、权重、评分算法等

6. 拥有单集群过百节点运维经验,并进行过针对性优化, 对集群灾备有深入研究,可以针对不同场景给出合理的灾备方案

7. 针对 ES 容器化有丰富经验


社区招聘栏目是一个新的尝试,帮助社区的小伙伴找到心仪的职位,也帮助企业找到所需的人才,为伯乐和千里马牵线搭桥。有招聘需求的企业和正在求职的社区小伙伴,可以联系微信 medcl123 提交招聘需求和发布个人简历信息。


Elastic中文社区公众号 (elastic-cn)

为您汇集 Elastic 社区的最新动态、精选干货文章、精华讨论、文档资料、翻译与版本发布等。

喜欢本篇内容就请给我们点个[在看]吧




本文分享自微信公众号 - Elastic中文社区(elastic-cn)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部