最近做一个比较大的电子商务项目,预计每天订单量将在5万多单,客服人员需要频繁的下单、查询订单、操作订单,客人预订完订单后,会立即进入处理流程,为了提高服务质量,要求流水化作业,平均要在40分钟-80分钟内处理完订单,对于疑难订单要到第二天,才能处理完。所以订单在创建后,会在短时间内,被频繁的修改和查看。
由于在项目中ORM层主要是基于Hibernate框架,所以在调优时,很自然的就想到打开Hibernate的二级缓存,以次来减小由于Load 订单大对象时N+1次查询给数据造成的压力,自己做的测试效果也非常好,也顺利通过压力测试。
但在上线时,性能却并不佳,经过分析业务的操作特点,查找原因有以下几占:,
1.但由于中台每天在工作当中,频繁的批量分配工单,
因为要批量将订单分配给某一个工作人员处理,在代码当中执行了一个bulkUpdate的操作:
template.bulkUpdate("update order set owner = ? where id in (?, ?,?)");
这时Hibernate会直接将Order对象的二级缓存清楚掉。
由于二级缓存,总是被刷掉,再查询时,需要重新从数据库Load,所以二级缓存变相直接起的作用很少。
2.由于工作人员在处理订单时,每一次查看之后,都有更新操作,在更新之后,订单被清除缓存,下一组人在处理订单时,又得重新LOAD,所以效果并不好。
3.无论是白盒测试,还是压力测试时,所基于的案例太过于简单,没有更深入的模仿业务操作,对于压力测试的脚本,也很难精确的模拟出真实的流程化的业务操作过程。
开始想到,直接获得Session,直接使用JDBC来编写更新代码,并在更新后,使用sessionFactory.evict(Order.class, id);来有目标的逐个清除特定的对象,以避免全部清楚缓存。
但样做,会对DAO层,修改过大。
由于整个模块最核心的商业对象就是订单,最后决定在Service层对订单开小灶,对订单缓存的单独的定制处理。
我觉得应用缓存存在以下优点:
1。速度要快于ORM缓存,
2。对于缓存的控制权更大,可以直接控制缓存工具的API进行操作,可以避免一些盲目清除的操作。
3。更灵活的控制缓存中对象的失效,如根据事件来清除缓存,如订单的处理流程结束时,将该订单从缓存中清除掉,
4。在更新数据库时,不是直接清除缓存,而是更新缓存(尽管这有风险),当业务层抛出异常时,才去清空缓存,避免由于频繁更新,而清空缓存。
缺点:
1。订单的更新操作,必须是单点的,只能通过IOrderService提供的接口,进行更新操作,否则数据不一致的风险较大。
2。想要透明化,需要有一定的代码工作量,不容易达到ORM缓存最强大的那种透明化和灵活可配置,你可以使用Ehcache, 也可以选Jboss,有钱的话,可以用Tangosol。
3。如果不对第三方缓存包,进行一定的封装的话,会直接耦合于第三方的缓存包,不能像Hibernate那样,灵活选择和配置缓存工具。
4。对业务层代码有一定的侵入
目前的方案是采用应用层的现代化,同时使用如Proxy模式来提供透明化的设计,
IOrderService -》 OrderService -》 CacheableOrderService
通过Spring的Bean配置,一样可以实现透明化的操作。
结论:
1。缓存的清空与更新,要尽量精确的去操作受到更新影响的对象,而不是全部搞掉。
在Hibernate当中,也提供了sessionFactory.evict(class, id)这样细粒度的清空缓存对象的方法。
sessionFactory.evice(class)的操作,要看这样的操作是否频繁,如果频繁,对于缓存的作用就会大大的折扣。
2。如果缓存对象过多,对于失效的算法与处理,要与业务对象的特性紧密的联合起来,通过事件来驱动对象的失效。
3。对于商业对象的缓存,必须要深刻分析对象的生命周期,业务特性。
4。对于数据不一致的风险,要有足够的认识与预防手段。
5。合理的估计订单对象的大小,分配足够的内存
6。如果只使用中心缓存,只能减小数据库的压力,对于网络带宽的压力,还是有的,速度上也远远逊于本地缓存的效果,所以要结合本地缓存+中心缓存的策略方案,即提高速度,避免群集复制时的瓶颈。
分享到:
相关推荐
Hibernate 是一个流行的对象关系映射(ORM)框架,它提供了数据缓存机制以优化数据库访问性能。缓存机制分为一级缓存和二级缓存,两者都有助于减少对物理数据库的直接访问,从而提高应用程序的运行效率。 一级缓存...
一级缓存是ORM框架(如Hibernate)自身提供的缓存,它存储了最近查询的数据,减少了对数据库的直接访问,提高了性能。而二级缓存则是在一级缓存之外的全局共享缓存,它可以跨会话、跨应用地共享数据,进一步优化系统...
ORM,全称Object-Relational Mapping,即对象关系映射,是一种编程技术,用于将关系数据库的数据模型映射到面向对象的软件应用中。在Java领域,Hibernate和MyBatis是两种广泛应用的ORM框架,它们极大地简化了数据库...
二级缓存是ORM框架(如Hibernate)中的一个重要特性,它可以在数据库和应用程序之间存储经常访问的数据,以减少对数据库的直接访问,从而提高性能。通常,一级缓存由Hibernate Session管理,而二级缓存则可以跨越多...
Hibernate的缓存机制分为两层:第一级缓存(Session缓存)和第二级缓存(SessionFactory缓存)。这两种缓存分别服务于不同的应用场景和目的。 ##### 1. 第一级缓存(Session缓存) - **定义**:第一级缓存是在`...
**1.6 本地缓存VS远程缓存** - **Local Cache (本地缓存)**:应用程序与缓存位于同一进程中,无需网络通信,响应速度快。 - **Remote Cache (远程缓存)**:不同应用程序间共享缓存,但需要网络通信,增加了延时。 ...
通过Coherence Hibernate连接器,开发者可以实现透明的缓存层,提升应用程序的响应速度。 六、JMX管理和监控 Java Management Extensions (JMX) 提供了管理和监控Coherence集群的能力。通过JMX,管理员可以监控缓存...
9. **自定义扩展**:如果项目有特殊需求,学习如何扩展Moon.Orm,如创建自定义的数据访问层、自定义日志记录等。 总之,Moon.Orm是一个强大的ORM框架,通过它可以极大地提升.NET开发者的数据库操作效率,减少与...
7. **缓存机制**:探讨ORM框架中的缓存技术,MyBatis的一级缓存和二级缓存的原理及配置,以及如何优化缓存策略。 8. **性能优化**:分析ORM框架可能带来的性能问题,比如N+1查询问题,以及相应的优化措施,如批处理...
当涉及到高性能、大数据量的应用时,合理利用缓存机制可以显著提升系统性能。本文将详细探讨如何在Spring集成的Hibernate环境中配置二级缓存,以及其背后的原理和实践。 首先,我们需要了解什么是二级缓存。在...
2. **持久层缓存**:ORM框架如Hibernate提供了1级和2级缓存,1级缓存是Session级别的,2级缓存则是SessionFactory级别的。 3. **业务层缓存**:虽然较少直接设置,但在大型系统中,业务逻辑缓存能有效减少数据库交互...
二级缓存是在多个Session之间共享的缓存层,主要用于跨会话的数据共享,可以显著提高数据密集型应用的性能。与一级缓存相比,二级缓存具有更广泛的适用范围和更高的定制化能力,但同时也引入了更多的配置和管理...
3. **应用框架集成的缓存**:例如`Spring Cache`,它提供了一种抽象层,可以将缓存逻辑注入到Spring管理的bean中,支持多种底层缓存实现,如Ehcache、Guava等。 接下来,我们关注几个关键的Java缓存库: - **...
这个标题表明我们将探讨一个具体的应用示例,即如何在Hibernate4框架中实现实现二级缓存,并且提供了源码供参考。Hibernate是一个流行的Java对象关系映射(ORM)框架,它允许开发者使用面向对象的方式来操作数据库。...
在实际开发中,理解并熟练运用这些核心概念和机制,可以帮助我们更高效地利用Hibernate ORM进行数据访问层的设计,减少数据库操作的复杂性,提高代码的可维护性。对于初学者,建议从简单的JAR包开始,逐步熟悉其API...
4. **Spring Cache**:Spring框架提供的抽象缓存层,允许开发者使用任何兼容的缓存提供者,如Gemfire、Ehcache、Hazelcast或Redis。 5. **Guava Cache**:Google Guava库提供的本地缓存解决方案,适用于简单的内存...
在Android开发中,ORM框架可以帮助我们简化数据访问层的代码,提高开发效率。常见的Android ORM框架有SQLiteOpenHelper、GreenDao、ORMLite等。 本示例中提到的ORM可能是指使用了某个特定的ORM库,但没有具体指出是...
在这个特定的案例中,我们讨论的是一个结合了消息缓存和自动重传功能的基于ORM框架的电商系统,它在电子政务场景下应用,提升了服务效率和可靠性。ORM,即对象关系映射(Object-Relational Mapping),是一种编程...