事务回滚 缓存处理_极端事务处理模式:后写缓存

本文探讨了后写缓存如何通过异步批处理更新降低数据库负载,提高性能,适用于高并发事务处理场景。后写缓存减少了数据库调用,改善响应时间,并在数据库故障时保护应用程序。通过WebSphere eXtreme Scale的示例,展示了如何配置和使用后写功能以应对门户个性化等业务案例。
摘要由CSDN通过智能技术生成

事务回滚 缓存处理

介绍

应用程序通常使用数据缓存来提高性能,尤其是在应用程序主要使用只读事务的情况下。 这些应用程序直接更新数据库以更改数据。 这里的问题是,随着负载增加,这些更新的响应时间也会增加。 数据库不擅长执行大量并发事务,每个事务的记录数很少。 数据库在执行批处理事务方面要好得多。

最终,数据库将使CPU或磁盘饱和,并且此时响应时间将随着增加的额外负载而增加。 常规的内存中高速缓存还仅限于仅存储可容纳在JVM的空闲内存中的内容。 一旦我们需要缓存的数据量超过此数据量,就会在缓存连续逐出数据以为其他数据腾出空间的情况下发生崩溃。 然后必须连续读取所需的记录,从而使缓存无效,并使数据库承受全部读取负载。

当前有几种产品可用,包括IBM®WebSphere®eXtreme Scale,Oracle Coherence和Gigaspaces,这些产品允许将JVM集群的所有可用内存用作缓存,而不仅仅是单个JVM的可用内存。 这样,可以在合并更多JVM时扩展缓存的容量。 如果这些JVM位于具有CPU,内存和网络的其他物理服务器上,则可以对读取请求进行可扩展的服务。 他们还可以利用其后写技术为升级请求提供可扩展的服务。 后写缓存的可伸缩性使其非常适合处理极端事务处理(XTP)方案。 XTP被Gartner定义为“一种旨在支持分布式TP应用程序的设计,开发,部署,管理和维护的应用程序样式,其特征是对性能,可伸缩性,可用性,安全性,可管理性和可靠性的要求特别高。”(1)

在本文中,我们将说明如何通过使用IBM WebSphere eXtreme Scale的后写模式和示例来优化应用程序的性能。 后写功能在用户可配置的时间间隔内将批处理更新异步批处理到后端数据库。 这种情况的明显优势是减少了数据库调用,因此减少了事务负载并加快了对网格中对象的访问。 这种情况下的响应时间也比直写式缓存方案快,后者通过对缓存进行更新可以立即对数据库进行更新。 在“后写”情况下,事务不再需要等待数据库写操作完成。 此外,它可以保护应用程序免受数据库故障的影响,因为后写缓冲区将通过内存复制保留更改,直到可以将更改传播到数据库为止。

定义和配置关键概念

什么是“后写”缓存?

在后写式高速缓存中,数据读取和更新均由高速缓存提供服务,但是与直写式高速缓存不同,更新不会立即传播到数据存储中。 而是在缓存中进行更新,缓存跟踪脏记录列表,并定期将当前的脏记录集刷新到数据存储中。 作为一项额外的性能改进,缓存会对这些脏记录进行合并。 合并表示如果同一记录在缓冲期内被多次更新或弄脏,则仅保留最后一次更新。 在价值变化非常频繁的情况下(例如金融市场中的股票价格),这可以显着提高性能。 如果股票价格每秒变化100次,则通常意味着每30秒对加载程序进行30 x 100次更新。 合并将其减少为一个更新。

使用WebSphere eXtreme Scale,可复制脏记录的列表以确保其在JVM退出时仍然存在,并且客户可以通过设置同步和异步副本的数量来指定复制级别。 同步复制意味着在JVM退出时不会丢失任何数据,但是它会慢一些,因为主复制必须等待副本确认它们已收到更改。 异步复制要快得多,但是如果JVM在复制之前退出,则最新事务的更改可能会丢失。 使用大批量事务将脏记录列表写入数据源。 如果数据源不可用,则网格将继续处理请求,并将稍后再试。 网格在扩展更改时可以减少响应时间,因为更改仅提交给网格,并且即使数据库关闭也可以提交事务

后写高速缓存可能并不适合所有情况。 后写的性质意味着,一段时间以来,用户认为已提交的更改不会反映在数据库中。 该时间延迟称为“缓存写延迟”或“数据库陈旧”; 数据库更改和要更新(或无效)以反映这些更改的缓存之间的延迟称为“缓存读取延迟”或“缓存陈旧”。 如果系统的所有部分都通过高速缓存(例如,通过公共接口)访问数据,则后写将是可以接受的,因为高速缓存将始终具有正确的最新记录。 期望对于使用后写的系统,所有更改都是通过缓存而不是通过其他路径进行的。

稀疏缓存或完整缓存都可以与后写功能一起使用。 稀疏缓存仅存储数据的子集,并且可以延迟填充。 稀疏缓存通常使用键来访问,因为并非所有数据都可以在缓存中使用,因此无法使用缓存进行查询。 完整的缓存包含所有数据,但最初可能需要很长时间才能加载。 可以使用第三种方法,这是这两个选项之间的折衷方案。 它在短时间内将数据的子集预加载到缓存中,然后延迟加载其余数据。 预加载的子集大约占记录总数的20%,但可以满足80%的请求。

以这种方式使用缓存的应用程序通常仅用于使用简单的CRUD(创建,读取,更新和删除)模式访问可分区数据模型的方案。

配置后写功能

通过将writeBehind属性添加到backingMap元素,在objectgrid.xml配置中启用了write-behind函数(在WebSphere eXtreme Scale的情况下),如下所示。 该参数的值使用语法““ [T(time)] [;] [C(count)]”,该语法指定何时进行数据库更新。 当以秒为单位的指定时间过去或队列映射中的更改数达到计数值时,更新将被写入持久性存储。

清单1.后写配置示例

<objectGrid name="UserGrid">

<backingMap name="Map" pluginCollectionRef="User" lockStrategy="PESSIMISTIC" writeBehind="T180;C1000"/>

JPA加载器

WebSphere eXtreme Scale使用加载程序从内存缓存中读取数据并将数据写入数据库。 从WebSphere eXtreme Scale 6.1.0.3开始,有两个与JPA提供程序进行交互以将关系数据映射到ObjectGrid映射的内置加载器,即JPALoader和JPAEntityLoader。 JPALoader用于存储POJO的缓存,而JPAEntityLoader用于存储ObjectGrid实体的缓存。

要配置JPA加载程序,必须对objectgrid.xml进行更改,并且必须将persistence.xml文件添加到META-INF目录。 加载程序bean和必要的实体类名称一起添加到了objectgrid.xml中。 必须在objectgrid.xml中定义一个事务回调,以接收事务提交或回滚事件并将其发送到JPA层。 persistence.xml文件表示持久性单元的特定JPA提供程序以及提供程序特定的属性。

探索示例业务案例

一个拥有越来越多用户的在线银行网站正在经历较慢的响应时间以及其环境的可伸缩性问题。 他们需要一种通过现有硬件支持其客户的方法。 接下来,我们将引导您完成该用例,以了解后写功能如何帮助解决他们的问题。

用例:门户个性化

他们将直接从数据库中提取配置文件,而不是直接从数据库中提取用户配置文件信息。 这意味着缓存可以为读取请求而不是数据库提供服务。 配置文件更新也直接写入旧系统中的数据库。 由于数据库计算机将饱和,因此这限制了每秒的并发更新数和可接受的响应时间。 新系统将概要文件更改写入网格,然后使用后写技术将这些更改推送到数据库。 这使网格能够以通常的网格服务质量和性能为它们提供服务,并且将单个实例数据库与读取和写入配置文件操作完全分离。 现在,客户只需将更多的JVM /服务器添加到网格即可扩展配置文件服务。 由于不再有发送到后端的事务,因此数据库不再是瓶颈。 更快的响应导致更快的页面加载,并导致更好的用户体验以及概要文件服务器的经济高效扩展和更高的可用性,因为数据库不再是单点故障。

在这种情况下,我们将WebSphere eXtreme Scale与DB2Ò数据库和OpenJPA提供程序一起使用。 此方案的数据模型是一个User,其中包含一对多的UserAccount和UserTransaction。 User类的以下代码片段显示了这种关系:

清单2:用例实体关系

@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = { Cas-cadeType.ALL })

private Set<UserAccount> accounts = new HashSet<UserAccount>();


    
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = { Cas-cadeType.ALL })

private Set<UserTransaction> transactions = new HashSet<UserTransaction>();
1.填充数据库

示例代码包含类PopulateDB,该类将一些用户数据加载到数据库中。 在前面显示的persistence.xml中定义了DB2数据库连接信息。 persistence.xml中列出的持久性单元名称用于创建JPA EntityManagerFactory。 创建用户对象,然后将其分批保存到数据库。

2.热缓存

加载数据库后,将使用数据网格代理预加载缓存。 记录将批量写入缓存,因此客户端和服务器之间的行程减少了。 还应使用多个客户端来加快预热时间。 可以使用“热”数据集对缓存进行预热,这是所有记录的子集,其余数据将被延迟加载。 预加载缓存会增加缓存命中的机会,并减少从后端层检索数据的需求。 对于此示例,与数据库记录匹配的数据被插入到缓存中,而不是从数据库中加载以加快执行时间。

3.产生电网负载

该示例代码包括一个客户端驱动程序,该驱动程序模仿了网格上的操作,以演示后写缓存功能如何提高性能。 客户端有几个选项可以调整负载行为。 以下命令将使用10个线程将500K条记录加载到“ UserGrid”网格中,每个线程200个请求。

$JAVA_HOME/bin/java -Xms1024M -Xmx1024M -verbose:gc -classpath
$TEST_CLASSPATH ogdriver.ClientDriver -m Map -n 500000 -g UserGrid -nt 10 -r
200 -c $CATALOG_1
4.结果

使用后写功能可以提高性能。 我们使用直写式和后写式运行示例代码,以比较响应时间和数据库CPU利用率。 将数据插入与数据库中的记录匹配的缓存中,以避免预热时间并产生一致的读取响应时间,因此我们可以比较写入响应时间。 清单3显示了直写方案的响应时间,其中读取花费不到10 ms,而写入花费大约450-550 ms。 额外的网络跃点和磁盘I / O为事务增加了大量时间。 清单4显示了所有事务都提交到网格的后写方案的响应时间。 如图所示,这将导致相似的读写响应时间,其中两种操作都需要2.5-5 ms。 这两个图表说明了直写方案如何导致更新的响应时间更长,而后写方案的更新时间与读取的几乎相同。 可以添加更多的JVM以增加缓存的容量,而无需更改响应时间,因为数据库不再存在瓶颈。

清单3:直写式缓存方案的响应时间图

清单4:后写高速缓存场景的响应时间图

数据库CPU使用率图表说明了使用后写式时后端负载的改进。 清单5是带有直写用例的数据库CPU使用率图表。 您可以看到在整个运行过程中,CPU使用率是连续的,所有更新都将立即写入数据库。 使用时,CPU在4%到10-12%的空闲状态之间振荡。 后面写的情况不会像后端那样像在直写情况下那样在后端保持恒定的负载,而是导致仅在达到缓冲区间隔时才在后端提供较低的CPU负载,如清单6所示。该图显示出数据库在4%的CPU上处于相当空闲的状态,直到达到三分钟的间隔或更改计数,然后在将批处理的更改写入磁盘时,CPU使用率在短时间内增加到12-16%。 在写事务的比率,相同的记录更新频率和数据库更新延迟方面,应调整后写配置,使其与您的环境最匹配。

清单5:直写式高速缓存方案的数据库CPU使用率图表

清单6:后写高速缓存方案的数据库CPU使用率图表

结论

本文回顾了写后缓存方案,并展示了如何使用WebSphere eXtreme Scale实现此功能。 后写高速缓存功能可减少后端负载,减少事务响应时间,并使应用程序与后端故障隔离。 这些好处及其简单的配置使后写缓存成为真正强大的功能。

参考资料

1. Gartner集团的Gartner RAS核心研究说明G00131036- http: //www.gartner.com/

2. WebSphere eXtreme Scale用户指南

3. WebSphere eXtreme Scale Wiki

资源资源

1. WebSphere eXtreme Scale免费试用版下载

2. Amazon Elastic Compute Cloud(EC2上的WebSphere eXtreme Scale V7.0

致谢

感谢Billy Newport,Jian Tang,Thuc Nguyen,Tom Alcott和Art Jolin对本文的帮助。

翻译自: https://www.infoq.com/articles/write-behind-caching/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

事务回滚 缓存处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值