最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

全網(wǎng)獨(dú)一無(wú)二值得收藏的,Web開(kāi)發(fā)基本準(zhǔn)則-緩存策略

2022-02-15 22:05 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

提綱:

  1. Web訪問(wèn)安全

  2. 緩存策略

  3. 存儲(chǔ)介質(zhì)連接池

  4. 業(yè)務(wù)降級(jí)

  5. 并發(fā)請(qǐng)求的處理

關(guān)鍵詞:

  • 會(huì)話串號(hào),Cache-Control頭域,緩存穿透,緩存集體失效,緩存重建,緩存雪崩,緩存永不過(guò)期,緩存計(jì)數(shù)器,

緩存策略

  • 這里的“緩存”概念不只限于服務(wù)器端的“緩存”。

防會(huì)話串號(hào)

  • 如果你收到一個(gè)投訴,說(shuō)訪問(wèn)“我的個(gè)人中心”頁(yè)面時(shí)進(jìn)入其他人的帳號(hào),至少訂單列表上顯示的不是自己的。此時(shí),技術(shù)支持人員可以提三個(gè)問(wèn)題,

  1. 第一,對(duì)頁(yè)面上顯示的信息是否有操作權(quán)限,如取消訂單;

  2. 第二,瀏覽器地址欄上給URL增加訪問(wèn)參數(shù),如追加一個(gè)&111之類的字符串,看看頁(yè)面是否還是顯示別人的信息;

  3. 第三,投訴者上網(wǎng)接入方式是什么,如鐵通光纖寬帶,如通過(guò)某款代理軟件上網(wǎng)。

  • 如果既無(wú)操作權(quán)限,追加URL參數(shù)后又能看到自己的帳號(hào)信息或頁(yè)面提示處于未登錄狀態(tài),那么說(shuō)明是URL已被各級(jí) HTTP Proxies 緩存:

  • 即在服務(wù)器端收到 Request 之前,網(wǎng)絡(luò)鏈路上的某一級(jí)代理已返回緩存數(shù)據(jù)。

簡(jiǎn)單辦法,如利用Expiration Model

  • 第一種:如果頁(yè)面 Response 里設(shè)置了正確的 Last-modified 和 Expires 頭域,那么 基本過(guò)期模型 已經(jīng)能正常運(yùn)轉(zhuǎn)了,因此,頭域里的 Cache-Control:private 聲明就已經(jīng)夠了,HTTP Caches 和 User Agent 都會(huì)根據(jù)這兩個(gè)字段檢查緩存網(wǎng)頁(yè)是否陳舊。

  • 第二種:重要頁(yè)面的URL上加時(shí)間戳參數(shù)。

  • 第三種:像淘寶博文[注1]所描述的:“cookie 里增加一個(gè)值,用來(lái)記錄通過(guò)關(guān)鍵 cookie 計(jì)算出來(lái)的簽名,這個(gè)簽名的算法非常簡(jiǎn)單。每次請(qǐng)求到服務(wù)端的時(shí)候 session 框架代碼里會(huì)對(duì)此簽名進(jìn)行匹配,如果和服務(wù)端獲取的數(shù)據(jù)簽名出來(lái)的值是一致的,則認(rèn)為合法,否則清空 session 信息和 cookie 信息,讓用戶重新登錄。”

需要有更多背景知識(shí)的辦法:利用 Cache-Control 頭域控制

  • Web開(kāi)發(fā)工程師都需要了解 Cache-control 頭域背后的 HTTP 1.1緩存控制機(jī)制和緩存重驗(yàn)證機(jī)制。

  • 先說(shuō)處理辦法是:含個(gè)人敏感信息的網(wǎng)頁(yè)響應(yīng)頭里,聲明 Cache-Control:must-revalidate,proxy-revalidate,no-store,private,no-cache 即可。

  • HTTP1.1協(xié)議定義,Response 是可以被各種 HTTP caches 緩存的。

  • 除非有 Cache-Control 控制指令的特殊約定,否則從瀏覽器端到源服務(wù)器(origin server)端之間鏈路上所存在的各種 Caching System 都完全有可能緩存一個(gè)成功的 response:

  • ?如果這個(gè) cache entry 是 fresh 的,可能不會(huì)(去源服務(wù)器端)校驗(yàn)直接返回;也可能會(huì)做一個(gè)校驗(yàn)再返回。 ?一個(gè)狀態(tài)碼是200, 203, 206, 300, 301, 410的 response,可能會(huì)被緩存。

緩存穿透

目的

  • 防止訪問(wèn)(短期內(nèi))必然不存在的數(shù)據(jù)導(dǎo)致請(qǐng)求穿透緩存直接打到 DB。

原因

  • 可能是數(shù)據(jù)真的不存在,但也可能是第三方惡意構(gòu)造大量不存在的 id 來(lái)沖擊 DB。

多種手段結(jié)合

  • 『存儲(chǔ)EMPTY』思路:存儲(chǔ)一個(gè) EMPTY 對(duì)象到緩存對(duì)應(yīng)鍵值,設(shè)置一個(gè)較短的過(guò)期時(shí)間。這樣在緩存失效后,還能繼續(xù)查詢數(shù)據(jù)是否存在。

  • 必須認(rèn)真對(duì)待(不同業(yè)務(wù)不同端口的)緩存命中率(get_hits/cmd_get * 100)定期監(jiān)控的結(jié)果,認(rèn)真審視那些命中率低的緩存端口,找到命中率低的原因,提出優(yōu)化方案。

  • 『先行校驗(yàn)』思想:采用布隆過(guò)濾器算法,將所有可能存在的數(shù)據(jù)(如所有有效商品的id)哈希到一個(gè)足夠大的 bitmap 里,那么一個(gè)一定不存在的數(shù)據(jù)會(huì)被這個(gè) bitmap 攔截掉,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。


”半緩存“策略

  • 緩存命中率低,其中一個(gè)原因是,你緩存的數(shù)據(jù)被人訪問(wèn)間隔長(zhǎng)、幾率低,于是在下次訪問(wèn)到來(lái)之前緩存早已失效。命中率低,為我們指出了優(yōu)化方向。

  • 如,用戶在查詢一個(gè)列表頁(yè)時(shí),我們可以把前6頁(yè)的數(shù)據(jù)緩存起來(lái),再往后的頁(yè)碼,訪問(wèn)頻次很低,也許就不需要緩存了。

緩存集體失效

  • 以下原因都會(huì)導(dǎo)致緩存集體失效,從而引發(fā)系統(tǒng)”抖動(dòng)“甚至”雪崩“:

  1. 系統(tǒng)預(yù)熱數(shù)據(jù)的緩存過(guò)期時(shí)間過(guò)于整齊劃一;

  2. 緩存系統(tǒng)宕機(jī)或重啟;

  3. 訪問(wèn)高峰期間種下了一大批緩存,過(guò)期時(shí)間非常接近。

?處理手段:

  • 緩存過(guò)期時(shí)間散列開(kāi):在過(guò)期時(shí)間基礎(chǔ)上增加一個(gè)隨機(jī)值,如1秒~120秒隨機(jī),將大家的過(guò)期時(shí)間盡量打散。

防范緩存節(jié)點(diǎn)暫不可用的緩存雙寫策略:

  • memcache雙寫:向 memcahce 的 Master Ring 和 Backup Ring 雙寫,如下圖1所示:

  • 圖1 memcache 雙寫 原圖出自點(diǎn)評(píng)技術(shù)PPT

  • Redis備份寫:向 memcache 寫入的同時(shí),寫一份到備份緩存 Redis 里,鍵值的緩存過(guò)期時(shí)間非常大,如原鍵值在 memcache 過(guò)期時(shí)間5分鐘,在 Redis 里則8小時(shí)過(guò)期。當(dāng) memcache 集群節(jié)點(diǎn)暫不可用時(shí),Web工程就切換讀取備用緩存 Redis。這種思路是保證基本可用性,所以必要時(shí)刻可以給用戶返回臟數(shù)據(jù)。

對(duì)于不同的業(yè)務(wù)場(chǎng)景,緩存的使用策略也不同:

  • 當(dāng)系統(tǒng)面臨緩存異常的危險(xiǎn)時(shí),有些系統(tǒng)可以采用備份方案繼續(xù)支撐服務(wù)。有些系統(tǒng)則會(huì)優(yōu)雅降級(jí),將某些依賴緩存的功能直接去除,保證主服務(wù)的正確性。所以這兩種策略的選擇需要根據(jù)實(shí)際的業(yè)務(wù)場(chǎng)景考慮并實(shí)施。

2.5.分級(jí)緩存

  • 有些業(yè)務(wù)場(chǎng)景里,應(yīng)該把 DB 當(dāng)成僅是一個(gè)存儲(chǔ)而已,靠分級(jí)緩存策略來(lái)層層抵擋緩存失效,不讓請(qǐng)求打到 DB。

手段:

  • 由遠(yuǎn)及近分層建立緩存,越靠近前端,緩存片段越大(或存儲(chǔ)粒度越大)。

  • 上一層的緩存失效,可以靠下一級(jí)的緩存迅速重建。

目的:

  • 避免系統(tǒng)產(chǎn)生抖動(dòng)。

  • 減少緩存雪崩,防止 DB 連接數(shù)暴漲、響應(yīng)變慢,連累前端應(yīng)用連接數(shù)持續(xù)高漲、最后宕機(jī)。



緩存重建

  • 既然有緩存過(guò)期,自然有緩存重建。

  • 熱點(diǎn)數(shù)據(jù)的緩存重建,無(wú)論是本地緩存還是遠(yuǎn)端緩存,都有必要加鎖來(lái)確保進(jìn)程內(nèi)同一時(shí)刻只有一個(gè) Worker 負(fù)責(zé)重建,甚至利用分布式鎖保證集群環(huán)境下只有一個(gè)重建者,避免緩存雪崩時(shí)的 Race Condition。TimYang 早在2010年在《Memcache mutex設(shè)計(jì)模式》中描述過(guò)如下風(fēng)險(xiǎn):”在大并發(fā)的場(chǎng)合,當(dāng)cache失效時(shí),大量并發(fā)同時(shí)取不到cache,會(huì)同一瞬間去訪問(wèn)db并回設(shè)cache,可能會(huì)給系統(tǒng)帶來(lái)潛在的超負(fù)荷風(fēng)險(xiǎn)。我們?cè)?jīng)在線上系統(tǒng)出現(xiàn)過(guò)類似故障。“孫立將這種場(chǎng)景稱為 cache key mutex 問(wèn)題[注7]。

  • 簡(jiǎn)而言之,緩存重建時(shí),當(dāng)多個(gè) Client 對(duì)同一個(gè)緩存數(shù)據(jù)發(fā)起請(qǐng)求時(shí),會(huì)在客戶端采用加鎖等待的方式,對(duì)同一個(gè) CacheKey 的重建需要獲取到相應(yīng)的排他鎖才行,只有拿到鎖的 Client 才能訪問(wèn)數(shù)據(jù)庫(kù)重建緩存,其他的 Client 都需要等待這個(gè)拿到鎖的 Client 重建好緩存后直接讀緩存。這樣,對(duì)同一個(gè)緩存數(shù)據(jù),只有一次數(shù)據(jù)庫(kù)重建訪問(wèn)。但是如果訪問(wèn)分散比較嚴(yán)重,還是會(huì)瞬間對(duì)數(shù)據(jù)庫(kù)造成非常大的壓力。

  • 當(dāng)然也可以不加(悲觀)鎖,那么多線程并發(fā)讀寫同一個(gè) cache key 可能會(huì)帶來(lái)“ABA問(wèn)題”。

  • 解決方法很簡(jiǎn)單:memcached 1.2.5以及更高版本提供了 gets 和 cas 命令。如果使用 gets 命令查詢某個(gè)鍵值,memcached 會(huì)返回該鍵值的唯一標(biāo)識(shí) casUnique。如果覆寫了這個(gè)鍵值并想把它寫回到 memcached 中,可以通過(guò) cas 命令把那個(gè) casUnique 一起發(fā)送給 memcached。如果該鍵值存放在 memcached 中的 casUnique 與提供的一致,寫操作將會(huì)成功。如果另一個(gè)進(jìn)程在這期間也修改了這個(gè)鍵值,那么該鍵值存放在 memcached 中的 casUnique 將會(huì)改變,寫操作就會(huì)失敗。

緩存永不過(guò)期

  • 因?yàn)閾?dān)心緩存失效帶來(lái)的系統(tǒng)抖動(dòng),所以有些業(yè)務(wù)場(chǎng)景會(huì)讓緩存永不過(guò)期,數(shù)據(jù)變化時(shí),由后端負(fù)責(zé)維護(hù)緩存數(shù)據(jù)一致性。

電商場(chǎng)景里的緩存計(jì)數(shù)器:秒殺和超賣

  • 分布式緩存的另一個(gè)應(yīng)用場(chǎng)景是緩存計(jì)數(shù)器。

  • 對(duì)于多服務(wù)器的系統(tǒng),分布式緩存提供了統(tǒng)一的存儲(chǔ)和原子操作,便于集群環(huán)境下的使用。庫(kù)存計(jì)數(shù)器是分布式緩存的一個(gè)典型應(yīng)用場(chǎng)景, 對(duì)于集群中的每一臺(tái)機(jī)器,庫(kù)存都應(yīng)該是一個(gè)統(tǒng)一的值,因此使用本地緩存記錄庫(kù)存,數(shù)據(jù)肯定是不準(zhǔn)確的(下面會(huì)陳述例外情況)。因此,統(tǒng)一的存儲(chǔ)空間是必要 的條件。

  • 由于庫(kù)存數(shù)據(jù)被多臺(tái)機(jī)器共享,因此,必須使用鎖機(jī)制控制多個(gè)請(qǐng)求的并行并發(fā)問(wèn)題?;谶@樣的機(jī)制就可以實(shí)行庫(kù)存技術(shù)器的作用,防止貨物超賣。最近的積分商城超值兌換就是使用的這種機(jī)制。

  • 這種機(jī)制下,需要注意操作的邏輯順序,錯(cuò)誤的順序會(huì)導(dǎo)致意想不到的結(jié)果。積分兌換的業(yè)務(wù)流程為,用戶看到要搶兌的商品,如果庫(kù)存大于0,則用戶可以點(diǎn)擊搶兌操作,這時(shí)用戶會(huì)獲得兌換該商品的權(quán)限,從而優(yōu)惠購(gòu)買,這時(shí)庫(kù)存商品應(yīng)該減一。

  • 如果完全按照這個(gè)業(yè)務(wù)流程,我們會(huì)完成下面這三步操作:

  1. 驗(yàn)證庫(kù)存是否大于0;

  2. 給用戶打標(biāo),使其獲得優(yōu)惠購(gòu)買資格;

  3. 獲得資格后,原子減庫(kù)存,記錄用戶購(gòu)買記錄。

  • 乍一看這樣的邏輯是很正常的,但是考慮一下異常情況,就會(huì)發(fā)現(xiàn)它防不住超賣。如果庫(kù)存只有一件,那么多個(gè)用戶并發(fā)驗(yàn)證庫(kù)存時(shí),都大于0。這樣并發(fā)的多個(gè)用戶都會(huì)獲得優(yōu)惠資格,產(chǎn)生了超賣。

正確的邏輯為:

  1. 驗(yàn)證庫(kù)存是否大于0,小于0直接返回;

  2. 原子減庫(kù)存,返回的結(jié)果如果小于0說(shuō)明已經(jīng)沒(méi)有庫(kù)存,直接返回;

  3. 如果返回的當(dāng)前庫(kù)存大于等于0,為用戶打標(biāo),如果打標(biāo)成功,記錄用戶購(gòu)買記錄;如果打標(biāo)失敗,回補(bǔ)原子庫(kù)存。

  • 這樣的方法,無(wú)法保證緩存中的值一定大于等于0,因?yàn)椴l(fā)的發(fā)生會(huì)把緩存減為負(fù)數(shù),但是,真正能夠優(yōu)惠購(gòu)買的用戶一定是小于等于庫(kù)存數(shù)的。因?yàn)?,每次原子減操作后,只有返回的庫(kù)存值大于等于零的用戶才能夠獲得購(gòu)買資格。無(wú)論并發(fā)量有多大,原子操作都會(huì)成功的防止超賣的發(fā)生。


  • 對(duì)于上述的邏輯,可以應(yīng)對(duì)絕大多數(shù)的情況。

  • 但是隨著量的增加,這種方式也有風(fēng)險(xiǎn)。當(dāng)用戶量極大、貨物的庫(kù)存極少時(shí),就變成了秒殺。這個(gè)時(shí)候,大量的用戶涌入分布式緩存減庫(kù)存,對(duì)分布式緩存有極大沖擊,一旦分布式緩存掛掉,秒殺活動(dòng)也就宣告失敗。使用分布式緩存,目的是為了讓用戶準(zhǔn)確的看到剩余庫(kù)存數(shù) 目,秒殺活動(dòng)非常快,用戶還沒(méi)有看清楚庫(kù)存,活動(dòng)就結(jié)束了。其實(shí)用戶只關(guān)心有沒(méi)有秒到商品,并不關(guān)心庫(kù)存的剩余數(shù)量,因此,庫(kù)存減得準(zhǔn)不準(zhǔn)確并不是主要矛盾,這時(shí)就可以放棄分布式緩存的設(shè)計(jì),轉(zhuǎn)而使用本地緩存存儲(chǔ)庫(kù)存數(shù),這也就是本地緩存使用的第二個(gè)場(chǎng)景。

  • 比如,一共有10件商品,2臺(tái)機(jī)器,可以設(shè)置每臺(tái)機(jī)器的本地內(nèi)存中庫(kù)存等于10,那么對(duì)于外網(wǎng)的千萬(wàn)個(gè)用戶,就可以有20個(gè)人搶到商品,剩下的人都 被擋在庫(kù)存之外。當(dāng)這20個(gè)人搶到后,就可以實(shí)現(xiàn)另一個(gè)處理邏輯,從20個(gè)人中選出10個(gè)真正中標(biāo)的人,獲得10個(gè)商品的購(gòu)買權(quán)限。這個(gè)選擇的邏輯非常靈活,可隨意定制。但是從20選10的操作,無(wú)論如何也比從千千萬(wàn)萬(wàn)個(gè)人中選10要好的多,這樣可以確保秒殺的安全完成。

  • 如果秒殺的人繼續(xù)增多,那么也可以通過(guò)客戶端(即javascript)設(shè)置格擋率的方法,使少量的用戶可以發(fā)出請(qǐng)求到服務(wù)器,絕大多數(shù)的用戶都被擋在瀏覽器上。(注:一些技術(shù)人士在2013年吐槽小米網(wǎng)站搶購(gòu)小米手機(jī)時(shí),瀏覽器模擬排隊(duì)等待其實(shí)沒(méi)有發(fā)出任何網(wǎng)絡(luò)請(qǐng)求,這就是客戶端格擋率生效的結(jié)果。)


全網(wǎng)獨(dú)一無(wú)二值得收藏的,Web開(kāi)發(fā)基本準(zhǔn)則-緩存策略的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
台东市| 张北县| 双流县| 烟台市| 古田县| 温州市| 微山县| 巴中市| 万安县| 霍林郭勒市| 佳木斯市| 涞源县| 麦盖提县| 合江县| 桃江县| 拜泉县| 同心县| 许昌市| 安福县| 江陵县| 邯郸市| 衡东县| 永年县| 乌兰察布市| 绥棱县| 巧家县| 南丰县| 贡觉县| 东港市| 佛山市| 天台县| 赤城县| 辉县市| 桃园市| 呼和浩特市| 玉屏| 福清市| 个旧市| 大同县| 义乌市| 揭东县|