WZ_XJTU_JAVA_SPACE

while(true) {System.out.println("wz.xjtu");}

Cache之我见

这两日对Cache研究了一点,读了一些源代码,自己也写了点code,借此假期也算是休闲加学习了。

什么时候用Cache?

在系统中,如果要考虑系统的性能,我们最好都使用Cache,在各个层次上都用上Cache,这样的话可以尽最大程度的减少数据库的压力。估计现在的系统都在分层,vo,po,do(domain object);我们可以把这些东西能缓存的都缓存起来,当然要根据具体系统具体分析(Cache多长时间,Cache多少东西)。
Tip:公司的系统中,由于用一台数据库,数据库的压力一直都是一个很大的问题,timeout,too many connection,等问题应接不暇。

怎么用Cache?

估计每个公司都有自己的Cache framework,简单的就是几个类,麻烦的可以做个小的framework去包装已有的opensource的cache provider。很多opensource的cache provider(例如:oscahe,ehcache)都对性能进行了优化,所以肯定性能比Map好很多,但是肯定不能拿过来就用,那样的话每次调用的时候太过于麻烦,写很多的类,很多的方法。所以说包装是很重要的,建议包装成一个Bus一样的东西(CacheBus,叫做CacheManager比较好),这样的话就可以在各个层次都向上面写和读了。

Tip: Cache就是key value,我们只要能写好key-value怎么写都可以的。这样也让系统变得简单实用(更能体现OO)

Cache Provider

Oh,这方面太多东西了,oscache(貌似停止开发了),ehcache(被terracotta收购了,前途不错),treecache(jbosstreecache大而全),memecached(很火了很久),nosql相关的东西(couchdb,mongodb)。Oh...不能忘记Map

其实用什么都可以,关键是用好,一般的解决方案很简单,既然你要在系统中用Cache并且想风风火火的用一下,那就来个二级Cache,第一级用本地Cache(速度快,但是东西不能太多),第二级,用memcached (能存放大的东东,便宜)。第一级Cache上3分钟(自己要调试确定时间),自动收割到第二级Cache中。

什么在第一级Cache中永远存活? 小的,永远都要用的,例如用户信息,Site信息,一些template等。

特别强调一下nosql 这方面mongodb和couchdb做的很好,在document相关的东西,可以缓存到这里面,例如:系统要在半天后发一封邮件,这封邮件所有的数据现在内存中都有,比较大的东东。到时候再去太复杂,太浪费内存了。怎么办呢? 放在一级缓存肯定不合适,放在二级缓存,要存活半天呀,太浪费时间了,存在数据库里面,增加压力,也不是很好,NOSQL的mongodb和couchdb就可以解决这个问题,这个schemaless的数据库,可以让你轻松的存任何的东西(性能不错)。(自己要优化一下代码)


举例:

Annotation

@Documented
@java.lang.annotation.Target(value
={java.lang.annotation.ElementType.TYPE})
@java.lang.annotation.Retention(value
=java.lang.annotation.RetentionPolicy.RUNTIME)
public @interface CacheIt {
    
//Provide the cacheProvider which will be use to cache the object which is just used to replace the xml configuration.
    public String cacheProvider();
    
//Used to define how long the cache need to be provide
    public long cacheDuration();
    
//The level of the cache, define, level1, level2 (If there is level2 defination in the annotation, the cache will be kick to level2 after the timeout in the level1)
    public int cacheLevel();

}

一个VO的configuration

@CacheIt(cacheProvider="com.javaeye.wmwm.cache.impl.HashMapCacheProvider", cacheDuration=10000, cacheLevel=1)
public class TestVo {
    
    @Identifier
    
public String key;

    
public String test;

    
public String getKey() {
        
return key;
    }

    
public void setKey(String key) {
        
this.key = key;
    }

    
public String getTest() {
        
return test;
    }


之后写一个CacheManager

public class CommonCacheManager implements CacheManager {
    
/**
     * Cache the object into the cache.
     * <p> the provider is defined in the annotation in the related Vo/PO/DO
     * <p> the key is annotated by the <code>Identifier</code>.
     * 
@param object represents the input objects which needs to be cached.
     
*/
    
public void cache(Object object) {
        Cache cache 
= CachePool.getInstance().loadCache(object.getClass());
        Object key 
= new CacheKeyFinder().find(object);
        cache.put(key, object);
    }

    
public Object load(Class<?> clazz, Object key) {
        Cache cache 
= CachePool.getInstance().loadCache(clazz);
        
return cache.get(key);
    }
}






posted on 2009-12-09 11:44 wz.xjtu 阅读(1913) 评论(6)  编辑  收藏

评论

# re: Cache之我见 2009-12-10 10:44 凡客诚品网

三度空间富商大贾客服  回复  更多评论   

# re: Cache之我见 2009-12-19 13:01 awp001

我这几天正在研究在系统内引入缓存,楼主说的一级缓存 二级缓存 是一个很好的想法。  回复  更多评论   

# re: Cache之我见 2009-12-19 13:13 awp001

目前我的核心任务是实现一个对象池,减少垃圾收集,楼主能否提供一些建议?  回复  更多评论   

# re: Cache之我见 2009-12-19 14:06 awp001

在分布式环境里,多个用户共用一个Cache,从Cache中获取对象的时候,如何解决用户之间的争抢问题,锁定吗?  回复  更多评论   

# re: Cache之我见 2009-12-20 01:01 wz.xjtu

@awp001

对象池能减少垃圾收集吗?现在的Cache(TreeCache)一般都能设置最大存储数目和存储的时间长度,这样的话就可以实现当达到这个时间长度后进行GC了。不需要单独的进行垃圾收集吧。

一般系统中可以设置一个CacheBus一样的东西,你的所有的应用都可以往CacheBus里面扔东西,只要Key不同就好了。这样的话基本上就是一个Key-Value的内存结构了。也就是一个简单的池了。

分布式环境多个用户共用一个Cache? (好像跟分布式无关吧),应该说是多个用户共用一个Cache的话,会出现怎么读数据的问题,最简单的实现如果是用ConcurrentHashMap是不用设置锁的(读的时候),而且性能还不错。如果是一些Cache Solution基本上也都解决了这样的问题。

如果是分布式环境,仍然要用Cache,这样的话MemCached无疑是一个最好的选择,也不用考虑这么多了。(现在也有很多好的实现。)  回复  更多评论   

# re: Cache之我见 2009-12-20 13:32 awp001

呵呵,对象池当然能减少垃圾收集啦,你说的TreeCache一般都能设置最大存储数目和存储的时间长度,对于单个对象的利用率已经提高了很多,不采用Cache的话,new一个对象,调用完了以后,过不了多久就被收集器回收了。所以啊采用Cache实际上已经减少垃圾收集了。
我说的分布式环境,多个用户共用一个Cache的争抢问题,实际上通俗的说就是该Cache是不是线程安全,要解决资源竞争导致的死锁。我研究了一下OSCache,它的规则是当一个线程访问Cache,在Cache被更新之前,其他线程都被阻塞。这样实际上也限制了系统的吞吐率。
我目前在自己写一个Map结构的对象池,正要解决资源竞争的问题。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2009年12月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

统计

常用链接

留言簿

随笔档案

搜索

最新评论

  • 1. re: Cache之我见
  • 评论内容较长,点击标题查看
  • --awp001
  • 2. re: Cache之我见
  • 评论内容较长,点击标题查看
  • --wz.xjtu
  • 3. re: Cache之我见
  • 在分布式环境里,多个用户共用一个Cache,从Cache中获取对象的时候,如何解决用户之间的争抢问题,锁定吗?
  • --awp001
  • 4. re: Cache之我见
  • 目前我的核心任务是实现一个对象池,减少垃圾收集,楼主能否提供一些建议?
  • --awp001
  • 5. re: Cache之我见
  • 我这几天正在研究在系统内引入缓存,楼主说的一级缓存 二级缓存 是一个很好的想法。
  • --awp001

阅读排行榜

评论排行榜