ActiveMQ:java.io.IOException: Failed to recover data at position:2

测试环境一套activemq-Broker-Cluster集群,近期服务宕机。登录到服务器上查看,发现warpper.log日志巨大,已经将可用分区用尽。

ActiveMQ:java.io.IOException: Failed to recover data at position:2

如何处理wrapper.log过大的问题


ActiveMQ服务器data目录下wrapper.log文件,默认产生的日志是不覆盖的,文件的大小逐渐增大,经过查询资料,和阅读Activemq的官方文档,找到了解决方案:

<1>找到wrapper.conf文件:

<2>修改wrapper.conf文件:设置文件大小

修改maxsize的值,默认是0,也就是无限制,设置1024mb表示最大为1024mb,可以重新生成文件。实验证实,最后生成文件大小是1024mb.ActiveMQ:java.io.IOException: Failed to recover data at position:2

<3>设置文件数量

可以设置最多可以有多少个wrapper.log文件,比如我设置了值为5,大小为1024mb,日志到了1024mb的时候文件就无法增大了。如果5个文件都生成了,就从wrapper.log开始覆盖,但是文件大小不变,日志覆盖。

解决了wrapper.log无限增长的问题,重启activemq发现还有报错导致无法启动:


1,WARN  | Exception encountered during context initialization – cancelling reror creating bean with name ‘org.apache.activemq.xbean.XBeanBrokerService#0’ defined in class path reis java.io.IOException: Failed to recover data at position:2:9420703

2,Failed to start Apache ActiveMQ |org.apache.activemq.broker.BrokerService | main

ActiveMQ:java.io.IOException: Failed to recover data at position:2

如何处理java.io.IOException: Failed to recover data at position这种报错呢?

简单分析下,有可能是异常关闭导致kahadb数据库存储异常。由于是集群另一台activemq正常,因此本台服务器本地持久化数据删除问题不大。删除所有data/kahadb/下的文件,正常启动。

扩展阅读:


KahaDB存储配置

在 conf/activemq.xml 中配置如下:

<broker brokerName=”broker” … >
<persistenceAdapter>
<kahaDB directory=”activemq-data” journalMaxFileLength=”32mb”/>
</persistenceAdapter>

</broker>

<persistenceAdapter>中指定了kahaDB,并表明数据存储在 “activemq-data”目录下,日志文件最大长度是32MB。

比如一个实际的ActiveMQ的KahaDB存储方式下的数据目录如下:

可以看出,上面directory一共有四个文件:

#db-*.log:

存放完整的每条消息(包括事务、目的地、id、优先级、具体内容等)和producerSequenceIdTracker(用来验证每个消息生成者发送的消息是否重复的数据结构)。它随着消息数量的增多,如每32M一个文件,文件名按照数字进行编号,如db-1.log、db-2.log、db-3.log …

#db.data

通过存放多个Btree数据结构来保存各类重要信息,下面一一进行介绍:

n Metadata类的destinations:用来保存该broker上有哪些Queue或队列

n StoredDestination类的orderIndex属性中的

defaultPriorityIndex、lowPriorityIndex、highPriorityIndex,这3个btree是为消息优先级排序而设计的(应该是版本5.4引入的,唉,有时候一个功能的引入带来的代价可能比较大)。它们的主要作用是为AbstractStoreCursor类的doFillBatch方法服务的,也就是常说的消息指针(message cursors)。当消息指针需要从磁盘文件中装载一批消息的时候会使用这3个btree实例(kahadb版本小于2的不支持lowPriorityIndex、highPriorityIndex)

n StoredDestination类的locationIndex:该btree的主要作用包括:

. 系统重启进行恢复操作的时候,要移除掉不在db-*.log文件里的消息;

. 在系统进行定时checkpointUpdate时使用

n StoredDestination类的messageIdIndex:该btree的主要作用是消息确认acknowledge操作时,通过消息ID在messageIdIndex中删除对应的记录,并依据返回的值删除orderIndex和locationIndex中的记录

上面这些就是kahadb中最主用的btree实例。

#db.redo

它的作用是“Double Write”,具体代码参看PageFile类的writeBatch方法。它的原理可参考(http://www.mysqlperformanceblog.com/2006/08/04/innodb-double-write/)

#db.free

当前db.data文件里哪些页面是空闲的,文件具体内容是所有空闲页的ID

下面是具体每个文件的内部数据格式:ActiveMQ:java.io.IOException: Failed to recover data at position:2 ActiveMQ:java.io.IOException: Failed to recover data at position:2 ActiveMQ:java.io.IOException: Failed to recover data at position:2

另外,一些关于KahaDB的配置选项如下:

1)indexWriteBatchSize  默认值1000,当Metadata Cache中更新的索引到达了1000时,才同步到磁盘上的Metadata Store中。不是每次更新都写磁盘,而是批量更新写磁盘,比较写磁盘的代价是很大的。

2)indexCacheSize      默认值10000,(number of index pages cached in memory),在内存中最多分配多个页面来缓存index。缓存的index越多,命中的概率就越大,检索的效率就越高。

3)journalMaxFileLength  默认值32MB,当存储的消息达到32MB时,新建一个新文件来保存消息。这个配置对生产者或消息者的速率有影响。比如,生产者速率很快而消费者速率很慢时,将它配置得大一点比较好。

4)enableJournalDiskSyncs  默认值true,默认采用同步写磁盘,即消息先存储到磁盘中再向Producer返回ACK

normally,the broker performs a disk sync(ensuring that a message has been physically written to disk)
before sending the ACK back to a producer

5)cleanupInterval  默认值30000ms,当消息被消息者成功消费之后,Broker就可以将消息删除了。

6)checkpointInterval  默认值5s,每隔5s将内存中的Index(Metadata Cache)更新到磁盘的Index文件中(Metadata Store)

原创文章,作者:shengbao,如若转载,请注明出处:https://baogebiji.com/444.html

发表评论

电子邮件地址不会被公开。