`
my_corner
  • 浏览: 84473 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate的优化:Cache

阅读更多
写这个的目的不是为了说明哪种cache的效率高,或者哪种cache更适合hibernate。只是为了阐明hibernate在使用cache时的机制,和自己碰到的实际问题。
二、hibernate二级缓存避免查询Cache需要先获得db连接
hibernate自身管理一级缓存,如果需要使用二级缓存,则要自己来实现相应的代码,这个实现起来并不复杂只需要实现
hibernate提供的相应的接口即可。我们在项目中选用了最为通用的memcached,具体配置如下:
在spring中配置hibernateProperties是增加一项配置
<prop key="hibernate.cache.provider_class">com.*.frame.cache.memcached.MemcachedCacheProvider</prop>

MemcachedCacheProvider需要实现hibernate提供的CacheProvider接口:
public class MemcachedCacheProvider implements CacheProvider {
	public final static String DEFAULT_REGION_NAME="____DEFAULT_CACHE_REGION";

	public void start(Properties props) throws CacheException {
		CachePoolManager pool = CachePoolManager.getInstance();
	}

	public Cache buildCache(String name, Properties props) throws CacheException {
		if(StringUtils.isEmpty(name))
			name = DEFAULT_REGION_NAME;
		//项目中已经实现并且再用的的Memacached工具类
		MemCache mCache = (MemCache)CachePoolManager.getInstance().getCache(name);
		return mCache;
	}

	public void stop() {
//		CachePoolManager.getInstance().finalize();
	}

	public boolean isMinimalPutsEnabledByDefault() {
		return false;
	}

	public long nextTimestamp() {
		return Timestamper.next();
	}
}

Memcached实体类也要实现hibernate提供的Cache接口:
public class MemCache implements Cache {
	private static final Log log = LogFactory.getLog(MemCache.class);
	private static final int SIXTY_THOUSAND_MS = 60000;
	private MemCachedClient mc;
	private int secondToLive;
	private String cache_name;
	private String poolName;
	public MemCache(String poolName, String regionName, int secondToLive){
*****部分代码省略
/**
	 * Get an item from the cache
	 * @param key
	 * @return the cached object or <tt>null</tt>
	 * @throws CacheException
	 */
	public Object read(Object key) throws CacheException;
	/**
	 * Get an item from the cache, nontransactionally
	 * @param key
	 * @return the cached object or <tt>null</tt>
	 * @throws CacheException
	 */
	public Object get(Object key) throws CacheException;
	/**
	 * Add an item to the cache, nontransactionally, with
	 * failfast semantics
	 * @param key
	 * @param value
	 * @throws CacheException
	 */
	public void put(Object key, Object value) throws CacheException;
	/**
	 * Add an item to the cache
	 * @param key
	 * @param value
	 * @throws CacheException
	 */
	public void update(Object key, Object value) throws CacheException;
	/**
	 * Remove an item from the cache
	 */
	public void remove(Object key) throws CacheException;
	/**
	 * Clear the cache
	 */
	public void clear() throws CacheException;
	/**
	 * Clean up
	 */
	public void destroy() throws CacheException;
	/**
	 * If this is a clustered cache, lock the item
	 */
	public void lock(Object key) throws CacheException;
	/**
	 * If this is a clustered cache, unlock the item
	 */
	public void unlock(Object key) throws CacheException;
	/**
	 * Generate a timestamp
	 */
	public long nextTimestamp();
	/**
	 * Get a reasonable "lock timeout"
	 */
	public int getTimeout();
	
	/**
	 * Get the name of the cache region
	 */
	public String getRegionName();

	/**
	 * The number of bytes is this cache region currently consuming in memory.
	 *
	 * @return The number of bytes consumed by this region; -1 if unknown or
	 * unsupported.
	 */
	public long getSizeInMemory();

	/**
	 * The count of entries currently contained in the regions in-memory store.
	 *
	 * @return The count of entries in memory; -1 if unknown or unsupported.
	 */
	public long getElementCountInMemory();

	/**
	 * The count of entries currently contained in the regions disk store.
	 *
	 * @return The count of entries on disk; -1 if unknown or unsupported.
	 */
	public long getElementCountOnDisk();
	
	/**
	 * optional operation
	 */
	public Map toMap();
}

至于Memcached实体类里的MemCachedClient 的实现,可以更加网上流传的不同版本进行修改和优化。
第四步,在需要使用缓存的类对应的映射文件中加入缓存策略的配置,如:<cache usage="nonstrict-read-write" />,还有其他选项read-only,read-write,transactional等。
    大功告成,打开hibernate.show_sql重启应用。刷新列表,第一次看到一大堆的sql语句,再次刷新只出现两条,第三次还是两条,我们配置的二级缓存生效了。
做一次压力测试,具体压力测试的报告丢失没法拿出具体的数字。当时大概的现象是,应用响应比较慢,数据库连接几乎耗尽,队列等待情况严重
我们知道hibernate从cache中查找的时候,先从数据库拿到相应的id然后根据id去cache中取到相应的数据后返回。压力测试只是模拟的同一个请求,意味着每次要查询的东西必然已经存在于cache里了,为什么dbConnection会不够用呢
    一个分析系统问题的利器该出场了——log4j。顺便说句,java开发不可避免的采用框架,当然有人坚持原生态,这个另说。几乎所有的框架都采用log4j输出日志,仔细分析日志不难发现很多问题。首先,设置日志级别Debug,其次去掉一些无用的信息,比如初始化、加载配置文件等等。准备工作完成后,咱们模拟用户的行为进行一次操作。这个时候输出的日志就会记录一个请求执行的所有的过滤器,拦截器,方法等堆栈信息。   
[DEBUG] 2010-07-28 11:28:31 org.hibernate.transaction.JDBCTransaction - begin
[DEBUG] 2010-07-28 11:28:31 org.hibernate.jdbc.ConnectionManager - opening JDBC connection
[DEBUG] 2010-07-28 11:28:31 org.hibernate.transaction.JDBCTransaction - current autocommit status: true
[DEBUG] 2010-07-28 11:28:31 org.hibernate.transaction.JDBCTransaction - disabling autocommit
[DEBUG] 2010-07-28 11:28:31 org.hibernate.cache.NonstrictReadWriteCache - Cache lookup: com.**#3827849
[DEBUG] 2010-07-28 11:28:31 com.**.frame.cache.memcached.MemCache - key: com.**#3827849
[DEBUG] 2010-07-28 11:28:31 com.**.frame.cache.memcached.SockIOPool$SockIO - ++++ marking socket (Socket[addr=/127.0.0.1,port=11211,localport=56135]) as closed and available to return to avail pool
[DEBUG] 2010-07-28 11:28:31 org.hibernate.cache.NonstrictReadWriteCache - Cache hit//已经命中
[DEBUG] 2010-07-28 11:28:31 org.hibernate.engine.StatefulPersistenceContext - initializing non-lazy collections
[DEBUG] 2010-07-28 11:28:31 org.hibernate.transaction.JDBCTransaction - commit
[DEBUG] 2010-07-28 11:28:31 org.hibernate.transaction.JDBCTransaction - re-enabling autocommit
[DEBUG] 2010-07-28 11:28:31 org.hibernate.transaction.JDBCTransaction - committed JDBC Connection
[DEBUG] 2010-07-28 11:28:31 org.hibernate.jdbc.ConnectionManager - aggressively releasing JDBC connection
[DEBUG] 2010-07-28 11:28:31 org.hibernate.jdbc.ConnectionManager - releasing JDBC connection

    通过对log4j日志分析发现,hibernate每次先get一个jdbcConnection,从数据库查询出一堆id,然后去cache查找对象。如果数据在cache中存在则取出,并提交事务释放连接;如果cache中没有,则查询数据库并将结果保存的cache中,提交事务释放连接。问题来了:既然cache中有想要查询的数据,为什么要先获取一个数据库连接、开启事务然后再去缓存中查找呢?假如所有用户查询的内容在cache中都存在,每个请求都要获取一个jdbc连接才能去查找cache,那么系统瓶颈必然会出现的连接池的连接数上。这也就不难解释为什么做压力测试时出现数据库连接耗尽的情况。由此我们得出一个结论:hibernate需要维持着数据库连接去cache中查找数据,只是减少了对数据库的查找次数,并没有减少应用的db连接数。
    如何解决这个问题?理想的情况是,cache中有的直接去cache中查找,cache中没有的去db查询然后放入cache中。将代码做些修改,只从数据库中查到id,根据id去cache中查找相应的数据,cache中没有的数据则调用hibernate的查询方法。由于之前我们已经配置了缓存策略,所以hibernate查询到相应的数据后会自动放入cache中。这样一来,当第一次请求的时候先去db中拿到id,然后把所有的数据装入到cache中,第二次请求时先去查询出id,然后去cache中查找数据。以后的每次操作,只有查询id时取得数据库连接,结果集返回连接就被释放掉。这样避免了hibernate需要维持着db连接去查询cache的问题。
    在从cache中获取数据的地方遇到了些麻烦,hibernate写入cache中的对象,我们能写代码取到但是无法进行解析。相关的资料介绍,hibernate对存入二级缓存的东西默认进行了封装且不提供对外的接口进行数据的解析,至于原因和封装成什么类型这里不再赘述。我们可以通过配置改变hibernate保存的对象在cache中的数据结构。具体办法:在配置hibernateProperties是增加一项配置
<prop key="hibernate.cache.use_structured_entries">true</prop>
,这样存入二级缓存的对象是一个保存属性名和属性值的map,解析map即可得到相应数据。
    虽然这样一来,针对二级缓存的使用有些侵入性,但是可以保证了hibernate对二级缓存的读取不会像默认的那样需要保持着一个数据库连接。第二个问题解决
分享到:
评论
48 楼 lyndon.lin 2010-12-15  
最新要学习hibernate cache,看到这个不错!
47 楼 my_corner 2010-08-02  
呵呵,新手帖
46 楼 xly_971223 2010-08-02  
楼主有测试数据吗
采用新方法之后性能上提高了多少?
45 楼 my_corner 2010-08-02  
分离的北极熊 写道
aimer311 写道
我想是的,你没有将表述的关键点比较明显的表述出来。我理解没错的话,你的观点是:
hibernate的执行过程是这样:
打开连接,取得id,到cache去找,若找到,则取cache,没有找到,执行查询,关闭连接。
而你修改后的执行过程是这样:
打开连接,打开事务,取得id,关闭连接,到cache去找,若找到,则取cache,没有找到,执行查询。
你没有强调问题所在,所以我们(至少包括xuzhfa123 )看得云里雾里


理解没错吧,因为我理解也这样,但是第二句(打开连接,打开事物,取得ID,关闭连接,查找CACHE,如果找到,则取CACHE,执行查询,******连接都关掉了,还查什么了,要再次创建了)

回复"分离的北极熊":1、从数据库查id,从cache中拿到数据,如果cache中没有则从数据库中拿出,存入cache。你问道:一个是id是从数据库中查找ID,一个是从缓存中查找记录差距就有你想的那么大吗?这其中的时间会差多少?
这和数据库连接的时间没有关系,在一个并发高的系统中,数据库连接资源是有限的。你是想让连接保持长时间被占用不释放,还是想短时间用完 就释放?
2、memcache的缓存时间和程序没有任何关系,也不是jvm来控制的,是c写的。你说:memcache,就不知道了,还没时间来了解。等了解了,咱们在讨论吧
44 楼 my_corner 2010-08-02  
aimer311 写道
我想是的,你没有将表述的关键点比较明显的表述出来。我理解没错的话,你的观点是:
hibernate的执行过程是这样:
打开连接,取得id,到cache去找,若找到,则取cache,没有找到,执行查询,关闭连接。
而你修改后的执行过程是这样:
打开连接,打开事务,取得id,关闭连接,到cache去找,若找到,则取cache,没有找到,执行查询。
你没有强调问题所在,所以我们(至少包括xuzhfa123 )看得云里雾里

问题所在我已经用黑色字体标识出来了。hibernate需要保持着数据库连接去cache中查找数据。前面已经有很多同学看明白了。
43 楼 my_corner 2010-08-02  
xly_971223 写道
my_corner 写道
xly_971223 写道
问题虽然解决了 但是方法不是特别优雅
还不然直接抛弃hibernate 二级缓存自己封装一套更痛快

===========================================

另外如果采用opensessioninview的话,一个请求只打开一个jdbc connction
把连接池开大点 比如1000 也没啥关系
你的并发应该也大不过1000吧

呵呵,难道一个系统中只有这一个请求吗?如果只是一个查询就消耗那么多数据库连接,那还有update,insert等等操作呢。另外,opensessioninview的前提是 lazy 加载,lazy 会出现另外一个问题cache连接数的问题,改天会写篇博文描述一下。


opensessioninview的前提是 lazy 加载
这话不知道你从哪儿看到的,不用lazy加载就不能用opensessioninview吗?

lazy 会出现另外一个问题cache连接数的问题
什么问题能说详细点吗?

由于Hibernate引入了Lazy Load特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个 LazyLoad的Exception。所以为了解决这个问题,Spring引入了OpenSessionInViewFilter这个Filter,使得Hibernate的Session的生命周期变长。
你不用lazy,用OpenSessionInViewFilter做什么?
42 楼 xly_971223 2010-08-02  
my_corner 写道
xly_971223 写道
问题虽然解决了 但是方法不是特别优雅
还不然直接抛弃hibernate 二级缓存自己封装一套更痛快

===========================================

另外如果采用opensessioninview的话,一个请求只打开一个jdbc connction
把连接池开大点 比如1000 也没啥关系
你的并发应该也大不过1000吧

呵呵,难道一个系统中只有这一个请求吗?如果只是一个查询就消耗那么多数据库连接,那还有update,insert等等操作呢。另外,opensessioninview的前提是 lazy 加载,lazy 会出现另外一个问题cache连接数的问题,改天会写篇博文描述一下。


opensessioninview的前提是 lazy 加载
这话不知道你从哪儿看到的,不用lazy加载就不能用opensessioninview吗?

lazy 会出现另外一个问题cache连接数的问题
什么问题能说详细点吗?
41 楼 分离的北极熊 2010-08-02  
aimer311 写道
我想是的,你没有将表述的关键点比较明显的表述出来。我理解没错的话,你的观点是:
hibernate的执行过程是这样:
打开连接,取得id,到cache去找,若找到,则取cache,没有找到,执行查询,关闭连接。
而你修改后的执行过程是这样:
打开连接,打开事务,取得id,关闭连接,到cache去找,若找到,则取cache,没有找到,执行查询。
你没有强调问题所在,所以我们(至少包括xuzhfa123 )看得云里雾里


理解没错吧,因为我理解也这样,但是第二句(打开连接,打开事物,取得ID,关闭连接,查找CACHE,如果找到,则取CACHE,执行查询,******连接都关掉了,还查什么了,要再次创建了)
40 楼 分离的北极熊 2010-08-02  
my_corner 写道
xuzhfa123 写道

你讲得和hibernate做的一样,你查id不需要获取连接吗

我查id需要获取连接(这里还可以优化,可以缓存id list,而且已经实现了,是为了讲查询维持连接cache的机制把id list这个地方忽略掉了)。
我查询id获得连接了,查询结束连接就释放了。我并没有保持着数据库连接去cache里面查找东西。比如查询1000个id,如果1000个id对应的数据在缓存里都有,我的链接时间,只是从数据库中把id取回来。而hibernate是的链接,是要等这1000个id对应的数据从cache里全都查询到,拼装好才释放掉的。
参见log4j的日志,谢谢!


疑问:当你查询ID获取连接,查询结束连接释放,期间不查找CACHE?如果不查找CACHE,你释放连接,如果CACHE中没有,是否要再次创建连接?
感觉有点自相矛盾的意思,还是我由于半夜看文字出现的问题,GOD。。。

LZ的想法是没错,我写过一个记录google经纬度的程序,也是采用类似的方法,不过好像都是采用这样的方法吧
取得的记录,先去cache 中查找,有则返回,没有则查找数据库记录,然后关闭连接,大多都这样

取1000个id,和取1000个id后,去CACHE中查所对应的数据从cache中查询到,一个是id是从数据库中查找ID,一个是从缓存中查找记录
差距就有你想的那么大吗?这其中的时间会差多少?这可是从缓存拿数据哦,况且最后都会进行数据库的关闭操作

如果你要缓存ID LIST,那你何不key = id & value = ID对应的对象信息,这不一样?

直接ID --> VALUE的形式即可

----

Hibernate的二级缓存和你文中说的一样,下面引用LZ的文字
“通过对log4j日志分析发现,hibernate每次先get一个jdbcConnection,从数据库查询出一堆id,然后去cache查找对象。如果数据在cache中存在则取出,并提交事务释放连接;如果cache中没有,则查询数据库并将结果保存的cache中,提交事务释放连接。”

通过文字得到结论:1、建立连接获取ID,然后根据ID查找CACHE,有责获得数据返回关闭连接,没有,责查找数据,保存CACHE,关闭连接返回。

引用LZ第二段文字
”理想的情况是,cache中有的直接去cache中查找,cache中没有的去db查询然后放入cache中。将代码做些修改,只从数据库中查到id,根据id去cache中查找相应的数据,cache中没有的数据则调用hibernate的查询方法“

通过文字得到结论:1、重点(只从数据库中查到ID,根据ID去CACHE中查找相应的数据)

还是要先建立连接去查找ID,然后对应的数据去保存CACHE,只是关闭连接的时间不同(还是上面的疑问,如果ID所对应的CACHE不存在,咋做,是否要再次建立连接?LZ采用的框架,我的程序中就加入缓存框架加逻辑,可以很容易的控制)

Hibernate默认采用的第三方缓存Oscache,亦可设置缓存时间(至于其他memcache就不晓得了)源码阅读过一部分,采用Properties 以key value的形式缓存对象

还有一点疑问:LS有说,如果程序关闭,memcache有缓存时间,那在程序关闭的时候,这个缓存时间还有效么?我理解是没有作用的,只有在缓存到硬盘的时候,才可以再重启的服务器的时候从缓存硬盘中读取数据,再次加载到缓存中,以内存+硬盘的缓存形式来缓存数据,这样的效果最佳
而memcache直接是内存缓存,不可能在重启的时候以判断是否超过缓存时间来断定数据是否还在缓存中保存,因为此时缓存在重启的时候已经清空了

至于楼主曾经讲述到memcache,就不知道了,还没时间来了解,希望下次有机会和LZ沟通
39 楼 aimer311 2010-08-01  
我想是的,你没有将表述的关键点比较明显的表述出来。我理解没错的话,你的观点是:
hibernate的执行过程是这样:
打开连接,取得id,到cache去找,若找到,则取cache,没有找到,执行查询,关闭连接。
而你修改后的执行过程是这样:
打开连接,打开事务,取得id,关闭连接,到cache去找,若找到,则取cache,没有找到,执行查询。
你没有强调问题所在,所以我们(至少包括xuzhfa123 )看得云里雾里
38 楼 my_corner 2010-08-01  
aimer311 写道
my_corner 写道
xuzhfa123 写道


你讲得和hibernate做的一样,你查id不需要获取连接吗

我查id需要获取连接(这里还可以优化,可以缓存id list,而且已经实现了,是为了讲查询维持连接cache的机制把id list这个地方忽略掉了)。
我查询id获得连接了,查询结束连接就释放了。我并没有保持着数据库连接去cache里面查找东西。比如查询1000个id,如果1000个id对应的数据在缓存里都有,我的链接时间,只是从数据库中把id取回来。而hibernate是的链接,是要等这1000个id对应的数据从cache里全都查询到,拼装好才释放掉的。
参见log4j的日志,谢谢!

首先声明,我刚开始用hibernate。
文章看了第一遍,没明白lz的意思,再看第二遍,还是没明白,看到这个回复算是明白了。

你意思是我描述有问题?
37 楼 aimer311 2010-08-01  
my_corner 写道
xuzhfa123 写道


你讲得和hibernate做的一样,你查id不需要获取连接吗

我查id需要获取连接(这里还可以优化,可以缓存id list,而且已经实现了,是为了讲查询维持连接cache的机制把id list这个地方忽略掉了)。
我查询id获得连接了,查询结束连接就释放了。我并没有保持着数据库连接去cache里面查找东西。比如查询1000个id,如果1000个id对应的数据在缓存里都有,我的链接时间,只是从数据库中把id取回来。而hibernate是的链接,是要等这1000个id对应的数据从cache里全都查询到,拼装好才释放掉的。
参见log4j的日志,谢谢!

首先声明,我刚开始用hibernate。
文章看了第一遍,没明白lz的意思,再看第二遍,还是没明白,看到这个回复算是明白了。
36 楼 my_corner 2010-08-01  
xly_971223 写道
问题虽然解决了 但是方法不是特别优雅
还不然直接抛弃hibernate 二级缓存自己封装一套更痛快

===========================================

另外如果采用opensessioninview的话,一个请求只打开一个jdbc connction
把连接池开大点 比如1000 也没啥关系
你的并发应该也大不过1000吧

呵呵,难道一个系统中只有这一个请求吗?如果只是一个查询就消耗那么多数据库连接,那还有update,insert等等操作呢。另外,opensessioninview的前提是 lazy 加载,lazy 会出现另外一个问题cache连接数的问题,改天会写篇博文描述一下。
35 楼 xly_971223 2010-08-01  
问题虽然解决了 但是方法不是特别优雅
还不然直接抛弃hibernate 二级缓存自己封装一套更痛快

===========================================

另外如果采用opensessioninview的话,一个请求只打开一个jdbc connction
把连接池开大点 比如1000 也没啥关系
你的并发应该也大不过1000吧
34 楼 my_corner 2010-08-01  
XTU_xiaoxin 写道

具体,你从缓存里取数据和从数据库了取数据的代码修改是怎么样的?
我是想问你是怎么修改查询数据逻辑的?
能给点代码,大伙看看吗?

我想,你没搞明白我的意思。我没有修改hibernate的代码,是修改自己代码里的逻辑。利用hibernate查询的时候,只差id,然后通过id和,hibernate存储的key的格式去cache里拼装对象。如果cache中没有的,再通过id和hql去数据库查询,让hibernate自动的放入cache,下次查询cache中就存在了。
33 楼 XTU_xiaoxin 2010-07-31  

具体,你从缓存里取数据和从数据库了取数据的代码修改是怎么样的?
我是想问你是怎么修改查询数据逻辑的?
能给点代码,大伙看看吗?
32 楼 my_corner 2010-07-29  
Hyphoon 写道
想问下楼主, Hibernate在获取id的同时, 是否也获取了版本号, 以便比较Cache内容是否过时?

这个问题一直想搞清楚, 更想知道它是否支持JTA事务, 不过本人懒惰。。。 拜服楼主的探索精神。

cache的内容是否过期?cache内容过期是memcached维护的,lru算法失效了就不存在了。
支持jta,以前曾经用过,这个项目里没有用到。
31 楼 Hyphoon 2010-07-29  
想问下楼主, Hibernate在获取id的同时, 是否也获取了版本号, 以便比较Cache内容是否过时?

这个问题一直想搞清楚, 更想知道它是否支持JTA事务, 不过本人懒惰。。。 拜服楼主的探索精神。
30 楼 guanliScott 2010-07-29  
my_corner 写道
xuzhfa123 写道


你讲得和hibernate做的一样,你查id不需要获取连接吗

我查id需要获取连接(这里还可以优化,可以缓存id list,而且已经实现了,是为了讲查询维持连接cache的机制把id list这个地方忽略掉了)。
我查询id获得连接了,查询结束连接就释放了。我并没有保持着数据库连接去cache里面查找东西。比如查询1000个id,如果1000个id对应的数据在缓存里都有,我的链接时间,只是从数据库中把id取回来。而hibernate是的链接,是要等这1000个id对应的数据从cache里全都查询到,拼装好才释放掉的。
参见log4j的日志,谢谢!


呵呵,真没注意。
长知识了。
29 楼 guanliScott 2010-07-29  
分离的北极熊 写道
kaowww153 写道
my_corner 写道
kaowww153 写道
分离的北极熊 写道
Hibernate 不是采取的Oscache做的二级缓存么…………

为什么还要单独的去换其他的缓存框架来做二级缓存?

理由是什么

Oscache也是第三方的,hibernate本身只有一个只能放在内存里的缓存只能测试时用,叫什么名字忘了。

是想说EHCache?oscache也好,ehcache也好,memcached也好,都是放在内存里的缓存,这样才能提高读取速度。即便是硬盘式的缓存Tokyo Tyrant,也是在内存里维护了一个缓存区。

很显然我说的不是ehcache,ehcache地球人都知道,而且是可以支持硬盘的,我说的是org.hibernate.cache.HashtableCacheProvider


Oscache 既支持内存也支持硬盘缓存的,可以缓存任何对象……

memcached 确实没了解过,有时间去查阅下资料


正解,Oscache支持内存和硬盘,也可以扩展成支持数据库。
Memcached用过PHP的,支持内存,硬盘,数据库

相关推荐

    Hibernate性能优化:一级缓存

    本文将深入探讨Hibernate性能优化中的一个重要概念——一级缓存,并结合给出的压缩包文件“hibernate_cache_level1”,来详细解析一级缓存的工作原理及其优化策略。 一级缓存是Hibernate内置的一种缓存机制,它存在...

    Hibernate性能优化:二级缓存

    &lt;property name="hibernate.cache.region.factory_class"&gt;org.hibernate.cache.ehcache.EhCacheRegionFactory ``` 同时,为特定的实体或查询开启缓存: ```xml ... &lt;cache usage="read-write"/&gt; ``` 或者对于...

    hibernate_cache_level_1

    总之,“hibernate_cache_level_1”主要关注的是Hibernate的二级缓存机制,通过理解和掌握如何配置、使用以及优化二级缓存,我们可以提升Java应用在处理大数据量时的性能,为用户提供更流畅的体验。

    hibernate cache

    本文将深入探讨 Hibernate 中的缓存概念,以及它如何通过三种主要类型的缓存来优化数据库操作。 ### 1. 第一级缓存:Session 缓存 每个 Hibernate `Session` 对象都有一个内置的第一级缓存。当我们在 Session 中...

    java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider

    二级缓存是Hibernate性能优化的一种手段,它存储了之前查询过的对象,以便于快速访问,减少对数据库的直接查询。 这个问题可能是由以下几个原因引起的: 1. **缺失的依赖**:最常见的情况是项目的类路径或Maven/...

    Hibernate 2nd-level cache: JBoss Caching 配置与注意事项

    &lt;cache-config xmlns="urn:jboss:cache:config:1.0"&gt; &lt;tree-cache name="my-entity-cache" statistics-enabled="true"&gt; &lt;replicated-cache/&gt; &lt;/tree-cache&gt; &lt;/cache-config&gt; ``` 这里配置了一个名为"my...

    hibernate-memcached包

    这通常涉及修改Hibernate的配置文件,添加相关的provider和cache regions。同时,还需要在应用环境中部署并配置Memcached服务器,以供Hibernate连接和存储数据。一旦配置完成,Hibernate会在适当的时候自动将数据...

    Hibernate Jboss cache

    通过上述详细的介绍和分析,我们可以看出,将Jboss Cache与Hibernate相结合,不仅能够显著提高数据访问的速度,还能够通过合理的配置和优化,更好地适应各种应用场景的需求。这对于开发高性能、高可用性的企业级应用...

    hibernate2.1相关jar包

    请注意,Hibernate 2.1是一个较旧的版本,现代开发中通常使用更先进的Hibernate 5.x或更高版本,它们提供了更多的特性、优化和对新Java及JPA标准的支持。尽管如此,理解Hibernate 2.1的基本工作原理对于学习ORM框架...

    springboot+jpa(hibernate配置redis为二级缓存) springboot2.1.4

    Hibernate是JPA的一个实现,提供了更丰富的功能和更强大的性能优化。 Redis则是一个开源的高性能键值存储系统,常用于缓存和消息中间件。它的高速读写能力使其成为缓存的理想选择,尤其是在处理大量数据时。 二级...

    Hibernate缓存,性能优化

    一级缓存,也称为会话缓存(Session Cache),是默认启用的,由Hibernate自动管理。它存储了当前会话期间加载的所有实体对象和关联的集合对象。当会话关闭时,一级缓存中的数据会被清除。一级缓存的主要作用是减少对...

    spring hibernate cache

    1. 配置 Spring Cache:在 Spring 配置文件中启用缓存支持,并指定使用的缓存管理器(如 EhCacheCacheManager)。 2. 绑定 Hibernate 二级缓存:Spring Cache 可以与 Hibernate 二级缓存集成,通过配置让 Spring 的...

    hibernate性能优化方案

    ### Hibernate性能优化方案详解 #### 一、引言 Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,其高效性和灵活性受到众多开发者的青睐。然而,不当的设计和配置往往会导致性能瓶颈,严重影响应用程序...

    Hibernate的cache缓存解析

    ### Hibernate的Cache缓存解析 #### 基本的缓存原理 在深入探讨Hibernate缓存之前,我们先来了解一下缓存的基本原理。缓存是一种用于提高数据访问速度的技术,通常用于存储最近或频繁访问的数据副本。通过将这些...

    Hibernate 缓存 实例

    了解并熟练使用Hibernate的缓存机制是优化应用程序性能的关键步骤。通过Ehcache和Spring的集成,我们可以实现高效的数据库缓存策略。一级缓存适用于单个Session的操作,而二级缓存则能在更大范围内提升性能。在实际...

    hibernate 优化方案

    ### Hibernate优化方案详解 在企业级应用开发中,Hibernate作为一款优秀的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,在处理大量数据或复杂查询时,Hibernate的性能问题逐渐凸显。本文将深入探讨...

Global site tag (gtag.js) - Google Analytics