Elasticsearch 7.0 新一代实际内存熔断器

本文翻译自https://www.elastic.co/blog/improving-node-resiliency-with-the-real-memory-circuit-breaker,侵删

Elasticsearch在演进过程中,考虑了集群及节点维度的稳定性。例如,向节点发送了太多请求或者请求体太大,那么这些请求会被拒绝。这个拒绝的过程是靠Elastics的各种熔断器实现的。熔断器被放置在读写请求处理的关键路径中,如当网络请求进入节点,或执行聚合之前。熔断器的核心思想,是通过估算请求使用的内存是否会超过熔断器的限制而避免OOM。Elasticsearch设置有各种类型的熔断器,如in-flight request熔断器、field ddata熔断器等。在这些子熔断器之上,Elasticsearch还有一个父熔断器,提供所有子熔断器的全局视图。某些场景下,请求没有超过任何子熔断器的限制,但是预估的jvm使用量总和会超过父熔断器,此时父就会生效。

跟踪每个对象的分配申请是不切实际的,所以熔断器只能跟踪那些经常会出问题的内存使用。在某些情况下,可能无法精切的预估内存的使用情况。这意味着熔断器只是一种尽力而为的机制,由于为跟踪的内存申请相对的占比较大,因此节点设置的堆越小,越容易因未追踪的内存申请造成OOM

创建一个更好的熔断器

如果我们想在熔断器中准确的知道节点正在使用多少内存,应该怎么办?如果解决了这个问题,我们就可以根据系统在当前时刻的实际状态拒绝请求而不是基于熔断器对部分跟踪的内存分配值来预估。我们在Elastics7.0版本中,开发了新的实际内存熔断器完成这项工作。实际内存熔断器是老版本父熔断器的替代实现,它使用JVM中的接口来获取当前内存的使用量,而不是仅考虑当前所有子熔断器所跟踪的内存。虽然这比之前增加JVM的接口调用,但是这个操作的耗时仍然是非常低的:在微基准测试中,我们观察到400ns~900ns的额外开销。

我们进行了各种实验来测试实际内存使用熔断器在不同条件下的有效性。在一个场景中,我们针对仅有256MB的JVM的节点运行了全文索引的基准测试。早期版本的Elasticsearch无法维持次工作负载且熔断器未生效,几乎立即OOM。但实际内存熔断器会拒绝请求,保证Elasticsearch的正常使用。这里需要注意,熔断器起作用的时候,Elasticsearch将返回错误响应,业务需要保证客户端有适当的退避和重试机制。当然,只要您已经使用我们提供的官方SDK,如.NET,Ruby,Python和Java客户端都已经实现了这些重试策略,并提供了扩展来处理批量索引。

在另一个实验中,我们执行了一个聚合,该聚合在一个有16GBJVM的节点上故意产生了大量无用的桶。同样,早起版本的Elasticsearch会因为内存不足,导致聚合执行了将近半小时直到错误的发生。而在7.0版本的集群上,节点提供了响应,这取决于我们是否允许在稍微超过一分钟或大约二十分钟之后的部分结果。通过多次实验,我们将新的父熔断器的默认值设置为JVM的95%。这意味着Elasticsearch将允许使用高达95%的JVM,直到实际内存熔断器熔断为止。

让我们看一个实际的例子,在这个例子中批量发送的请求所使用的内存足够小,可以通过所有的子熔断器,但是会使实际内存熔断器熔断。测试节点配置128MB的JVM运行,父熔断器设置为95%,即JVM使用达到117.5MB会触发熔断。如果此时继续发送请求,则节点将返回code 429,如下:

{
  'error': {
    'type': 'circuit_breaking_exception',
    'reason': '[parent] Data too large, data for [<http_request>] would be [123848638/118.1mb], which is larger than the limit of [123273216/117.5mb], real usage: [120182112/114.6mb], new bytes reserved: [3666526/3.4mb]',
    'bytes_wanted': 123848638,
    'bytes_limit': 123273216,
    'durability': 'TRANSIENT'
  },
  'status': 429
}

上面的错误提示表明熔断器熔断是一个瞬态的故障,客户端可以在一段时间后重试。然而,在某些情况下,如果熔断器设置的预留内存太小,熔断可能是一个长时间的故障。

结语

虽然在某些情况下,依然会存在Elasticsearch节点内存不足的情况,但是新的实际内存熔断器使用基于实际测量的JVM使用量来执行熔断而不是像早期版本的只考虑跟踪的内存,从而极大地提高了集群的稳定性。在我们的实验中,Elasticsearch现在可以维持相对于早期版本中远远无法实现的负载和更大的峰值。要试用新的实际内存熔断器,请下载最新的7.0版本,并欢迎提出反馈。

本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
Elasticsearch 7.0 新一代实际内存熔断器
Elasticsearch在演进过程中,考虑了集群及节点维度的稳定性。例如,向节点发送了太多请求或者请求体太大,那么这些请求会被拒绝。这个拒绝的过程是靠Elas...
<<上一篇
下一篇>>