- 浏览: 370230 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (292)
- jbpm3.2 (4)
- hibernate (1)
- struts (2)
- spring (7)
- oracle (20)
- TCP/UDP (3)
- SpringSide (4)
- maven (4)
- eclipse插件 (11)
- 模板引擎 (2)
- javascript (4)
- 设计模式 (2)
- 工作中遇到异常及解决 (3)
- java文件编译问题 (1)
- ehcache应用 (1)
- java反射 (1)
- jbpm4 (1)
- Google-Gson (1)
- Jquery (6)
- XML (5)
- 工作记事 (2)
- flash builder 4 (1)
- Lucene (8)
- struts2 (1)
- AspectJ (1)
- spring proxool连接池配置 (1)
- StringUtils (1)
- spring security (5)
- JAVA点滴 (9)
- jbpm4.3 (1)
- ACL (0)
- 线程 (7)
- Java线程:新特征-线程池 (1)
- MemCache (5)
- compass (0)
- NIO (2)
- zookeeper (4)
- 并发 (2)
- redis (9)
- Nginx (5)
- jvm (1)
- 互联网 (24)
- shell (3)
- CAS (1)
- storm (4)
- 数据结构 (3)
- MYSQL (3)
- fsdfsdfsd (0)
- hadoop (19)
- hive (3)
- IntelliJ (3)
- python (3)
- 23423 (0)
- spark (7)
- netty (9)
- nmon (1)
- hbase (8)
- cassandra (28)
- kafka (2)
- haproxy (3)
- nodejs (3)
- ftp (1)
最新评论
-
记忆无泪:
遇到这个问题我用的sed -i 's/\r$//' /mnt/ ...
CentOS6 Shell脚本/bin/bash^M: bad interpreter错误解决方法 -
alenstudent:
Windows 下Nexus搭建Maven私服 -
dandongsoft:
lucene3+IK分词器 改造 lucene2.x+paoding -
duanyanrui:
学习了,支持
Google-Gson -
yscyfy:
这是你直接翻译过来的???
Google-Gson
OSCache 缓存重建在 Race Condition 下的 NRE 问题
一,现象:
高并发情况下,使用 OSCache 作为本地缓存中间件的前端服务,日志文件中会出现大量如下错误信息:
异常堆栈: |
java.lang.IllegalStateException: Cannot complete cache update - current state (2) is not UPDATE_IN_PROGRESS at com.opensymphony.oscache.base.EntryUpdateState.completeUpdate(EntryUpdateState.java:105) at com.opensymphony.oscache.base.Cache. completeUpdate (Cache.java:762) at com.opensymphony.oscache.base.Cache. putInCache (Cache.java:619) at com.opensymphony.oscache.base.Cache.putInCache(Cache.java:580) at com.opensymphony.oscache.general.GeneralCacheAdministrator.putInCache(GeneralCacheAdministrator.java:249) at com.opensymphony.oscache.general.GeneralCacheAdministrator.putInCache(GeneralCacheAdministrator.java:259) |
二,NRE 背景:
无论你使用哪一种本地缓存中间件,如果你缓存数据片段时设置了过期时间,都需要考虑缓存失效后的缓存重建(repopulate the cache )场景。
进一步必须考虑 Race Condition (同进程下多线程,或不同进程)下如何重建。
也就是说,某个线程在重建缓存过程中,其他线程发现缓存不存在或已过期,该如何处置?
从2005 年OSCache 的版本到现在,它一直这么声称:
* @throws NeedsRefreshException Thrown when the object either
* doesn't exist, or exists but is stale. When this exception occurs,
* the CacheEntry corresponding to the supplied key will be locked
* and other threads requesting this entry will potentially be blocked
* until the caller repopulates the cache . If the caller choses not
* to repopulate the cache, they <em>must</em> instead call
* {@link #cancelUpdate(String)}.
即,
当 key 不存在,或者存在但数据过期(stale )时,
调用 getFromCache 函数时会抛出 NRE 异常;
当异常发生时,
对应于这个 key 的 CacheEntry 将被锁住,
而请求这个 entry 的其他线程将可能(注意,仅仅是可能) 被阻塞,直到调用者重建缓存。
如果调用者没有选择重建缓存,必须 调用 cancelUpdate 函数来“Cancels any pending update for this cache entry ”。
三,缓存重建的 OSCache 官方推荐做法:
读取缓存遇到 NRE 异常时,OSCache 官方推荐的做法是:
1 String myKey = "myKey";
2 String myValue;
3 int myRefreshPeriod = 1000;
4 try {
5 // Get from the cache
6 myValue = (String) admin. getFromCache (myKey, myRefreshPeriod);
7 } catch ( NeedsRefreshException nre) {
8 try {
9 // Get the value (probably from the database)
10 myValue = "This is the content retrieved.";
11 // Store in the cache
12 admin. putInCache (myKey, myValue);
13 } catch (Exception ex) {
14 // We have the current content if we want fail-over.
15 myValue = (String) nre.getCacheContent();
16 // It is essential that cancelUpdate is called if the
17 // cached content is not rebuilt
18 admin. cancelUpdate (myKey);
19 }
20 }
即,本线程先试图重建缓存,如果再次发生异常,则本线程(不管三七二十一)直接调用 cancelUpdate 函数。
现在的一些 OSCache Manager 工具类, get 方法也就实现为一旦捕获 NRE 异常就直接 canelUpdate :
1 public OSCache get(String key, int myRefreshPeriod){
2 try {
3 return (OSCache) this .admin. getFromCache (key,myRefreshPeriod);
4 } catch ( NeedsRefreshException ex){
5 this .admin. cancelUpdate (key);
6 return null ;
7 }
8 }
四,OSCache 在 Race Condition 下缓存重建的特殊场景
简单地说,就是:
线程1 正在重建缓存;
线程2 读取缓存时得到 NRE 异常,主动 cancel update ;
线程1 重建缓存完毕,却发现状态被改为了 UPDATE_CANCELLED ,与期望不符,于是抛出异常 java.lang.IllegalStateException 。
具体过程如下:
(0 )缓存过期;
(1 )线程 T1 获得 update lock ,并开始调用 putInCache 函数 ;
(2 ) 线程 T2 在 T1 没有结束 update 之前,也开始 getCacheEntry 了;
(3 )T2 调用的 getCacheEntry 函数捕获 NeedsRefreshException 异常;
(4 )T2 调用 cancelUpdate 函数来“取消所有试图更新本 cache entry 的操作”, 于是 EntryUpdateState 变为 UPDATE_CANCELLED ,它是一个正整数 2 ;
(5 )T1 其实已经重建了缓存 ;
(6 )T1 随后调用 completeUpdate (EntryUpdateState.java,93 行) 来通知那些等着本次更新操作的线程; 但 completeUpdate 函数却发现当前 EntryUpdateState 居然不等于 UPDATE_IN_PROGRESS (对应0 ),而是 UPDATE_CANCELLED (对应2 ),于是抛出异常 。即下面代码抛出的 IllegalStateException 异常,文字通常为:“ Cannot complete cache update - current state ( 2 ) is not UPDATE_IN_PROGRESS ”,其中的 2 就是指 UPDATE_CANCELLED :
1. /**
2. * Updates the state to <code>UPDATE_COMPLETE</code>. This should <em>only</em>
3. * be called by the thread that managed to get the update lock.
4. * @return the counter value after the operation completed
5. */
6. public int completeUpdate() {
7. if (state != UPDATE_IN_PROGRESS) {
8. throw new IllegalStateException( "Cannot complete cache update - current state (" + state + ") is not UPDATE_IN_PROGRESS" );
9. }
10.
11. state = UPDATE_COMPLETE;
12. return decrementUsageCounter();
13. }
总之,按目前 OSCacheManager 的做法,在高并发环境下,一旦一个 OSCache 缓存失效,而缓存的数据片段很大,那么很有可能让其他线程在 getFromCache 时有机会捕获 NRE 异常,最终导致做缓存重建的线程抛出 IllegalStateException 异常,虽然此时缓存已经重建完毕。
发表评论
-
无备案小站的最好的广告收益来源
2020-08-09 10:52 239现在无备案的无名小站运营维持真的很难,广告难接,各大广告联盟 ... -
老番茄访问IP突破1W
2019-11-13 10:19 5感谢大家,老番(www.laofanqie.com) 用户访问 ... -
Nmon工具的使用以及通过nmon_analyse生成分析报表
2016-09-07 11:44 385Nmon工具的使用以及通过nmon_a ... -
用“逐步排除”的方法定位Java服务线上“系统性”故障
2015-08-27 19:12 732一、摘要 由于硬件问题、系统资源紧缺或者程序本身的BUG, ... -
simple-spring-memcached简介
2015-07-09 15:06 416memcached是一款非常优秀的分布式缓存工具,有效提升了 ... -
Tomcat 7 的新JDBC连接池的使用说明
2015-06-28 22:55 1312Tomcat 7 的JDBC连接池实 ... -
CentOS安装JDK1.6
2015-04-01 11:56 10271、获得程序包 jdk-6u16-dlj-linux- ... -
abtest
2014-12-01 11:51 1034Apache服务自带了应该用于压力测试的工具ab(Apach ... -
mysql优化
2014-08-29 11:36 60219195.cn 手游网站mysql 优化一: v ... -
怎么快速搭建游戏网站,手游网站,手机应用网站??
2014-07-28 13:14 1592大家好,作为19195手游 ... -
mysql备份还原
2014-06-13 11:31 2备份数据库 -
centos6利用yum安装php mysql
2014-05-18 13:47 910一、安装mysql #yum -y install my ... -
Centos如何挂载硬盘
2014-05-15 13:03 767远程SSH登录上Centos服务器后,进行如下操作提醒:挂 ... -
远程监控JVM--VisualVM
2013-01-09 18:26 1161对于使用命令行远程监控jvm太麻烦?那可以试试sun ... -
聊聊并发(五)原子操作的实现原理
2013-01-07 17:50 01 引言 原子(atom)本意是“不能被进一步分 ... -
聊聊并发(四)深入分析ConcurrentHashMap
2013-01-07 17:48 0术语定义 术语 英文 解释 哈希算法 ... -
聊聊并发(三)Java线程池的分析和使用
2013-01-07 17:45 8301. 引言 合理利用线程池能够带来三个好处。第一 ... -
聊聊并发(二)Java SE1.6中的Synchronized
2013-01-07 17:42 9061 引言 在多线程并发编程中Synchronized一 ... -
聊聊并发(一)深入分析Volatile的实现原理
2013-01-07 17:41 804作者http://ifeve.com 引言 在 ... -
虚拟机stack全解析
2013-01-07 14:40 1329转载 通过jps -lv 获取到本地的一个JVM实例进 ...
相关推荐
OsCache还提供了线程安全的缓存操作,确保在多线程环境下数据的一致性。 在天气预报Web服务示例中,我们可能会频繁地查询某个城市的天气信息。如果每次都去调用外部的Web服务,那么将增加网络延迟和服务器压力。...
- **事件监听**:osCache允许注册监听器来处理缓存的添加、删除和更新事件,这在实现缓存同步或记录日志时非常有用。 - **缓存预热**:在应用启动时,可以预先加载一部分常用数据到缓存,提高系统启动后的响应速度...
4. 缓存同步:在多线程或多服务器环境下,osCache提供了一套机制来确保缓存数据的一致性和完整性。 三、osCache配置 osCache的配置主要通过XML文件完成,包括缓存配置、更新策略、缓存监听器等。例如: ```xml ...
当用户请求一个页面时,OSCache会先检查该页面是否已经在缓存中,如果存在则直接返回,否则生成页面并将其放入缓存。 要使用OSCache,我们需要在项目的类路径下引入OSCache的jar包,如`oscache.jar`。然后,在初始...
此外,OSCache还支持集群环境下的缓存同步,通过`ClusteredCache`接口,可以在多台服务器之间共享缓存数据,实现分布式缓存。这在大型分布式系统中非常关键,因为它能确保数据的一致性和可用性。 OSCache的配置主要...
除了静态配置文件外,osCache还支持动态编程配置,可以在代码中通过`CacheManager`实例创建和管理缓存。例如: ```java import net.sf.oscache.CacheManager; CacheManager.init("oscache.properties"); // 初始化...
OSCache支持分布式缓存,可以在多台服务器之间共享数据。通过配置网络通信和序列化策略,可以实现跨节点的缓存操作。 **7. 过期与清理机制** OSCache支持自动过期,可以设置对象的存活时间和空闲时间。当达到预设...
在使用 Hibernate OSCache 缓存之前,首先需要在项目中引入必要的依赖。将 `oscache.jar` 文件放入 `/WEB-INF/lib` 目录或相应的类库目录。同时,需要一个 `oscache.properties` 配置文件,通常放在项目的 `src` 根...
在本文中,我们将深入探讨OSCache在缓存JSP页面方面的应用,以及如何利用它来优化Web应用。 首先,我们需要理解缓存的基本概念。缓存是一种存储技术,用于临时存储频繁访问的数据,以便快速检索。在Web开发中,JSP...
4. **缓存同步**:在多线程或多服务器环境下,OSCache 提供了缓存同步机制,确保了在并发操作下的数据一致性。 5. **缓存分区**:OSCache 支持将缓存划分为多个分区,每个分区可以有不同的配置,这有助于管理和优化...
- 同步管理:OSCache支持多线程环境下的缓存同步,确保了在并发访问时的数据一致性。 - 自动过期:可以设置缓存项的存活时间和空闲时间,当达到预设时间后自动清理,防止内存溢出。 - 动态更新:当源数据发生变化...
osCache是Java平台上的一个高效的缓存解决方案,主要用于在应用程序中缓存数据,以提高性能和减少数据库的负载。这个工具特别适用于那些需要频繁访问但更新不频繁的数据,例如经常查询但很少更改的数据库记录。...
OSCache 是一个广泛使用的开源缓存解决方案,尤其在Java应用中,它被JBoss, Hibernate, Spring等知名框架所支持。其主要特点是配置简单,适用于页面级别的缓存管理。以下是对OSCache配置和使用过程的详细说明: 1. ...
标题与描述概述的知识点主要集中在oscache的使用及其在Java环境下的配置与实施。oscache是一种缓存机制,主要用于提高Web应用的响应速度和优化系统性能。以下是对这些知识点的详细解析: ### oscache简介 oscache...
osCache是Java开发中常用的缓存框架之一,它主要用于提高应用程序的性能和效率,通过将数据存储在内存中,减少对数据库的访问。osCache不仅可以用于Web应用,也可以用于任何Java应用程序,支持集群环境,提供了丰富...
OSCache标记库由OpenSymphony设计,它是一种开创性的缓存方案,它提供了在现有JSP页面之内实现内存缓存的功能。OSCache是个一个被广泛采用的高性能的J2EE缓存框架,OSCache还能应用于任何Java应用程序的普通的缓存...
1、OSCache是什么? 2、OSCache的特点 3、有关“用OSCache进行缓存对象”的研究