設(shè)置
  • 日夜間
    隨系統(tǒng)
    淺色
    深色
  • 主題色

CDN 是什么,用了 CDN 就一定比不用更快嗎

小白debug 2023/1/6 12:58:09 責(zé)編:夢澤

對于開發(fā)同學(xué)來說,CDN 這個詞,既熟悉又陌生。

平時搞開發(fā)的時候很少需要碰這個,但卻總能聽到別人提起。

我們都聽說過它能加速,也大概知道個原因,但是往深了問。

用了 CDN 就一定比不用更快嗎?

就感覺有些懵了。但沒關(guān)系,今天我們換個角度重新認(rèn)識下 CDN。

CDN 是什么

對于數(shù)字和文本類型的數(shù)據(jù),比方說名字和電話號碼相關(guān)的信息。我們需要有個地方存起來。

我們通常會用 mysql 數(shù)據(jù)庫去存。

文本存在 mysql 中

當(dāng)我們需要重新將這一數(shù)據(jù)取出的時候,就需要去讀 mysql 數(shù)據(jù)庫。

但因為 mysql 的數(shù)據(jù)是存在磁盤上的,單臺實例,讀性能到差不多 5kqps 就已經(jīng)很不錯了。

看起來還湊合,但對于稍微大一點的系統(tǒng),就稍微有點捉急了。

為了提升點性能,我們在 mysql 之前再加一層內(nèi)存做緩存層,比如常說的 redis,讀數(shù)據(jù)優(yōu)先到內(nèi)存里讀,讀不到才到 mysql 里讀,大大減少了讀 mysql 的次數(shù)。有了這套組合拳,讀性能輕松上萬 qps。

mysql 和 redis

好了,到這里,我們說的都是我們平時比較容易接觸的開發(fā)場景。

但如果現(xiàn)在我要處理的,不再是上面提到的文本類數(shù)據(jù),而是圖片數(shù)據(jù)。

比如,我有一張帥氣的照片。就下面這張。

每次刷某音聽到有人翻唱蔡健雅的《letting go》的時候,我都忍不住想發(fā)這張圖。

并配文 "還是忘不了"。

那么問題來了。

這張圖片數(shù)據(jù)應(yīng)該存在哪?,又該從哪里讀?

我們回過頭去看 mysql 和 redis 的場景,無非就是存儲層加緩存層。

存儲層和緩存層

對于圖片這樣的文件對象,存儲層不太可能再用 mysql,應(yīng)該改用專業(yè)的對象存儲,比如亞馬遜的 S3(Amazon Simple Storage Service,注意后面是三個 S 開頭的單詞,所以叫 s3),或者阿里云的 oss(Object Storage Service)。下面的內(nèi)容,我們就用比較常見的 oss 去做解釋。

緩存層,也不能繼續(xù)用 redis 了,需要改成使用 CDNContent Delivery Network,內(nèi)容分發(fā)網(wǎng)絡(luò))。

可以將 CDN 簡單理解為對象存儲對應(yīng)的緩存層。

CDN 和 OSS

現(xiàn)在就可以回答上面的提問,對用戶來說,這張圖片數(shù)據(jù)存在了對象存儲那,當(dāng)有需要的時候,會從 CDN 那被讀出來。

CDN 的工作原理

有了 CDN 和對象存儲之后,現(xiàn)在我們來看下他們之間是怎么工作的。

我們平時看到的圖片,可以右鍵復(fù)制查看它的 URL。

1667103075060

會發(fā)現(xiàn)圖片的 URL 長這樣。

https://cdn.xiaobaidebug.top/1667106197000.png

其中前面的 cdn.xiaobaidebug.top 就是 CDN 的域名,后面的 1667106197000.png 是圖片的路徑名。

當(dāng)我們在瀏覽器輸入這個 URL 就會發(fā)起 HTTP GET 請求,然后經(jīng)歷以下過程。

CDN 的查詢流程

第一階段: 你的電腦會先通過 DNS 協(xié)議獲得 cdn.xiaobaidebug.top 這個域名對應(yīng)的 IP。

?step1 和 step2:先查看瀏覽器緩存,再看操作系統(tǒng)里的 / etc / hosts 緩存,如果都沒有,就會去詢問最近的 DNS 服務(wù)器(比如你房間里的家用路由器)。最近的 DNS 服務(wù)器上有沒有對應(yīng)的緩存,如果有則返回。

?step3:如果最近的 DNS 服務(wù)器上沒有對應(yīng)的緩存,就會去查詢根域,一級域,二級域,三級域服務(wù)器。

?step4:然后,最近的 DNS 服務(wù)器會得到這個 cdn.xiaobaidebug.top 域名的別名(CNAME),比如 cdn.xiaobaidebug.top.w.kunlunaq.com。

? kunlunaq.com 是阿里 CDN 專用的 DNS 調(diào)度系統(tǒng)。

?step5 到 step7:此時最近的 DNS 服務(wù)器會去請求這個 kunlunaq.com,然后返回一個離你最近的 IP 地址返回給你。

第二階段: 對應(yīng)上圖里的 step8。瀏覽器拿著這個 IP 去訪問 cdn 節(jié)點,然后,cdn 節(jié)點返回數(shù)據(jù)。

上面第一階段流程里,提到了很多新的名詞,比如 CNAME,根域,一級域啥的,它們在之前寫的 「DNS 中有哪些值得學(xué)習(xí)的優(yōu)秀設(shè)計」有很詳細(xì)的描述,如果不了解的話可以去看下。

我們知道 DNS 的目的就是通過域名去獲得 IP 地址。

但這只是它的眾多功能之一。

DNS 消息有很多種類型,其中 A 類型,就是用域名去查域名對應(yīng)的 IP 地址。而 CNAME 類型,則是用域名去查這個域名的別名

對于普通域名,DNS 解析后一般就能直接得到域名對應(yīng)的 IP 地址(又叫 A 類型記錄,A 指 Address)。

比如下面,我用 dig 命令發(fā)出 DNS 請求并打印過程數(shù)據(jù)。

$ dig +trace xiaobaidebug.top
;; ANSWER SECTION:
xiaobaidebug.top. 600 IN A 47.102.221.141

可以看到 xiaobaidebug.top 直接解析得到對應(yīng)的 IP 地址 47.102.221.141。

但對于 cdn 域名,一波查詢下來,先得到的卻是一條 CNAME 的記錄 xx.kunlunaq.com,然后 dig 這個 xx.kunlunaq.com 才能得到對應(yīng)的 IP 地址。

$ dig +trace cdn.xiaobaidebug.top
cdn.xiaobaidebug.top. 600 IN CNAME cdn.xiaobaidebug.top.w.kunlunaq.com.

$ dig +trace cdn.xiaobaidebug.top.w.kunlunaq.com
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.243
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.241
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.244
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.249
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.248
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.242
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.250
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.251

看到這里,問題就又來了。

為什么要加個 CNAME 那么麻煩?

CNAME 里指向的,其實是 CDN 專用的 DNS 域名服務(wù)器,它對整個 DNS 體系來說,只是其中一臺小小的 DNS 域名服務(wù)器,看起來就跟其他域名服務(wù)器一樣,平平無奇。DNS 請求也會正常打入這個服務(wù)器里。

但當(dāng)請求真正打到它上面的時候,它的特別之處就體現(xiàn)出來了,當(dāng)查詢請求打入域名服務(wù)器時,普通的 DNS 域名服務(wù)器返回域名對應(yīng)的部分 IP 就夠了,但 CDN 專用的 DNS 域名服務(wù)器卻會要求返回離調(diào)用方 " 最近的 " 服務(wù)器 IP。

CDN 專用的 DNS 解析服務(wù)器會返回就近的 CDN 節(jié)點 IP

怎么知道哪個服務(wù)器 IP 里調(diào)用方最近?

可以看到 "最近" 這個詞其實是加了雙引號的。

CDN 專用的 DNS 域名服務(wù)器其實是 CDN 提供商提供的,比如阿里云當(dāng)然知道自己的的 CDN 節(jié)點有哪些,以及這些 CDN 服務(wù)器目前的負(fù)載情況和響應(yīng)延時甚至權(quán)重啥的,并且也能知道調(diào)用方的 IP 地址是什么,可以通過調(diào)用方的 IP 知道它所屬的運(yùn)營商以及大概所在地,根據(jù)條件篩選出最合適的 CDN 服務(wù)器,這就是所謂的 " 最近 "。

舉個例子。假設(shè)地理位置最近的 CDN 機(jī)房流量較多,響應(yīng)較慢,但地理位置遠(yuǎn)一些的服務(wù)器卻能更好的響應(yīng)當(dāng)前請求,那按理說可能會選擇地理位置遠(yuǎn)一些的那臺 CDN 服務(wù)器。

也就是說,選出來的服務(wù)器不一定在地理位置最近,但一定是當(dāng)前最合適的服務(wù)器。

回源是什么

上面的圖片 URL,是 https://cdn 域名 / 圖片地址.png 的形式。

也就是說這張圖片是訪問 CDN 拿到的。

那么,直接訪問對象存儲能不能拿到圖片數(shù)據(jù)并展示?

比如像下面這樣。

https://oss域名/圖片地址png

這就像問,不走 redis,直接從 mysql 中能不能讀取到文本數(shù)據(jù)并展示一樣。

當(dāng)然能。

我之前放在博客里的圖片就是這么干的。

但這樣成本更高,這里的成本,可以指性能成本,也可以指調(diào)用成本??聪孪旅孢@個圖。

1667101182393

可以看到直接請求 oss 的費(fèi)用差不多是通過 cdn 請求 oss 的兩倍,考慮到家境貧寒,同時也為了讓博客獲取圖片的速度更快,我就接入了 CDN。

但看到這里,問題又又來了。

上面的截圖里,紅框里有個詞叫 " 回源 "。

回源是什么?

當(dāng)我們訪問 https://cdn 域名 / 圖片地址.png 時,請求會打到 cdn 服務(wù)器上面。

但 cdn 服務(wù)器本質(zhì)上就是一層緩存,并不是數(shù)據(jù)源,對象存儲才是數(shù)據(jù)源

第一次訪問 cdn 獲取某張圖片時,大概率在 cdn 里并沒有這張圖片的數(shù)據(jù),因此需要到數(shù)據(jù)那去取出這份圖片數(shù)據(jù)。然后再放到 cdn 上。下次再次訪問 cdn 時,只要緩存不過期,就能命中緩存直接返回,這就不需要再回源。

于是訪問的過程就變成了下面這樣。

1668605964836

那還有哪些情況會發(fā)生回源呢?

除了上面提到的 cdn 上拿不到數(shù)據(jù)會回源站外,還有 cdn 上的緩存過期失效了也會導(dǎo)致回源站。

另外,就算有緩存,且緩存不過期,也可以通過 cdn 提供的開放接口來觸發(fā)主動回源,但這個我們比較少機(jī)會能接觸到。

另外,回源這個事情,其實用戶是感知不到的,因為用戶去讀圖片的時候,只能知道自己讀到了還是讀不到。

同樣是讀到了,還細(xì)分為是從 cdn 那直接讀的,還是 cdn 回源讀對象存儲之后返回的

有緩存直接返回和沒緩存回源的區(qū)別

那么,我們有辦法判斷是否發(fā)生過回源嗎?

有。我們接著往下看。

怎么判斷是否發(fā)生回源

我們以某里云的對象存儲和 CDN 為例。

假設(shè)我要請求下面這張圖 https://cdn.xiaobaidebug.top/ image / image-20220404094549469.png

為了更方便的查看響應(yīng)數(shù)據(jù)的 http header,我們可以用上 postman。

通過 GET 方法去請求圖片數(shù)據(jù)。

然后通過下面的 tab 切換查看 response header 信息。

查看 response header

回源的情況

此時查看 response header 下的 X-Cache 的值是 MISS TCP_MISS。意思是未命中緩存導(dǎo)致 CDN 回源查 oss,拿到數(shù)據(jù)后再返回。

那此時 CDN 里肯定是有這張圖片的緩存了。我們可以試著再執(zhí)行一次 GET 方法獲取圖片。

1667095186020

X-Cache 的值就變成了 HIT TCP_MEM_HIT,這就是命中緩存了。

這個是某里云的做法,其他比如騰某云啥的,也都大差不差,幾乎都可以從 response header 里找到相關(guān)的信息。

用了 CDN 一定比不用的更快嗎?

看到這里我們就可以回答文章開頭的問題了。

如果沒有接入 CDN,直接訪問源站,流程是這樣的。

更新直接訪問源站

但如果接入了 CDN,且 CDN 上沒有緩存數(shù)據(jù),那就會觸發(fā)回源。

更新走了 CDN 還回源

相當(dāng)于在原來的流程上還多了一層 CDN 的調(diào)用流程。

也就是,用了 CDN 時,未命中 CDN 緩存導(dǎo)致回源,就會比不用的時候更慢。

未命中緩存,可能是 cdn 里壓根就沒這一數(shù)據(jù),也可能是曾經(jīng)有這條數(shù)據(jù)但后來過期失效了

這兩種情況都正常,大部分時候并不需要做任何處理。

但對于極個別場景,我們可能需要做些優(yōu)化。比如你們源站數(shù)據(jù)有大版本更新,就像更換 cdn 域名啥的,那在上線的那一刻用戶全用新 cdn 域名去請求圖片啥的,新 CDN 節(jié)點基本上百分百觸發(fā)回源,嚴(yán)重的時候甚至可能會拖垮對象存儲。這時候你可能需要提前將熱點數(shù)據(jù)篩選出來,利用工具預(yù)先請求一波,讓 CDN 加載上熱數(shù)據(jù)緩存。比如某里云上的 CDN 就有這樣的 " 刷新預(yù)熱 " 功能。

cdn 刷新預(yù)熱

當(dāng)然也可以通過灰度發(fā)布的模式,先讓少量用戶體驗新功能,讓這些用戶把 cdn"熱" 起來,然后再逐步放開流量。

還有就是曾經(jīng)有這條數(shù)據(jù)但后來過期失效了,對于熱點數(shù)據(jù),可以適當(dāng)提高一下 cdn 數(shù)據(jù)的緩存時間。

1667344813600

什么情況下不應(yīng)該使用 CDN?

從上面的描述看下來,CDN 最大的優(yōu)勢在于,對于來自世界各地的用戶,它可以就近分配 CDN 節(jié)點獲取數(shù)據(jù),并且多次重復(fù)獲取同一個文件數(shù)據(jù)的時候,有緩存加速的作用。

這對于網(wǎng)頁圖片這樣的場景,是再合適不過了。因為底層用的是對象存儲,也就是說,只要是文件對象,比如視頻啥的,都可以用這套流程接入 cdn 做加速。比如平時刷的某音某手短視頻就是這么干的。

那反過來想想,問題就來了。

什么情況下不應(yīng)該使用 CDN?

如果你有一個公司內(nèi)網(wǎng)的服務(wù),并且服務(wù)請求的圖片等文件不太可能被多次重復(fù)調(diào)用,這時候其實沒必要使用 CDN。

注意上面兩個加粗了的關(guān)鍵點。

內(nèi)網(wǎng)服務(wù),是為了保證你是了解服務(wù)的請求來源的,也能拿到對象存儲的讀權(quán)限,并且如果你的對象存儲也是公司內(nèi)部的,那大概率跟你的服務(wù)已經(jīng)在同一個機(jī)房里,這已經(jīng)很近了。接入 CDN 也享受不到 "就近分配 CDN 節(jié)點" 所帶來的好處。

? 圖片或其他文件不太可能被多次重復(fù)使用,如果接入了 CDN,那你每次去訪問 CDN 獲取圖片的時候,CDN 節(jié)點上大概率沒有你要的數(shù)據(jù),相當(dāng)于每次都需要回源到對象存儲去取一把。那接入 CDN 相當(dāng)于給自己加了一層代理,多一層代理,就多一層耗時。

1668612494972

關(guān)于上面的第二點,如果你需要一個明確的指標(biāo)去說服自己,那我可以給你一個。從上面的介紹內(nèi)容,我們知道,可以通過 cdn 響應(yīng)的 http header 中的 X-Cache 字段,看到一個請求是否觸發(fā)過回源,統(tǒng)計次數(shù),再除以總的請求數(shù),就能得到回源的比例,比如回源比例高達(dá) 90%,那還接啥 cdn。

總結(jié)

? 對于文本類數(shù)據(jù)我們習(xí)慣用 mysql 做存儲,redis 做緩存。但屬于文件類數(shù)據(jù),比如視頻圖片,則需要使用 oss 等做對象存儲,cdn 做緩存。

? 用了 CDN 如果發(fā)生回源,那實際上會比不用的時候更慢一些。

? CDN 最大的優(yōu)勢在于,對于來自世界各地的用戶,它可以就近分配 CDN 節(jié)點獲取數(shù)據(jù),并且多次重復(fù)獲取同一個文件數(shù)據(jù)的時候,有緩存加速的作用。如果你的服務(wù)和對象存儲都在內(nèi)網(wǎng),并且文件數(shù)據(jù)也不太會有重復(fù)使用的可能性,那其實沒必要接入 cdn。

本文來自微信公眾號:小白 debug (ID:xiaobaidebug),作者:小白

廣告聲明:文內(nèi)含有的對外跳轉(zhuǎn)鏈接(包括不限于超鏈接、二維碼、口令等形式),用于傳遞更多信息,節(jié)省甄選時間,結(jié)果僅供參考,IT之家所有文章均包含本聲明。

相關(guān)文章

關(guān)鍵詞:CDN

軟媒旗下網(wǎng)站: IT之家 最會買 - 返利返現(xiàn)優(yōu)惠券 iPhone之家 Win7之家 Win10之家 Win11之家

軟媒旗下軟件: 軟媒手機(jī)APP應(yīng)用 魔方 最會買 要知