<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          分布式實(shí)戰(zhàn):緩存穿透解決方案

          共 3075字,需瀏覽 7分鐘

           ·

          2022-01-04 21:58

          28782cb2d3339a51d10d2edef91fa190.webp

          本文首發(fā)于Ressmix個(gè)人站點(diǎn):https://www.tpvlog.com

          本章,我將講解與緩存相關(guān)的最后兩個(gè)場(chǎng)景——緩存穿透緩存失效

          所謂緩存穿透,是指緩存沒(méi)有發(fā)揮作用,業(yè)務(wù)系統(tǒng)雖然去緩存查詢數(shù)據(jù),但緩存中沒(méi)有數(shù)據(jù),業(yè)務(wù)系統(tǒng)需要再次去存儲(chǔ)系統(tǒng)查詢數(shù)據(jù)。

          所謂緩存失效,是指在某一時(shí)間點(diǎn),緩存中的數(shù)據(jù)都過(guò)期了,此時(shí)緩存沒(méi)有發(fā)揮作用,大量請(qǐng)求直接打到后臺(tái)服務(wù)。

          一、緩存穿透

          1.1 典型場(chǎng)景

          對(duì)于我們的epay-cache應(yīng)用,一種緩存穿透的典型場(chǎng)景就是:Redis正常運(yùn)行,但是很多請(qǐng)求并沒(méi)有命中緩存,接著去源服務(wù)(數(shù)據(jù)庫(kù))查詢也不存在:

          ec7e01a3f12b3844f0b36e6e96430614.webp

          緩存穿透的問(wèn)題很明顯,本來(lái)我們加緩存就是為了提升系統(tǒng)性能,防止請(qǐng)求直接打到數(shù)據(jù)庫(kù),現(xiàn)在緩存命中不了了,所有請(qǐng)求會(huì)直接去數(shù)據(jù)庫(kù)查詢。如果并發(fā)量很高,會(huì)瞬間讓數(shù)據(jù)庫(kù)崩掉。

          1.2 解決方案

          針對(duì)緩存穿透問(wèn)題,常見(jiàn)的解決思路就是:如果數(shù)據(jù)庫(kù)中也找不到數(shù)據(jù),就緩存一個(gè)空對(duì)象。以epay-cache中商品信息查詢?yōu)槔槍?duì)指定的productId創(chuàng)建一個(gè)空商品對(duì)象,緩存到Redis中,這樣下次請(qǐng)求過(guò)來(lái)的時(shí)候就直接從Redis中查詢到了空對(duì)象,而不會(huì)去數(shù)據(jù)庫(kù)查詢。

          二、緩存失效

          針對(duì)緩存失效的場(chǎng)景,一種常見(jiàn)的解決方案就是:對(duì)于某一種類型的緩存,比如我們的商品詳情緩存,設(shè)置隨機(jī)的緩存過(guò)期時(shí)間,防止在某一時(shí)刻緩存同時(shí)失效。

          2.1 解決方案

          我們之前在OpenResty的應(yīng)用層進(jìn)行了商品詳情數(shù)據(jù)的緩存,可以在lua腳本中設(shè)置隨機(jī)的緩存過(guò)期時(shí)間:

           1--獲取請(qǐng)求參數(shù)
          2local?uri_args?=?ngx.req.get_uri_args()
          3local?productId?=?uri_args["productId"]
          4local?shopId?=?uri_args["shopId"]
          5
          6--Nginx本地緩存
          7local?cache_ngx?=?ngx.shared.product_cache
          8
          9--緩存key
          10local?productCacheKey?=?"product_info_"..productId
          11local?shopCacheKey?=?"shop_info_"..shopId
          12
          13--先從Nginx本地緩存查找
          14local?productCache?=?cache_ngx:get(productCacheKey)
          15local?shopCache?=?cache_ngx:get(shopCacheKey)
          16
          17if?productCache?==?""?or?productCache?==?nil?then
          18????--本地緩存不存在,調(diào)用緩存數(shù)據(jù)生產(chǎn)服務(wù)接口查找
          19????local?http?=?require("resty.http")
          20????local?httpc?=?http.new()
          21
          22????--http://192.168.0.101:8080是緩存數(shù)據(jù)生產(chǎn)服務(wù)的地址,生產(chǎn)一般是內(nèi)部域名
          23????local?resp,?err?=?httpc:request_uri("http://192.168.0.101:8080",{
          24??????????method?=?"GET",
          25??????????path?=?"/getProductInfo?productId="..productId
          26????})
          27
          28????--將結(jié)果更新到Nginx本地緩存
          29????productCache?=?resp.body
          30
          31????--緩存過(guò)期時(shí)間:隨機(jī)
          32????math.randomseed(tostring(os.time()):reverse():sub(1,?7))
          33????local?expireTime?=?math.random(600,?1200)?
          34????cache_ngx:set(productCacheKey,?productCache,?expireTime)
          35end
          36
          37if?shopCache?==?""?or?shopCache?==?nil?then
          38????local?http?=?require("resty.http")
          39????local?httpc?=?http.new()
          40
          41????local?resp,?err?=?httpc:request_uri("http://192.168.0.101:8080",{
          42??????????method?=?"GET",
          43??????????path?=?"/getShopInfo?shopId="..shopId
          44????})
          45
          46????shopCache?=?resp.body
          47
          48????--緩存過(guò)期時(shí)間:隨機(jī)
          49????math.randomseed(tostring(os.time()):reverse():sub(1,?7))
          50????local?expireTime?=?math.random(600,?1200)??
          51????cache_ngx:set(shopCacheKey,?shopCache,?expireTime)
          52end
          53
          54--json字符串轉(zhuǎn)json對(duì)象
          55local?cjson?=?require("cjson")
          56local?productCacheJSON?=?cjson.decode(productCache)
          57local?shopCacheJSON?=?cjson.decode(shopCache)
          58
          59--html模板渲染
          60local?context?=?{
          61????productId?=?productCacheJSON.id,
          62????productName?=?productCacheJSON.name,
          63????productPrice?=?productCacheJSON.price,
          64????productPictureList?=?productCacheJSON.pictureList,
          65????productSpecification?=?productCacheJSON.specification,
          66????productService?=?productCacheJSON.service,
          67????productColor?=?productCacheJSON.color,
          68????productSize?=?productCacheJSON.size,
          69????shopId?=?shopCacheJSON.id,
          70????shopName?=?shopCacheJSON.name,
          71????shopLevel?=?shopCacheJSON.level,
          72????shopGoodCommentRate?=?shopCacheJSON.goodCommentRate
          73}
          74
          75local?template?=?require("resty.template")
          76template.render("product.html",?context)

          三、總結(jié)

          本章,我主要介紹了緩存穿透和緩存失效的兩種常見(jiàn)解決方案,本章屬于對(duì)《分布式理論之高性能:分布式緩存》這篇文章的補(bǔ)充。


          瀏覽 64
          點(diǎn)贊
          1評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          全部評(píng)論
          QS724765499d3e22cb82023-11-07 10:13
          您好,您的博客怎么訪問(wèn)不了了啊?求
          點(diǎn)贊回復(fù)
          推薦
          點(diǎn)贊
          1評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩黄色电影中文版 | 国产天堂视频 | 亚洲a在线l | 另类综合激情 | 亚洲人妻在线视频 |