WZ_XJTU_JAVA_SPACE

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

          Cache之我見

          這兩日對(duì)Cache研究了一點(diǎn),讀了一些源代碼,自己也寫了點(diǎn)code,借此假期也算是休閑加學(xué)習(xí)了。

          什么時(shí)候用Cache?

          在系統(tǒng)中,如果要考慮系統(tǒng)的性能,我們最好都使用Cache,在各個(gè)層次上都用上Cache,這樣的話可以盡最大程度的減少數(shù)據(jù)庫(kù)的壓力。估計(jì)現(xiàn)在的系統(tǒng)都在分層,vo,po,do(domain object);我們可以把這些東西能緩存的都緩存起來(lái),當(dāng)然要根據(jù)具體系統(tǒng)具體分析(Cache多長(zhǎng)時(shí)間,Cache多少東西)。
          Tip:公司的系統(tǒng)中,由于用一臺(tái)數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)的壓力一直都是一個(gè)很大的問(wèn)題,timeout,too many connection,等問(wèn)題應(yīng)接不暇。

          怎么用Cache?

          估計(jì)每個(gè)公司都有自己的Cache framework,簡(jiǎn)單的就是幾個(gè)類,麻煩的可以做個(gè)小的framework去包裝已有的opensource的cache provider。很多opensource的cache provider(例如:oscahe,ehcache)都對(duì)性能進(jìn)行了優(yōu)化,所以肯定性能比Map好很多,但是肯定不能拿過(guò)來(lái)就用,那樣的話每次調(diào)用的時(shí)候太過(guò)于麻煩,寫很多的類,很多的方法。所以說(shuō)包裝是很重要的,建議包裝成一個(gè)Bus一樣的東西(CacheBus,叫做CacheManager比較好),這樣的話就可以在各個(gè)層次都向上面寫和讀了。

          Tip: Cache就是key value,我們只要能寫好key-value怎么寫都可以的。這樣也讓系統(tǒng)變得簡(jiǎn)單實(shí)用(更能體現(xiàn)OO)

          Cache Provider

          Oh,這方面太多東西了,oscache(貌似停止開發(fā)了),ehcache(被terracotta收購(gòu)了,前途不錯(cuò)),treecache(jbosstreecache大而全),memecached(很火了很久),nosql相關(guān)的東西(couchdb,mongodb)。Oh...不能忘記Map

          其實(shí)用什么都可以,關(guān)鍵是用好,一般的解決方案很簡(jiǎn)單,既然你要在系統(tǒng)中用Cache并且想風(fēng)風(fēng)火火的用一下,那就來(lái)個(gè)二級(jí)Cache,第一級(jí)用本地Cache(速度快,但是東西不能太多),第二級(jí),用memcached (能存放大的東東,便宜)。第一級(jí)Cache上3分鐘(自己要調(diào)試確定時(shí)間),自動(dòng)收割到第二級(jí)Cache中。

          什么在第一級(jí)Cache中永遠(yuǎn)存活? 小的,永遠(yuǎn)都要用的,例如用戶信息,Site信息,一些template等。

          特別強(qiáng)調(diào)一下nosql 這方面mongodb和couchdb做的很好,在document相關(guān)的東西,可以緩存到這里面,例如:系統(tǒng)要在半天后發(fā)一封郵件,這封郵件所有的數(shù)據(jù)現(xiàn)在內(nèi)存中都有,比較大的東東。到時(shí)候再去太復(fù)雜,太浪費(fèi)內(nèi)存了。怎么辦呢? 放在一級(jí)緩存肯定不合適,放在二級(jí)緩存,要存活半天呀,太浪費(fèi)時(shí)間了,存在數(shù)據(jù)庫(kù)里面,增加壓力,也不是很好,NOSQL的mongodb和couchdb就可以解決這個(gè)問(wèn)題,這個(gè)schemaless的數(shù)據(jù)庫(kù),可以讓你輕松的存任何的東西(性能不錯(cuò))。(自己要優(yōu)化一下代碼)


          舉例:

          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();

          }

          一個(gè)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;
              }


          之后寫一個(gè)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 閱讀(1934) 評(píng)論(6)  編輯  收藏

          評(píng)論

          # re: Cache之我見 2009-12-10 10:44 凡客誠(chéng)品網(wǎng)

          三度空間富商大賈客服  回復(fù)  更多評(píng)論   

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

          我這幾天正在研究在系統(tǒng)內(nèi)引入緩存,樓主說(shuō)的一級(jí)緩存 二級(jí)緩存 是一個(gè)很好的想法。  回復(fù)  更多評(píng)論   

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

          目前我的核心任務(wù)是實(shí)現(xiàn)一個(gè)對(duì)象池,減少垃圾收集,樓主能否提供一些建議?  回復(fù)  更多評(píng)論   

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

          在分布式環(huán)境里,多個(gè)用戶共用一個(gè)Cache,從Cache中獲取對(duì)象的時(shí)候,如何解決用戶之間的爭(zhēng)搶問(wèn)題,鎖定嗎?  回復(fù)  更多評(píng)論   

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

          @awp001

          對(duì)象池能減少垃圾收集嗎?現(xiàn)在的Cache(TreeCache)一般都能設(shè)置最大存儲(chǔ)數(shù)目和存儲(chǔ)的時(shí)間長(zhǎng)度,這樣的話就可以實(shí)現(xiàn)當(dāng)達(dá)到這個(gè)時(shí)間長(zhǎng)度后進(jìn)行GC了。不需要單獨(dú)的進(jìn)行垃圾收集吧。

          一般系統(tǒng)中可以設(shè)置一個(gè)CacheBus一樣的東西,你的所有的應(yīng)用都可以往CacheBus里面扔?xùn)|西,只要Key不同就好了。這樣的話基本上就是一個(gè)Key-Value的內(nèi)存結(jié)構(gòu)了。也就是一個(gè)簡(jiǎn)單的池了。

          分布式環(huán)境多個(gè)用戶共用一個(gè)Cache? (好像跟分布式無(wú)關(guān)吧),應(yīng)該說(shuō)是多個(gè)用戶共用一個(gè)Cache的話,會(huì)出現(xiàn)怎么讀數(shù)據(jù)的問(wèn)題,最簡(jiǎn)單的實(shí)現(xiàn)如果是用ConcurrentHashMap是不用設(shè)置鎖的(讀的時(shí)候),而且性能還不錯(cuò)。如果是一些Cache Solution基本上也都解決了這樣的問(wèn)題。

          如果是分布式環(huán)境,仍然要用Cache,這樣的話MemCached無(wú)疑是一個(gè)最好的選擇,也不用考慮這么多了。(現(xiàn)在也有很多好的實(shí)現(xiàn)。)  回復(fù)  更多評(píng)論   

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

          呵呵,對(duì)象池當(dāng)然能減少垃圾收集啦,你說(shuō)的TreeCache一般都能設(shè)置最大存儲(chǔ)數(shù)目和存儲(chǔ)的時(shí)間長(zhǎng)度,對(duì)于單個(gè)對(duì)象的利用率已經(jīng)提高了很多,不采用Cache的話,new一個(gè)對(duì)象,調(diào)用完了以后,過(guò)不了多久就被收集器回收了。所以啊采用Cache實(shí)際上已經(jīng)減少垃圾收集了。
          我說(shuō)的分布式環(huán)境,多個(gè)用戶共用一個(gè)Cache的爭(zhēng)搶問(wèn)題,實(shí)際上通俗的說(shuō)就是該Cache是不是線程安全,要解決資源競(jìng)爭(zhēng)導(dǎo)致的死鎖。我研究了一下OSCache,它的規(guī)則是當(dāng)一個(gè)線程訪問(wèn)Cache,在Cache被更新之前,其他線程都被阻塞。這樣實(shí)際上也限制了系統(tǒng)的吞吐率。
          我目前在自己寫一個(gè)Map結(jié)構(gòu)的對(duì)象池,正要解決資源競(jìng)爭(zhēng)的問(wèn)題。  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

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

          統(tǒng)計(jì)

          常用鏈接

          留言簿

          隨筆檔案

          搜索

          最新評(píng)論

          • 1.?re: Cache之我見
          • 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
          • --awp001
          • 2.?re: Cache之我見
          • 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
          • --wz.xjtu
          • 3.?re: Cache之我見
          • 在分布式環(huán)境里,多個(gè)用戶共用一個(gè)Cache,從Cache中獲取對(duì)象的時(shí)候,如何解決用戶之間的爭(zhēng)搶問(wèn)題,鎖定嗎?
          • --awp001
          • 4.?re: Cache之我見
          • 目前我的核心任務(wù)是實(shí)現(xiàn)一個(gè)對(duì)象池,減少垃圾收集,樓主能否提供一些建議?
          • --awp001
          • 5.?re: Cache之我見
          • 我這幾天正在研究在系統(tǒng)內(nèi)引入緩存,樓主說(shuō)的一級(jí)緩存 二級(jí)緩存 是一個(gè)很好的想法。
          • --awp001

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 凯里市| 海宁市| 沧源| 巴彦淖尔市| 中牟县| 深泽县| 东辽县| 固镇县| 七台河市| 红安县| 洪江市| 伊川县| 铁力市| 赣榆县| 湖北省| 长泰县| 海阳市| 五寨县| 绿春县| 龙海市| 台东县| 延安市| 彭泽县| 淮北市| 谢通门县| 和平县| 朔州市| 合山市| 五原县| 阳朔县| 武乡县| 岳西县| 唐河县| 彩票| 阳西县| 西青区| 沛县| 南通市| 长海县| 庆元县| 磴口县|