将ActiveMQ持久消息传递性能提高25倍

Apache ActiveMQ,JBoss A-MQ和Red Hat

Apache ActiveMQ是一个非常受欢迎的开源消息传递代理,由创建(和工作) Apache Karaf , Apache Camel , Apache ServiceMix以及许多其他工具的人提供给您。 它拥有一个充满活力的社区,非常灵活,可以部署在高性能和高可用性的场景中。

在Red Hat (我工作的地方),我们支持一种名为JBoss A-MQ的产品 ,该产品是生产增强 ,受企业支持的,完全开源的上游ActiveMQ项目版本。 红帽完全致力于开源,而我们所有的产品都是开源的(不属于这种开放式核心技术)。我们的客户(特别是使用JBoss A-MQ的客户)在各自领域中名列前茅(零售/ e-零售,政府,航运,医疗服务提供商,金融,电信等),并在非常关键的情况下部署JBoss A-MQ。

由于JBoss A-MQ代码库来自上游ActiveMQ社区,并且我们在Red Hat方面所做的所有错误修复和增强功能都重新融入了社区中,因此,我想与您分享我们最近贡献的增强功能将我们的用例在知名客户上的速度提高了25倍,并且还可能对您的用例有所帮助。 已提交的补丁程序位于master分支中,直到5.12社区发行版才可用(尽管比JBoss A-MQ 6.1的补丁程序更早提供,希望本周末或下周初可用)。 ,尽管我鼓励您每晚检出5.12版SNAPSHOT以早日尝试( 夜间快照可以在这里找到 )。

我们的问题...

为了设置上下文,我们正在谈论通过代理的持久消息传递。 这意味着,在消息已安全存储到持久性存储之前,代理将不承担消息的责任。 在这一点上,由经纪人将消息传递给消费者,并且在消费者确认了消息的责任之前,不应丢失消息。

ActiveMQ文档描述了这样的流程:

快速商店

但是,为了确保消息不会丢失,我们必须假定消息传递存储库具有高可用性。 在本文其余部分描述的情况下,我们使用KahaDB Persistence Adapter ,这是开箱即用提供的默认持久性适配器 。 我们需要将kahadb数据库文件存储在高度可用的存储设备(NAS,SAN等)上。 第二个要求是,当我们将消息写入文件系统时,我们必须将数据同步到磁盘(aka,刷新应用程序,操作系统,网络和硬件之间的所有缓冲区),以便可以确保磁盘不会丢失数据。 您可以通过不与磁盘同步并允许OS缓冲写操作来获得非常快的“持久性”的折衷,但这会导致失败时丢失消息的可能性。

但是回到我们的故事:在我们的用例中,我们在带有RHEL 6.5的块存储设备上使用了GFS2文件系统 。 当ActiveMQ将消息写入数据库时​​,它将要求OS文件描述符“同步”,以便将所有内容安全地存储在磁盘上,并将阻塞写入线程,直到完成为止(还有更多操作正在进行,但是将简化一秒钟)。 这种同步非常昂贵,我们注意到它甚至更慢,因为在每次调用时都正在同步数据和同步元数据。 (所有这些都在一定程度上因操作系统,文件系统等而异……对于这种特定情况,我们正在谈论RHEL 6.5和GFS2)。

在我们的用例中,我们决定不需要在所有同步调用上都同步元数据,只有操作系统认为必要的那些元数据才能保持一致性。 因此,ActiveMQ中有一个未记录的功能(提醒我记录此功能),您可以将其配置为在每个同步调用中不强制元数据同步,并委派给操作系统。 为此,请在启动时将此标志传递给JVM:

-Dorg.apache.activemq.kahaDB.files.skipMetadataUpdate=true

这将使操作系统可以决定是否同步元数据。 对于某些用例,这可以加快写入磁盘的速度,然后同步数据。

但是,在我们的用例中,事实并非如此。 我们每秒收到约76条消息,这对我来说没有通过气味测试。

带有ActiveMQ的DiskBenchmark

因此,我们抽出了一个鲜为人知的磁盘基准测试工具,它与ActiveMQ一起提供(请注意。 它进行测试以查看其可以从基础文件系统写入/读取的速度。 由于ActiveMQ也是用Java编写的,因此在这种情况下很有用,该DiskBenchmark将使用Java API来完成此任务。 因此,您可以将它用作写入速度的一个数据点。 您还可以执行其他系统级别的测试来测试存储/文件系统设置的各个部分,但是我很烦恼-这篇文章已经太长了。

要运行磁盘基准测试,请导航到ActiveMQ安装目录并运行以下命令:

java -classpath "lib/*" \
org.apache.activemq.store.kahadb.disk.util.DiskBenchmark

这将运行一个基准并吐出结果。 考虑到硬件,我们在这种情况下的结果看起来不错

Benchmarking: /mnt/gfs2/disk-benchmark.dat                                                                       
Writes:                                                                                                          639996 writes of size 4096 written in 10.569 seconds.                                                          60554.074 writes/second.                                                                                       236.53935 megs/second.                                                                                         Sync Writes:                                                                                                     23720 writes of size 4096 written in 10.001 seconds.                                                           2371.763 writes/second.                                                                                        9.264699 megs/second.                                                                                          Reads:                                                                                                           3738602 reads of size 4096 read in 10.001 seconds.                                                             373822.8 writes/second.                                                                                        1460.2454 megs/second.

将块大小增加到4MB(这是ActiveMQ的默认最大块大小):

java -classpath "lib/*" \
org.apache.activemq.store.kahadb.disk.util.DiskBenchmark \
--bs=4194304Benchmarking: /mnt/gfs2/disk-benchmark.dat                                                                       
Writes:                                                                                                          621 writes of size 4194304 written in 10.235 seconds.                                                          60.674156 writes/second.                                                                                       242.69662 megs/second.                                                                                         Sync Writes:                                                                                                     561 writes of size 4194304 written in 10.017 seconds.                                                          56.00479 writes/second.                                                                                        224.01917 megs/second.                                                                                         Reads:                                                                                                           2280 reads of size 4194304 read in 10.004 seconds.                                                             227.90884 writes/second.                                                                                       911.6354 megs/second.

那些9.x megs / sec和224.x megs / sec的同步写入并没有达到我们的76 msg / s,因此我们进行了更深入的研究。

非常感谢Red Hat的存储团队的Robert Peterson。。。在筛选strace并依靠Bob对文件系统/存储的了解之后,我们能够看到,由于文件大小随着每次写入而不断增长,因此操作系统确实也会同步元数据,因此不会使用该JVM标志加快写入速度以跳过元数据更新。 鲍勃建议我们预分配要写入的文件,然后让我大吃一惊.. duh ..这就是Disk Benchmark实用程序正在做的事情!

因此,在编写了用于预分配日志文件的补丁程序之后,我们看到性能数字从76 TPS上升到大约2000 TPS。 我在其他文件系统上进行了一些快速测试,似乎在那里产生了显着影响,尽管我不能肯定地说,如果不进行更全面的基准测试。

因此,现在有了该补丁,我们可以将KahaDB配置为“预分配”日志文件。 开箱即用,它将文件预分配为稀疏文件 。 此类文件可能不足或不足以满足您的调优需求,因此请首先试用。 对于我们来说,这还不够—我们需要预分配块/结构,因此我们使用零进行了预分配:

<kahaDB directory="/mnt/gfs2/kahadb" \
enableJournalDiskSyncs="true" preallocationStrategy="zeros" />

这使我们能够进行数据的同步/同步,并保存元数据更新,并减少了必须分配这些块的文件系统负载。 这导致性能显着提高。

注意,有三种预分配策略:

  • sprase_file默认,开箱即用
  • zeros -ActiveMQ通过将零(0×00)写入这些块来预分配文件
  • os_kernel_copy — ActiveMQ将分配委托给操作系统

测试哪个更适合您。 我还在制作一个补丁,以批量或整个文件方式进行预分配。

请参阅文档以获取有关KahaDB和预分配的更多信息

最终结果

经过一些快速的场景测试之后,我注意到用于此特定用例的不同文件系统的性能有所提高。 当然,您的测试/硬件/场景/ OS /网络/配置/文件系统等可能与此测试中使用的有所不同,因此在开始将产品投入生产之前,请先询问计算机。 尽管如此,我们在较新的,令人兴奋的硬件上针对该用例的数量:

| strategy         |Local storage | GFS2     | NFSv4
|------------------|--------------|----------|---------
| `sparse_file`    | 64 m/s       | 76 m/s   | 522 m/s |
| `zeros`          | 163 m/s      | 2072 m/s | 613 m/s |
| `os_kernel_copy` | 162 m/s      | BUG      | 623 m/s |------------------------------------------------------

注意!!!!

只需注意,对于os_kernel_copy选项,如果在RHEL 6.x / 7.x上运行并使用GFS2,它可能会失败,因此请远离该选项,直到修复内核错误为止:)

翻译自: https://www.javacodegeeks.com/2015/03/speeding-up-activemq-persistent-messaging-performance-by-25x.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sql数据库恢复

先附加,然后再备份,然后按如下: --数据还原到指定时间点的处理示例--创建测试数据库CREATE DATABASE DbGO --对数据库进行备份BACKUP DATABASE Db TO DISKc:\db.bak WITH FORMATGO --创建测试表CREATE TABLE Db.dbo.TB_test(ID int) --延时1秒钟,再进行后面的操作(这是由于SQL …

ECMA学习小结(3)——constructor 和 prototype

每个函数都有一个prototype的属性&#xff0c;当我们以这个函数为构造函数创建实例时&#xff08;即用new的形式&#xff09;&#xff0c;创建出来的这个对象是没有prototype的属性的。以下代码为例&#xff1a;在console里进行调试cf 拥有一个prototype的属性&#xff0c;这个…

java什么是网络接口_java 网络编程 -- IP地址的表示与网络接口信息的获取(InetAddress和NetworkInterface)...

使用java进行网络程序的开发&#xff0c;可以说是一件令人愉悦的事情&#xff0c;对于用惯了C网络接口编程的人来说&#xff0c;当他们首次使用Java开发网络应用程序&#xff0c;会发现java开发网络应用是如此的简单&#xff0c;甚至仅用几分钟时间&#xff0c;您就可以学会这种…

如何使用悲观锁定修复乐观锁定竞争条件

概括 在我以前的文章中 &#xff0c;我解释了使用显式乐观锁定的好处。 然后我们发现&#xff0c;在很短的时间范围内&#xff0c;并发交易仍可以在我们当前交易被提交之前立即提交产品价格更改。 此问题可以描述如下&#xff1a; 爱丽丝拿产品 然后&#xff0c;她决定订购…

分支限界

分支界定是一种在问题的解空间树上搜索问题的解的方法&#xff0c;其实就是剪枝广搜&#xff0c;它始终维护一个上下界用来剪枝&#xff0c;一个限界函数计算对解的最有期望。主要用于解决离散问题的优化。 分支界定的关键问题&#xff1a; &#xff08;1&#xff09;如何确定合…

mysql表变量临时表_表变量和临时表详解

首先让我们来看看什么是表变量和临时表。sql server 表变量1.初识表变量表变量在sql server 2000中首次被引用。表变量的定义和创建一个表大致相同&#xff0c;只不过是使用DECLARE variable而不是CREATE Table&#xff0c;表变量定义包括列定义&#xff0c;列名&#xff0c;数…

SWT外观:自定义FlatScrollBar颜色等

最近&#xff0c;我引入了一个自定义滑块控件 &#xff0c;该控件可用于改善SWT外观和更细微的视图布局的感觉。 令人高兴的是&#xff0c;该小部件似乎已经在Code Affine世界之外找到了较早的采用者 。 这导致了一些增强 &#xff0c;这些增强将在以下各节中介绍。 SWT滚动条…

类的静态数据成员

有时需要为某个类的所有对象分配一个单一的存储空间。在C语言中&#xff0c;可以用全局变量&#xff0c; 但这样很不安全。全局数据可以被任何人修改&#xff0c;而且&#xff0c;在一个项目中&#xff0c;它很容易与其他的名字 相冲突。如果可以把一个数据当成全局变量那样去存…

【Android 13】使用Android Studio调试系统应用之Settings移植(三):构建settingsLib项目目录

文章目录 一、篇头二、系列文章2.1 Android 13 系列文章2.2 Android 9 系列文章2.3 Android 11 系列文章三、AS新建SettingsLib New Moudle3.1 创建 New Moudle3.2 替换源文件(1)选定复制目标(2)复制到AS目录,并改名(3)完成创建四、下一步动作五、篇尾

java虚拟机编译_[四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式...

前言简介前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明想要了解JVM的运行机制,以及如何优化你的代码,你还需要了解一下,java编译器到底是如何编译你的代码的本文不是从最底层的编译原理讲解本文是针对java代码,去查看归纳总结编译…

提高性能:流的非阻塞处理

1.简介 想象一下&#xff0c;我们有一个需要访问外部Web服务的应用程序&#xff0c;以便收集有关客户端的信息&#xff0c;然后对其进行处理。 更具体地说&#xff0c;我们无法在一次调用中获得所有这些信息。 如果我们要查找不同的客户端&#xff0c;则需要多次调用。 如下图…

通过NAT转发实现私网对外发布信息

我们可以在防火墙的外部网卡上绑定多个合法IP地址&#xff0c;然后通过ip映射使发给其中某一个IP地址的包转发至内部某一用户的WWW服务器上&#xff0c;然后再将该内部WWW服务器响应包伪装成该合法IP发出的包。具体的IP分配如下&#xff1a; &#xff08;1&#xff09;该ISP分配…

java支付管理有源码_java支付宝支付案例源码

【实例简介】※运行环境※Eclipse JDK1.6及以上 Tomcat6.0及以上※使用方法※SDK下载地址&#xff1a;https://doc.open.alipay.com/docs/doc.htm?treeId193&articleId103419&docType1第一步&#xff1b;请下载【JAVA版资源】的SDK。第二步&#xff1a;下载完毕后&…

CDI和EJB:在事务成功时发送异步邮件

再一次问好&#xff01; :) 这次&#xff0c;我选择了一项常见任务&#xff0c;我认为大多数情况下都以错误的方式完成&#xff1a;发送电子邮件。 并非所有人都不知道电子邮件API的工作方式&#xff0c;例如JavaMail或Apache的commons-email 。 我通常看到的一个问题是&#…

SPFILE 、PFILE 的全面解读

这里先阐述一下数据库的启动过程&#xff1a; 1. 启动实例/例程&#xff08;nomount状态&#xff09;时&#xff0c;读取参数文件(文本文件PFILE 或服务器参数文件SPFILE)&#xff0c;分配SGA、启动后台进程、打开告警文件及后台进程跟踪文件&#xff1b; 2. 装载数据…

JAVA确定这天是这年的某一天_[Java] 练习题014: 输入某年某月某日,判断这一天是这一年的第几天?...

import java.util.*;public class Test014{public static void main(String[] args) throws Exception{int y,m,d;int sum0;int feb28;Scanner in new Scanner(System.in);System.out.print("请输入年份:");y in.nextInt();System.out.print("请输入月份:&quo…

使用默认方法的界面演变–第一部分:方法

几周前&#xff0c;我们详细研究了默认方法 -Java 8中引入的一项功能&#xff0c;该功能允许为接口方法提供实现&#xff0c;即方法主体&#xff0c;从而定义接口中的行为。 引入此功能是为了实现接口演进 。 在JDK的上下文中&#xff0c;这意味着在不破坏所有代码的情况下向接…

java左手握右手_环保型燃料—丙烷(C3H8)曾用于北京奥运会“祥云”火炬燃料,下列有关烷烃的说法不正确的是()A.丙烷分子中三个...

参考答案如下环保会祥【单选题】环境景观设计的核心就是以研究()为基础。型燃下列【判断题】构成中央处理器的两大部件是运算器和存储器。料丙料【单选题】通过下列哪种方式可以获得最强的免疫效果【单选题】根据断面图的标注形式&#xff0c;烷C烷烃下列绘制规范的断面图是【单…

windbg script ---- 禁用IsDebuggerPresent

简单的script r $t0 kernelBase!IsDebuggerPresent; eb $t00x9 31 c0 90 90强制把原代码改成xor eax, eax; nop; nop 注意在xp下&#xff0c;使用kernel32 转载于:https://www.cnblogs.com/hgy413/p/3693400.html

java两个和三个_Java语言基础(day_03)

数据类型中补充的几个小问题1)在定义Long或者Float类型变量的时候&#xff0c;要加L或者f。整数默认是int类型&#xff0c;浮点数默认晨double。byte&#xff0c;short在定义的肘候&#xff0c;他们接收的某实是一个int类型的值。这个是自己做了一个数据检测的&#xff0c;如果…