自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

談?wù)勑阅軆?yōu)化之緩存篇

存儲(chǔ) 存儲(chǔ)軟件
用戶數(shù)增長,架構(gòu)演變,數(shù)據(jù)量增大,開始考慮怎么去做性能優(yōu)化。而性能優(yōu)化的第一定律就是:優(yōu)先考慮使用緩存。

本文轉(zhuǎn)載自微信公眾號(hào)「 架構(gòu)師之殤」,轉(zhuǎn)載本文請(qǐng)聯(lián)系 架構(gòu)師之殤公眾號(hào)。

[[329769]]

 1. 前言:為什么要用緩存?

用戶數(shù)增長,架構(gòu)演變,數(shù)據(jù)量增大,開始考慮怎么去做性能優(yōu)化。

而性能優(yōu)化的第一定律就是:優(yōu)先考慮使用緩存。

2. 緩存的基本原理

2.1 緩存的作用

1、加快數(shù)據(jù)訪問速度;

2、減輕后端應(yīng)用和數(shù)據(jù)存儲(chǔ)的負(fù)載壓力。

2.2 緩存的特征

1、命中率:命中率 = 命中數(shù) / 請(qǐng)求數(shù)。

這是衡量緩存有效性的重要指標(biāo)。命中率越高,表明緩存的使用率越高。

2、最大元素(最大空間)。

一旦緩存中元素?cái)?shù)量超過這個(gè)值(或者緩存數(shù)據(jù)空間超過其最大支 持空間),將會(huì)觸發(fā)淘汰策略。

3、淘汰策略。

這個(gè)我前文其實(shí)已經(jīng)說過。

FIFO(First In First Out) 先進(jìn)先出,淘汰最早數(shù)據(jù)。

判斷存儲(chǔ)時(shí)間,離目前最遠(yuǎn)的數(shù)據(jù)優(yōu)先淘汰。

LRU (Least Recently Used)剔除最近最少使用。

判斷最近使用時(shí)間,離目前最遠(yuǎn)的數(shù)據(jù)優(yōu)先淘汰。

LFU (Least Frequently Used)剔除最近使用頻率最低的數(shù)據(jù)。

在一段時(shí)間內(nèi),數(shù)據(jù)被使用次數(shù)最少的,優(yōu)先淘汰。

具體可以看這篇文章常見的緩存剔除策略 & LRU與LFU的區(qū)別。

3. 緩存的分類

緩存的主要手段有:瀏覽器緩存、CDN、反向代理、本地緩存、分布式緩存、數(shù)據(jù)庫緩存。

在解讀《大型網(wǎng)站技術(shù)架構(gòu)》一文中,其實(shí)已經(jīng)說到過。

我們一般說做性能優(yōu)化時(shí)是指后三個(gè):本地緩存、分布式緩存、數(shù)據(jù)庫緩存。

前面三個(gè)緩存策略屬于網(wǎng)站前端的范疇。

從硬件介質(zhì)上來看,緩存分為內(nèi)存和硬盤兩種。

但從技術(shù)上,又可以分成內(nèi)存、硬盤文件、數(shù)據(jù)庫。

我們通常意義上說的緩存一般都是基于內(nèi)存的。

因?yàn)橹挥袃?nèi)存,才足夠快。

數(shù)據(jù)庫緩存一般也是基于內(nèi)存的,但這個(gè)活一般是DBA在配置數(shù)據(jù)庫的時(shí)候就設(shè)置好了。

對(duì)于大部分開發(fā)人員來說,我們一般所說的緩存優(yōu)化都是基于本地緩存(ocal cache)和遠(yuǎn)程緩存(remote cache)。

而現(xiàn)在遠(yuǎn)程緩存這個(gè)詞一般也被分布式緩存這個(gè)常用方案所代指。

4. 什么時(shí)候使用緩存?

4.1 緩存的使用判斷

什么時(shí)候使用緩存的判斷其實(shí)比較簡單,抓住兩點(diǎn)就行了:

1、是不是熱點(diǎn)數(shù)據(jù)?

所謂熱點(diǎn),一般是遵循二八定律,即百分之八十的訪問集中在百分之二十的數(shù)據(jù)上。

2、是不是讀比寫多?

這個(gè)比例一般為2:1。

4.2 什么時(shí)候不應(yīng)該使用緩存?

反過來就是了。

1、沒有熱點(diǎn)數(shù)據(jù)不要使用緩存,也沒什么意義。

因?yàn)閮?nèi)存資源是比較寶貴的。

2、頻繁修改的數(shù)據(jù)不要使用緩存。

因?yàn)榭赡軐懭牒筮€來不及讀取就已失效或被淘汰,并且容易產(chǎn)生臟讀。

4.3 合理使用緩存

最后,最重要的是確認(rèn)是否需要使用緩存?

確定了后,再選擇合適的緩存工具及使用緩存的方式。

5. 緩存時(shí)常見的一些問題

使用緩存優(yōu)點(diǎn)很多,但也存在一些很常見的問題。雙刃之劍,就看怎么用了。

列舉一些我們工作中常見的一些緩存問題,并給出至少一種解決方案。

5.1 緩存更新帶來的數(shù)據(jù)不一致與臟讀

緩存更新的常見策略有:

1、先更新數(shù)據(jù)庫再更新緩存;

2、先更新數(shù)據(jù)庫再刪除緩存;

3、先刪除緩存再更新數(shù)據(jù)庫;

4、定時(shí)清理緩存;

5、有請(qǐng)求訪問數(shù)據(jù)時(shí),判斷緩存是否過期,過期從數(shù)據(jù)庫中刷新緩存。

在這幾種方案中,如果修改緩存與數(shù)據(jù)庫不在同一個(gè)事物中,就帶來了數(shù)據(jù)不一致和臟讀的問題。

對(duì)應(yīng)方案1:先刪除緩存再更新數(shù)據(jù)庫,并且在同一個(gè)事物中。

對(duì)應(yīng)方案2:緩存自動(dòng)失效后,另外的異步線程進(jìn)行緩存更新。

對(duì)應(yīng)方案3:緩存更新在并發(fā)、分布式要考慮鎖,redis天生就是單線程,比較有優(yōu)勢。

5.2 怎么做緩存預(yù)熱

緩存預(yù)熱是指在用戶可訪問服務(wù)之前,將熱點(diǎn)數(shù)據(jù)加載到緩存的操作,這樣可以有效避免上線后瞬時(shí)大流量造成系統(tǒng)不可用。

緩存預(yù)熱的一般性策略:

1、開發(fā)個(gè)緩存刷新功能,手工刷新;

2、項(xiàng)目啟動(dòng)的時(shí)候自動(dòng)進(jìn)行加載(一般為字典表等數(shù)據(jù)量不大的數(shù)據(jù));

3、設(shè)置個(gè)定時(shí)器,自動(dòng)刷新緩存;

4、提前統(tǒng)計(jì)熱點(diǎn)數(shù)據(jù),事先批量加載到如redis這樣緩存工具中。

5.3 緩存重建

緩存失效后,重建熱點(diǎn)緩存,如果耗時(shí)較長,在重建過程中,性能、負(fù)載不好。

對(duì)應(yīng)方案:

1、正常情況下,交錯(cuò)緩存失效時(shí)間,減輕緩存壓力;

2、崩潰失效的情況下,可以使用帶持久化功能的緩存來恢復(fù),比如Redis;

3、如果是MongoDB則不太一樣,它是采用mmap來將數(shù)據(jù)文件映射到內(nèi)存中,所以當(dāng)MongoDB重啟時(shí),這些映射的內(nèi)存并不會(huì)清掉,不需要進(jìn)行緩存重建與預(yù)熱。

5.4 緩存雪崩與可用性

緩存雪崩:緩存在同一時(shí)間失效時(shí),訪問直達(dá)數(shù)據(jù)庫層,可能導(dǎo)致DB掛掉、系統(tǒng)崩潰。

對(duì)應(yīng)方案1:交錯(cuò)緩存失效時(shí)間或隨機(jī)緩存失效時(shí)間。

對(duì)應(yīng)方案2:主從熱備(Redis sentinel)。

對(duì)應(yīng)方案3:集群/水平切分(Redis Cluster、一致性哈希)。

5.5 緩存穿透

緩存穿透:持續(xù)高并發(fā)訪問某個(gè)不存在的Key。

對(duì)應(yīng)方案1:空值緩存。

對(duì)應(yīng)方案2:布隆過濾器(bloom filter) + bitmap。窮舉可能訪問的數(shù)據(jù)放入bitmap中,使用hash訪問。

5.6 緩存擊穿

緩存擊穿:熱點(diǎn)Key失效,高并發(fā)請(qǐng)求,直擊數(shù)據(jù)庫。

緩存擊穿與緩存穿透很相似,不同點(diǎn)是是緩存擊穿前訪問的是真實(shí)的熱點(diǎn)數(shù)據(jù),只是在某一剎那失效了,造成了擊穿的效果。

這樣看,它其實(shí)也是緩存雪崩的一個(gè)特例。與雪崩的區(qū)別即在于擊穿是對(duì)于特定的熱點(diǎn)數(shù)據(jù),而雪崩是全部數(shù)據(jù)。

對(duì)應(yīng)方案:多級(jí)緩存及交錯(cuò)失效時(shí)間 + LRU 淘汰算法。

對(duì)于熱點(diǎn)數(shù)據(jù)進(jìn)行二級(jí)或多級(jí)緩存,并對(duì)于不同級(jí)別的緩存設(shè)定不同的失效時(shí)間,緩解雪崩。

此外可使用LRU的變種算法LRU-K緩存數(shù)據(jù)。

5.7 緩存降級(jí)

緩存降級(jí)是服務(wù)降級(jí)中的一環(huán)。

在訪問量劇增,導(dǎo)致服務(wù)出現(xiàn)問題時(shí),為了保證核心服務(wù)可用,防止發(fā)生緩存雪崩,可進(jìn)行服務(wù)降級(jí)。

以redis為例,比較常見的做法就是,不去數(shù)據(jù)庫查詢,而是直接返回默認(rèn)值給用戶。

緩存降級(jí)也可根據(jù)日志級(jí)別進(jìn)行預(yù)案設(shè)置。

6. 分布式緩存的選型

說了這么多緩存的原理與策略,說說我們?cè)趯?shí)際工作中應(yīng)該怎么去做緩存選型。

以下就是常用的幾種緩存工具。

6.1 Ehcache

Ehcache是純Java開源的緩存框架,最早從hibernate發(fā)展而來,現(xiàn)在算是springboot中的官配緩存工具,整合簡單。特點(diǎn)如下:

  • 快速,針對(duì)大型高并發(fā)系統(tǒng)場景,Ehcache的多線程機(jī)制有相應(yīng)的優(yōu)化改善;
  • 簡單,很小的jar包,簡單配置就可直接使用,單機(jī)場景下無需過多的其他服務(wù)依賴;
  • 支持多種的緩存策略,靈活;
  • 緩存數(shù)據(jù)有兩級(jí):內(nèi)存和磁盤,與一般的本地內(nèi)存緩存相比,有了磁盤的存儲(chǔ)空間,將可以支持更大量的數(shù)據(jù)緩存需求;
  • 具有緩存和緩存管理器的偵聽接口,能更簡單方便的進(jìn)行緩存實(shí)例的監(jiān)控管理;
  • 支持多緩存管理器實(shí)例,以及一個(gè)實(shí)例的多個(gè)緩存區(qū)域。

6.2 Guava Cache

Guava Cache是Google開源的Java重用工具集庫Guava里的一款緩存工具,特點(diǎn)如下:

  • 自動(dòng)將entry節(jié)點(diǎn)加載進(jìn)緩存結(jié)構(gòu)中;
  • 當(dāng)緩存的數(shù)據(jù)超過設(shè)置的最大值時(shí),使用LRU算法移除;
  • 具備根據(jù)entry節(jié)點(diǎn)上次被訪問或者寫入時(shí)間計(jì)算它的過期機(jī)制;
  • 緩存的key被封裝在WeakReference引用內(nèi);
  • 緩存的Value被封裝在WeakReference或SoftReference引用內(nèi);
  • 統(tǒng)計(jì)緩存使用過程中命中率、異常率、未命中率等統(tǒng)計(jì)數(shù)據(jù)。

6.3 Memcache

memcache本身不支持分布式,是通過客戶端的路由處理來達(dá)到分布式解決方案的目的。特點(diǎn)如下:

  • memcache使用預(yù)分配內(nèi)存池的方式管理內(nèi)存;
  • 所有數(shù)據(jù)存儲(chǔ)在物理內(nèi)存里;
  • 非阻塞IO復(fù)用模型,純KV存取操作;
  • 多線程,效率高,會(huì)遇到鎖等上下文切換問題;
  • 只支持簡單KV數(shù)據(jù)類型;
  • 數(shù)據(jù)不支持持久化。

6.4 Redis

Redis是當(dāng)前主流的高性能內(nèi)存數(shù)據(jù)庫,多用于存儲(chǔ)緩存數(shù)據(jù),并能實(shí)現(xiàn)輕量級(jí)的MQ功能。特點(diǎn)如下:

  • 臨時(shí)申請(qǐng)空間,可能導(dǎo)致碎片;
  • 有VM機(jī)制,能存儲(chǔ)更多數(shù)據(jù),超過內(nèi)存空間后會(huì)導(dǎo)致swap,降低效率;
  • 非阻塞IO復(fù)用模型,支持額外CPU計(jì)算:排序、聚合,會(huì)影響IO性能;
  • 單線程,無鎖,無上下文切換,單實(shí)例無法利用多核性能;
  • 支持多種數(shù)據(jù)類型:string / hash / list / set / sorted set;
  • 數(shù)據(jù)支持持久化:AOF(語句增量)/RDB(fork全量);
  • 天然支持高可用分布式方案sentinel +;
  • cluster(故障自動(dòng)轉(zhuǎn)移+集群)。

6.5 推薦

通常情況下,單機(jī)我們會(huì)用Ehcache,甚至java自己的concurrenthashmap來實(shí)現(xiàn)緩存。分布式一般使用redis。

責(zé)任編輯:武曉燕 來源: 架構(gòu)師之殤
相關(guān)推薦

2015-09-16 15:48:55

Android性能優(yōu)化電量

2015-09-16 14:37:50

Android性能優(yōu)化運(yùn)算

2015-09-16 13:54:30

Android性能優(yōu)化渲染

2012-06-20 11:05:47

性能調(diào)優(yōu)攻略

2012-06-21 09:43:45

2011-10-19 09:41:15

ASP.NET性能優(yōu)化

2009-08-13 15:49:18

ASP.NET性能優(yōu)化

2009-08-13 16:22:18

ASP.NET性能優(yōu)化

2011-10-17 09:54:18

ASP.NET性能

2024-02-20 19:53:57

網(wǎng)絡(luò)通信協(xié)議

2021-07-05 14:55:28

前端優(yōu)化圖片

2019-03-15 15:00:49

Webpack構(gòu)建速度前端

2021-07-29 14:20:34

網(wǎng)絡(luò)優(yōu)化移動(dòng)互聯(lián)網(wǎng)數(shù)據(jù)存儲(chǔ)

2012-06-20 13:54:44

架構(gòu)性能優(yōu)化

2022-02-16 14:10:51

服務(wù)器性能優(yōu)化Linux

2021-11-29 11:13:45

服務(wù)器網(wǎng)絡(luò)性能

2015-09-16 15:21:23

Android性能優(yōu)化內(nèi)存

2021-08-02 10:50:57

性能微服務(wù)數(shù)據(jù)

2021-09-06 06:45:06

Webpack優(yōu)化MindMaster

2011-09-08 13:56:41

ASP.NET性能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)