6行代碼節(jié)省超千萬成本——記一次字段治理的“巧渡金沙江”
導(dǎo)讀:本文回顧了關(guān)于快手的核心數(shù)據(jù)對象“Photo”存儲系統(tǒng)的一次巧妙降本增效的故事。通過充足細(xì)致的前期調(diào)研分析,以極少的人力投入取得了相當(dāng)可觀的收益。文中對有巨大UGC歷史數(shù)據(jù)存量的平臺型公司如何應(yīng)對挑戰(zhàn)有一些思考和總結(jié)。
一、引言
Premature optimization is the root of all evil (or at least most of it) in programming. —— Donald Knuth
快手作為國民級短視頻平臺,歷史上短視頻的總量已達(dá)千億級,每日新增短視頻作品超過4000萬。本文的主角是快手短視頻在系統(tǒng)中的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)——Photo對象。
為什么叫Photo而不是video?
快手的前身是2011年推出的“Gif快手”,當(dāng)時的主要功能是將視頻在手機(jī)上方便高效地轉(zhuǎn)換為Gif動圖。由于Gif兼具視頻動效和圖片的輕量特性,適合在微博等平臺傳播,因此早期將Gif動圖命名為Photo并無不妥。隨著產(chǎn)品轉(zhuǎn)型為短視頻和直播社區(qū),核心數(shù)據(jù)結(jié)構(gòu)的名稱為沿用至今。
Photo對象是什么?
Photo對象是快手生態(tài)中短視頻的核心數(shù)據(jù)結(jié)構(gòu),包含除音視頻信息(通常在MB~GB級別)外的大部分屬性信息,如標(biāo)題、碼率、封面、上傳時間、位置、商業(yè)化信息等。截至2023年初,Photo對象已包含200多個屬性,平均大小在3k~4k之間。本文的故事圍繞Photo對象的存儲優(yōu)化展開。
為什么標(biāo)題叫"巧渡金沙江"?
巧渡金沙江?和?強(qiáng)渡大渡河?是在1935年4、5月間發(fā)生在中央紅軍長征途中的兩場著名戰(zhàn)斗,前者僅用了7條小船經(jīng)7天7夜實(shí)現(xiàn)了紅軍的戰(zhàn)略轉(zhuǎn)移意圖,后者經(jīng)過激烈的浴血奮戰(zhàn)獲得勝利后成功打開了轉(zhuǎn)移的通道,兩者在長征史上具有同樣重要的戰(zhàn)略意義。本文對Photo對象的優(yōu)化因其投入極小卻取得不小的收益,故而借用巧渡金沙江的典故。
?
二、治理優(yōu)化的背景和收益
2.1 治理優(yōu)化的項(xiàng)目背景
Photo對象存儲在關(guān)系數(shù)據(jù)庫中,在快手承載著有數(shù)以千計(jì)的上游服務(wù)調(diào)用,中間用緩存扛流量,緩存請求量QPS在億級別,并且緩存回源DB的請求也高達(dá)百萬次QPS。為了支撐如此龐大的數(shù)據(jù)庫請求,我們采取了數(shù)據(jù)庫分片加讀寫分離的多從庫策略,從而將單個數(shù)據(jù)庫分片從庫的請求壓力降低至每秒千次級別。然而,這種高可用性和擴(kuò)展性的提升,是以數(shù)據(jù)存儲冗余度成倍增加為代價(jià)的。
在緩存與磁盤存儲空間成本相差懸殊的背景下,如何平衡成本與性能成為了選擇緩存空間規(guī)模的關(guān)鍵問題。快手Photo服務(wù)的緩存容量雖已達(dá)TB級別,但面對千億級的歷史冷數(shù)據(jù)存量,TB級的緩存資源仍然捉襟見肘,這一點(diǎn)集中體現(xiàn)在緩存命中率隨時間的持續(xù)下降趨勢上。在極高的請求量背景下,緩存命中率的每一個百分點(diǎn)下降都會轉(zhuǎn)化為回源服務(wù)對DB請求量的顯著增加。因此,我們追求的理想緩存命中率應(yīng)盡可能接近100%。
下圖可以看出在22年時緩存平均命中率已經(jīng)退化到了94%,這意味著著需要部署更多的回源服務(wù)和更高的DB請求量,而這一數(shù)值在2019年時曾維持在98%以上。
2.2 優(yōu)化收益
本次photo優(yōu)化治理取得了較為顯著的成效,具體體現(xiàn)以下三個方面:
1.存儲空間大幅縮減:成功將快手核心數(shù)據(jù)資產(chǎn)Photo的存量數(shù)據(jù)縮減約25%,累計(jì)節(jié)省數(shù)百TB,有效降低了存儲成本。
2.新增數(shù)據(jù)體積優(yōu)化:優(yōu)化后的新增Photo作品平均體積減少近1KB,結(jié)合每日數(shù)千萬的上傳量,每日新增DB空間減少數(shù)百GB。
3.緩存命中率提升:Photo緩存系統(tǒng)的命中率從95%提升至97%,在億級QPS的規(guī)模下,每提升一個百分點(diǎn)意味著年化成本節(jié)省達(dá)百萬級別,顯著提升了系統(tǒng)效率并降低了運(yùn)營成本。
?
2.3 Photo架構(gòu)簡圖
?
通過對DB單分庫的全量數(shù)據(jù)進(jìn)行清洗,我們可觀察到存儲量的明顯拐點(diǎn)。存量數(shù)據(jù)清洗后,DB存儲總計(jì)下降了400T,清洗過程中還留下了許多“空洞”,隨后被新的增量數(shù)據(jù)優(yōu)先填補(bǔ),這引出存儲量曲線在一段時間內(nèi)保持水平。此外,在增量優(yōu)化邏輯上線后,新增Photo對象大小同樣減少了約25%。
三、Photo緩存命中率的意義
在快手這一大型內(nèi)容平臺上,爆款作品往往會在極短時間內(nèi)獲得海量的展現(xiàn)和播放,從而對熱點(diǎn)Photo的請求量極高。與此同時,對于數(shù)月甚至數(shù)年前的冷數(shù)據(jù),其請求則具有較大的隨機(jī)性和不可預(yù)測性。
Photo緩存常年處于滿載狀態(tài),這意味著每有一條新數(shù)據(jù)寫入緩存,就必須有一條舊數(shù)據(jù)被淘汰以騰出空間。熱點(diǎn)數(shù)據(jù)的高請求量決定了必須依賴緩存來應(yīng)對,而冷數(shù)據(jù)的隨機(jī)訪問則導(dǎo)致緩存中持續(xù)進(jìn)行數(shù)據(jù)的換入換出。下圖展示了歷史上某日Photo緩存(單個Memcached集群)的請求量級。從讀寫請求的角度來看,下圖綠色的讀緩存QPS穩(wěn)定在約千萬級,而黃色的寫緩存QPS則保持在百萬級。這些寫請求主要源于讀緩存未命中后,服務(wù)回源DB并將數(shù)據(jù)回寫至緩存所產(chǎn)生的結(jié)果。這種讀寫請求的分布清晰地反映了緩存系統(tǒng)在應(yīng)對熱點(diǎn)與冷數(shù)據(jù)訪問時的動態(tài)平衡。
當(dāng)請求獲取Photo數(shù)據(jù)時,若命中緩存,則立即返回結(jié)果;若未命中,則會觸發(fā)一次DB讀請求并回寫緩存后再返回。在千萬QPS的緩存請求量級下,命中率每下降一個百分點(diǎn),就意味著1%的緩存讀取請求會轉(zhuǎn)化為數(shù)十萬的數(shù)據(jù)庫讀取QPS和緩存寫入QPS。如果命中率下降4個百分點(diǎn),數(shù)據(jù)庫將額外承受超百萬的讀取請求QPS,這也進(jìn)一步解釋了為何數(shù)據(jù)庫需要采用分庫分表結(jié)合一主多從的設(shè)計(jì)架構(gòu)。
此外,快手的回源服務(wù)采用獨(dú)立部署架構(gòu),緩存命中率每下降1個百分點(diǎn),都會導(dǎo)致回源服務(wù)流量增加數(shù)十萬QPS。因此,緩存命中率提升2個百分點(diǎn),大致可減少60萬的數(shù)據(jù)庫讀取QPS和回源服務(wù)QPS,相當(dāng)于節(jié)省了3個數(shù)百TB級別的數(shù)據(jù)庫從庫以及數(shù)千個CPU核心資源。
由此我們可以得出結(jié)論:對于Photo這種承載巨量QPS和數(shù)據(jù)規(guī)模的緩存系統(tǒng)而言,命中率每提升1個百分點(diǎn),就能為上下游系統(tǒng)帶來年化百萬元級別的成本節(jié)約收益。這一優(yōu)化不僅顯著降低了數(shù)據(jù)庫和回源服務(wù)的壓力,也為整體系統(tǒng)的資源利用率帶來了大幅提升。
從下方兩張圖數(shù)據(jù)對比可以看出,本次治理確實(shí)顯著提升了緩存命中率,漲幅約為2個百分點(diǎn)。具體來看,上圖展示了治理期間緩存命中率變化趨勢。紅框內(nèi)數(shù)據(jù)顯示,日均命中率隨時間呈現(xiàn)遞增趨勢,四周的時間上升達(dá)到了近1個百分點(diǎn)(圖例中的-1d代表前一天,-4w代表4周前的同一天)。作為對比,下圖呈現(xiàn)在未進(jìn)行優(yōu)化時的常規(guī)狀態(tài)下緩存命中率走勢,不難看出紅框內(nèi)的數(shù)據(jù)隨時間呈現(xiàn)逐步下降的趨勢。
?
對照組數(shù)據(jù)(2024-8),紅框內(nèi)命中率隨時間下降【從下往上看】
讀者可能會好奇,為什么Photo的緩存命中率會隨著時間的推移自然下降?
這是因?yàn)槠脚_每天新增的數(shù)千萬上傳作品會同步產(chǎn)生同樣數(shù)量的新增對象存入DB。隨著數(shù)據(jù)“與日俱增”,緩存的總?cè)萘繀s保持不變,導(dǎo)致“緩存容量/DB總數(shù)據(jù)量”這一比值自然隨時間逐漸降低。那么,為什么在優(yōu)化治理過程中命中率會有顯著提升呢?這是因?yàn)閮?yōu)化措施使每個Photo對象的體積縮小,相同容量的緩存能夠存儲的Photo數(shù)量隨之增加,從而提升了命中率。這一優(yōu)化過程可以類比為“克服重力做功”,或者說系統(tǒng)外部的力量在對抗“系統(tǒng)的熵增”而做功。
值得注意的是,下圖展示2024年8月某日的平均命中率略高于治理期間的數(shù)據(jù),這是因?yàn)?024年進(jìn)行了一次緩存擴(kuò)容,通過“硬拉升”的方式提升了命中率。事實(shí)上,隨著歷史數(shù)據(jù)的不斷積累,類似的緩存擴(kuò)容在過去幾年中已經(jīng)執(zhí)行過多次。這也是快手這類擁有海量UGC內(nèi)容增量的平臺所面臨的共同挑戰(zhàn)。從下方的趨勢圖可以看出,命中率提升的過程從22年12月初持續(xù)到23年2月,在過億QPS的訪問量下,平均命中率從95%穩(wěn)步提升至97%,這一成果實(shí)屬不易。
四、Photo對象如何變小
4.1 Photo庫結(jié)構(gòu)
Photo庫的表結(jié)構(gòu)是一個典型的數(shù)據(jù)庫實(shí)體表,包含約20個字段,主要由作品ID、作者ID、時間戳以及若干狀態(tài)信息組成。其中,有一個JSON結(jié)構(gòu)的擴(kuò)展字段,存儲各業(yè)務(wù)線的業(yè)務(wù)屬性。這種設(shè)計(jì)的好處在于,當(dāng)業(yè)務(wù)需要擴(kuò)展時,無需頻繁變更庫表結(jié)構(gòu)。然而,這種設(shè)計(jì)也并非沒有弊端。如果缺乏有效管控,隨著業(yè)務(wù)規(guī)模的擴(kuò)大,擴(kuò)展字段中的屬性數(shù)量會迅速膨脹。到2023年,Photo表的擴(kuò)展字段中已經(jīng)包含了超過200個屬性,這無疑增加了數(shù)據(jù)存儲和處理的復(fù)雜性。
?
統(tǒng)計(jì)時間 | 擴(kuò)展字段內(nèi)屬性數(shù) |
19年5月 | 約60個 |
20年5月 | 約120個 |
21年5月 | 約160個 |
22年3月 | 約210個 |
23年5月 | 約230個 |
?
從上表可以看出,從2019年到2023年,擴(kuò)展字段內(nèi)的屬性數(shù)量呈現(xiàn)明顯的增長趨勢。但在2022年Q3之后,屬性數(shù)量的增速得到了顯著遏制,這主要得益于負(fù)責(zé)團(tuán)隊(duì)的同學(xué)著手施行了較嚴(yán)格的字段管控,業(yè)務(wù)字段需業(yè)務(wù)自己維護(hù),非必要不允許進(jìn)Photo表。
?
4.2 治理思路
經(jīng)過統(tǒng)計(jì)分析,我們發(fā)現(xiàn)200多個屬性中,TOP30的屬性占據(jù)了總空間的93%,而前6個屬性占據(jù)了總空間的一半以上。這些屬性多為復(fù)合結(jié)構(gòu),也即json嵌套子結(jié)構(gòu),且多數(shù)值為0、false、null等默認(rèn)值。這一發(fā)現(xiàn)讓解決方案自然浮現(xiàn)——“把這些默認(rèn)值拿掉可取得顯著收益”。
?
從下圖可以看出,除了videoId屬性外,其他屬性都被不必要地存儲在每個Photo對象中。無數(shù)個Photo對象疊加起來,這部分冗余存儲成本累積到了驚人的地步。
?
?
在JAVA生態(tài)下應(yīng)對此類問題,只要在類中相應(yīng)的字段上加寫一條@JsonInclude(Include.NON_DEFAULT)的注解語句,即可避免將這些冗余信息存儲到DB里了。隨后在占存儲大頭的6個復(fù)合結(jié)構(gòu)上添加同樣的代碼,成功地將一個Photo元數(shù)據(jù)對象的尺寸縮減了25%。雖然單個Photo對象僅縮減了約1KB,但在千億量級的規(guī)模下,這一優(yōu)化聚沙成塔,累計(jì)節(jié)省了數(shù)百TB的存儲空間。
經(jīng)過測算,本次治理工作至今已累計(jì)節(jié)省了超千萬元的成本,且這一收益仍在持續(xù)增加中。此外,不可忽略的是Photo對象縮小25%后,億級QPS的流量在內(nèi)外網(wǎng)傳輸時帶寬需求顯著降低。各請求上游服務(wù)處理的數(shù)據(jù)量也相應(yīng)減少,甚至快手用戶在手機(jī)上刷短視頻時,每條視頻的流量也減少了若干KB——盡管如今流量成本已經(jīng)很低,但積少成多,依然帶來了可觀的收益。總之,本次優(yōu)化的收益涵蓋了多個環(huán)節(jié),包括存儲、緩存、回源服務(wù)、網(wǎng)絡(luò)帶寬、客戶端流量以及所有在線和離線下游服務(wù)處理Photo時所節(jié)省的時間和空間等。
?
4.3 存量數(shù)據(jù)的清洗
?
存量數(shù)據(jù)清洗的挑戰(zhàn)與決策
坦率地講,對于仍處于藍(lán)海增長階段的互聯(lián)網(wǎng)大廠來說,如果沒有特別大的成本壓力,增量數(shù)據(jù)優(yōu)化完成后,存量數(shù)據(jù)的清洗往往難以被視為高ROI的事項(xiàng)。坐等存量數(shù)據(jù)自然冷卻,也能被動取得一定的效果。反而要是清洗數(shù)以千億計(jì)的存量數(shù)據(jù)不僅耗時漫長,還蘊(yùn)藏著不可忽視的穩(wěn)定性風(fēng)險(xiǎn)。快手近兩年著重加強(qiáng)穩(wěn)定性意識的建設(shè),在當(dāng)前業(yè)界穩(wěn)定性事件頻發(fā)的背景下,決定是否清洗存量數(shù)據(jù)實(shí)屬不易。兩年前,我們以服務(wù)Owner的角色,秉持追求極致和最高標(biāo)準(zhǔn)的理念,做出了推進(jìn)存量數(shù)據(jù)清洗的決定。這一決策的前提是通過審慎的正確性驗(yàn)證過程和持續(xù)2個月的放量觀察階段,同時同事間對清洗代碼的每一行都進(jìn)行了認(rèn)真負(fù)責(zé)的評審。
清洗過程的技術(shù)細(xì)節(jié)與穩(wěn)定性保障
整個數(shù)據(jù)清洗過程使用了一臺16核的容器實(shí)例,并開啟了數(shù)百個線程進(jìn)行數(shù)據(jù)庫IO操作。除了確保數(shù)據(jù)正確性外,還需要特別關(guān)注穩(wěn)定性風(fēng)險(xiǎn)。例如,單庫清洗速度不能過快,否則可能導(dǎo)致從庫同步時的binlog延遲,以及下游監(jiān)聽消費(fèi)服務(wù)的過載風(fēng)險(xiǎn)。Photo庫共有100個分庫,每個分庫中包含10張分表。在數(shù)據(jù)清洗的初期,我們像林黛玉初進(jìn)大觀園一樣,“處處小心,時時注意”。從下圖可以看出,第202分庫的10張分表花費(fèi)了數(shù)天時間,通過嚴(yán)格控制清洗速度逐步完成。在完成近10個分庫的清洗后,我們逐漸通過庫間并行提速推進(jìn),最終用了近兩個月的時間完成了全部清洗工作。
縮表操作的嘗試與發(fā)現(xiàn)
在清洗前幾個分庫時,我們曾考慮通過縮表操作(alter table xxx engine=innodb)來量化治理成果。初次嘗試時,驚喜地發(fā)現(xiàn)單個分庫縮小了17GB,但后續(xù)嘗試其他分庫時效果卻不盡如人意,部分分庫甚至出現(xiàn)了表空間不降反增的情況。這一現(xiàn)象令人困惑,最終我們放棄了縮表操作。盡管如此,清洗過程中在庫文件中產(chǎn)生的“空洞”為新插入的數(shù)據(jù)提供了填充空間,從而在下圖中形成了明顯的拐點(diǎn)。上方分庫的變化曲線更為平滑,這是因?yàn)樵诔跗诘男⌒那笞C階段,清洗速度控制得較低。
?
令人欣慰的是,困擾數(shù)日的縮表后空間不降反增的詭異問題在一年后被快手的MySQL內(nèi)核研發(fā)組同事定位到了原因,且向mysql官方提交了bug并得到官方的確認(rèn)復(fù)現(xiàn)。大致原因和上面的DDL語句執(zhí)行過程中的增量數(shù)據(jù)優(yōu)先插入有關(guān),由于存量數(shù)據(jù)的主鍵id一般都小于縮表期間新增的增量數(shù)據(jù)主鍵id,后面的存量數(shù)據(jù)插入臨時影子表時可能會不斷地引發(fā)頁分裂并且挪移已插入的增量數(shù)據(jù)從而形成新的碎片。由于這部分浪費(fèi)的比例和每行的尺寸大小有一定的相關(guān)性,單行在3~5kB時該不增反降現(xiàn)象會比較明顯,photo的單行大小又恰好處于這個區(qū)間,所以就出現(xiàn)了數(shù)據(jù)清洗完后縮表時概率性的不降反增現(xiàn)象。關(guān)于該問題的詳見描述有興趣的讀者可以參考快手KSQL團(tuán)隊(duì)提交給mysql的Bug。
注:Bug鏈接:????https://bugs.mysql.com/bug.php?id=113733???
五、治理過程的一些思考
結(jié)合本次治理經(jīng)驗(yàn),我們將經(jīng)驗(yàn)泛化到一般情況,從道法器術(shù)四個角度談?wù)勎覀兊乃伎肌?/span>
?
1、業(yè)界對于龐大用戶的存量歷史數(shù)據(jù)有什么好的應(yīng)對辦法?(道)
首先,要從商業(yè)模式角度思考。如何區(qū)分高價(jià)值用戶數(shù)據(jù)和低價(jià)值數(shù)據(jù)是關(guān)鍵。高價(jià)值數(shù)據(jù)應(yīng)通過能夠維持其存儲成本的商業(yè)模式運(yùn)行,例如會員制、續(xù)費(fèi)制等,使存儲和傳輸成本不再完全由平臺單方承擔(dān)。這對于處于維護(hù)期的大型產(chǎn)品或?qū)Υ鎯Τ杀久舾械拇诡愋∑脚_尤為重要,有效的商業(yè)模式是維持業(yè)務(wù)正常運(yùn)轉(zhuǎn)的必要保障。快手目前所處的短視頻賽道仍處于較熱階段,加之公司也通過擁抱AI和探索新業(yè)態(tài)來努力做到不使用戶去分擔(dān)這部分成本 ,但不可否認(rèn)的是,技術(shù)成本正在逐年快速上升的事實(shí)。
其次,從技術(shù)架構(gòu)選型和迭代來看。互聯(lián)網(wǎng)行業(yè)“小步快跑”的特點(diǎn)決定了業(yè)務(wù)初期需要快速落地驗(yàn)證商業(yè)模式,留給工程師仔細(xì)思考和分析架構(gòu)特征的時間有限。當(dāng)業(yè)務(wù)成熟、系統(tǒng)穩(wěn)定后,架構(gòu)師需要抓住時機(jī)進(jìn)行重構(gòu)和架構(gòu)升級,以排除穩(wěn)定性風(fēng)險(xiǎn)并提升系統(tǒng)效率。在存儲領(lǐng)域,每隔5-10年往往會有新的中間件出現(xiàn),快手的工程團(tuán)隊(duì)一直在探索更穩(wěn)定高效的存儲架構(gòu),同時快手也成立了專門的架構(gòu)治理團(tuán)隊(duì),橫向推動多個領(lǐng)域的平臺迭代和演化。
另一個切入點(diǎn)是數(shù)據(jù)結(jié)構(gòu)和算法的優(yōu)化。本文的巧妙之處在于以極低的人力成本取得了堪比架構(gòu)迭代的收益。我們希望本文能對業(yè)務(wù)一線的工程師有所啟發(fā),他們通常是組織內(nèi)最貼近數(shù)據(jù)結(jié)構(gòu)和高頻算法的人。如果能夠孜孜不倦地鉆研業(yè)務(wù)和代碼,即使面對接手過來“祖?zhèn)鳌钡睦洗a和算法,稍作調(diào)整也可能挖掘出巨大的價(jià)值。雖然不是大規(guī)模的架構(gòu)升級,卻也是新質(zhì)生產(chǎn)力的有力注解。
2、高QPS高容量的緩存集群命中率提升有哪些手段?(法)
從時間維度來看,縮短冷數(shù)據(jù)在緩存中的駐留時間是一個可行的方向。常用的LRU/LFU等緩存淘汰算法天然具備對冷熱數(shù)據(jù)分層的能力,但如果緩存集群的單個節(jié)點(diǎn)特別大,冷數(shù)據(jù)從加載到淘汰的最小逐出時間可能會變得不可忽略。通過預(yù)先設(shè)定分級的過期時間,可以有效縮短這一最小逐出時間,但這需要對具體的數(shù)據(jù)使用場景和頻率進(jìn)行深入調(diào)研和分析。
從空間維度來看,減少冷數(shù)據(jù)在緩存中的占用空間是一個有效的方法。以Photo為例,某些冷數(shù)據(jù)召回場景僅需要用到Photo對象中的某幾個字節(jié)的屬性,但卻將整個幾KB的Photo對象加載到緩存中,并經(jīng)歷完整的最小逐出時間周期,這降低了緩存的空間利用效率。快手直播在類似場景下,獨(dú)立部署了一套“高頻不可變屬性字段最小集”的架構(gòu)設(shè)計(jì)方案,針對大量調(diào)用冷數(shù)據(jù)的主調(diào)方進(jìn)行定制優(yōu)化,有效降低了冷數(shù)據(jù)的緩存空間占用規(guī)模,從而提升了緩存命中率。這種方法雖然會使接入流程復(fù)雜化,但從長期來看,收益是值得的。本文正是從空間維度提升命中率的一次巧妙嘗試。
3、擴(kuò)展字段為什么用json存儲, 用protobuf是不是更有空間效率? (器)
Protobuf的編碼效率遠(yuǎn)高于JSON,但在并發(fā)修改時容易相互覆蓋,且MySQL對PB的支持不如JSON成熟。PB + MySQL的組合更適合結(jié)構(gòu)性開銷比例大且編輯頻率低的場景。因此,盡管PB在空間效率上具有優(yōu)勢,但在高并發(fā)和頻繁修改的場景下,JSON仍然是更穩(wěn)妥的選擇。
4、Photo 的擴(kuò)展字段這么大,可以在DB里壓縮存儲嗎?(術(shù))
實(shí)際上,Photo數(shù)據(jù)庫已經(jīng)在進(jìn)行壓縮存儲,但由于早期MySQL版本不支持列壓縮,壓縮字典只能局限在行內(nèi),壓縮效率無法充分發(fā)揮。快手MySQL團(tuán)隊(duì)在新引入的8.0版本中支持了列壓縮功能,在類似場景下已經(jīng)能夠?qū)崿F(xiàn)更高的壓縮效率。從架構(gòu)選型的角度來看,初期也可以直接考慮使用HBase等具有原生列壓縮能力的存儲層,以進(jìn)一步提升存儲效率。
?
六、總結(jié)
自移動互聯(lián)網(wǎng)和4G、5G網(wǎng)絡(luò)普及以來,已過去十多年,許多公司正面臨海量UGC歷史數(shù)據(jù)的挑戰(zhàn)。如何讓歷史數(shù)據(jù)變?yōu)橘Y產(chǎn)而非技術(shù)負(fù)債,將會成為是一道日益凸顯的考題。盡管技術(shù)的進(jìn)步會涌現(xiàn)出更高效的架構(gòu)和產(chǎn)品,但對于龐大體量的業(yè)務(wù)進(jìn)行架構(gòu)遷移和升級本身的成本和風(fēng)險(xiǎn)也不可小覷,這就給貼近業(yè)務(wù)的工程師在現(xiàn)有的架構(gòu)體系下發(fā)掘系統(tǒng)"低效率"的邏輯并加以優(yōu)化提供了價(jià)值空間,操之得當(dāng)便可有效延長現(xiàn)有系統(tǒng)的生命周期。
對于工程師來說,尋找系統(tǒng)中的“跑冒滴漏”可以像探礦一樣充滿樂趣。如果能被幸運(yùn)之神眷顧,探到一座"金礦",不但能為公司帶來可觀收益,工程師個人也能收獲滿滿的成就感。但在探礦和開采過程中也要牢記本文開頭引用圖靈獎得主Donald Knuth的名言 ——"過早的優(yōu)化是萬惡之源",優(yōu)化時機(jī)選取也很重要,對線上系統(tǒng)的每一步優(yōu)化操作都要抱有"戰(zhàn)戰(zhàn)兢兢,如臨深淵,如履薄冰"的心態(tài),要時刻保持對系統(tǒng)穩(wěn)定性的敬畏之心。
一個擁有龐大用戶量和訪問量的平臺能穩(wěn)定運(yùn)行多年,離不開優(yōu)秀的架構(gòu)設(shè)計(jì),快手的架構(gòu)設(shè)計(jì)便是如此。然而,如同飛機(jī)和汽車,再優(yōu)秀的系統(tǒng)在長期運(yùn)行后也會面臨“老化”和“熵增”問題——低效存儲、無用請求增多、緩存命中率下降、延遲上升等,都在消耗系統(tǒng)的生命力。本文描述的正是對抗熵增的過程,其巧妙之處在于通過細(xì)致的調(diào)研分析,以極低的人力投入,取得了顯著的收益。相比于跨部門大規(guī)模架構(gòu)迭代的"強(qiáng)渡大渡河"來說,本文故事稱得上是一次"巧渡金沙江"。
本文作者:王興邦
