掐指算算:你的CDN多花了幾百萬?
互聯(lián)網(wǎng)中對象訪問頻率的91分布 我們通過 90%的流量由10%的內容產(chǎn)生 這句經(jīng)驗描述, 得出了訪問頻率的zipf模型:

CDN (Content delivery network) 就是一個典型的符合zipf分布的緩存系統(tǒng): 將緩存服務部署在距離用戶最近的上百個地區(qū)(CDN邊緣機房), 當用戶需要訪問熱門內容時,只需在邊緣機房讀取,以此達到性能優(yōu)化。
因為符合zipf模型, 所以,如果一個邊緣機房的容量對全量數(shù)據(jù)的占比變化1%,會帶來每年數(shù)十萬元的成本變化。一個中等規(guī)模的CDN系統(tǒng),調優(yōu)前后,可能會有每年幾百萬的成本差別。
本文從原理到實踐跟大家一起分析下CDN的成本構成,以及zipf如何影響成本。
本文結構:

文件訪問頻率的分布規(guī)律
按照前文 互聯(lián)網(wǎng)中對象訪問頻率的91分布 中介紹, 下圖是從真實業(yè)務中提取的1000個URL訪問次數(shù), 按照訪問次數(shù)從高到低進行排序的zipf曲線:

圖1 訪問頻率分布
基于上圖所呈現(xiàn)的訪問熱度分布,CDN邊緣機房會緩存最熱的文件 (對應圖中橘黃色部分), 為用戶提供更好的訪問質量, 而剩下藍色部分不太頻繁被訪問的文件, 則按照正常的方式回源站拉取,再返回給用戶。
于是就有了由存儲/回源構成的CDN的成本:
CDN成本構成
構成CDN的成本主要由2部分組成:
- 邊緣機房中用于存儲熱文件(橘黃色)的服務器開銷;
- 拉取本地不存在的冷文件(藍色)時,訪問內容源站(存儲全量數(shù)據(jù))的帶寬開銷。
顯然邊緣存儲量越大,可緩存的內容就越多, 回源率(回源下載帶寬/業(yè)務總下載帶寬)就會越低,因此:
- 邊緣存儲成本上升,會帶來回源帶寬成本下降。
- 反之邊緣存儲成本下調,則會帶來回源成本的上升。
接下來我們通過3個步驟,找到一個合適的邊緣容量,讓存儲和帶寬的成本總和達到一個極小值:
- 量化業(yè)務參數(shù);
- 確定業(yè)務的模型,也就是zipf中的參數(shù);
- 根據(jù)單位成本找出業(yè)務場景中的最優(yōu)邊緣容量,以及其對應的最低成本。
確定業(yè)務參數(shù)
一個假想的業(yè)務場景和CDN服務配置如下:
- 每個CDN邊緣機房對外提供的日常下載總帶寬: 20Gbps,
- 源站中所有文件的總量n: 7200TB,
- 邊緣機房的存儲容量占源站文件總量的比值: e(edge),例如(圖1)中,e=10%,每個邊緣機房能存儲1/10的內容。
- 回源率b(backsource) 是邊緣機房消耗的回源帶寬跟這個邊緣機房下載帶寬的比值,例如(圖1)中,e=10%時,b=6%。

其中下載帶寬和文件總量n是業(yè)務屬性; e和b是CDN的屬性,不取決于業(yè)務,是由CDN提供商選擇,并最終決定成本的因素。
e,邊緣容量 對應(圖1)中橘黃色部分的x方向的寬度,圖中e的值是10%。
b 對應(圖1)中的藍色部分, 是需要回源的請求,在(圖1)中,b的值是藍色部分的訪問次數(shù)之和(不同于e,不是寬度), 跟所有文件總訪問次數(shù)之和的比值。
確定業(yè)務模型-擬合zipf曲線
業(yè)務場景確定后,找出最佳成本的第一步是為這個熱度分布曲線建立模型, 以便后面的計算。根據(jù)我們上一篇中介紹過的 轉換成對應的zipf分布的公式 的方法,找出zipf曲線的2個參數(shù):
把x,y軸分別取對數(shù)后,圖像會呈現(xiàn)一個線性關系:

(圖2) 取對數(shù)后呈現(xiàn)線性關系
然后通過多項式回歸,對(圖2)中的點擬合一條直線,就可以得到c和s。
例如我們使用預先準備好的url計數(shù)文件 file-access-count.txt[1] 作為例子, 使用這個 find-zipf.py[2] 腳本來擬合可以得到:
- > python2 find-zipf.py6.796073 - 0.708331x
再分別對兩邊取指數(shù),就從日志中得到了zipf 曲線的參數(shù): 第k熱的對象和它被訪問次數(shù)的關系:

其中s的值 s=0.708331是我們后面計算需要用到的。
zipf中的c參數(shù)在我們的分析中沒有被使用到, 因為c只決定了文件被訪問頻率的分布的絕對值,而不影響分布的相對值。而我們要考察的回源率b,是一個比值,它只跟頻率分布的相對值有關。
通過zipf建立CDN邊緣容量和回源率的關系
確定了zipf方程后, 我們就可以準確的給出CDN系統(tǒng)中以下3個關鍵變量的關系:
- 全量文件nTB,
- 邊緣機房容量e*nTB,
- 和回源率b。

因為s 已經(jīng)通過直線擬合得到了,而e和b可以從邊緣機房的具體配置和訪問日志得到。 于是我們可以確定n的值, 也就是說(劃重點):
CDN可以根據(jù)訪問模型估算源站的總文件量。
雖然源站信息一般不會直接透漏給CDN提供商, 但實際上這個信息對CDN來說是可估算的。同樣,對于源站來說,他知道自己的全量數(shù)據(jù)n的值,以及回源率b的值, 通過這個公式也可以知道CDN的 一個邊緣機房的存儲容量e。
確定IT設施單位成本
有了b,e的關系,接下來給出基礎成本數(shù)據(jù),就可以確定最優(yōu)成本對應的e的值了:
從網(wǎng)上搜一些基礎數(shù)據(jù)(如服務器價格,硬盤價格,各家云大廠提供的帶寬單價等), 折算成單位成本為后面計算時使用:
- 邊緣機房的存儲的成本是 1 元/TB/天,包括服務器和租機房的費用,三年均攤。
- 邊緣機房拉取源站內容的帶寬成本是 600 元/Gbps/天。
價格等數(shù)值因為是從網(wǎng)上搜來的,可能跟實際運營中的數(shù)據(jù)相差很多,這里只為用來說明原理, 確定方法,不保證數(shù)值上跟真實環(huán)境完全吻合。
根據(jù)以上設定,我們可以得到一個邊緣機房中:
- 存儲成本是: 7200TB * e * 1元/TB/天
- 回源帶寬成本: 20Gbps * b * 600元/Gbps/天
找出最優(yōu)配置
現(xiàn)在所有的模型,場景和數(shù)據(jù)都準備好了, 最后我們把它們放在一起得到最終結論: 成本對邊緣容量的變化:
- 選擇不同的邊緣容量e的值((圖1)橘黃色部分的寬度),
- 根據(jù)公式(2)計算對應的回源率b((圖1)藍色部分積分/藍色黃色部分積分),
- 再結合單位成本,得出每個e對應的總成本,
最后我們得到如下一個邊緣容量e決定回源率b和成本的表格:

我們看到,在這個業(yè)務場景中,邊緣容量取到6%時,總成本會達到最低: 1419.6 元/天。
把e變化作為x軸,畫出邊緣存儲成本和回源帶寬成本隨e變化的曲線如下圖, 趨勢看起來就更清楚了:

我們看到總成本(紅色曲線)在這個圖上有一個極小值,大概在e=6%的位置。
而如果邊緣機房的容量配置不在6%這個位置,譬如達到10%, 一個邊緣機房每天就會多花掉1507-1419= 88 元, 如果整個CDN系統(tǒng)有100個邊緣機房,一年多花的錢就是320萬 (88 * 100 * 365)。
當然,在實際運營一個CDN這種龐大的系統(tǒng)的時候,還有很多因素需要考慮:
- 如邊緣機房的存儲容量帶來的性能提升,
- 低回源率帶來的整體延遲降低等。
因此我們的結論尚不能作為優(yōu)化的標準,而只能作為優(yōu)化的參考:
- 知道理論上限在哪,
- 不做無效的嘗試,
- 制定有依據(jù)的目標,
- 了解運營策略調整的成本等等。
總結
算完了,休息一下。
互聯(lián)網(wǎng)的各種服務之間都是相互關聯(lián)的。雖然目前看來,源站和CDN之間的協(xié)作還是單方面的,一方去適應另一方, 或一方服務另一方的模式。其實源站和邊緣之間,本應是一個整體,但市場的劃分導致了技術和設施層面上的分離, 讓這個本應完整的框架分離成了2個或多個部分。
這里我們看到的源站和邊緣之間的關系, 還只是開始,這些只不過是數(shù)學結論上的互相了解, 源站和邊緣之間應該有比這更大的的協(xié)作空間。
試想一下,邊緣和源站之間如果能在單向數(shù)據(jù)下載的基礎上建立雙向數(shù)據(jù)通訊, 在中心源站數(shù)據(jù)發(fā)生變化要通知邊緣緩存的基礎上, 如果邊緣發(fā)生的事情能很快推送到中心, 才是真正的互聯(lián)網(wǎng)模式。
市場一直在變化, 每次在這些變化背后, 一定是有一個什么新的東西出現(xiàn),是讓用戶使用到了更方便或更高效的東西, 才讓技術的格局發(fā)生了變化(google之于yahoo,微信之于郵箱,twitter之于博客)。
出色的支持和適配可以產(chǎn)生優(yōu)質的產(chǎn)品,但我相信協(xié)作和互通更能帶來質的變化。作為一個技術從業(yè)人員,發(fā)現(xiàn)這些改變的可能,實現(xiàn)這些改變,并把這種改變服務于可受益的人, 也許就是最開心的事情了: Discover, Design, Distribute…
文中鏈接:
[1] http://openacid.github.io/post-res/cache-hit/file-access-count.txt
[2] http://openacid.github.io/post-res/cache-hit/find-zipf.py
作者張炎潑 (xp)。