写点什么

在 Twitter,Netty 4 GC 开销降为五分之一

  • 2013-11-12
  • 本文字数:1966 字

    阅读完需:约 6 分钟

Netty 项目在 7 月份发布了 Netty 4 的第一个版本,其性能的显著提升主要来源于垃圾收集开销的降低。在 Twitter,Netty 4 经过完善已经获得了 5 倍的性能提升,但也有一些代价。

Netty 项目创始人和 Twitter 软件工程师 Trustin Lee 从 2003 年开始就一直编写网络应用程序框架。Netty 第一次公开发布是在 2004 年 6 月,其项目主页这样描述它,“一种异步事件驱动的网络应用程序框架,用于可维护的高性能协议服务器和客户端的快速开发。”

Lee 在博文“ Netty 4 在 Twitter:降低 GC 开销”中写道,Twitter 在许多地方使用 Netty 实现联网功能:

Netty 包含一个反应堆模式的实现,它同时也是 Play 框架的核心。Play、Grails 和许多其它 Web 框架都采用一种 WAR-less Web 应用程序模式,它允许与底层 HTTP 服务器更紧密地集成。使用内部包含像 Netty 这种框架的服务器,异步编程会简单很多。异步编程和非阻塞 I/O 是“响应宣言( The Reactive Manifesto )”的核心。InfoQ 在“新兴趋势:响应式编程”中报道了这一新兴模式。

Netty 3 使用 Java 对象表示 I/O 事件。Lee 谈道:

这样简单,但会产生大量的垃圾,尤其是在我们这样的规模下。Netty 4 在新版本中对此做出了更改,取代生存周期短的事件对象,而以定义在生存周期长的通道对象上的方法处理 I/O 事件。它还有一个使用池的专用缓冲区分配器。

……每当收到新信息或者用户发送信息到远程端,Netty 3 均会创建一个新的堆缓冲区。这意味着,对应每一个新的缓冲区,都会有一个‘new byte[capacity]’。这些缓冲区会导致 GC 压力,并消耗内存带宽:为了安全起见,新的字节数组分配时会用零填充,这会消耗内存带宽。然而,用零填充的数组很可能会再次用实际的数据填充,这又会消耗同样的内存带宽。如果 Java 虚拟机(JVM)提供了创建新字节数组而又无需用零填充的方式,那么我们本来就可以将内存带宽消耗减少 50%,但是目前没有那样一种方式。

在 Netty 4 中,代码定义了粒度更细的 API,用来处理不同的事件类型,而不是创建事件对象。它还实现了一个新缓冲池,那是一个纯 Java 版本的 jemalloc (Facebook 也在用)。现在,Netty 不会再因为用零填充缓冲区而浪费内存带宽了。不过,由于它不依赖于 GC,开发人员需要小心内存泄漏。如果忘记在处理程序中释放缓冲区,那么内存使用率会无限地增长。

这些变化没有向后兼容 Netty 3,但其垃圾生成速度是原来的 1/5,而垃圾清理速度快了 5 倍。

Lee 写道:

我们比较了两个分别建立在 Netty 3 和 4 基础上 echo 协议服务器。(Echo 非常简单,这样,任何垃圾的产生都是 Netty 的原因,而不是协议的原因)。我使它们服务于相同的分布式 echo 协议客户端,来自这些客户端的 16384 个并发连接重复发送 256 字节的随机负载,几乎使千兆以太网饱和。

根据测试结果,Netty 4:

  • GC 中断频率是原来的 1/5:45.5 vs. 9.2 次 / 分钟
  • 垃圾生成速度是原来的 1/5:207.11 vs 41.81 MiB/ 秒

Lee 提到,在 Twitter 中采用 Netty 4 还有一些障碍,那就是缓冲区泄漏和核心复杂。该项目希望增加更多功能,包括 HTTP/2、异步 DNS 解析以及客户端 HTTP 和 SOCKS 代理支持。

Yahoo 工程部门有一篇类似的文章,内容是关于 Netty 如何帮助他们成倍地提升 Storm 集群的速度。在名为“ Netty 让 Storm 飞速运行”的文章中,Bobby Evans 写道:

在雅虎,我们都是用自己的产品进行开发。在将 Netty 作为 Storm 集群的默认消息层之前,我需要一些数据来确认,它与当前的默认消息层 zeromq 相比怎么样。要做到这一点,我需要一个能够使 Storm 消息层达到极限的基准测试程序,因此,我写了一个。那是一个简单的高速测试,用于确认 Storm 在不同的 Bolt 和 Spout 之间推送消息有多快。它允许同时启动多个具有不同复杂度的 Topology 来发送定长消息。

Evans 指出,在小规模测试中(没有资源冲突),Netty 比 zeromq 更快(40-100%)。在大规模测试中,它也遇到了性能问题,但减少了解决问题的线程数。

对于大量短消息而言,Netty 的默认设置并不是很好,即使该节点上只有它自己在运行。但是,当把它限制在单线程上,我们每秒能够获得比 zeromq 多 85% 到 111% 的消息,之后网络再次饱和。

Evans 指出,Netty 现在是 Yahoo Storm 集群的默认消息层。

Netty 4 的改进对许多开源项目都大有益处。该框架有一个长长的相关项目列表,包括 Akka Apache James HornetQ Vert.x ,这里仅举这几例。要了解更多关于 Netty 4 的信息,请查看 netty.io Lee 的博文

查看英文原文: Netty 4 Reduces GC Overhead by 5x at Twitter

2013-11-12 07:408392
用户头像

发布了 256 篇内容, 共 96.5 次阅读, 收获喜欢 12 次。

关注

评论

发布
暂无评论
发现更多内容

Jsoup解析html

Java 程序员 后端

MyBatis 框架系列之基础初识

Java 程序员 后端

JetBrains 又出了一款新神器,一套代码适应多端!

Java 程序员 后端

keepalived实现双机热备

Java 程序员 后端

Kubernetes 常用命令大全

Java 程序员 后端

Mybatis一二级缓存实现原理与使用指南

Java 程序员 后端

JSP“三大请求传参方式”及“中文乱码问题解决方案”详解

Java 程序员 后端

k8s常见问题大收集

Java 程序员 后端

Linux入门(二) ~ Linux的常用命令

Java 程序员 后端

markdown+七牛云,让写文更容易

Java 程序员 后端

Memcached缓存

Java 程序员 后端

Kurento实战之一:KMS部署和体验

Java 程序员 后端

JVM之调优及常见场景分析

Java 程序员 后端

JVM及GC机制

Java 程序员 后端

Kurento实战之四:应用开发指南

Java 程序员 后端

Linux极速上手,超全面总结

Java 程序员 后端

MongoDB :第六章:Java程序操作MongoDB

Java 程序员 后端

Jenkins部署springboot项目

Java 程序员 后端

K8S环境的Jenkin性能问题处理续篇(任务Pod设置)

Java 程序员 后端

keepalived实现双机热备(1)

Java 程序员 后端

MyBatis事务管理

Java 程序员 后端

Kubernetes任务调用Job与CronJob及源码分析

Java 程序员 后端

Layui图片上传组件使用指南

Java 程序员 后端

Linux下jdk的安装卸载切换

Java 程序员 后端

Linux系统:第四章:Linux文件系统

Java 程序员 后端

MyBatis初级实战之二:增删改查

Java 程序员 后端

Linux常用命令(面试题)

Java 程序员 后端

Linux系统:第六章:Linux服务

Java 程序员 后端

Log4j2的Appenders配置详解

Java 程序员 后端

MyBatis 源码分析 - MyBatis入门

Java 程序员 后端

MyBatis初级实战之二:增删改查(1)

Java 程序员 后端

在Twitter,Netty 4 GC开销降为五分之一_Java_Matt Raible_InfoQ精选文章