jinfeng_wang

          G-G-S,D-D-U!

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks

          轉(zhuǎn)載請(qǐng)注明出處哈:http://carlosfu.iteye.com/blog/2269678


           一、緩存的幾種更新策略

           

            從下面的表格看,緩存的更新策略大致分為三種,本文將從一致性和維護(hù)成本兩個(gè)方面對(duì)于三種緩存更新策略進(jìn)行簡(jiǎn)要說(shuō)明,因?yàn)檫@些東西比較理論和抽象,如哪里說(shuō)得不對(duì),歡迎拍磚。

             

            注:

            (1) 一致性:緩存和真實(shí)數(shù)據(jù)源(例如mysql, hbase, elasticsearch等等)是否存在一段時(shí)間數(shù)據(jù)的不一致。

            (2) 維護(hù)成本: 開(kāi)發(fā)人員的開(kāi)發(fā)和維護(hù)成本。

          策略一致性維護(hù)成本
          LRU/LIRS/FIFO算法剔除最差
          超時(shí)剔除較差較低
          主動(dòng)更新強(qiáng)

           

          二、LRU/LFU/FIFO算法剔除

           

          1. 使用場(chǎng)景:

              通常用于緩存使用量超過(guò)了預(yù)設(shè)的最大值時(shí)候(緩存空間不夠),如何對(duì)現(xiàn)有的數(shù)據(jù)進(jìn)行清理。例如FIFO會(huì)把最新進(jìn)入緩存的數(shù)據(jù)清理出去, LRU會(huì)把最近最少使用的數(shù)據(jù)清理掉。

          例如:Memcache使用的是LRU,具體Memcache如何實(shí)現(xiàn)的,這里就不在贅述了,網(wǎng)上資料多的是。

          例如:Redis使用maxmemory-policy這個(gè)配置作為內(nèi)存最大值后對(duì)于數(shù)據(jù)的更新策略。

          配置名含義默認(rèn)值
          maxmemory最大可用內(nèi)存不使用該配置,也就對(duì)內(nèi)存使用無(wú)限制
          maxmemory-policy內(nèi)存不夠時(shí),淘汰策略volatile-lru
          • volatile-lru -> 用lru算法刪除過(guò)期的鍵值
          • allkeys-lru -> 用lru算法刪除所有鍵值
          • volatile-random -> 隨機(jī)刪除過(guò)期的鍵值
          • allkeys-random -> 隨機(jī)刪除任何鍵值
          • volatile-ttl -> 刪除最近要到期的鍵值
          • noeviction -> 不刪除鍵,只返回一個(gè)錯(cuò)誤

           

          2. 常用算法:

          這里不再贅述,常用的算法有如下幾種:

          FIFO[first in first out] 

          LFU[Less Frequently Used] 

          LRU[Least Recently used] 

           

           

          3. 一致性

          可以想象,要清理哪些數(shù)據(jù),不是由開(kāi)發(fā)者決定(只能決定大致方向:策略算法),數(shù)據(jù)的一致性是最差的。

           

          4. 維護(hù)成本

          這些算法不需要開(kāi)發(fā)者自己來(lái)實(shí)現(xiàn),通常只需要配置最大maxmemory和對(duì)應(yīng)的策略即可。

          開(kāi)發(fā)者只需要有這個(gè)東西,知道是什么意思,選擇自己需要的算法,算法的實(shí)現(xiàn)是由緩存服務(wù)器實(shí)現(xiàn)的。

           

           

          三、超時(shí)剔除

           

          1. 使用場(chǎng)景:

             就是我們通常做的緩存數(shù)據(jù)過(guò)期時(shí)間設(shè)置,例如redis和memcache都提供了expire這樣的API,來(lái)設(shè)置K-V的過(guò)期時(shí)間。

             一般來(lái)說(shuō)業(yè)務(wù)可以容忍一段時(shí)間內(nèi)(例如一個(gè)小時(shí)),緩存數(shù)據(jù)和真實(shí)數(shù)據(jù)(例如:mysql, hbase等等)數(shù)據(jù)不一致(一般來(lái)說(shuō),緩存可以提高訪問(wèn)速度降低后端負(fù)載),那么我們可以對(duì)一個(gè)數(shù)據(jù)設(shè)置一定時(shí)間的過(guò)期時(shí)間,在數(shù)據(jù)過(guò)期后,再?gòu)恼鎸?shí)數(shù)據(jù)源獲取數(shù)據(jù),重新放到緩存中,繼續(xù)設(shè)置過(guò)期時(shí)間。

             例如: 一個(gè)視頻的描述信息,我們可以容忍一個(gè)小時(shí)內(nèi)數(shù)據(jù)不一致,但是涉及到錢的方面,如果不一致可想而知。

             

          2. 一致性:

              一段時(shí)間內(nèi)(取決于過(guò)期時(shí)間)存在數(shù)據(jù)一致性問(wèn)題,即緩存數(shù)據(jù)和真實(shí)數(shù)據(jù)源數(shù)據(jù)不一致。

           

          3. 維護(hù)成本

                用戶的維護(hù)成本不是很高,只需要設(shè)置expire過(guò)期時(shí)間即可(前提是你的業(yè)務(wù)允許這段時(shí)間可能發(fā)生的數(shù)據(jù)不一致)。

           

          四、主動(dòng)更新

           

          1. 使用背景:

             業(yè)務(wù)對(duì)于數(shù)據(jù)的一致性要求很高,需要在真實(shí)數(shù)據(jù)更新后,立即更新緩存數(shù)據(jù)。

             具體做法:例如可以利用消息系統(tǒng)或者其他方式(比如數(shù)據(jù)庫(kù)觸發(fā)器,或者其他數(shù)據(jù)源的listener機(jī)制來(lái)完成)通知緩存更新。

           

          2.  一致性:

             可以想象一致性最高(幾乎接近強(qiáng)一致),但是有個(gè)問(wèn)題:如果主動(dòng)更新發(fā)生了問(wèn)題,那么這條數(shù)據(jù)很可能很長(zhǎng)時(shí)間不會(huì)更新了(所以可以結(jié)合超時(shí)剔除一起使用,下面最佳實(shí)踐會(huì)說(shuō)到)

           

          3. 維護(hù)成本:

             相當(dāng)高,用戶需要自己來(lái)完成更新(需要一定量的代碼,從某種程度上加大了系統(tǒng)的復(fù)雜性),需要自己檢查數(shù)據(jù)是否真的更新了之類的工作。

           

          五、最佳實(shí)踐

              其實(shí)最佳實(shí)踐就是組合使用:

              1. 一般來(lái)說(shuō)我們都需要配置超過(guò)最大緩存后的更新策略(例如:LRU)以及最大內(nèi)存,這樣可以保證系統(tǒng)可以繼續(xù)運(yùn)行(例如redis可能存在OOM問(wèn)題)(極端情況下除外,數(shù)據(jù)一致性要求極高)。

              2. 一般來(lái)說(shuō)我們需要把超時(shí)剔除和主動(dòng)更新組合使用,那樣即使主動(dòng)更新出了問(wèn)題,也能保證過(guò)期時(shí)間后,緩存就被清除了(不至于永遠(yuǎn)都是臟數(shù)據(jù))。

           

           

          posted on 2016-12-20 17:12 jinfeng_wang 閱讀(230) 評(píng)論(0)  編輯  收藏 所屬分類: 2016-REDIS
          主站蜘蛛池模板: 龙川县| 营山县| 平陆县| 墨玉县| 临清市| 安丘市| 内江市| 陆川县| 增城市| 顺昌县| 张家界市| 张家港市| 诸城市| 大理市| 中牟县| 锡林浩特市| 永宁县| 获嘉县| 东乌| 丘北县| 平塘县| 酉阳| 泰宁县| 千阳县| 平顺县| 巨野县| 武冈市| 乌兰县| 巴林左旗| 老河口市| 阿克陶县| 康保县| 南京市| 宾川县| 伊宁市| 开远市| 内江市| 京山县| 彰武县| 紫云| 河池市|