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

原文:http://www.infoq.com/cn/news/2013/11/netty4-twitter/

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

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

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

  • Finagle是我们的协议无关的RPC系统,用于实现大部分内部服务,如搜索,它的传输层建立在Netty上。
  • TFE(Twitter前端)是我们专有的填鸭式反向代理,它使用Netty为大部分面向公众的HTTP和SPDY流量提供服务。
  • Cloudhopper每月用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

 

 

你可能感兴趣的:(storm,netty,netty,4)