放翁(文初)的一畝三分地

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            210 隨筆 :: 1 文章 :: 320 評(píng)論 :: 0 Trackbacks

          今天組里的同學(xué)和我談起local cache的一點(diǎn)需求,希望考慮在性能和業(yè)務(wù)上找到平衡點(diǎn)應(yīng)該怎么考慮實(shí)現(xiàn)。下午給他的意見(jiàn)可能還是有點(diǎn)問(wèn)題,回家稍微整理了一下,說(shuō)出來(lái)也可以激發(fā)大家的討論,覺(jué)得現(xiàn)在local cache + 遠(yuǎn)端cache是提高性能的必備,所以如何做好local cache 很有講究。

              由于有網(wǎng)絡(luò)傳輸帶來(lái)的性能損失(包括連接數(shù)并發(fā)限制),很多大請(qǐng)求量系統(tǒng)都會(huì)考慮做部分本地緩存。但本地緩存最大的問(wèn)題就是數(shù)據(jù)同步,如果讓集中式存儲(chǔ)(cache,queue)來(lái)通知只會(huì)增加復(fù)雜度,因此通常最簡(jiǎn)單的方式就是根據(jù)業(yè)務(wù)數(shù)據(jù)的敏感度設(shè)置不同長(zhǎng)短的本地失效時(shí)間。但現(xiàn)在如果要設(shè)置一個(gè)較短的有效期(例如一秒),對(duì)于計(jì)算機(jī)來(lái)說(shuō)已經(jīng)大大的減輕了壓力(1秒對(duì)程序來(lái)說(shuō)太久了),但是整體本地緩存對(duì)后端保護(hù)的效果不佳(特別是后端如果是并發(fā)處理能力較弱的系統(tǒng)),如果遇到并發(fā)量大的系統(tǒng),那么就更為突出了。

             早先有想過(guò)通過(guò)鎖來(lái)保證請(qǐng)求不會(huì)全部放過(guò)去(失效時(shí)就一個(gè)請(qǐng)求過(guò)去更新,其他請(qǐng)求等待),一來(lái)是針對(duì)內(nèi)容作鎖,對(duì)鎖的需求量很大(當(dāng)業(yè)務(wù)數(shù)據(jù)很多時(shí)),二來(lái)如果采用其他請(qǐng)求阻塞(對(duì)于系統(tǒng)來(lái)說(shuō)壓力也很大),這點(diǎn)后來(lái)談起可以直接返回老數(shù)據(jù)而不等待。但總體看起來(lái)消耗依然很大。

             因此給了下圖:

                                                                                                                  

            

                首先開(kāi)始的時(shí)候會(huì)有部分?jǐn)?shù)據(jù)被推送到本地緩存(當(dāng)然也可以是客戶端主動(dòng)獲取全部數(shù)據(jù)),也可以全部采用lazy加載,推送來(lái)的數(shù)據(jù)緩存在本地,并且設(shè)置失效時(shí)間,為每一個(gè)key還會(huì)有一份失效時(shí)間Map用于檢查是否失效。應(yīng)用發(fā)起get的請(qǐng)求,先從本地拿,如果有數(shù)據(jù)且有效,就直接返回。如果沒(méi)有命中,則去遠(yuǎn)端獲取資源,并緩存在本地,最后返回給應(yīng)用(這里如果要防攻擊可以采用布隆算法建立白名單)。如果發(fā)現(xiàn)本地?cái)?shù)據(jù)失效,則將失效事件放入到一個(gè)本地的EventMap中,key為當(dāng)前請(qǐng)求數(shù)據(jù)的key,然后設(shè)置這個(gè)key的時(shí)間為當(dāng)前時(shí)間+有效間隔時(shí)間(不做并發(fā)控制,多次放入EventMap會(huì)被覆蓋,多次設(shè)置時(shí)間有效期還是當(dāng)前時(shí)間+間隔時(shí)間),后續(xù)請(qǐng)求就會(huì)認(rèn)為這個(gè)數(shù)據(jù)是有效的不會(huì)連續(xù)請(qǐng)求更新,然后返回老數(shù)據(jù)。后臺(tái)分發(fā)線程檢查消息Map,將事件分發(fā)到后臺(tái)線程池異步執(zhí)行,最后更新結(jié)果并設(shè)置有效時(shí)間。
                最后還有一個(gè)后臺(tái)清理線程將過(guò)老的數(shù)據(jù)從緩存中移除,在map滿或者到了清理間隔的時(shí)候去執(zhí)行。

               這種設(shè)計(jì)有一定的復(fù)雜度,但是還算是松耦合,在并發(fā)高的情況下,犧牲數(shù)據(jù)較小的即時(shí)性換取對(duì)后端的保護(hù)。不過(guò)如果沒(méi)有必要,做的簡(jiǎn)單粗暴一點(diǎn)即可,不需要那么復(fù)雜。同時(shí)如果有更好的意見(jiàn)和建議的同學(xué)請(qǐng)回帖討論,或者去我的微薄討論: t.sina.com.cn/fangweng

          posted on 2010-12-14 22:34 岑文初 閱讀(3422) 評(píng)論(4)  編輯  收藏

          評(píng)論

          # re: Local Cache的小TIP 2010-12-15 03:26 安全
          學(xué)習(xí)了 這個(gè)還不錯(cuò)  回復(fù)  更多評(píng)論
            

          # re: Local Cache的小TIP 2010-12-20 09:17 鐵木真
          top為什么不搞OAuth認(rèn)證?國(guó)內(nèi)各大巨頭都開(kāi)放了OAuth認(rèn)證  回復(fù)  更多評(píng)論
            

          # re: Local Cache的小TIP 2010-12-20 11:12 岑文初
          @鐵木真
          包括google,flickr都有自己的認(rèn)證,雖然支持OAuth,這種看起來(lái)大而全的標(biāo)準(zhǔn),在實(shí)際使用中最多只能用于平臺(tái)互通,在初期的平臺(tái)建設(shè)上,并不一定要去趕著潮流,呵呵。而且我做開(kāi)放平臺(tái)的時(shí)候,OAuth還是0.1呢。OAuth1和2差異也很大,不過(guò)明年我為了平臺(tái)間互通也會(huì)考慮支持一下。  回復(fù)  更多評(píng)論
            

          # re: Local Cache的小TIP 2010-12-20 14:58 鐵木真
          @岑文初
          實(shí)現(xiàn)OAuth是必須的,top搞自己的一套對(duì)開(kāi)發(fā)者不友好

          OAuth不大也不全,過(guò)程只有三步,目的也只有一個(gè)就是獲取一個(gè)Access Token,這就是標(biāo)準(zhǔn),拿到Access Token之后的操作就是各開(kāi)放平臺(tái)自己的事情.

          第三方網(wǎng)站可以使用新浪網(wǎng)易搜狐騰訊豆瓣的id以O(shè)Auth的方式登錄,開(kāi)發(fā)者只需要根據(jù)具體每個(gè)開(kāi)放平臺(tái)提供的api獲取用戶profile,目前各個(gè)平臺(tái)的api有差異,有些是xml有些是json,schema也不一樣,說(shuō)不定將來(lái)OAuth也會(huì)把這個(gè)也標(biāo)準(zhǔn)化了.

            回復(fù)  更多評(píng)論
            


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 华亭县| 通辽市| 沁水县| 宝应县| 杨浦区| 于田县| 岳阳市| 巴中市| 天长市| 天全县| 阳朔县| 昌乐县| 义马市| 黄石市| 宜兴市| 玉山县| 五华县| 邵阳市| 敦化市| 新竹县| 江口县| 通城县| 庆安县| 平定县| 瓮安县| 淮阳县| 安西县| 辰溪县| 灵石县| 济阳县| 荔波县| 黑山县| 夏津县| 景东| 宝应县| 新泰市| 龙陵县| 昂仁县| 玉田县| 襄汾县| 盐山县|