在集群环境中对象关系模型缓存一致性设计

2017-09-08 04:41黎子晨
物联网技术 2017年8期
关键词:集群

黎子晨

摘 要:企业开发中常用到对象关系映射,随着技术和业务的发展,应用系统常需要集群部署来减轻每一台服务器的压力。对象关系映射中的缓存技术对于提升性能有较大益处,但在集群环境中常导致缓存不一致,从而影响业务处理的正确性。文中设计了缓存同步的设计方案,试图解决同步问题,为在集群环境中部署使用ORM缓存技术提供借鉴意义。

关键词:对象关系映射;缓存;集群;同步方案

中图分类号:TP393 文献标识码:A 文章编号:2095-1302(2017)08-00-03

0 引 言

随着信息化技术的快速发展,人们依赖于使用软件解决日常工作中碰到的问题。软件的规模随着技术及业务的发展变得越来越庞大和复杂。从过去个人桌面软件的普及,到现在的分布式软件架构,软件系统已经和企业现有的业务模式紧密结合在一起。对于企业级系统,其最为核心的部分是与业务紧密关联的各类数据。在数据存储方面,企业使用最多的还是关系型数据库系统。关系型数据库从数学理论发展而来,和目前主流的软件开发方式,即面向对象的软件开发方式不匹配。对象关系映射(Object Relational Mapping,ORM)技术的出现从很大程度上解决了两者的不匹配问题,即以系统开发程序员的角度来看,数据是面向对象的,而数据依然存储于关系型数据库,即数据逻辑面向对象,物理关系存在于关系模型中。

使用对象关系映射可通过减轻对底层数据库的访问频率来提高系统性能。该性能提升功能通过启用缓存来实现,即数据的获取可以通过缓存而非访问数据库来满足。缓存通常存在于内存中(也可能存在于本地磁盘中),相对于数据库存取数据需要访问磁盘寻找数据,再将数据通过网络传输给请求者,当缓存命中时所带来的性能提升十分明显。依据局部性原理,设置一个合理的缓存将会有一个可观的缓存命中率,可明显提升系统的存取性能。

在ORM中开启缓存存在一个严重的问题,即在集群环境中会产生数据不一致的现象。以B/S模式为例:当一个应用只部署在一个Web站点上时,不存在上述问题;但当该应用采取集群方式部署在多个不同的Web站点上时,极有可能出现相同的对象。在不同站点中存在不同缓存项会导致生产环境中的业务数据出现错误。目前主流的ORM框架均不建议采用集群方式来部署,但随着业务的发展,逐渐增多的业务会对系统产生更大的压力,采用集群方式部署以减小单台设备的压力乃大势所趋。本文通过提出几种设计方案来解决集群部署采用ORM技术系统时存在的缓存不一致问题。

1 集群环境中ORM缓存不一致性分析

在企业应用系统中,目前使用最为广泛的架构为浏览器-服务器架构,即B/S模式[1]。如图1所示,在B/S模式中,客户端使用浏览器,通过HTTP协议访问部署于应用系统的Web服务器[2]。客户向Web服务器请求或提交数据,服务器对客户的访问进行处理,将结果返回给客户,产生的数据存储在数据库中。

当Web服务器中使用了ORM技术后,Web服务器同数据库服务器交换数据的方式将有所变化,如图2所示。Web服务器不再直接通过SQL或存储过程和数据库服务器进行交互,而是将数据对象提交给对象关系映射的框架,该框架再依据系统操作使用SQL或存储过程完成数据存取,将数据存储于数据库或从中获取数据。使用了ORM框架后,为取数方式增添了灵活性,易于开发且具有理想的访问性能[3]。启用ORM缓存,当框架从数据库中成功取数后,获取的数据将会在框架中留有副本,称之为缓存项,所有的缓存项构成了ORM的数据缓存。当进行下一次取数操作时,应用系统向ORM框架提出取数请求,ORM框架首先查找缓存项,试图找出能满足请求的数据对象,并将结果返回给应用系统,如果不存在满足条件的对象则会进行一次数据库访问请求以获取所需数据。根据局部性原理,一个适当大小的缓存能明显提高缓存的命中率,从而减少对数据库的访问,提升系统性能[4]。

以目前最流行的ORM框架Hibernate为例:在Hibernate中,所有的Session都由同一个SessionFactory实例产生。一级缓存的作用范围为Session,二级缓存就是Session.Factory级别的缓存。二级缓存可在不同Session对象间共享,它属于进程范围的缓存。二级缓存可进行配置和更改,并且可以动态加载和卸载。当Hibernate发现缓存中已有该条数据,便会直接使用,而不必去数据库查询,当缓存中没有找到对应项时才会到数据库中查找[5]。

ORM框架使用缓存的方式在单点部署方面不存在任何问题,但在集群环境下部署会产生数据不一致的问题[6]。如图3所示,在一个网络中将若干台客户端及部署了相同应用系统的两台Web服务器作为集群,这两台Web服务器会访问同一个数据库服务器,所有客户端都可以通过浏览器访问Web服务器1或Web服务器2,并完成相同的工作。若两台Web服务器上所受理的业务为只读,则不存在上述问题。如果业务存在读写的情况,当不同客户端通过不同Web服务器读写同一数据时,则极有可能出现不一致的状态。

以银行转账业务为例:存在两个用户Tom和Jerry,当Tom收到来自Jerry的汇款后,Tom打算将自己账户中所有的金钱全部取出。在数据库中存在关系account(id,money)用于存储用户账户的金额,其中id作为主键用于标识用户身份,money用于存储用户帐户的金额,Tom的id为1,Jerry的id为2。表1说明了两个用户的转账取款过程。假设Tom账户余额为300元,Jerry账户余额为400元,Jerry的转账金额为100元。在关系account中存在两个元组,分别存储Tom和Jerry的账户金额。正常情況下,时间1时Tom看到自己的余额为300元,时间3的余额为400元,时间4时将400元从自己的账户中取出。

表2显示了在集群环境中使用ORM缓存后的执行过程,Tom取出的金额为300元,但却不是理想的结果,其问题出现的关键在时间序号2和3,即两个Web服务器中的缓存不一致,没有客观反映现实世界的状态。解决该问题的关键在于如何使数据库和所有启用ORM缓存的应用服务器对于相同的元组反映一致的状态。endprint

2 集群环境中ORM缓存同步方案设计

为解决在集群环境中使用ORM带来的数据不一致问题,主要采取以下几种解决措施:

(1)禁用ORM缓存,使所有数据访问请求都产生一个数据库访问;

(2)采用某种方式使得对于数据库中记录的修改都能够及时反映到所有存储了该记录的ORM缓存中。

第一种方案最简单直接,但会明显降低系统数据存取的性能。对于第二种方案,采用合理的设计方案可以使得在不影响系统性能的前提下使缓存中的数据同步,从而得到一致性的状态。但在开发和部署方面会相对复杂,也可能产生一些新的问题。本文將着重探讨集群环境中的ORM缓存同步方案。

2.1 集中式ORM缓存同步方案设计

通常看来,ORM框架负责ORM缓存的管理工作,即缓存项的创建,更新,读取,删除。ORM缓存和框架运行在同一台服务器中,对缓存的操作都在本地完成。使用集中式ORM缓存同步方案,其基本思路是将ORM缓存和管理与缓存数据的使用分离开来,ORM集群中部署一台专用的计算机用于数据缓存以及对缓存的管理,应用服务器不在本地保存数据的缓存。图4简要说明了该设计方案。所有服务器连接到缓存服务器,缓存服务器再连接到数据库服务器。所有的Web服务器对于数据的请求,都必须经由缓存服务器处理,缓存服务器还起到了代理作用。

对于应用系统数据操作来说(以读取数据为例),Web服务器首先向缓存服务器请求数据,缓存服务器在ORM缓存中执行数据查找,试图找到满足条件的数据项;如果能从缓存中找到满足要求的数据项则返回给提出请求的应用服务器,否则向数据库提交一个数据查询请求,将获取的数据添加到缓存中并交付给提出请求的应用系统。所有应用所看到的数据缓存是一份唯一的副本,完全可以满足一致性要求。与直接访问数据库相比,集中式访问缓存管理只需网络IO,无需访问数据库时产生的磁盘IO,可以明显提升性能。但集中式管理也存在一些问题。

所有应用连接到缓存服务器,当应用系统集群中服务器有较大数量时,必然会对缓存服务器产生极大的负载,缓存服务器可能会成为集群系统的IO瓶颈,从而影响整个系统的性能。缓存服务器也必须保证具有高可用性,该服务器的故障会导致整个集群系统瘫痪。当多个应用同时请求同一数据时,也会存在现在、潜在的不一致风险。为解决上述问题,可在缓存中引入锁的概念。对于每一个缓存数据项的请求都必须加锁。锁分为两种,即共享锁和排他锁。其中共享锁之间相容,排他锁与共享锁,排他锁和排他锁之间不相容[7]。对于缓存数据的请求,必须被授予锁之后才能被满足。只读请求建议申请共享锁,而对数据的修改必须申请排他锁。数据使用完毕后必须要及时释放占有的锁,以便对该缓存项的后续请求予以满足。由于锁的冲突,不同应用服务器对于同一缓存项的大量读写请求也会成为潜在的性能瓶颈,大量的锁请求对于集群中不同的服务器来说可能会造成死锁[8],使系统无法正常运行。由于对缓存项锁的管理由缓存服务器进行,可以采用各种死锁预防和死锁检测及恢复算法进行处理[9]。

2.2 分布式ORM缓存同步方案设计

与集中式ORM缓存同步方案不同,分布式方案不存在一个专门用于管理缓存的服务器。分布式部署方案同图3中的部署方式类似,不同之处在于每台Web服务器之间缓存的同步方式。对于每一台应用服务器而言,其ORM缓存都存储在本地,通过本地管理来满足对缓存的需求,同时缓存管理也可以同时与其他集群中的应用服务器协调以实现缓存同步。缓存同步方案如下所示:

监视数据库元组改动:该方案的基本原理是所有应用服务器监视对数据库的操作。数据库操作分为查询,删除,增加和修改。查询操作不会改动关系中的元组,故不会使ORM缓存数据与数据库中的数据不一致。增加操作虽然会更新数据库的状态,但增加的记录必然只存在于数据库中和执行增加操作的应用服务器缓存中,且两者同步,其他服务器不会缓存该新增数据。修改和删除操作会影响到缓存了该元组的其他应用服务器,导致缓存和数据库中的记录不一致。这时数据库应当通知所有集群中的应用服务器,使该缓存中的数据无效。将数据的改动通知给应用服务器,以Oracle数据库为例,可以使用如下方案,其基本思想用到了观察者模式。观察者模式定义了对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并被自动更新[10]。可以针对Oracle数据库中涉及的表编写触发器,当更新和删除操作发生时通知所有Web服务器,以将涉及修改或删除的元组从缓存中移除。发送通知的消息中可以包含所有涉及元组的主键。Oracle数据库可以挂接Java程序并被PLSQL调用[11],挂接的Java程序通过网络完成后续的消息发送。

更新操作通知所有应用系统:针对系统的修改和删除操作,发起操作的服务器在完成数据库操作后,立即将消息发送给所有集群中的应用系统,收到消息的应用系统从缓存中移除指定的缓存对象,使得缓存中不存在与数据库不一致的对象。该方案与前一方案相比,前者对数据库的负载较小,所有消息的发送路径均建立在应用服务器之间,数据库不参与同步过程。但当应用服务器之间由于网络或安全策略而无法相互通信时,该方案则无法实现同步信息的交互。

2.3 ORM缓存同步方案设计对比

对于系统部署来说,集中式方案需要额外部署一台缓存服务器,且所有数据访问都需经由该服务器来完成,对该服务器压力较大,但便于系统的开发和管理。分布式方案中监视数据库的方案对于数据库服务器会产生额外的负载,使得本来在性能上捉襟见肘的数据库拥有更大的压力,虽然如此,但其却具有良好的可靠性。通知所有系统的方案可以将同步工作分摊到所有应用系统服务器上,但对于网络带宽及稳定性有着较高的要求,由于网络而未收到消息会导致数据出现不一致的可能。

3 结 语

在应用系统集群中使用ORM技术并开启缓存,通过分析缓存不一致现象找出产生该问题的原因。笔者提出了集中式和分布式缓存两种设计方案,试图解决该问题。通过对比各种方案的特点及其适用环境,为实现缓存一致性提供了思路和方法。

参考文献

[1]查修齐,吴荣泉,高元钧. C/S到B/S模式转换的技术研究[J].计算机工程, 2014, 40(1):263-267.

[2]张凤娟,冉宝才,刘丽.基于B_S模式的医院运维管理系统设计与实现[J].医学信息学杂志,2016,37 (7):26-30.

[3]陈正举.基于HIBERNATE的数据库访问优化[J].计算机应用与软件, 2012, 29(7):144-149.

[4]朱保锋, 蔡艳.计算机系统中不同组织方式的Cache性能分析[J].河南教育学院学报(自然科学版), 2012, 21(1):38-39.

[5]曹伟,应君,董黎刚. Hibernate的缓存机制及其应用的研究[J].杭州电子科技大学学报,2013,33(5):158-161.

[6]张吉良, 陈德宗.服务器集群环境下Hibernate使用问题和解决方案[J].科技资讯, 2011(23):14.

[7] Abraham Silberschatz, Henry F.Korth, S.Sudrashan. Database System Concepts[M].New York: McGraw-Hill, 2011: 661.

[8]孙国营.计算机中的死锁问题[J].科技传播, 2010(12).

[9]塔嫩鲍姆.现代操作系统[M].北京:机械工业出版社,2009: 248.

[10] Erich Gamma, Richard Helm, Ralph Johnson, et al.设计模式-可复用面向对象软件的基础[M].北京:机械工业出版社,2012.

[11]全立新.使用Java编写Oracle存储过程[J].计算机时代,2004 (6):35-36.endprint

猜你喜欢
集群
功能性新材料产业集群加速形成
海上小型无人机集群的反制装备需求与应对之策研究
一种无人机集群发射回收装置的控制系统设计
中国空军6月将进行智能无人机集群竞技赛
Python与Spark集群在收费数据分析中的应用
三生打造全生态链健康产业集群
对构建智慧产业集群的几点思考
TD-LTE多业务集群系统无线通信技术及应用
中华医学会医学期刊集群化发展的模式分析
B-TrunC标准成为ITU PPDR宽带集群国际标准