中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

攜程圖片服務(wù)架構(gòu)

2018-07-20    來源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用

作者簡(jiǎn)介

胡健,攜程框架高級(jí)研發(fā)經(jīng)理,目前負(fù)責(zé)多媒體服務(wù)的構(gòu)建和研發(fā)工作。

近些年攜程業(yè)務(wù)突飛猛進(jìn),用戶遍及世界各地。公司對(duì)用戶體驗(yàn)也越來越重視,每一個(gè)小的功能改動(dòng)、頁面改版的背后,都有大量的A/B實(shí)驗(yàn)提供保障。與此同時(shí),與用戶體驗(yàn)息息相關(guān)的媒體文件的應(yīng)用質(zhì)量也被放到重要位置,如圖片加載延時(shí)、成功率、清晰度等數(shù)據(jù)。

本文將分享攜程圖片服務(wù)架構(gòu),包括 服務(wù)架構(gòu)的演變過程,以及在生產(chǎn)上實(shí)際遇到的一些問題,避免大家重復(fù)踩坑。  

一、服務(wù)架構(gòu)

1、初始階段

攜程圖片的服務(wù)架構(gòu)主要經(jīng)歷了三次比較大的調(diào)整。早些年為了滿足業(yè)務(wù)快速上線的需求,我們做了簡(jiǎn)單實(shí)現(xiàn),架構(gòu)如下:

這個(gè)架構(gòu)開發(fā)工作量不大,因?yàn)楫?dāng)時(shí)業(yè)務(wù)對(duì)圖片尺寸的需求單一,也沒有復(fù)雜的圖片組合處理需求,因此有大量圖片都被Squid緩存住,緩存命中率很高,取圖速度非?臁

圖片裁剪命令的執(zhí)行,則由業(yè)務(wù)發(fā)布的時(shí)候上傳處理。存儲(chǔ)通過NFS讓整個(gè)Nginx服務(wù)集群共享。直到移動(dòng)端流量開始爆發(fā)的時(shí)候,這個(gè)架構(gòu)有點(diǎn)力不從心。    

首先,同一張?jiān)瓐D需要裁剪出大量不同尺寸的小圖片,占用了大量存儲(chǔ)資源。其次,業(yè)務(wù)圖片越來越多加上大量不同尺寸的小圖片的出現(xiàn),導(dǎo)致Squid緩存命中率變差,大量流量穿透到NFS上,I/O迅速變?yōu)槠款i。

從監(jiān)控看,當(dāng)時(shí)的NFS Read I/O一直處于高水位水平,告警更是24小時(shí)不斷,回源流量的上升也導(dǎo)致Squid服務(wù)集群開始變得不穩(wěn)定,經(jīng)常需要重啟。鑒于這些問題,我們做了下面架構(gòu)上的調(diào)整。

2、發(fā)展階段

用Varnish替換了Squid,作為緩存和反向代理服務(wù)。

從實(shí)際監(jiān)控情況看,同等壓力下Varnish的表現(xiàn)比Squid更穩(wěn)定,Varnish虛擬內(nèi)存swap機(jī)制比Squid自己管理的更好,因此性能上更優(yōu),并且Varnish配置方便,對(duì)運(yùn)維友好。

當(dāng)然Squid也有更適合的使用場(chǎng)景,選擇Varnish是因?yàn)樵诋?dāng)前場(chǎng)景下更符合我們的需求。

為了解決Varnish節(jié)點(diǎn)宕機(jī)會(huì)引發(fā)大量緩存數(shù)據(jù)失效,LB上對(duì)URL做了一致性Hash,這樣能盡量減少緩存失效帶來的其他節(jié)點(diǎn)數(shù)據(jù)的遷移,同時(shí)也解決了Varnish利用率的問題。

Nginx內(nèi)嵌Lua腳本用于在圖片訪問的時(shí)候直接對(duì)圖片進(jìn)行處理,而不是上傳的時(shí)候處理,這樣很多不同尺寸的小圖不用在存儲(chǔ)上保留,存儲(chǔ)上少了大量I/O,并且減少存儲(chǔ)量的同時(shí)也會(huì)減輕運(yùn)維的壓力。

從訪問效率看,因?yàn)閳D片需要實(shí)時(shí)處理,服務(wù)響應(yīng)延時(shí)相比上一個(gè)版本有大幅上升,平均延時(shí)大概在300毫秒左右。但是這個(gè)影響實(shí)際對(duì)端的影響有限。

首先,國(guó)內(nèi)CDN普遍質(zhì)量較好,95%以上的圖片資源訪問都會(huì)被CDN擋掉,正常情況下回源流量不會(huì)太大。其次,我們Varnish集群命中率大概在40~50%之間,所以整體圖片實(shí)時(shí)處理壓力占整體流量約1%~2%之間,這些流量訪問延時(shí)會(huì)上升300毫秒左右是完全能夠接受的。

存儲(chǔ)用FastDFS替換了NFS,當(dāng)時(shí)Ceph還不像現(xiàn)在那么穩(wěn)定,F(xiàn)astDFS的特性又能夠滿足我們需求,并且架構(gòu)簡(jiǎn)單,源碼能完全掌控。事實(shí)證明,F(xiàn)astDFS集群完全支撐了每天數(shù)億次的原圖讀寫操作,并多次在多機(jī)房DR演練中完成各項(xiàng)指標(biāo)。

當(dāng)時(shí)這個(gè)架構(gòu)的核心是Lua的圖片處理模塊,Coroutine的性能非常好,當(dāng)有大量圖片回源請(qǐng)求的時(shí)候,CPU不會(huì)浪費(fèi)在線程的context switch上,開發(fā)也很直白,在I/O操作的時(shí)候不需要用異步方式編碼,并且Lua的執(zhí)行在Nginx里足夠高效。

這里唯一的缺點(diǎn)是Lua擴(kuò)展性相對(duì)較弱,很多模塊需要自己寫,比如對(duì)接我們自己的監(jiān)控系統(tǒng)的時(shí)候就遇到難題。 

隨著業(yè)務(wù)的發(fā)展,用戶對(duì)圖片的處理要求越來越高,多重濾鏡的應(yīng)用,需要在Lua里實(shí)現(xiàn)很多功能,并且很多基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)都要自己寫或者依賴第三方,不僅開發(fā)工作量大,穩(wěn)定性和正確性的驗(yàn)證也需要花費(fèi)不少的精力。

是不是還有一種技術(shù)方案可替代,既能享受協(xié)程帶來的簡(jiǎn)單,高效。又能兼顧擴(kuò)展性和完善的功能包,不用重復(fù)造輪子。

3、現(xiàn)階段

我們選擇了Golang做為當(dāng)前版本的開發(fā)語言,架構(gòu)如下:

采用多進(jìn)程單協(xié)程圖片處理模型。圖片庫主要依賴的是GraphicsMagick,和少部分ImageMagick,通過封裝cgo調(diào)用實(shí)現(xiàn)。

Golang調(diào)用cgo會(huì)申明一個(gè)進(jìn)入syscall的指令,意味著調(diào)度器會(huì)創(chuàng)建一個(gè)M去執(zhí)行g(shù)oroutine。因此當(dāng)有大量并發(fā)調(diào)用,并且圖片處理足夠慢,比如一張像素特別大的原圖,就會(huì)引發(fā)大量線程同時(shí)存在,造成不必要context switch,CPU load看上去很高,實(shí)際效率很低。

因此我們通常會(huì)通過Master進(jìn)程fork出和CPU相等數(shù)量的Worker進(jìn)程做圖片處理,每個(gè)進(jìn)程只有一個(gè)協(xié)程來處理圖片,每個(gè)進(jìn)程會(huì)創(chuàng)建一個(gè)可配置的buffer用于保存原圖的blob, 這樣能最大化利用單協(xié)程的利用率。

采用這種架構(gòu)當(dāng)時(shí)主要還為了規(guī)避GM本身的一個(gè)問題,參考我們向作者提交的issue:

https://sourceforge.net/p/graphicsmagick/mailman/graphicsmagick-help/?viewmonth=201708 .

問題描述是setjmp函數(shù)和longjmp函數(shù)在某些操作系統(tǒng)非線程安全,作者需要一個(gè)全局鎖來保證線程安全。因此多線程調(diào)用本身是低效的。

這個(gè)問題在java或者.net封裝的GM也會(huì)存在。上一個(gè)版本的Lua不存在這個(gè)問題,因?yàn)镹ginx本身會(huì)fork多個(gè)Worker進(jìn)程進(jìn)行圖片處理,并且只可能存在一個(gè)正在運(yùn)行的協(xié)程。事實(shí)上Linux執(zhí)行這兩個(gè)函數(shù)本身是線程安全的,作者可以通過build的時(shí)候來決定是不是需要加上線程安全的flag。在發(fā)表本文的時(shí)候,作者已經(jīng)在最新的release中修復(fù)了這個(gè)bug。

這里的Nginx不僅僅用來做LB,因?yàn)镹ginx能提供很豐富的腳本,可以省去很多開發(fā)工作量,并且當(dāng)有獲取原圖的需求,可以通過Nginx sendfile直接從存儲(chǔ)取回,節(jié)省不必要的系統(tǒng)開銷。

LB算法并不是簡(jiǎn)單的RR,我們會(huì)根據(jù)每個(gè)進(jìn)程的CPU消耗,以及原圖像素,buffer消耗等維度動(dòng)態(tài)算出各進(jìn)程的負(fù)載量,如果Nginx RR到一個(gè)負(fù)載非常大的進(jìn)程,可以通過返回重定向狀態(tài)碼讓Nginx重新跳轉(zhuǎn),這里可能會(huì)出現(xiàn)幾次網(wǎng)絡(luò)跳轉(zhuǎn),但是因?yàn)槭荓oopback,網(wǎng)絡(luò)上的消耗相對(duì)圖片處理的消耗可以忽略不計(jì)。

Master進(jìn)程用來管理Worker進(jìn)程,當(dāng)有Worker意外Crash,則會(huì)重新拉起一個(gè)Worker進(jìn)程,始終保持和CPU數(shù)量一致。 Master進(jìn)程的健康安全會(huì)定期Report給監(jiān)控系統(tǒng)做告警。  

二、 小結(jié)

當(dāng)前的圖片服務(wù)架構(gòu),支撐了攜程每天上億次原圖處理,平均圖片處理延時(shí)控制在200毫秒以內(nèi),圖片處理失敗率小于萬分之一,從發(fā)布至今節(jié)點(diǎn)沒有出現(xiàn)宕機(jī)現(xiàn)象,偶爾Worker進(jìn)程有性能問題和Crash也通過日志和分析工具逐一解決。 

如上所述,攜程圖片服務(wù)架構(gòu)經(jīng)歷了三次改版,從一開始沒有設(shè)計(jì)復(fù)雜的架構(gòu),只是為了解決碰到實(shí)際問題而重構(gòu),到后來根據(jù)遇到的問題,不斷調(diào)整,也說明了沒有完美的架構(gòu),只有適合的架構(gòu)。

當(dāng)然,要提供穩(wěn)定圖片服務(wù),架構(gòu)是一方面,也必須有其他技術(shù)上的支持,比如圖片本身質(zhì)量和尺寸的優(yōu)化,盜鏈和版權(quán)問題,端到端的實(shí)時(shí)監(jiān)控和預(yù)警機(jī)制,不良內(nèi)容識(shí)別,產(chǎn)品圖片管理和編輯功能,以及海外用戶圖片訪問加速問題。這些問題每個(gè)都能寫下不少篇幅的文章,有時(shí)間再和小伙伴分享。 

目前,攜程圖片服務(wù)已在github上開源了小部分功能,開源地址: https://github.com/ctripcorp/nephele

 

來自:http://mp.weixin.qq.com/s/MSR18sqUznuiUgUM5YkvZg

 

標(biāo)簽: linux swap 安全 機(jī)房 腳本 媒體 網(wǎng)絡(luò)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:Java 堆內(nèi)存溢出梗概分析

下一篇:用Python構(gòu)建你自己的RSS提示系統(tǒng)