国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

談談服務端緩存的幾種用法

CocoaChina / 2568人閱讀

摘要:緩存是一個常談常新的話題,作為一名服務端的技術,如果你入行一年都還沒用過類產品,那只能說你的公司實在太小了,或者你干的活實在太邊緣了。這是緩存最原始的意義,同時也引申出了緩存最普遍的用法。但是現(xiàn)實中還有一種緩存,是主動更新的。

緩存是一個常談常新的話題,作為一名服務端的技術,如果你入行一年都還沒用過memcached類產品,那只能說你的公司實在太小了,或者你干的活實在太邊緣了。

說起緩存,可能大家最直接想到的就是:“在數(shù)據(jù)庫前面擋一層”。這是緩存最原始的意義,同時也引申出了緩存最普遍的用法。

原始模式 代碼示例1(原始模式):
//從緩存中獲取數(shù)據(jù)[較快的方式]
data = getfromcache(id)
if data == null then
    //從數(shù)據(jù)庫中獲取數(shù)據(jù)[較慢的方式]
    data = getfromdb(id)
    //緩存1天
    setintocache(id, data, 86400)
    return data
end

return data
緩存加鎖

上面這種情況下,當同時有N個請求到達,都同時執(zhí)行getfromcache,那么都會發(fā)現(xiàn)data在緩存中不存在,然后都會去調用getfromdb,以及setintocache。這是不必要的,那么我們有沒有辦法減少這些并發(fā)呢。

最直接的想法是加鎖,當進入if條件中時,加一把鎖,讓其他進程不再執(zhí)行下面的邏輯,而是等第一個進程的setintocache執(zhí)行完成后,再重新執(zhí)行一次getfromcache。

那這個鎖如何加呢?這里推薦一種省時省力的方法。通過直接在緩存value中設置過期時間來實現(xiàn)。

比如緩存的value值為data,那我們修改一下,把它放到一個json中,改成

{data:data,atime:1429618765}

我們增加了一個atime來記錄緩存生成的時間。而邏輯就變成下面這樣。

代碼示例2(緩存加鎖):
//從緩存中獲取數(shù)據(jù)[較快的方式]
data = getfromcache(id)
data = json.decode(data)
//如果通過檢查緩存生成時間,發(fā)現(xiàn)緩存已經(jīng)過于陳舊,那么就將緩存過期時間設置為現(xiàn)在開始的5分鐘以后(這樣其他并發(fā)進程就會以為此緩存還未過期,還會繼續(xù)使用5分鐘,只讓當前這一個請求去重建緩存)
if data != null && data.atime+86400 < now then
    data.atime = now+300-86400
    data = json.encode(data)
    //對真正的cache來說,緩存10天或者更長時間
    setintocache(id, data, 864000)
    //這里把data設置成null是為了走到下面的if中去重建緩存
    data = null
end

if data == null then
    //從數(shù)據(jù)庫中獲取數(shù)據(jù)[較慢的方式]
    data = getfromdb(id)
    data = {data:data, atime:now}
    data = json.encode(data)
    //對真正的cache來說,緩存10天或者更長時間
    setintocache(id, data, 864000)
    return data
end

return data

你可以會發(fā)現(xiàn),這里也會存在并發(fā)啊,和上面例1一樣,第一個getfromcache到setintocache之間,如果同時有N個請求到來,不還是都會執(zhí)行這段操作,都會去查庫嗎。

沒錯,是這樣的。但是我們仔細看一下,例1中,從getfromcache到setintocache之間,經(jīng)歷了一次漫長的getfromdb操作,這個時間耗費可能是上百毫秒的。而我們例2中,并沒有進行什么操作,這個時間耗費只在毫秒甚至微秒級的。

所以例1中getfromcache到setintocache之間的并發(fā)是遠大于例2中的。例2中通過減小時間窗口,有效的模擬了鎖機制。同時還沒有增強額外的存儲復雜度。所以是推薦的一種方式。

可以說,我們所有的緩存都應該是例2的方式,他在各方面都優(yōu)于例1(多保存的一個atime字段耗費的內存基本可以忽略不計。且atime很多時候對于調試程序還很有用)。

主動更新緩存

那這樣就夠了嗎?對于被動過期型的緩存,這樣基本就可以了。但是現(xiàn)實中還有一種緩存,是主動更新的。試想有一種緩存,我們要求必須和數(shù)據(jù)庫中的數(shù)據(jù)一致,不能出現(xiàn)陳舊數(shù)據(jù)。那么上面的緩存方式就不合適了。

我們必然會添加一個流程:即當數(shù)據(jù)庫有更新時,同時更新緩存,因為緩存會自己重建,也可以修改為當數(shù)據(jù)庫有更新時,同時刪除緩存。

這里提到刪除或者更新緩存,就有點意思了。我們上面講到的都是非常簡單的緩存,即一個id對應一個key。那么試想,如果我們有一個分頁緩存,緩存了某一個文章最新的前10頁數(shù)據(jù)。分別的key是page_1,page_2...page10。

那么當我們有一條新數(shù)據(jù)產生,這10頁就都失效了,需要更新或者刪除10次。這顯然是不太科學的做法。

那么我們應該怎么做呢。我們可以借用上面例2中的方法,例2中,我們在緩存中增加了一個atime字段,標識為緩存的生成時間。我們既然知道緩存什么時候生成的,那問題就好解決了。我們在每次有新數(shù)據(jù)產生時,都去更新一個updatetime字段。然后獲取分頁緩存的時候,看一下這個updatetime字段是不是在atime之后,如果是,那么說明這份緩存太舊了,需要走更新流程。

代碼示例3(避免批量更新):
//從緩存中獲取數(shù)據(jù)[較快的方式][這里的兩次get普通的緩存系統(tǒng)都支持一個請求完成]
data = getfromcache(id)
updatetime = getupdatetime(id)
data = json.decode(data)
//如果通過檢查緩存生成時間,發(fā)現(xiàn)緩存已經(jīng)過于陳舊,那么就將緩存過期時間設置為現(xiàn)在開始的5分鐘以后(這樣其他并發(fā)進程就會以為此緩存還未過期,還會繼續(xù)使用5分鐘,只讓當前這一個請求去重建緩存)
if data != null && (data.atime+86400 < now || date.atime < updatetime) then
    data.atime = now+300-86400
    data = json.encode(data)
    //對真正的cache來說,緩存10天或者更長時間
    setintocache(id, data, 864000)
    //這里把data設置成null是為了走到下面的if中去重建緩存
    data = null
end

if data == null then
    //從數(shù)據(jù)庫中獲取數(shù)據(jù)[較慢的方式]
    data = getfromdb(id)
    data = {data:data, atime:now}
    data = json.encode(data)
    //對真正的cache來說,緩存10天或者更長時間
    setintocache(id, data, 864000)
    return data
end

return data

這僅僅是在代碼示例2的基礎上增加了下面這一個條件判斷而已

date.atime < updatetime

這樣,無論是緩存保存時間過期了,還是緩存本身有更新,都會觸發(fā)帶鎖機制的緩存更新。

好了,先說到這里,回頭有想起來的再做更新。原文地址


順便插播一則招聘廣告。(碼字不易,求別刪招聘廣告,謝!)

易手機坐標深圳,做一款易用安全的老年智能手機,做老年手機第一品牌。現(xiàn)在灰常需要服務端同學入伙。有興趣的同學請私信或簡歷發(fā)郵箱:ligang#pingyijinren.com

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/61769.html

相關文章

  • 談談服務緩存幾種用法

    摘要:緩存是一個常談常新的話題,作為一名服務端的技術,如果你入行一年都還沒用過類產品,那只能說你的公司實在太小了,或者你干的活實在太邊緣了。這是緩存最原始的意義,同時也引申出了緩存最普遍的用法。但是現(xiàn)實中還有一種緩存,是主動更新的。 緩存是一個常談常新的話題,作為一名服務端的技術,如果你入行一年都還沒用過memcached類產品,那只能說你的公司實在太小了,或者你干的活實在太邊緣了。 說起...

    tianhang 評論0 收藏0
  • 史上最全阿里 Java 面試題總結

    摘要:以下為大家整理了阿里巴巴史上最全的面試題,涉及大量面試知識點和相關試題。的內存結構,和比例。多線程多線程的幾種實現(xiàn)方式,什么是線程安全。點擊這里有一套答案版的多線程試題。線上系統(tǒng)突然變得異常緩慢,你如何查找問題。 以下為大家整理了阿里巴巴史上最全的 Java 面試題,涉及大量 Java 面試知識點和相關試題。 JAVA基礎 JAVA中的幾種基本數(shù)據(jù)類型是什么,各自占用多少字節(jié)。 S...

    winterdawn 評論0 收藏0
  • 基礎

    摘要:談起閉包,它可是兩個核心技術之一異步基于打造前端持續(xù)集成開發(fā)環(huán)境本文將以一個標準的項目為例,完全拋棄傳統(tǒng)的前端項目開發(fā)部署方式,基于容器技術打造一個精簡的前端持續(xù)集成的開發(fā)環(huán)境。 這一次,徹底弄懂 JavaScript 執(zhí)行機制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機制,如果讀完本文還不懂,可以揍我。 不論你是javascript新手還是老鳥,不論是面試求職,還是日...

    graf 評論0 收藏0
  • 面試題總結(js、html、小程序、React、ES6、Vue、算法、全棧熱門視頻資源)

    摘要:并總結經(jīng)典面試題集各種算法和插件前端視頻源碼資源于一身的文檔,優(yōu)化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快速搭建項目。 本文是關注微信小程序的開發(fā)和面試問題,由基礎到困難循序漸進,適合面試和開發(fā)小程序。并總結vue React html css js 經(jīng)典面試題 集各種算法和插件、前端視頻源碼資源于一身的文檔,優(yōu)化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快...

    pumpkin9 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<