最近,Apache社区中一位受人尊敬的成员尝试了Log4j 2并在Twitter上写道:

@TheASF #log4j2摇摇欲坠 ! 性能接近疯狂^^ http://t.co/04K6F4Xkaa

— Mark Struberg(@struberg) 2013年5月7日

(来自Mark Struberg的名言:@TheASF#log4j2摇摇欲坠!性能接近疯狂^^ http://logging.apache.org/log4j/2.x/)

在Remko Popma贡献了一些东西(现在称为“ AsyncLoggers”)之后不久便发生了。 某些人可能知道Log4j 2已经具有AsyncAppenders。 它们相似,就像您在Log4j 1和其他日志记录框架中可以找到的一样。

老实说:我对新功能并不感到兴奋,直到我阅读了有关其性能的推文并对此感到好奇。 显然,Java日志记录有许多目标。 其中: 日志记录必须和地狱一样快 。 没有人希望他的日志记录框架成为瓶颈。 当然,登录时总会有成本。 CPU必须执行一些操作。 即使您决定不编写日志语句,也正在发生某些事情。 预计日志是不可见的。

到目前为止,众所周知的日志记录框架在速度上是相似的。 基准毕竟是不可靠的。 我们已经在Apache Logging上建立了一些基准。 有时,一个日志记录框架会获胜,有时则是另一个。 但总而言之,您可以说他们都很好
您可以选择自己喜欢的任何方式。 直到获得Remko的贡献,Log4j 2变得“异常快速”。

运行一个线程的小型软件项目可能不太在乎性能。 在运行SaaS时,您根本不知道您的应用何时会吸引到您需要扩展的吸引力。 然后,您突然需要一些额外的电源。

使用Log4j 2,运行64个线程可能为您带来的日志吞吐量是同类框架的十二倍。

我们说每秒超过18,000,000条消息,而其他消息在同一环境中的发送量大约为1,500,000条或更少

我看到了图表,但简直不敢相信。 一定有问题。 我重新检查了。 我自己进行了测试。 就像这样: Log4j 2的速度非常快。

异步性能,最后阅读时间:2013年7月19日

截至目前,我们拥有一个日志记录框架,该框架的性能比那里的其他所有日志记录框架都要好。 到目前为止,如果速度很重要,那么当我们不想使用Log4j 2时,我们需要证明我们的决定是正确的。 Log4j 2之外的所有其他内容都可能成为瓶颈和风险。 有了如此快速的日志记录框架,您甚至可以考虑比以前更多地记录生产中的日志。

最终,我给雷姆科写了一封电子邮件,问他旧的AsyncAppenders和新的异步记录器之间到底有什么区别

旧的AsynAppenders和新的AsyncLoggers之间的区别

他告诉我:“异步记录器在做两件事上与AsyncAppender有所不同,”他们试图在将日志消息传递到另一个线程之前做最少的工作,并且他们使用不同的机制在生产者和生产者之间传递信息。消费者线程。 AsyncAppender使用ArrayBlockingQueue将消息传递给写入磁盘的线程, 异步记录器使用LMAX Disruptor库 。 特别是Disruptor的性能差异很大。”

换句话说,AsyncAppender使用先进先出队列来处理消息。 但是异步记录器使用了新的东西-Disruptor。 老实说,我从未听说过。 而且,我从未想过要扩展我的日志记录框架。 当有人说“扩展系统”时,我想到了数据库,应用服务器等等,但通常不会记录日志。 在生产中,记录已关闭。 故事结局。

但是,雷姆科(Remko)考虑进行日志记录时进行扩展。

“查看异步记录器的性能测试结果,您会注意到的第一件事是,某些记录方式的伸缩性要好于其他方式。 通过更好地扩展,我的意思是当添加更多线程时,您将获得更多的吞吐量。 如果您添加的每个线程的吞吐量都增加了一个恒定值,那么您将具有线性可伸缩性。 这是非常可取的,但可能很难实现。”他写道。

“将同步与异步进行比较,您将期望任何异步机制的扩展都比同步日志记录好得多,因为您不再在生产线程中执行I / O,而且我们都知道'I / O很慢'(而且我会再说一遍)”。

是的,完全是我的理解。 我认为将某些内容发送到队列就足够了,而其他的则可以将其接收并编写消息。 该应用程序将继续运行。 雷姆科写道,这正是旧的AsyncAppender所做的:

“使用AsyncAppender,您的所有应用程序线程所需要做的就是创建一个LogEvent对象,并将其放在ArrayBlockingQueue上; 然后,使用线程将这些事件从队列中移出并完成所有耗时的工作。 即,将事件转换为字节并将这些字节写入I / O设备的工作。 由于应用程序线程不需要执行I / O,因此您希望它可以更好地扩展,这意味着添加线程将允许您记录更多事件。

如果您相信像我一样,请坐下并深呼吸。 我们错了。

他写道:“事实可能并非如此。”

“如果查看所有日志记录框架的AsyncAppenders的性能数字,就会发现,每增加一倍的线程数,每个线程的吞吐量就会减少一半。”

“因此,您的总吞吐量或多或少保持不变! 他告诉我,AsyncAppenders比同步日志记录要快,但是它们在某种意义上是相似的,即当您添加更多线程时,它们都不为您提供更多的总吞吐量。

它像锤子一样打在我身上。 基本上,而不是通过添加更多线程来提高日志记录速度,基本上是:没有。 毕竟,直到现在Appender都没有扩展。 我问雷姆科为什么会这样。

事实证明,队列并不是在线程之间传递信息的最佳数据结构。 作为标准Java库的一部分的并发队列使用锁来确保值不会被破坏并确保线程之间的数据可见性。

LMAX破坏者?

“ LMAX团队对此进行了大量研究,发现这些队列有很多锁争用。 他们发现一个有趣的事情是队列始终是满的或空的:如果生产者速度更快,则在大多数情况下您的队列将是满的(这本身可能就是一个问题)。 如果您的使用者速度足够快,则您的队列在大多数情况下将是空的。 无论哪种方式,您都将在队列的开头或结尾都有争用,生产者线程和使用者线程都想在其中更新同一字段。 为了解决这个问题,LMAX团队提出了Disruptor库,该库是用于在线程之间传递消息的无锁数据结构。 这是Disruptor和ArrayBlockingQueue之间的性能比较 : 性能比较 。”

哇。 经过这些年的Java编程,我实际上再次感觉像是初级程序员。 我错过了LMAX破坏者,甚至从未考虑使用Queue带来的性能问题。 我想知道到目前为止还没有发现什么其他性能问题。 我意识到,我不得不重新学习Java。

我问雷姆科,他怎么能找到像LMAX破坏者这样的图书馆。 我的意思是,没有人编写软件,创建队列类的实例,怀疑其性能并最终在互联网上搜索“更好的东西”。

还是真的有这种人?

“我如何发现Disruptor? 简短的答案是,这全都是错误。”他开始说道。

“好吧,也许这有点太短了,所以答案更长一些:我的一位同事写了一个小的记录器,本质上在队列中添加了带时间戳的日志消息,并带有后台线程,这些线程使这些字符串脱离了队列。并将它们写入磁盘。 他之所以这样做,是因为他需要比log4j-1.x更好的性能。 我做了一些测试,发现它更快,我不记得确切多少。 我很惊讶,因为我已经使用log4j多年了,并且从未想到过它会轻易胜过。 在那之前,我一直以为著名的库会很快,因为……说实话,我只是以为。 因此,这让我大开眼界。 但是,自定义记录器在功能上有些勉强,所以我开始四处寻找替代方案。”

“在我开始谈论Disruptor之前,我必须坦白一些东西。 最近,我回过头来查看自定义记录器比log4j-1.x快多少,但是当我测量时,它实际上要慢一些! 原来,我一直在将自定义记录器与log4j-2.0的旧beta(我认为beta3或beta4)进行比较。 这些Beta版中的AsyncAppender仍然存在性能问题(如果您好奇,则为LOG4J2-153)。 如果我将自定义记录器与log4j-1.x中的AsyncAppender进行了比较,我会发现log4j-1.x更快,并且我不会再考虑了。 但是由于犯了这个错误,我开始寻找功能更丰富的其他高性能日志记录库。 我没有找到这样的日志库,但是遇到了很多其他有趣的东西,包括Disruptor。 最终,我决定尝试将具有良好代码基础的Log4j-2与Disruptor结合使用。 结果最终被Log4j-2本身接受,其余的,正如他们所说的,已成为历史。”

“我在这里提到的一件事是彼得·劳瑞(Peter Lawrey)的编年史图书馆 。 Chronicle使用内存映射文件以极低的延迟每秒将数千万条消息写入磁盘。 还记得上面我说过的“我们都知道I / O速度很慢”吗? 纪事表明,同步I / O可以非常非常快。 ”。

“通过彼得的工作,我遇到了破坏者。 关于Disruptor的资料很多。 只是给您一些提示:

  • 马丁·福勒(Martin Fowler):LMAX
  • 特里莎(Trisha Lee)在引擎盖下的LMAX上使用 (现在略过时,但我知道的最详细的资料)
  • …像这样的视频演示

强烈建议使用Disruptor Google组。

推荐的有关Java性能的阅读材料通常是:

  • 马丁·汤普森(Martin Thompson)的“机械同情”
  • 马丁·汤普森演讲。

Martin Thompson就Java高性能计算的各个方面做了很多文章和演示。 他出色地完成了引擎盖下正在进行的复杂操作。”

阅读此电子邮件后,我的书签文件夹已满,并且我非常感谢您有很多起点来提高我对Java性能的了解。

我应该默认使用AsyncLoggers吗?

我确定我想使用新的异步记录器。 这听起来真是太棒了。 但另一方面,我有点害怕,甚至有点偏执,无法包括新的依赖项或新技术,例如新的Log4j 2 Async Loggers。 我问雷姆科,他是否默认使用新功能,还是仅在少数有限的用例中启用它们。

我默认使用异步记录器 ,是的。”他写道。 “一个用例的时候,你会_not_要使用异步日志记录是当您使用日志记录审计目的。 在这种情况下,记录错误是您的应用程序需要了解和处理的问题。 我相信大多数应用程序都是不同的,因为它们不太在乎记录错误。 大多数应用程序都不想在发生日志记录异常时停止,实际上,他们甚至都不希望知道它。 默认情况下,Log4j-2.0中的追加器将抑制异常,因此应用程序无需尝试/捕获每个日志语句。 如果这是您的用法,那么使用异步记录器将不会造成任何损失,因此您只能获得收益,即性能得到改善。”

“我应该提到的一个不错的小细节是,异步记录器和异步附加器都修复了一些在Log4j-1.x中一直困扰我的东西,即它们将在记录队列中的最后一个事件后刷新缓冲区 。 对于Log4j-1.x,如果使用缓冲的I / O,则通常看不到最后几个日志事件,因为它们仍卡在内存缓冲区中。 唯一的选择是将InstantFlush设置为true,这将在每个单个日志事件上强制使用磁盘I / O,并会影响性能。 使用Log4j-2.0中的Async Loggers和Appenders,您的日志语句都被刷新到磁盘上,因此它们始终可见,但这是以非常有效的方式发生的。”

登录使用Log4js AsyncLoggers冒险吗?

但是考虑到Log4j-1存在严重的线程问题,并且现代世界一直在使用云计算和集群来扩展其应用程序, 异步日志记录不是某种额外的风险吗? 还是安全? 我知道我的问题听起来像是决策者而不是开发人员的问题。 但是整个LMAX对我来说还是那么新,并且由于我保留了旧的而且非常丑陋的Log4j 1代码,所以我只需要问一下。

雷姆科:“那里有很多问题。 首先,从并发角度看,Log4j-2是否比Log4j-1.x安全? 我相信是这样。 Log4j-2团队付出了巨大的努力来支持多线程应用程序,并且异步记录器只是该项目的一个非常新的且相对较小的功能。 与Log4j-1.x相比,Log4j-2使用的粒度锁定更多,并且在结构上更简单,这将导致更少的问题,并且出现的任何问题都将更易于解决。”

“另一方面,Log4j-2仍处于测试阶段,并且仍在积极开发中,尽管最近我认为大多数精力都花在了修复问题和捆绑松散的末端上,而不是添加新功能。 我相信它足够稳定以供生产使用。 如果出于性能或其他原因考虑使用Log4j-2,我建议您进行尽职调查和测试,就像在项目中采用任何其他第三方库之前一样。”

(旁注:可以很快找到Log4j2的稳定版本,很可能是2013年秋天)。

对我来说听起来不错。 是的,尽管我个人没有在Log4j 2存储库中编写代码,但从我对项目的观察中我可以完全同意这一点。

“我看到的另一个问题是: 异步日志记录比同步日志记录有风险吗? 我不这么认为,实际上,如果您的应用程序是多线程的,则情况可能恰恰相反:一旦将日志事件移交给执行I / O的使用者线程,则只有一个线程在处理布局,附加程序以及所有其他与日志记录相关的组件。 因此,在移交之后,您将成为单线程的,并且您无需再担心任何线程问题,例如死锁和活动性等。”

“您可以更进一步,使您的业务逻辑完全单线程化,并使用干扰器进行所有I / O或与外部系统的通信。 没有锁争用的单线程业务逻辑可以非常快。 LMAX的结果(600万笔事务/秒,延迟少于10毫秒)是不言而喻的。”

阅读雷姆科的信息,我学到了三件事。

  • 首先,我必须学习有关Java性能的更多信息。
  • 其次,我绝对想让我的应用程序使用Log4j2。首先,我将在经常使用的Struts 2应用程序中启用它。
  • 第三,使用LMAX Disruptor的Web应用程序框架可能会让我们震惊。

我要非常感谢您和一个拥抱Remko Popma,感谢他们回答我的问题并与我一起撰写此博客文章。 所有错误都是我自己的。

雷姆波波玛

二十年前,雷姆科(Remko)来到日本,以提高围棋比赛的水平。 不知何故他再也没有回来。 Remko开始为日本软件公司进行软件开发,短暂地担任自由开发人员,与日本合作伙伴一起经营了一家软件公司,现在正领导瑞穗证券IT的算法交易开发。 他与妻子Tomoe和儿子Tobias一起住在东京。

参考: Log4j 2: PHP和Java Entwickler博客上的JCG合作伙伴 Christian Grobmeier的性能接近疯狂 。

翻译自: https://www.javacodegeeks.com/2013/07/log4j-2-performance-close-to-insane.html

Log4j 2:性能接近疯狂相关推荐

  1. log4j性能 slf4j_Log4j 2:性能接近疯狂

    log4j性能 slf4j 最近,Apache社区中一位受人尊敬的成员尝试了Log4j 2并在Twitter上写道: @TheASF #log4j2摇摇欲坠 ! 性能接近疯狂^^ http://t.c ...

  2. mx250 计算能力_mx250相当于gtx多少 性能接近

    谈论到gtx,大多数人都知道,有人问mx250显卡满血版什么意思,当然了,还有朋友想问amd r540x和mx250,这到底怎么回事呢?实际上独显和mx250哪个好呢,下面是小编为大家整理的mx250 ...

  3. 他22岁在家自造芯片,性能接近英特尔初代,连光刻机都有解决方案

    金磊 发自 凹非寺 量子位 | 公众号 QbitAI 万万没想到,造芯这件事,竟然还能如此"亲民": 在22岁的年纪,一个人竟能凭一己之力,在自家车库里打造一块芯片! △ 图源:W ...

  4. logback log4j log4j2 性能实测

    日志已经成为系统开发中不可或缺的一部分. 但是针对logback, log4j和log4j2. 究竟改如何选择? 到底性能如何? 今天我们做一个实际的测评. 相信看完这篇文章, 对这三个日志框架会有很 ...

  5. java集合性能_Java集合性能分析-疯狂Java讲义

    一.各Set实现类的性能分析 HashSet和TreeSet是Set的两个典型实现.HashSet的性能总是比TreeSet好(特别是最常用的添加.查询元素等操作),因为TreeSet需要额外的红黑树 ...

  6. Java集合性能分析-疯狂Java讲义

    一.各Set实现类的性能分析 HashSet和TreeSet是Set的两个典型实现.HashSet的性能总是比TreeSet好(特别是最常用的添加.查询元素等操作),因为TreeSet需要额外的红黑树 ...

  7. ipmi nf5280m5 浪潮_浪潮NF5280M5和华为哪款服务器性能接近?

    NF5280M5应该对标的是华为FusionServer2288H V5以及Dell EMC PowerEdge R740XD 既然你问的是华为,那我就拿RH2288H V5列一下给你看看. 2288 ...

  8. log4j与log4j2性能对比及log4j升级至log4j2方案

    1.前言 之前某个服务在压测环境中出现了问题,分析之后得知是log4jLogger对象争用厉害,很多线程阻塞在此. 以上问题证明log4j在高并发高QPS情况下,是存在性能问题的. 之后把log4j升 ...

  9. Log4j2的性能为什么这么好?

    作者:詹嵩 某公司架构部中间件架构师 来源:https://www.jianshu.com/p/359b14067b9e 一.logback和log4j2压测比较 1.logback压测数据 logb ...

最新文章

  1. 出租房的网络环境研究
  2. Tomcat 8.5——配置阿里云免费SSL证书(PFX格式证书)[启用HTTPS协议]
  3. 数据结构-编程实现一个双链表的建立,双链表的打印,双链表的测长
  4. mingw64 下 java_在 Windows 10 64 位下安装 Mingw-w64
  5. python中如何将字典直接变成二维数组_python基础知识(列表、字典、二维数组)...
  6. [网络流24题-6]孤岛营救问题
  7. Netty学习总结(1)——Netty入门介绍
  8. Linux内存是怎么工作的
  9. vSphere4.1升级到vSphere5.0连载之一
  10. UNIX 高级环境编程 第10章 信号
  11. jQuery的对象访问函数(get,index,size,each)
  12. ExpandableListView
  13. 离线检查未安装的Windows更新
  14. 解决网页上内容不能复制的几种方法
  15. 兴义智力象机器人_中科院科普讲师专家赴黔西南州做科普报告巡讲
  16. 计算机网络的简单实验
  17. oracle 启动crs进程,由于CRS磁盘dismount造成的CRS进程无法启动问题
  18. 树莓派4 Ubuntu18.04安装xubuntu桌面 无线WIFI 及 ros melodic(解决apt update error,安装xubuntu error问题)
  19. iOS iPhone6分辨率与适配
  20. Unity动画DG.Tween插件

热门文章

  1. (转)如何查看java本地方法
  2. java序列化和反序列化_Java恶意序列化背后的历史和动机
  3. 自动化测试特定区域滑动_自动化用户特定实体的访问控制
  4. java orm框架有哪些_Java Stream ORM现在带有JOIN
  5. java agent_如何脚踏实地构建Java Agent
  6. junit5和junit4_JUnit 5 –下一代JUnit的初步了解
  7. java 可视化_可视化Java 9模块关系
  8. javafx窗体程序_JavaFX实际应用程序:AISO HRC-Matic
  9. apache camel_使用WildFly 8在Java EE7中自举Apache Camel
  10. junit:junit_简而言之,JUnit:Hello World