感谢您的阅读!如果您想了解我在Kafka,Scala,ZIO和JVM方面的最新信息,请在Twitter和Medium中关注我。 如果有任何不清楚的地方,或者您想指出点什么,请在下方留言。

> Photo by Franck V. on Unsplash

最近,我设法大大减少了Kubernetes上一个广泛使用的JVM应用程序容器的内存使用量,并节省了很多钱。 我弄清楚了哪些JVM标志更重要,如何正确设置它们以及如何轻松衡量我的操作对应用程序内存使用的各个部分的影响。 这是我的悬崖笔记。

故事从一个用例开始。 我作为数据流团队的一员在Wix工作,负责我们所有的Kafka基础架构。 最近,我负责为Node.js服务创建Kafka客户端代理。

用例:Kafka客户端sidecar浪费内存

这个想法是将所有与Kafka相关的动作(例如生产和消费)从Node.js应用委托给单独的JVM应用。 其背后的动机是,我们许多针对Kafka客户的基础架构都是用Scala编写的(称为greyhound-可以在此处找到开放源代码版本)。有了Sidecar,Scala代码不需要在其他代码中重复语言。 只需要一个薄的包装。

一旦将Sidecar部署到生产中,我们注意到它会消耗大量内存。

> Metric used — container_memory_working_set_bytes

从上表中可以看到,仅用于sidecar(运行openjdk 8)的内存占用量是过去包含kafka库的node-app容器的4-5倍。

我必须了解为什么以及如何大幅减少它。

试验生产数据

我着手创建一个模拟该特定节点应用程序的sidecar的测试应用程序,以便能够在不影响生产的情况下自由地对其进行实验。 该应用程序包含生产应用程序中所有生产相同主题的消费者。

作为监视内存消耗的一种方式,我使用了从我的应用程序内部的mxbeans暴露给Prometheus / Grafana的指标,例如heapMemoryUsed和nonHeapMemoryUsed,但是您也可以使用jconsole或jvisualvm(均与JDK 8或更高版本捆绑在一起)

首先,我试图了解每个消费者和生产者以及gRPC客户端(称为节点应用程序)的影响,得出的结论是,拥有一个(或更少)一个消费者并不会影响有意义的内存占用。 道路。

JVM堆标志

然后,我将注意力转向堆分配,有两个重要的JVM标志与堆分配有关-Xms(启动时堆内存大小)和-Xmx(最大堆内存大小)

我尝试了两者的许多不同组合,并记录了由此产生的容器内存使用情况:

> Container overall used memory with different heap flags

通过分析有关堆标志变化的数据得出的第一个结论是,如果Xmx高于Xms,并且您的应用程序具有很高的内存压力,那么分配给堆的内存几乎肯定会继续增长 到Xmx限制,导致容器的整体内存使用量也增加(请参见下表中的比较)。

> Xmx >> Xms

但是,如果Xmx与Xms相同,则可以对整体内存使用量进行更多控制,因为堆不会随时间逐渐增加(请参见下面的比较)。

> Xmx = Xms

我从堆标志数据得出的第二个结论是,只要您没有看到由于垃圾回收(GC)导致JVM暂停的时间很长,就可以显着降低Xmx —长时间超过500ms 。 我再次使用Grafana监视GC,但是您也可以使用visualgc或gceasy.io

> benign JVM pause times due to GC

请注意为Xmx设置的数字-如果您的应用程序在消息消耗吞吐量方面有很大差异,一旦您的应用程序遇到大量传入消息,您的应用程序将更容易受到GC风暴的影响。

Kafka相关的调整

我们的灵狮(Kafka)使用者有一个内部消息缓冲区,该缓冲区可以获取多达200条消息。 当我将最大允许大小减小到20时,我注意到堆内存使用率的波动范围比size = 200窄得多(总体上使用率也很低):

> Heap memory usage pattern when bufferMax=200

> Heap memory usage pattern when bufferMax=20

当然,减小缓冲区大小意味着该应用程序将无法很好地处理突发事件-因此这不适用于高吞吐量应用程序。 为了减轻这种情况,我将每个Pod的灰狗消费者处理程序的并行度提高了一倍。 也就是说,我将处理Kafka消息的线程数从3个增加到6个。在异常情况下,该应用将需要更多的Pod,或者必须更改最大缓冲区配置。

将Kafka Consumer fetch.max.bytes从50M减少到5M(以减少轮询的消息总大小)对内存占用没有明显的影响。 也没有从sidecar应用程序中提取出灵缇生产者(它可以驻留在DaemonSet中,因此它将在每个K8s节点上运行)。

摘要—有助于减少内存使用的因素

我进行的优化将容器内存使用量从1000M减少到了550-600M。 以下是有助于减少占用空间的更改:

· 保持一致的堆大小分配-Xms等于-Xmx

· 减少废弃物品(垃圾)的数量 缓冲较少的Kafka消息

· 只要GC(新一代+老一代)所用的百分比不高(CPU时间为0.25%),GC就可以继续降低XMX

没有帮助的(基本上)

· 减少KafkaConsumer的fetch.max.bytes

· 删除Kafka生产者

· 从gRPC客户端切换到Wix的自定义json-RPC客户端

未来的工作

· 探索GraalVM本机映像是否可以提供帮助

· 比较不同的GC实现。 (我使用过CMS,但有G1)

· 通过切换到基于开源ZIO的灵狮,减少从Kafka消费时使用的线程数。

· 减少为每个线程分配的内存(默认情况下,为每个线程分配1MB)

肯定会有更多的改进(以及第二篇博客文章)。

更多信息

Docker内存资源限制和一堆Java —博客文章

GeekOUT会议上的Java流程视频的内存占用量

(本文翻译自Natan Silnitsky的文章《How to reduce your JVM app memory footprint in Docker and Kubernetes》,参考:https://medium.com/wix-engineering/how-to-reduce-your-jvm-app-memory-footprint-in-docker-and-kubernetes-d6e030d21298)

unix 获取程序占用内存_如何减少Docker和Kubernetes中的JVM应用程序内存占用相关推荐

  1. big sur 虚拟机 网络_推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题...

    欢迎关注公众号[Ccww技术博客],原创技术文章第一时间推出 一. JVM内存区域的划分 1.1  java虚拟机运行时数据区 java虚拟机运行时数据区分布图: JVM栈(Java Virtual ...

  2. python应用程序开发者_用 NVIDIA ISAAC-SDK 在 Python 中开发机器人应用程序

    图 1 .使用 Jupyter 笔记本和 ISAAC SDK Python API 在 ISAAC Sim 中控制虚拟机器人. NVIDIA ISAAC 软件开发工具包 的模块化和易于使用的感知堆栈继 ...

  3. r语言中的shiny教程_如何使用Shiny在R中编写Web应用程序

    r语言中的shiny教程 新年快乐! 这个月我忙于撰写一些较大的文章,因此请在接下来的几周内查找这些文章. 对于本月的Nooks和Crannies,我想简要指出一个我一直在用它进行自我教育的出色R库. ...

  4. 踩内存是什么意思啊_Win10任务管理器中的quot;共享GPU内存quot;是什么意思?

    WIN10任务管理器中的"共享GPU内存"首次在WINDOWS任务管理器中集成. 红框内中专用GPU内存自然不用说,那是显卡带的内存也就是显存容量.因为我这台机的是GTX1060 ...

  5. docker 容器占用内存_如何限制Docker容器的内存

    容器何时销毁 现在很多服务采用容器化运行,一个容器中运行一个服务,因为容器的创建和启动都是在秒级,所以这种容器化的部署方式被称之为轻量化部署. 1. 容器中服务进程终止 容器的创建和运行是因某个服务进 ...

  6. antimalware service executable占用内存_解决 vue 项目运行过程中内存泄漏问题

    vue-cli3.0 内存溢出 JavaScript heap out of memory vue-cli3.0构建的项目,开发过程中,可能会遇到内存溢出的情况,改动一点代码,代码编译,进程就会断掉, ...

  7. 程序员 薪水_如何减少程序员的薪水

    程序员 薪水 要创建软件,您需要程序员. 不幸. 它们昂贵,懒惰,几乎无法控制. 他们创建的软件行不通,但您仍然必须每个月付费. 当然,少付总是最好的. 但是,有时他们可能会发现自己的薪水不足而辞职. ...

  8. 小程序 数据库 时间_使用云开发数据库构建更生动的小程序

    导语 长连接服务被广泛应用在消息提醒.即时通讯.推送.直播弹幕.游戏等场景.本篇文章将介绍云开发数据库的长连接服务--实时数据推送,使用它来构建更生动的小程序.什么是实时数据推送? 通过云开发数据库的 ...

  9. rfid 标签内存_智能仓库之RFID仓库管理中的条形码与电子标签应用-RFID仓库管理功能与特点-新导智能...

    智能仓库是近几年兴起的一个概念,仓库的货物繁杂,进出频繁,是很考验管理水平的随着新技术的不断发展 特别是近几年RFID技术的发展, 使仓库的管理更加自动化 人性化,苏州新导RFID仓库管理主要利用RF ...

最新文章

  1. 函数(复习),闭包,DOM
  2. OpencvSharp的踩坑之路
  3. 关于 epoch、 iteration和batchsize的区别
  4. 不同格式的json解析
  5. 【英语学习】【医学】Unit 08 The Cardiovascular System
  6. Perl语言必看书籍推荐
  7. JS广告代码效果大全
  8. 黑群晖折腾之此ip已被封锁
  9. 数据处理之衡量数据远近的多种距离公式
  10. 2022年荧光染料市场前景分析及研究报告
  11. 51单片机实验——模拟三台机器故障检测与指示系统
  12. java实现退出重启后保存_JAVA实现关机、重启等
  13. 数据集FFHQ和LSUN介绍
  14. 如何播放html文件类型,m3u8格式如何播放
  15. fgetc和方fread读不到文件末尾出现ffffff或0时解决方法
  16. 用 Python 实现股票指数移动平均线
  17. day36 rx全家桶
  18. color属性 python_Python curses.COLOR_BLUE属性代码示例
  19. 2022-5-15 Leetcode93.复原IP地址
  20. 联系苹果开发者客服的一些情况须知 App Store发布更新延迟原因

热门文章

  1. 基于JAVA+SpringBoot+Mybatis+MYSQL的送水公司后台管理系统
  2. 基于JAVA+SpringBoot+Mybatis+MYSQL的物流仓库后台管理系统
  3. 基于JAVA+SpringMVC+Mybatis+MYSQL的手表销售系统
  4. Echarts数据grid直角坐标系(xAxis、yAxis)详解
  5. Docker与虚拟机技术
  6. 结对编程1--模块化
  7. Pairs Forming LCM(素因子分解)
  8. 请阐述调用Activity有哪几种方法,并写出相关的Java代码
  9. lua java效率_luaJavaBridge详解
  10. 深入理解C语言系列之函数传参的那些事儿(函数参数、指针、地址、数组)