持久化消息和非持久化消息的存储原理:

  正常情况下,非持久化消息是存储在内存中的,持久化消息是存储在文件中的。能够存储的最大消息数据在${ActiveMQ_HOME}/conf/activemq.xml文件中的systemUsage节点SystemUsage配置设置了一些系统内存和硬盘容量。

<systemUsage>
<systemUsage>
<memoryUsage>
//该子标记设置整个ActiveMQ节点的“可用内存限制”。这个值不能超过ActiveMQ本身设置的最大内存大小。其中的
//percentOfJvmHeap属性表示百分比。占用70%的堆内存
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
//该标记设置整个ActiveMQ节点,用于存储“持久化消息”的“可用磁盘空间”。该子标记的limit属性必须要进行设置
<storeUsage limit="100 gb"/>
</storeUsage>
<tempUsage>
//一旦ActiveMQ服务节点存储的消息达到了memoryUsage的限制,非持久化消息就会被转储到 temp store区域,虽然
//我们说过非持久化消息不进行持久化存储,但是ActiveMQ为了防止“数据洪峰”出现时非持久化消息大量堆积致使内存耗
//尽的情况出现,还是会将非持久化消息写入到磁盘的临时区域——temp store。这个子标记就是为了设置这个temp
//store区域的“可用磁盘空间限制
<tempUsage limit="50 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>

  Ø 从上面的配置我们需要得到一个结论,当非持久化消息堆积到一定程度的时候,也就是内存超过指定的设置阀值时,ActiveMQ会将内存中的非持久化消息写入到临时文件,以便腾出内存。但是它和持久化消息的区别是,重启之后,持久化消息会从文件中恢复,非持久化的临时文件会直接删除。

消息的持久化策略:

  消息持久性对于可靠消息传递来说是一种比较好的方法,即时发送者和接受者不是同时在线或者消息中心在发送者发送消息后宕机了,在消息中心重启后仍然可以将消息发送出去。消息持久性的原理很简单,就是在发送消息出去后,消息中心首先将消息存储在本地文件、内存或者远程数据库,然后把消息发送给接受者,发送成功后再把消息从存储中删除,失败则继续尝试。接下来我们来了解一下消息在broker上的持久化存储实现方式。

持久化存储支持类型:

  ActiveMQ支持多种不同的持久化方式,主要有以下几种,不过,无论使用哪种持久化方式,消息的存储逻辑都是一致的。

    Ø KahaDB存储(默认存储方式)。

    Ø JDBC存储。

    Ø Memory存储。

    Ø LevelDB存储。

    Ø JDBC With ActiveMQ Journal。

KahaDB存储:

  KahaDB是目前默认的存储方式,可用于任何场景,提高了性能和恢复能力。消息存储使用一个事务日志和仅仅用一个索引文件来存储它所有的地址。KahaDB是一个专门针对消息持久化的解决方案,它对典型的消息使用模式进行了优化。在Kaha中,数据被追加到data logs中。当不再需要log文件中的数据的时候,log文件会被丢弃。

  配置方式:在${ActiveMQ_HOME}/conf/activemq.xml文件中:

<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>

  KahaDB的存储原理:

在data/kahadb这个目录下,会生成四个文件

Ø db.data 它是消息的索引文件,本质上是B-Tree(B树),使用B-Tree作为索引指向db-*.log里面存储的消息。
Ø db.redo 用来进行消息恢复。
Ø db-*.log 存储消息内容。新的数据以APPEND的方式追加到日志文件末尾。属于顺序写入,因此消息存储是比较快的。默认是32M,达到阀值会自动递增。
Ø lock文件 锁,表示当前获得kahadb读写权限的broker。

JDBC存储:

  使用JDBC持久化方式,数据库会创建3个表:activemq_msgs,activemq_acks和activemq_lock。
  ACTIVEMQ_MSGS :消息表,queue和topic都存在这个表中
  ACTIVEMQ_ACKS :存储持久订阅的信息和最后一个持久订阅接收的消息ID
  ACTIVEMQ_LOCKS :锁表,用来确保某一时刻,只能有一个ActiveMQ broker实例来访问数据库

  JDBC存储实践:

<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="# MySQL-DS " createTablesOnStartup="true" />
</persistenceAdapter>

  dataSource指定持久化数据库的bean,createTablesOnStartup是否在启动的时候创建数据表,默认值是true,这样每次启动都会去创建数据表了,一般是第一次启动的时候设置为true,之后改成false

  Mysql持久化Bean配置:

<bean id="Mysql-DS" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.11.156:3306/activemq?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>

  配置完以后需要往 ${ActiveMQ_HOME}/lib 文件夹中添加相应 jar 包:然后重启就OK了。

LevelDB存储:

  LevelDB持久化性能高于KahaDB,虽然目前默认的持久化方式仍然是KahaDB。并且,在ActiveMQ 5.9版本提供了基于LevelDB和Zookeeper的数据复制方式,用于Master-slave方式的首选数据复制方案。不过,据ActiveMQ官网对LevelDB的表述:LevelDB官方建议使用以及不再支持,推荐使用的是KahaDB。

<persistenceAdapter>
<levelDBdirectory="activemq-data"/>
</persistenceAdapter>

Memory 消息存储:

  基于内存的消息存储,内存消息存储主要是存储所有的持久化的消息在内存中。persistent=”false”,表示不设置持久化存储,直接存储到内存中。

<beans>
<broker brokerName="test-broker" persistent="false"
xmlns="http://activemq.apache.org/schema/core">
<transportConnectors>
<transportConnector uri="tcp://localhost:61635"/>
</transportConnectors> </broker>
</beans>

JDBC Message store with ActiveMQ Journal:

  这种方式克服了JDBC Store的不足,JDBC每次消息过来,都需要去写库和读库。ActiveMQ Journal,使用高速缓存写入技术,大大提高了性能。当消费者的消费速度能够及时跟上生产者消息的生产速度时,journal文件能够大大减少需要写入到DB中的消息。举个例子,生产者生产了1000条消息,这1000条消息会保存到journal文件,如果消费者的消费速度很快的情况下,在journal文件还没有同步到DB之前,消费者已经消费了90%的以上的消息,那么这个时候只需要同步剩余的10%的消息到DB。如果消费者的消费速度很慢,这个时候journal文件可以使消息以批量方式写到DB。

Ø 将原来的 persistenceAdapter 标签注释掉
Ø 添加如下标签

<persistenceFactory>
<journalPersistenceAdapterFactory dataSource="#Mysql-DS" dataDirectory="activemqdata"/>
</persistenceFactory>

  

ActiveMQ消息的持久化策略的更多相关文章

  1. 学习ActiveMQ(八):activemq消息的持久化

    1. 持久化方式介绍前面我们也简单提到了activemq提供的插件式的消息存储,在这里再提一下,主要有以下几种方式: AMQ消息存储-基于文件的存储方式,是activemq开始的版本默认的消息存储方式 ...

  2. ActiveMQ 消息队列服务

      1 ActiveMQ简介 1.1 ActiveMQ是什么 ActiveMQ是一个消息队列应用服务器(推送服务器).支持JMS规范. 1.1.1 JMS概述 全称:Java Message Serv ...

  3. ActiveMQ消息持久化存储策略

    ActiveMQ的内核是Java编写的,也就是说如果服务端没有Java运行环境ActiveMQ是无法运行的.ActiveMQ启动时,启动脚本使用wrapper包装器来启动JVM.JVM相关的配置信息在 ...

  4. JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系

    一,消息的持久化和非持久化 ①DeliveryMode 这是传输模式.ActiveMQ支持两种传输模式:持久传输和非持久传输(persistent and non-persistent deliver ...

  5. ActiveMQ 消息持久化到数据库(Mysql、SQL Server、Oracle、DB2等)

    ActiveMQ具体就不介绍了,直接介绍如何讲ActiveMQ持久化到本地数据库,以SQL Server 2008 R2为例1.下载ActiveMQ后直接解压,我下载的是apache-activemq ...

  6. RabbitMQ(三):消息持久化策略

    原文:RabbitMQ(三):消息持久化策略 一.前言 在正常的服务器运行过程中,时常会面临服务器宕机重启的情况,那么我们的消息此时会如何呢?很不幸的事情就是,我们的消息可能会消失,这肯定不是我们希望 ...

  7. ActiveMQ安装与持久化消息

    activityMQ官网:http://activemq.apache.org/ 有windows版与linux版  windows版启动 在bin目录下双击activemq.bat linux版的安 ...

  8. 消息中间件-activemq消息机制和持久化介绍(三)

    前面一节简单学习了activemq的使用,我们知道activemq的使用方式非常简单有如下几个步骤: 创建连接工厂 创建连接 创建会话 创建目的地 创建生产者或消费者 生产或消费消息 关闭生产或消费者 ...

  9. JMS学习八(ActiveMQ消息持久化)

    ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,还有一种内存存储的方式,由于内存不属于持久化范畴,而且如果使用内存队列,可以考虑使用更合适的产品,如ZeroMQ.所以 ...

随机推荐

  1. vue 中跨组件的表单验证

    使用的是element写的,里面提供了表单验证. 子组件是这样的 <template> <div> <el-form :model="value" r ...

  2. 5-23 CSS知识的补充

    1,后代选择器 使用空格表示后代选择器.顾名思义,父元素的后代(包括儿子,孙子,重孙子). <!DOCTYPE html> <html lang="en"> ...

  3. [Ynoi2016]这是我自己的发明 莫队

    传送门:here 很棒的莫队题啊..... 题意: 有一棵$ n$个点的树,树上每个点有点权,有$ m$次询问: 操作1:给定两个点$ x,y$,求二元组$ (a,b)$的数量,要求$ a$在$ x$ ...

  4. linux 共享内存的理解

    1.  共享内存是在shmget时创建出来的, 在 shmget(USER_SHARE_MEM_KEY,  sizeof(ADDR_NODE) , IPC_CREAT|0666)) ==-1) 的 s ...

  5. 【报错】java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[

    报错 java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleExce ...

  6. shell编程 之 ssh远程连接

    1,ssh理解 有两个服务器,一个是本地,一个是云端的,都是linux系统的,如果我们想要通过本地访问云端的系统,那我们可以用ssh命令,可以实现本地登入远程连接,上传或者下载文件到远程服务器. ss ...

  7. MySQL创建数据库指定字符集

    CREATE DATABASE IF NOT EXISTS dbname DEFAULT CHARSET utf8;

  8. UML类图表达

    什么是UML类图? 类图显示了一组类.接口.协作以及他们之间的关系.在UML中问题域最终要被逐步转化,通过类来建模,通过编程语言构建这些类从而实现系统.类加上他们之间的关系就构成了类图,类图中还可以包 ...

  9. string.Empty, "" 和 null 三者的区别

    转载:http://www.cnblogs.com/mxxblog/archive/2013/08/22/3275387.html 这是一个及其常见的问题,网上已经有关于这个问题的很多讨论.但是我觉得 ...

  10. Shell-find . -type f -name "*.log" -print0 | xargs -0 rm -f

    用 rm 删除太多的文件时候,可能得到一个错误信息:/bin/rm Argument list too long.