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

activemq消息持久化

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快照,以便尽快尝试( 可以在这里找到每晚快照 )。

我们的问题

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

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

快速商店

但是,为确保消息不会丢失,我们必须假定消息传递存储库具有高可用性。 在本文其余部分描述的情况下,我们使用KahaDB Persistence Adapter ,这是开箱即用提供的默认持久性适配器 。 我们需要将kahadb数据库文件存储在高度可用的存储设备(NAS,SAN等)上。 第二个要求是,当我们将消息写入文件系统时,我们必须将数据同步到磁盘(也就是刷新应用程序,操作系统,网络和硬件之间的所有缓冲区),以便可以确保磁盘不会丢失数据。 您可以通过不与磁盘同步并允许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兆秒/秒和224.x兆秒/秒的同步写入并没有达到我们的76毫秒/秒的速度,因此我们进行了更深入的研究。

非常感谢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

activemq消息持久化

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

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

相关文章

c语言实现两个有序链表的合并(代码示例)

c语言实现两个有序链表的合并&#xff1a;现有两个有序单链表&#xff0c;通过代码实现将两个单链表合并为一个有序的新表&#xff0c;要求使用旧表的空间&#xff0c;不能新分配内存#include #include typedef struct List{ int a; struct List *next;}list;void newLis…

hibernate工厂模式_Hibernate锁定模式–乐观锁定模式如何工作

hibernate工厂模式显式乐观锁定 在上一篇文章中 &#xff0c;我介绍了Java持久性锁定的基本概念。 隐式锁定机制可防止丢失更新 &#xff0c;它适用于我们可以主动修改的实体。 尽管隐式乐观锁定是一种广泛使用的技术&#xff0c;但很少有人了解显式乐观锁定模式的内部工作原理…

using用法是什么?

using用法是&#xff1a;1、命名空间using namespace 命名空间;//这样每次使用命名空间中的变量时就不用指定命名空间了注意&#xff1a;头文件中不应有using命名空间的声明2、类型别名&#xff08;C 11&#xff09;using aa double;//等价于typedef double aatypedef double …

学习C ,常见的误解

学习C 你是否会有以下几点误解&#xff1f;1. “要理解C &#xff0c;你必须先学习C”2. “C 是一门面向对象的语言”3. “为了软件可靠性&#xff0c;你需要垃圾回收”4. “为了效率&#xff0c;你必须编写底层代码”5. “C 只适用于大型、复杂的程序”如果你中*了&#xff0c…

openshift使用_OpenShift DIY:使用Gradle构建Spring Boot / Undertow应用程序

openshift使用由于此错误&#xff0c; Gradle 1.6是在OpenShift上运行的最后一个受支持的Gradle版本。 但是从Gradle 2.2开始&#xff0c;这不再是问题&#xff0c;因此&#xff0c;使用自己动手做墨盒&#xff0c;在OpenShift上运行最新的Gradle不再是问题。 DIY盒带是一种实验…

php管理智能dns,负载均衡之DNS轮询

域名注册商都支持对统一主机添加多条A记录&#xff0c;这就是DNS轮询&#xff0c;DNS服务器将解析请求按照A记录的顺序&#xff0c;随机分配到不同的IP上&#xff0c;这样就完成了简单的负载均衡。下图的例子是&#xff1a;有3台联通服务器、3台电信服务器&#xff0c;要实现“…

php怎么把时间戳转成日期格式,php怎么把时间格式转换为时间戳?,时间戳转为日期...

php怎么把时间格式转换为时间戳&#xff1f;PHP怎么把时间格式转换成时间戳&#xff1f;&#xff0c;php时间格式转换为时间戳的方法&#xff1a;1。使用mktime()将时间转换为时间戳&#xff0c;语法为“mktime(小时、分钟、秒、月、日、年)”&#xff1b;2.使用strtime()将字符…

C语言的标识符由什么组成

C语言的标识符由字母、数字、下划线组成&#xff0c;并且第一个字符必须是字母或下划线&#xff0c;不能是数字。在标识符中&#xff0c;字母的大小写是有区别的&#xff0c;例如BOOK与book是两个不同的标识符。定义变量时&#xff0c;我们使用了诸如 a、abc、mn123 这样的名字…

jdk8读取文件_JDK 7和JDK 8中大行读取速度较慢的原因

jdk8读取文件我早些时候发布了博客文章Reading Large Lines Slower in JDK 7和JDK 8&#xff0c;并且在描述该问题的文章上有一些有用的评论 。 这篇文章提供了更多解释&#xff0c;说明为何该文章中演示的文件读取&#xff08;并由Ant的LineContainsRegExp使用 &#xff09;在…

C 11 实现的 100行 线程池

C 线程池一直都是各位程序员们造轮子的首选项目之一。今天&#xff0c;小编带大家一起来看看这个轻量的线程池&#xff0c;本线程池是header-only的&#xff0c;并且整个文件只有100行&#xff0c;其中C 的高级用法有很多&#xff0c;很值得我们学习&#xff0c;一起来看看吧。…

openshift使用_OpenShift v3:使用WildFly和MySQL的Java EE 7入门

openshift使用OpenShift是Red Hat的开源PaaS平台。 OpenShift v3 &#xff08;将于今年发布&#xff09;将提供使用Docker和Kubernetes运行微服务的整体体验。 以经典的Red Hat方式&#xff0c;所有工作都在OpenShift Origin的开源中完成。 这也将推动OpenShift Online和OpenSh…

c程序的基本组成单位是什么?

C程序是由函数构成的。函数是C程序的基本组成单位。一个C源程序中仅有一个main()函数,除main函数之外可以有若干个其它的函数。每个函数实现某一特定的操作。因此&#xff0c;函数是C程序的基本单位。一个函数由两部分组成&#xff1a;函数的说明部分。包括函数名、函数类型、函…

C语言头文件 “ 细节 ”

很多事不深入以为自己懂了&#xff0c;但真正用到项目上&#xff0c;才发现了问题。曾以为自己写C语言已经轻车熟路了&#xff0c;特别是对软件文件的工程管理上&#xff0c;因为心里对自己的代码编写风格还是有自信的。(毕竟刚毕业时老大对我最初的训练就是编码格式的规范化处…

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

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

初学者宝典:C语言入门基础知识大全(中)

04常量在程序运行中&#xff0c;其值不能被改变的量称为常量。常量有5种类型&#xff1a;整型常量、实型常量、字符常量、字符串常量和符号常量。4.1 数值转换—数值的四种表现形式&#xff1a;①&#xff1a;二进制&#xff1a;所有数字由0,1构成&#xff0c;逢二进一&#xf…

stateless_Spring Stateless State Security第3部分:JWT +社会认证

stateless我的Stateless Spring Security系列文章的第三部分也是最后一部分是关于将基于JWT令牌的身份验证与spring-social-security混合在一起的。 这篇文章直接建立在它的基础上&#xff0c;并且主要集中在已更改的部分上。 想法是使用基于OAuth 2的“使用Facebook登录”功能…

return在c语言中是什么意思

函数是C语言的基本构件&#xff0c;一个C程序可以由一个主函数和若干个子程序函数构成&#xff0c;由主函数调用其它子程序函数&#xff0c;其他子程序函数也可以互相调用。通常希望通过函数调用使主函数能得到一个确定的值&#xff0c;这就是函数的返回值。在C语言中通过函数实…

为什么非阻塞io性能更好_提高性能:流的非阻塞处理

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

c语言的输入函数有哪些

c语言的输入函数有&#xff1a;1、scanf的返回值scanf()函数返回成功赋值的数据项数&#xff0c;读到文件末尾出错时则返回EOF。如&#xff1a;scanf("%d%d", &a, &b);如果a和b都被成功读入&#xff0c;那么scanf的返回值就是2如果只有a被成功读入&#xff0…

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

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