国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Jadual Kandungan
一、緩存案例
1、TLB
2、抖音
3、HTTP協(xié)議緩存
二、緩存分類
1、靜態(tài)緩存
2、分布式緩存
3、本地緩存
三、緩存的讀寫策略
1、Cache Aside策略
2、Read/Write Through
3、Write Back
四、緩存高可用
1、客戶端方案
2、中間代理層
3、服務(wù)端方案
五、緩存穿透
1、帕累托
2、回種空值
3、布隆過濾器
4、狗樁效應(yīng)
六、CDN
1、靜態(tài)資源加速的原因
2、CDN
3、搭建CDN系統(tǒng)
拓展
Rumah Java JavaAsas java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

Oct 10, 2020 pm 05:24 PM
java high concurrency

java基礎(chǔ)欄目今天介紹java高并發(fā)系統(tǒng)設(shè)計(jì)的緩存篇。

java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

常見硬件組件的延時(shí)情況如下圖:java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

從這些數(shù)據(jù)中,你可以看到,做一次內(nèi)存尋址大概需要 100ns,而做一次磁盤的查找則需要 10ms??梢?,我們使用內(nèi)存作為緩存的存儲介質(zhì)相比于以磁盤作為主要存儲介質(zhì)的數(shù)據(jù)庫來說,性能上會提高多個(gè)數(shù)量級。所以,內(nèi)存是最常見的一種緩存數(shù)據(jù)的介質(zhì)。

一、緩存案例

1、TLB

Linux 內(nèi)存管理是通過一個(gè)叫做 MMU(Memory Management Unit)的硬件,來實(shí)現(xiàn)從虛擬地址到物理地址的轉(zhuǎn)換的,但是如果每次轉(zhuǎn)換都要做這么復(fù)雜計(jì)算的話,無疑會造成性能的損耗,所以我們會借助一個(gè)叫做 TLB(Translation Lookaside Buffer)的組件來緩存最近轉(zhuǎn)換過的虛擬地址,和物理地址的映射。TLB 就是一種緩存組件。

2、抖音

平臺上的短視頻實(shí)際上是使用內(nèi)置的網(wǎng)絡(luò)播放器來完成的。網(wǎng)絡(luò)播放器接收的是數(shù)據(jù)流,將數(shù)據(jù)下載下來之后經(jīng)過分離音視頻流,解碼等流程后輸出到外設(shè)設(shè)備上播放。播放器中通常會設(shè)計(jì)一些緩存的組件,在未打開視頻時(shí)緩存一部分視頻數(shù)據(jù),比如我們打開抖音,服務(wù)端可能一次會返回三個(gè)視頻信息,我們在播放第一個(gè)視頻的時(shí)候,播放器已經(jīng)幫我們緩存了第二、三個(gè)視頻的部分?jǐn)?shù)據(jù),這樣在看第二個(gè)視頻的時(shí)候就可以給用戶“秒開”的感覺。

3、HTTP協(xié)議緩存

當(dāng)我們第一次請求靜態(tài)的資源時(shí),比如一張圖片,服務(wù)端除了返回圖片信息,在響應(yīng)頭里面還有一個(gè)“Etag”的字段。瀏覽器會緩存圖片信息以及這個(gè)字段的值。當(dāng)下一次再請求這個(gè)圖片的時(shí)候,瀏覽器發(fā)起的請求頭里面會有一個(gè)“If-None-Match”的字段,并且把緩存的“Etag”的值寫進(jìn)去發(fā)給服務(wù)端。服務(wù)端比對圖片信息是否有變化,如果沒有,則返回瀏覽器一個(gè) 304 的狀態(tài)碼,瀏覽器會繼續(xù)使用緩存的圖片信息。通過這種緩存協(xié)商的方式,可以減少網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)大小,從而提升頁面展示性能。java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

二、緩存分類

1、靜態(tài)緩存

靜態(tài)緩存在 Web 1.0 時(shí)期是非常著名的,它一般通過生成 Velocity 模板或者靜態(tài) HTML 文件來實(shí)現(xiàn)靜態(tài)緩存,在 Nginx 上部署靜態(tài)緩存可以減少對于后臺應(yīng)用服務(wù)器的壓力

2、分布式緩存

分布式緩存的大名可謂是如雷貫耳了,我們平時(shí)耳熟能詳?shù)?Memcached、Redis 就是分布式緩存的典型例子。它們性能強(qiáng)勁,通過一些分布式的方案組成集群可以突破單機(jī)的限制。所以在整體架構(gòu)中,分布式緩存承擔(dān)著非常重要的角色

3、本地緩存

Guava Cache 或者是 Ehcache 等,它們和應(yīng)用程序部署在同一個(gè)進(jìn)程中,優(yōu)勢是不需要跨網(wǎng)絡(luò)調(diào)度,速度極快,所以可以用來阻擋短時(shí)間內(nèi)的熱點(diǎn)查詢。

三、緩存的讀寫策略

1、Cache Aside策略

在更新數(shù)據(jù)時(shí)不更新緩存,而是刪除緩存中的數(shù)據(jù),在讀取數(shù)據(jù)時(shí),發(fā)現(xiàn)緩存中沒了數(shù)據(jù)之后,再從數(shù)據(jù)庫中讀取數(shù)據(jù),更新到緩存中。java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

這個(gè)策略就是我們使用緩存最常見的策略,Cache Aside 策略(也叫旁路緩存策略),這個(gè)策略數(shù)據(jù)以數(shù)據(jù)庫中的數(shù)據(jù)為準(zhǔn),緩存中的數(shù)據(jù)是按需加載的。

Cache Aside 策略是我們?nèi)粘i_發(fā)中最經(jīng)常使用的緩存策略,不過我們在使用時(shí)也要學(xué)會依情況而變,并不是一成不變的。Cache Aside 存在的最大的問題是當(dāng)寫入比較頻繁時(shí),緩存中的數(shù)據(jù)會被頻繁地清理,這樣會對緩存的命中率有一些影響。如果你的業(yè)務(wù)對緩存命中率有嚴(yán)格的要求,那么可以考慮兩種解決方案:

一種做法是在更新數(shù)據(jù)時(shí)也更新緩存,只是在更新緩存前先加一個(gè)分布式鎖,因?yàn)檫@樣在同一時(shí)間只允許一個(gè)線程更新緩存,就不會產(chǎn)生并發(fā)問題了。當(dāng)然這么做對于寫入的性能會有一些影響(推薦);

另一種做法同樣也是在更新數(shù)據(jù)時(shí)更新緩存,只是給緩存加一個(gè)較短的過期時(shí)間,這樣即使出現(xiàn)緩存不一致的情況,緩存的數(shù)據(jù)也會很快過期,對業(yè)務(wù)的影響也是可以接受。

2、Read/Write Through

這個(gè)策略的核心原則是用戶只與緩存打交道,由緩存和數(shù)據(jù)庫通信,寫入或者讀取數(shù)據(jù)。java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

Write Through

的策略是這樣的:先查詢要寫入的數(shù)據(jù)在緩存中是否已經(jīng)存在,如果已經(jīng)存在,則更新緩存中的數(shù)據(jù),并且由緩存組件同步更新到數(shù)據(jù)庫中,如果緩存中數(shù)據(jù)不存在,我們把這種情況叫做“Write Miss(寫失效)”。一般來說,我們可以選擇兩種“Write Miss”方式:一個(gè)是“Write Allocate(按寫分配)”,做法是寫入緩存相應(yīng)位置,再由緩存組件同步更新到數(shù)據(jù)庫中;另一個(gè)是“No-write allocate(不按寫分配)”,做法是不寫入緩存中,而是直接更新到數(shù)據(jù)庫中。 我們看到 Write Through 策略中寫數(shù)據(jù)庫是同步的,這對于性能來說會有比較大的影響,因?yàn)橄啾扔趯懢彺妫綄憯?shù)據(jù)庫的延遲就要高很多了。通過Write Back策略異步的更新數(shù)據(jù)庫。

Read Through

策略就簡單一些,它的步驟是這樣的:先查詢緩存中數(shù)據(jù)是否存在,如果存在則直接返回,如果不存在,則由緩存組件負(fù)責(zé)從數(shù)據(jù)庫中同步加載數(shù)據(jù)。

3、Write Back

這個(gè)策略的核心思想是在寫入數(shù)據(jù)時(shí)只寫入緩存,并且把緩存塊兒標(biāo)記為“臟”的。而臟塊兒只有被再次使用時(shí)才會將其中的數(shù)據(jù)寫入到后端存儲中。 在“Write Miss”的情況下,我們采用的是“Write Allocate”的方式,也就是在寫入后端存儲的同時(shí)要寫入緩存,這樣我們在之后的寫請求中都只需要更新緩存即可,而無需更新后端存儲了。注意與上面的write through策略作區(qū)分。java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

我們在讀取緩存時(shí)如果發(fā)現(xiàn)緩存命中則直接返回緩存數(shù)據(jù)。如果緩存不命中則尋找一個(gè)可用的緩存塊兒,如果這個(gè)緩存塊兒是“臟”的,就把緩存塊兒中之前的數(shù)據(jù)寫入到后端存儲中,并且從后端存儲加載數(shù)據(jù)到緩存塊兒,如果不是臟的,則由緩存組件將后端存儲中的數(shù)據(jù)加載到緩存中,最后我們將緩存設(shè)置為不是臟的,返回?cái)?shù)據(jù)就好了。java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

write back策略多用于向磁盤中寫數(shù)據(jù)。例如:操作系統(tǒng)層面的 Page Cache、日志的異步刷盤、消息隊(duì)列中消息的異步寫入磁盤等。因?yàn)檫@個(gè)策略在性能上的優(yōu)勢毋庸置疑,它避免了直接寫磁盤造成的隨機(jī)寫問題,畢竟寫內(nèi)存和寫磁盤的隨機(jī) I/O 的延遲相差了幾個(gè)數(shù)量級呢。

四、緩存高可用

緩存的命中率是緩存需要監(jiān)控的數(shù)據(jù)指標(biāo),緩存的高可用可以一定程度上減少緩存穿透的概率,提升系統(tǒng)的穩(wěn)定性。緩存的高可用方案主要包括客戶端方案、中間代理層方案和服務(wù)端方案三大類:

1、客戶端方案

在客戶端方案中,你需要關(guān)注緩存的寫和讀兩個(gè)方面: 寫入數(shù)據(jù)時(shí),需要把被寫入緩存的數(shù)據(jù)分散到多個(gè)節(jié)點(diǎn)中,即進(jìn)行數(shù)據(jù)分片; 讀數(shù)據(jù)時(shí),可以利用多組的緩存來做容錯,提升緩存系統(tǒng)的可用性。關(guān)于讀數(shù)據(jù),這里可以使用主從和多副本兩種策略,兩種策略是為了解決不同的問題而提出的。 具體的實(shí)現(xiàn)細(xì)節(jié)包括:數(shù)據(jù)分片、主從、多副本

數(shù)據(jù)分片

一致性Hash算法。在這個(gè)算法中,我們將整個(gè) Hash 值空間組織成一個(gè)虛擬的圓環(huán),然后將緩存節(jié)點(diǎn)的 IP 地址或者主機(jī)名做 Hash 取值后,放置在這個(gè)圓環(huán)上。當(dāng)我們需要確定某一個(gè) Key 需要存取到哪個(gè)節(jié)點(diǎn)上的時(shí)候,先對這個(gè) Key 做同樣的 Hash 取值,確定在環(huán)上的位置,然后按照順時(shí)針方向在環(huán)上“行走”,遇到的第一個(gè)緩存節(jié)點(diǎn)就是要訪問的節(jié)點(diǎn)。java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

這時(shí)如果在 Node 1 和 Node 2 之間增加一個(gè) Node 5,你可以看到原本命中 Node 2 的 Key 3 現(xiàn)在命中到 Node 5,而其它的 Key 都沒有變化;同樣的道理,如果我們把 Node 3 從集群中移除,那么只會影響到 Key 5 。所以你看,在增加和刪除節(jié)點(diǎn)時(shí),只有少量的 Key 會“漂移”到其它節(jié)點(diǎn)上,而大部分的 Key 命中的節(jié)點(diǎn)還是會保持不變,從而可以保證命中率不會大幅下降。 【提示】一致性hash出現(xiàn)的緩存雪崩現(xiàn)象使用虛擬節(jié)點(diǎn)解決。一致性hash分片與hash分片的區(qū)別在于,緩存命中率的問題,hash分片在存在機(jī)器加入或是減少的情況時(shí)候,會導(dǎo)致緩存失效,緩存命中率下降。

主從

Redis 本身支持主從的部署方式,但是 Memcached 并不支持,Memcached 的主從機(jī)制是如何在客戶端實(shí)現(xiàn)的。為每一組 Master 配置一組 Slave,更新數(shù)據(jù)時(shí)主從同步更新。讀取時(shí),優(yōu)先從 Slave 中讀數(shù)據(jù),如果讀取不到數(shù)據(jù)就穿透到 Master 讀取,并且將數(shù)據(jù)回種到 Slave 中以保持 Slave 數(shù)據(jù)的熱度。主從機(jī)制最大的優(yōu)點(diǎn)就是當(dāng)某一個(gè) Slave 宕機(jī)時(shí),還會有 Master 作為兜底,不會有大量請求穿透到數(shù)據(jù)庫的情況發(fā)生,提升了緩存系統(tǒng)的高可用性。

多副本

主從方式已經(jīng)能夠解決大部分場景的問題,但是對于極端流量的場景下,一組 Slave 通常來說并不能完全承擔(dān)所有流量,Slave 網(wǎng)卡帶寬可能成為瓶頸。為了解決這個(gè)問題,我們考慮在 Master/Slave 之前增加一層副本層,整體架構(gòu)是這樣的:java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

這個(gè)方案中,當(dāng)客戶端發(fā)起查詢請求時(shí),請求首先會先從多個(gè)副本組中選取一個(gè)副本組發(fā)起查詢,如果查詢失敗,就繼續(xù)查詢 Master/Slave,并且將查詢的結(jié)果回種到所有副本組中,避免副本組中臟數(shù)據(jù)的存在?;诔杀镜目紤],每一個(gè)副本組容量比 Master 和 Slave 要小,因此它只存儲了更加熱的數(shù)據(jù)。在這套架構(gòu)中,Master 和 Slave 的請求量會大大減少,為了保證它們存儲數(shù)據(jù)的熱度,在實(shí)踐中我們會把 Master 和 Slave 作為一組副本組使用。

2、中間代理層

業(yè)界也有很多中間代理層方案,比如 Facebook 的Mcrouter,Twitter 的Twemproxy,豌豆莢的Codis。它們的原理基本上可以由一張圖來概括:java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

3、服務(wù)端方案

Redis 在 2.4 版本中提出了 Redis Sentinel 模式來解決主從 Redis 部署時(shí)的高可用問題,它可以在主節(jié)點(diǎn)掛了以后自動將從節(jié)點(diǎn)提升為主節(jié)點(diǎn),保證整體集群的可用性,整體的架構(gòu)如下圖所示:java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

redis Sentinel 也是集群部署的,這樣可以避免 Sentinel 節(jié)點(diǎn)掛掉造成無法自動故障恢復(fù)的問題,每一個(gè) Sentinel 節(jié)點(diǎn)都是無狀態(tài)的。在 Sentinel 中會配置 Master 的地址,Sentinel 會時(shí)刻監(jiān)控 Master 的狀態(tài),當(dāng)發(fā)現(xiàn) Master 在配置的時(shí)間間隔內(nèi)無響應(yīng),就認(rèn)為 Master 已經(jīng)掛了,Sentinel 會從從節(jié)點(diǎn)中選取一個(gè)提升為主節(jié)點(diǎn),并且把所有其他的從節(jié)點(diǎn)作為新主的從節(jié)點(diǎn)。Sentinel 集群內(nèi)部在仲裁的時(shí)候,會根據(jù)配置的值來決定當(dāng)有幾個(gè) Sentinel 節(jié)點(diǎn)認(rèn)為主掛掉可以做主從切換的操作,也就是集群內(nèi)部需要對緩存節(jié)點(diǎn)的狀態(tài)達(dá)成一致才行。

【提示】上述客戶端到sentinel集群的連線是虛線,因?yàn)閷τ诰彺娴膶懭牒妥x取請求不會經(jīng)過 Sentinel 節(jié)點(diǎn)。

五、緩存穿透

1、帕累托

互聯(lián)網(wǎng)系統(tǒng)的數(shù)據(jù)訪問模型一般會遵從“80/20 原則”?!?0/20 原則”又稱為帕累托法則,是意大利經(jīng)濟(jì)學(xué)家帕累托提出的一個(gè)經(jīng)濟(jì)學(xué)的理論。簡單來說,它是指在一組事物中,最重要的部分通常只占 20%,而其他的 80% 并沒有那么重要。把它應(yīng)用到數(shù)據(jù)訪問的領(lǐng)域,就是我們會經(jīng)常訪問 20% 的熱點(diǎn)數(shù)據(jù),而另外的 80% 的數(shù)據(jù)則不會被經(jīng)常訪問。既然緩存的容量有限,并且大部分的訪問只會請求 20% 的熱點(diǎn)數(shù)據(jù),那么理論上說,我們只需要在有限的緩存空間里存儲 20% 的熱點(diǎn)數(shù)據(jù)就可以有效地保護(hù)脆弱的后端系統(tǒng)了,也就可以放棄緩存另外 80% 的非熱點(diǎn)數(shù)據(jù)了。所以這種少量的緩存穿透是不可避免的,但是對系統(tǒng)是沒有損害的。

2、回種空值

當(dāng)我們從數(shù)據(jù)庫中查詢到空值或者發(fā)生異常時(shí),我們可以向緩存中回種一個(gè)空值。但是因?yàn)榭罩挡⒉皇菧?zhǔn)確的業(yè)務(wù)數(shù)據(jù),并且會占用緩存的空間,所以我們會給這個(gè)空值加一個(gè)比較短的過期時(shí)間,讓空值在短時(shí)間之內(nèi)能夠快速過期淘汰?;胤N空值雖然能夠阻擋大量穿透的請求,但如果有大量的空值緩存,也就會浪費(fèi)緩存的存儲空間,如果緩存空間被占滿了,還會剔除掉一些已經(jīng)被緩存的用戶信息反而會造成緩存命中率的下降。所以這個(gè)方案,我建議你在使用的時(shí)候應(yīng)該評估一下緩存容量是否能夠支撐。如果需要大量的緩存節(jié)點(diǎn)來支持,那么就無法通過通過回種空值的方式來解決,這時(shí)你可以考慮使用布隆過濾器。

3、布隆過濾器

1970 年布隆提出了一種布隆過濾器的算法,用來判斷一個(gè)元素是否在一個(gè)集合中。這種算法由一個(gè)二進(jìn)制數(shù)組和一個(gè) Hash 算法組成。它的基本思路如下:我們把集合中的每一個(gè)值按照提供的 Hash 算法算出對應(yīng)的 Hash 值,然后將 Hash 值對數(shù)組長度取模后得到需要計(jì)入數(shù)組的索引值,并且將數(shù)組這個(gè)位置的值從 0 改成 1。在判斷一個(gè)元素是否存在于這個(gè)集合中時(shí),你只需要將這個(gè)元素按照相同的算法計(jì)算出索引值,如果這個(gè)位置的值為 1 就認(rèn)為這個(gè)元素在集合中,否則則認(rèn)為不在集合中。java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

如何使用布隆過濾器解決緩存穿透呢?

以存儲用戶信息的表為例進(jìn)行講解。首先我們初始化一個(gè)很大的數(shù)組,比方說長度為 20 億的數(shù)組,接下來我們選擇一個(gè) Hash 算法,然后我們將目前現(xiàn)有的所有用戶的 ID 計(jì)算出 Hash 值并且映射到這個(gè)大數(shù)組中,映射位置的值設(shè)置為 1,其它值設(shè)置為 0。新注冊的用戶除了需要寫入到數(shù)據(jù)庫中之外,它也需要依照同樣的算法更新布隆過濾器的數(shù)組中相應(yīng)位置的值。那么當(dāng)我們需要查詢某一個(gè)用戶的信息時(shí),先查詢這個(gè) ID 在布隆過濾器中是否存在,如果不存在就直接返回空值,而不需要繼續(xù)查詢數(shù)據(jù)庫和緩存,這樣就可以極大地減少異常查詢帶來的緩存穿透。java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇

布隆過濾器優(yōu)點(diǎn):

(1)性能高。無論是寫入操作還是讀取操作,時(shí)間復(fù)雜度都是 O(1) 是常量值

(2)節(jié)省空間。比如,20 億的數(shù)組需要 2000000000/8/1024/1024 = 238M 的空間,而如果使用數(shù)組來存儲,假設(shè)每個(gè)用戶 ID 占用 4 個(gè)字節(jié)的空間,那么存儲 20 億用戶需要 2000000000 * 4 / 1024 / 1024 = 7600M 的空間,是布隆過濾器的 32 倍。

布隆過濾器缺點(diǎn):

(1)它在判斷元素是否在集合中時(shí)是有一定錯誤幾率的,比如它會把不是集合中的元素判斷為處在集合中。

原因:Hash算法本身的缺陷。

解決方案:使用多個(gè) Hash 算法為元素計(jì)算出多個(gè) Hash 值,只有所有 Hash 值對應(yīng)的數(shù)組中的值都為 1 時(shí),才會認(rèn)為這個(gè)元素在集合中。

(2)不支持刪除元素。布隆過濾器不支持刪除元素的缺陷也和 Hash 碰撞有關(guān)。舉一個(gè)例子,假如兩個(gè)元素 A 和 B 都是集合中的元素,它們有相同的 Hash 值,它們就會映射到數(shù)組的同一個(gè)位置。這時(shí)我們刪除了 A,數(shù)組中對應(yīng)位置的值也從 1 變成 0,那么在判斷 B 的時(shí)候發(fā)現(xiàn)值是 0,也會判斷 B 是不在集合中的元素,就會得到錯誤的結(jié)論。

解決方案:我會讓數(shù)組中不再只有 0 和 1 兩個(gè)值,而是存儲一個(gè)計(jì)數(shù)。比如如果 A 和 B 同時(shí)命中了一個(gè)數(shù)組的索引,那么這個(gè)位置的值就是 2,如果 A 被刪除了就把這個(gè)值從 2 改為 1。這個(gè)方案中的數(shù)組不再存儲 bit 位,而是存儲數(shù)值,也就會增加空間的消耗。

4、狗樁效應(yīng)

比方說當(dāng)有一個(gè)極熱點(diǎn)的緩存項(xiàng),它一旦失效會有大量請求穿透到數(shù)據(jù)庫,這會對數(shù)據(jù)庫造成瞬時(shí)極大的壓力,我們把這個(gè)場景叫做“dog-pile effect”(狗樁效應(yīng))。解決狗樁效應(yīng)的思路是盡量地減少緩存穿透后的并發(fā),方案也比較簡單:

(1)在代碼中控制在某一個(gè)熱點(diǎn)緩存項(xiàng)失效之后啟動一個(gè)后臺線程,穿透到數(shù)據(jù)庫,將數(shù)據(jù)加載到緩存中,在緩存未加載之前,所有訪問這個(gè)緩存的請求都不再穿透而直接返回。

(2)通過在 Memcached 或者 Redis 中設(shè)置分布式鎖,只有獲取到鎖的請求才能夠穿透到數(shù)據(jù)庫

六、CDN

1、靜態(tài)資源加速的原因

在我們的系統(tǒng)中存在著大量的靜態(tài)資源請求:對于移動 APP 來說,這些靜態(tài)資源主要是圖片、視頻和流媒體信息;對于 Web 網(wǎng)站來說,則包括了 JavaScript 文件、CSS 文件、靜態(tài) HTML 文件等等。它們的讀請求量極大并且對訪問速度的要求很高還占據(jù)了很高的帶寬,這時(shí)會出現(xiàn)訪問速度慢帶寬被占滿影響動態(tài)請求的問題,那么你就需要考慮如何針對這些靜態(tài)資源進(jìn)行讀加速了。

2、CDN

靜態(tài)資源訪問的關(guān)鍵點(diǎn)是就近訪問,即北京用戶訪問北京的數(shù)據(jù),杭州用戶訪問杭州的數(shù)據(jù),這樣才可以達(dá)到性能的最優(yōu)。我們考慮在業(yè)務(wù)服務(wù)器的上層增加一層特殊的緩存,用來承擔(dān)絕大部分對于靜態(tài)資源的訪問,這一層特殊緩存的節(jié)點(diǎn)需要遍布在全國各地,這樣可以讓用戶選擇最近的節(jié)點(diǎn)訪問。緩存的命中率也需要一定的保證,盡量減少訪問資源存儲源站的請求數(shù)量(回源請求)。這一層緩存就是CDN。

CDN(Content Delivery Network/Content Distribution Network,內(nèi)容分發(fā)網(wǎng)絡(luò))。簡單來說,CDN 就是將靜態(tài)的資源分發(fā)到位于多個(gè)地理位置機(jī)房中的服務(wù)器上,因此它能很好地解決數(shù)據(jù)就近訪問的問題,也就加快了靜態(tài)資源的訪問速度。

3、搭建CDN系統(tǒng)

搭建一個(gè) CDN 系統(tǒng)需要考慮哪兩點(diǎn):

(1)如何將用戶的請求映射到 CDN 節(jié)點(diǎn)上

你可能會覺得這很簡單啊,只需要告訴用戶 CDN 節(jié)點(diǎn)的 IP 地址,然后請求這個(gè) IP 地址上面部署的 CDN 服務(wù)就可以了啊。但是,并不是這樣,需要把ip替換為相應(yīng)的域名。那么如何做到這一點(diǎn)呢?這就需要依靠 DNS 來幫我們解決域名映射的問題了。DNS(Domain Name System,域名系統(tǒng))實(shí)際上就是一個(gè)存儲域名和 IP 地址對應(yīng)關(guān)系的分布式數(shù)據(jù)庫。而域名解析的結(jié)果一般有兩種,一種叫做“A 記錄”,返回的是域名對應(yīng)的 IP 地址;另一種是“CNAME 記錄”,返回的是另一個(gè)域名,也就是說當(dāng)前域名的解析要跳轉(zhuǎn)到另一個(gè)域名的解析上。

舉個(gè)例子:比如你的公司的一級域名叫做 example.com,那么你可以把你的圖片服務(wù)的域名定義為“img.example.com”,然后將這個(gè)域名的解析結(jié)果的 CNAME 配置到 CDN 提供的域名上,比如 uclound 可能會提供一個(gè)域名是“80f21f91.cdn.ucloud.com.cn”這個(gè)域名。這樣你的電商系統(tǒng)使用的圖片地址可以是“img.example.com/1.jpg”。

用戶在請求這個(gè)地址時(shí),DNS 服務(wù)器會將域名解析到 80f21f91.cdn.ucloud.com.cn 域名上,然后再將這個(gè)域名解析為 CDN 的節(jié)點(diǎn) IP,這樣就可以得到 CDN 上面的資源數(shù)據(jù)了。

域名層級解析優(yōu)化

因?yàn)橛蛎馕鲞^程是分級的,每一級有專門的域名服務(wù)器承擔(dān)解析的職責(zé),所以域名的解析過程有可能需要跨越公網(wǎng)做多次 DNS 查詢,在性能上是比較差的。一個(gè)解決的思路是:在 APP 啟動時(shí)對需要解析的域名做預(yù)先解析,然后把解析的結(jié)果緩存到本地的一個(gè) LRU 緩存里面。這樣當(dāng)我們要使用這個(gè)域名的時(shí)候,只需要從緩存中直接拿到所需要的 IP 地址就好了,如果緩存中不存在才會走整個(gè) DNS 查詢的過程。同時(shí)為了避免 DNS 解析結(jié)果的變更造成緩存內(nèi)數(shù)據(jù)失效,我們可以啟動一個(gè)定時(shí)器定期地更新緩存中的數(shù)據(jù)。

(2)如何根據(jù)用戶的地理位置信息選擇到比較近的節(jié)點(diǎn)。

GSLB(Global Server Load Balance,全局負(fù)載均衡)的含義是對于部署在不同地域的服務(wù)器之間做負(fù)載均衡,下面可能管理了很多的本地負(fù)載均衡組件。它有兩方面的作用:一方面,它是一種負(fù)載均衡服務(wù)器,負(fù)載均衡,顧名思義嘛,指的是讓流量平均分配使得下面管理的服務(wù)器的負(fù)載更平均;另一方面,它還需要保證流量流經(jīng)的服務(wù)器與流量源頭在地緣上是比較接近的。

GSLB 可以通過多種策略來保證返回的 CDN 節(jié)點(diǎn)和用戶盡量保證在同一地緣區(qū)域,比如說可以將用戶的 IP 地址按照地理位置劃分為若干個(gè)區(qū)域,然后將 CDN 節(jié)點(diǎn)對應(yīng)到一個(gè)區(qū)域上,根據(jù)用戶所在區(qū)域來返回合適的節(jié)點(diǎn);也可以通過發(fā)送數(shù)據(jù)包測量 RTT 的方式來決定返回哪一個(gè)節(jié)點(diǎn)。

總結(jié):DNS 技術(shù)是 CDN 實(shí)現(xiàn)中使用的核心技術(shù),可以將用戶的請求映射到 CDN 節(jié)點(diǎn)上;DNS 解析結(jié)果需要做本地緩存,降低 DNS 解析過程的響應(yīng)時(shí)間;GSLB 可以給用戶返回一個(gè)離著他更近的節(jié)點(diǎn),加快靜態(tài)資源的訪問速度。

拓展

(1)百度域名的解析過程

一開始,域名解析請求先會檢查本機(jī)的 hosts 文件,查看是否有 www.baidu.com 對應(yīng)的 IP;如果沒有的話,就請求 Local DNS 是否有域名解析結(jié)果的緩存,如果有就返回標(biāo)識是從非權(quán)威 DNS 返回的結(jié)果;如果沒有就開始 DNS 的迭代查詢。先請求根 DNS,根 DNS 返回頂級 DNS(.com)的地址;再請求.com 頂級 DNS 得到 baidu.com 的域名服務(wù)器地址;再從 baidu.com 的域名服務(wù)器中查詢到 www.baidu.com 對應(yīng)的 IP 地址,返回這個(gè) IP 地址的同時(shí)標(biāo)記這個(gè)結(jié)果是來自于權(quán)威 DNS 的結(jié)果,同時(shí)寫入 Local DNS 的解析結(jié)果緩存,這樣下一次的解析同一個(gè)域名就不需要做 DNS 的迭代查詢了。

(2)CDN延時(shí)

一般我們會通過 CDN 廠商的接口將靜態(tài)的資源寫入到某一個(gè) CDN 節(jié)點(diǎn)上,再由 CDN 內(nèi)部的同步機(jī)制將資源分散同步到每個(gè) CDN 節(jié)點(diǎn),即使 CDN 內(nèi)部網(wǎng)絡(luò)經(jīng)過了優(yōu)化,這個(gè)同步的過程是有延時(shí)的,一旦我們無法從選定的 CDN 節(jié)點(diǎn)上獲取到數(shù)據(jù),我們就不得不從源站獲取數(shù)據(jù),而用戶網(wǎng)絡(luò)到源站的網(wǎng)絡(luò)可能會跨越多個(gè)主干網(wǎng),這樣不僅性能上有損耗也會消耗源站的帶寬,帶來更高的研發(fā)成本。所以我們在使用 CDN 的時(shí)候需要關(guān)注 CDN 的命中率和源站的帶寬情況。

相關(guān)學(xué)習(xí)推薦:java基礎(chǔ)

Atas ialah kandungan terperinci java高并發(fā)系統(tǒng)設(shè)計(jì)之緩存篇. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial PHP
1502
276