当前位置: 查字典论文网 >> 消息中间件持久化研究

消息中间件持久化研究

格式:DOC 上传日期:2022-07-24 00:30:19
消息中间件持久化研究
时间:2022-07-24 00:30:19     小编:

摘 要:本文从消息中间件的定义、基本体系结构入手,介绍消息中间件持久化的意义,着重提出了几种持久化的解决方案,同时分析了这几种解决方案各自适用的场景和性能。

关键词:消息中间件;持久化;高可用;容错

中图分类号:TN915

1 消息中间件概述

中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的。消息中间件也称消息服务,是一种由消息传送机制或消息队列模式组成的中间件技术,利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。一个典型的消息中间件体系结构如图1所示。

图1 消息中间件体系结构

根据JMS规范定义,消息中间件应提供可选择的消息在服务器端的可靠性级别,即持久化消息和非持久化消息,持久化消息指消息在服务器端存储后转发,当服务器发生故障或者正常退出后,能够在重启后恢复现场。此外在用户对主题进行持续订阅的应用场景下,如果不支持对消息的持久化存储,订阅者就不能收到它在不活动状态下,发布者发布到主题的消息。当然,持久化消息对消息中间件服务器的性能有一定影响。主要目的是为了满足消息中间件的高可用。

消息持久化存储的原理很简单,就是在消息的发布者将消息发布到服务器端时,先将消息存储到本地文件、数据库或者分布式文件系统等,然后再试图将消息转发给相应的接收者,并且更新该消息状态。直到所有订阅者都收到消息后将消息从存储中删除,并且由图1所知,消息服务运行过程中,只有持久化的数据需要存储到磁盘等持久化设备上,所以持久化方案是消息中间件转发消息的性能瓶颈,决定了消息中间件的吞吐量。

2 基于文件的消息持久化方法

2.1 存储模型

层次模型,基于文件的消息持久化存储模型采用的是层级结构,逻辑结构上分为应用程序访问接口、文件存储层来实现。

图2 文件持久化存储模型

持久化访问接口的设计是期望通过消息中间件业务逻辑与持久化逻辑实现分离,通过模块化、松耦合的方式降低软件设计实现以及维护的复杂性,有助于明确各模块的具体功能,明确职责以帮助实现更加健壮的持久化模块。程序访问接口的实现,参照hibernate的设计概念,实现结构化数据到关系对象的映射,在消息中间件的主题与队列,存储-转发消息的业务逻辑中,软件操作的是结构化的数据,当消息持久化到磁盘上时,是经过序列化的有key-value关系的data node,如果直接通过业务逻辑对消息持久化的文件进行操作,一方面是文件操作与业务操作耦合太过紧密,逻辑太过复杂,不易实现;另一方面,软件的实现不可能一簇而就,如果采用这种方式,在软件面临修改的时候,很容易造成从头再来的情况,软件重用率太低;此外,这样实现容易造成业务逻辑与文件操作无法分离,出现问题无法定位,软件不够健壮。

文件存储层居于操作系统与消息中间件中间,对下调用操作系统文件接口实现文件操作,对上将机构化的数据抽象并解析序列化为块状的datanode。文件存储层的实现分为数据文件和索引文件,对于消息中间件的业务逻辑来说,需要持久化的数据项粗略分为索引和消息,索引数据用以区分消息中间件的容器,订阅等,管理消息在服务器端存在的生命周期以及查找消息的位置。分别通过Index Manager和MsgData Manager管理。

2.2 性能

消息中间件基于文件的持久化方法的优势在于,由于是直接操作文件,所以能够提供消息中间件较高的可用性的同时提供较高的性能,经测试此种数据库持久化方式在服务器端吞吐率能达到每秒8200条左右。(本文测试使用的软硬件环境如下:硬件配置:Intel(R) Core(TM) 2 Duo CPU E8400 @ 3.00GHz,单核,内存4GB。硬盘转速7200转。操作系统:Microsoft windows XP professor sp3。)

2.3 可能面临的问题

直接操作文件可能面临的问题主要包括两个,一方面,消息中间件转发的消息以及对应的索引非定长数据,因此,在持续读写文件后,可能会造成文件碎片,文件不可继续使用的情况;另一个问题为,直接操作文件,如果没有设计文件锁的保护,一旦在读写文件的时候发生断电等意外情况,有可能导致消息文件发生了数据异常或其中存储的数据出现不一致,甚至于文件失效打不开的情况,此时该消息文件将被作废,该文件记录的信息也不可恢复,持久化以提供消息中间件的初衷则得不到满足。

可以通过一定策略一定程度的避免第一个问题:在服务器上同时持有几个备用文件,写满一个后换新文件,如果该文件所记录的所有消息都被取走,则弃用此文件并替换为新文件,这样不存在文件碎片以及索引管理的问题,消息从前往后存储,按照文件偏移量有序取出。对于第二个问题,较简单的方法是在应用中增加文件锁,一次消息存取的操作没有完全执行完,不更新到磁盘等存储设备。可以解决部分问题,但并不能解决将来数据不一致的情况(消息已被取走但未更新索引,导致无意义的重发,消息仍然丢失)。

3 基于文件数据库的持久化方法

3.1 存储模型

与基于文件持久化方法相同,基于数据库的持久化操作也是层级模型,同样由持久化访问接口与数据库访问层组成,可以利用良好的设计将持久化访问接口抽象成一组接口,将来可以作为规范,用于将消息中间件业务处理逻辑与持久化逻辑分离,同时提供多个版本的持久化方法支持不同的应用场景,理想情况下甚至可以由用户的选择进行切换。以下是作者提出的一组接口:

AddPersistMsg(Message msg);

QueryPersistMsg(MsgID id); updatePersistMsg(MsgId id,BodyValue value);

DeletePersistMsg(MsgId id);

数据库访问层则是将文件数据库API封装,将结构化的索引和消息存储到对应数据库表格中,封装为Save,Update,Query,Delete等操作,避免程序直接通过SQL语句对数据库进行访问,仍是为了程序的健壮和可维护性。基于文件数据库的持久化方法关键在于数据库设计,即如何组织索引与消息的表结构,能够支持尽量高的访问性能,这里采用将存储索引的表作为主表,存储消息的表作为子表,通过唯一消息标识作为关联主键的模式,具体方式如图3。

图3 基于数据库的存储模型

3.2 性能

业界有很多性能非常优秀的文件数据库,这些数据库实现的方式不尽相同,性能也千差万别,但在消息持久化的场景下,我们最需要的是数据库能否提供事务保护(能够保持数据一致性),同时性能较好,满足条件的有Berkeley DB(需要复杂配置)、Sqlite DB、Berkeley DB(已不更新),这里采用的文件数据库为Sqlite3,Sqlite3在的机器上能够达到每秒数万次到十万次的访存效率,并且Sqlte3支持事务保护,内部分为5级文件锁,可以保证不会出现写数据库出现数据失效的情况。

3.3 可能面临的问题

Sqlite3的性能与使用模式相关,在开启同一个事务的情况下性能最高,可达每秒十万条,如果在要求绝对实时的使用模式下,相当于每条数据库操作当作一个事务,每秒只能操作到160条消息存储,究其原因在于sqlite3提供的5级文件锁导致每次事务提交要进行4次IO操作,因此数据库性能被每秒能操作的事务限制,机器性能越高(主要依赖于硬盘转速),能操作的事务越多,但不会有太大提高,数据的可靠性需要牺牲时间保证。如果不是要求绝对实时的情况下,可以通过一定机制解决这个问题,作者采用时间+消息条数双重判定的方式来开启,提交事务,服务器每收到n条消息或者m秒内未收到n条消息,就将缓存中的这些消息和索引持久化到数据库,如果没达到提交条件,就将收到的消息存储到临时文件上,能最高程度的满足实时性和性能的要求。如果要求绝对实时的情况,以上的设计仍不能满足要求(临时文件的消息可能丢失),鉴于Sqlite3性能低下的原因是逐条提交事务,而Sqlite3为开源软件,研究其源代码发现,在开启事务的情况下,Sqlite3性能较高,但是在此次事务提交之前如果断电,此次事务会自动回滚,因此,对事务处理进行优化,去除不必要的文件同步及互斥操作,则可支持完全实时并且可以达到接近每秒万条的性能,缺点为可能仍有极低的概率出现文件不可读的异常情况。

4 基于分布式系统的消息持久化方法

消息中间件的持久化主要目的是为了保证消息在服务器上转发时的可靠性,尽量不要丢失消息,即使因为某种原因停机也能通过持久化的消息及索引信息将停机前一瞬间的场景恢复,在此基础上能够保证尽量高的吞吐率。从这个角度来看,上面提出的持久化方法,在性能和可靠性上均有瑕疵。性能的瓶颈主要在于单机的存储设备性能有限制(如硬盘转速有上限),单机的存储设备无法满足不断增长的数据需求,考虑到高并发的访问场景下,单机的消息中间件服务器由于操作系统限制,能够同时响应的访问请求也受到限制,这里作者提出一个新的解决方案,通过多个服务器的集群来提高消息中间件服务器的并发响应能力,依靠多服务器的冗余备份保证消息的可靠存储转发。

4.1 存储模型

图4 基于分布式系统的存储模型

Client(消息服务用户)访问管理节点,查询索引表获知需要访问的数据位于哪个数据节点机器上,到数据节点机器上获取消息。Index Node(管理节点)与Data Node(数据节点)都可以存储在内存中,因为多机冗余,每份数据均有备份,消息存储在内存中关机也并不会丢失,并且消息持久化的效率可以接近内存操作。

图5 数据在节点上存在形式

图6 数据访问模式

冗余管理节点多份备份,管理多个数据节点,管理节点存储索引表,数据节点存储数据块,服务器集群一共处理的容器按照现有的数据节点个数,通过哈希计算的方式,确定存储在哪个数据节点上,数据节点直接也有冗余备份,数据在节点间的冗余备份由以下方式实现:其中管理节点之间,定时通信将索引表备份,保持管理节点之间索引一致;管理节点上持续运行管理线程,专门管理数据的冗余备份,即在一个数据节点上增加一条数据,一定会在另外两个数据节点上同时添加两份备份,在管理节点上记录三份数据时始终指定一份为主数据;消息服务用户访问时取主数据进行操作,通过数据备份线程定时备份保证备份数据与主数据之间的一致性,依次保证备份数据操作不会降低服务器吞吐率;每个数据节点按时向数据节点发送保活命令,表明该节点仍然处于工作状态,一旦某个数据节点发生异常,管理节点可即时获知,调用管理线程将该节点上存储的数据备份到其他机器上,始终保持数据节点上存在三份数据备份。 当有消息服务用户登录服务器端请求数据处理时,管理节点记录该节点用户名,以及想要访问的数据块,当同名用户想要访问相同数据块时,每次数据请求在管理节点之间加互斥锁进行限制访问,如果访问不同数据块则无此限制。

管理节点维持一个管理节点索引和一个数据节点索引,分别记录当前活动管理节点和当前活动数据节点和数据块对应关系,当有新节点加入,新节点向当前局域网广播保活命令,管理节点受到此命令后会将该节点加入对应索引表,备份线程按照索引表将该节点应该备份的数据进行备份操作。当管理节点失效,其他管理节点侦知后,将该管理节点从索引表中删除,如果数据节点失效,则通过查询数据节点索引表将该节点的数据备份到另外的节点上,之后将该节点从数据节点索引中删除。

4.2 性能分析

上述描述的基于分布式系统的消息持久化方法性能与用户使用模式相关,理想情况下,如果多个管理节点均接入消息服务用户进行数据存取操作,且多个消息服务用户操作数据不冲突的情况下,该持久化方式能达到N倍于非持久消息(仅通过内存转发)的吞吐率(N为服务节点个数),最差情况下也能与单机非持久消息吞吐率相当,约为每秒2W条。

4.3 存在的问题

至少需要3+3台计算机组成服务器集群,规模较大,不适合作为轻量级解决方案,另外,为了保持数据一致性,数据备份线程与存取操作对同一个数据块进行操作时会需要同步,因此导致服务器处理数据的吞吐量与数据访问的实时性冲突,即在高并发访问的情况下,数据访问响应时间会比较长,如果为了保证数据能够实时响应,服务处理数据的吞吐量会下降。

5 结束语

本文首先介绍了消息中间件、消息中间件体系结构以及消息中间件持久化对于消息中间件的意义后,详细介绍了三种消息中间件的持久化方案,以应多各种应用场景、用户使用模式的需求。本文提供的持久化方案参照了消息中间件的使用场景、使用模式,以及业界几种与持久化相关的比较流行的开源软件的设计思路,如文件数据库参照和使用了sqlite3,分布式文件系统参照了memcached、Hadoop分布式文件系统。以上介绍的消息中间件的持久化方法,都是适用于各自特定的场景的,每一种持久化方法都各有利弊,在实际应用中应考虑实际情况,选择合适的方式。

参考文献:

[2]Korhonen M.Message Oriented Middleware.Helsinki University of Technology,http://www.tml.hut.fi/Opinnot/Tik-110.551/1997/mqs.htm,1997(08).

[3]Lingel K.Security Requirements for Message-oriented Middleware.http://www.eaijournal.com/PDF/MomSecure.pdf,2001(06).

[4]徐晶,许炜.消息中间件综述[J].计算机工程,2005(08):16-31.

[5]周园春,李淼,张建,李晓欧,张飞.中间件技术概述[J].计算机工程与应用,2002(08).

[6]刘伯睿.海量数据小文件分布式存储系统的设计与实现[D].湖南大学,2013.

[7]王伟娜.分布式存储系统中容错子系统的设计与实现[D].东北大学,2008.

[8]舒敏.分布式数据存储机制与优化方法研究[D].西安电子科技大学,2013.

[9]何润润.网络环境下的分布式存储系统的设计与实现[D].华中科技大学,2011.

全文阅读已结束,如果需要下载本文请点击

下载此文档

相关推荐 更多