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

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

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

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

作者簡介

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

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

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

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

1、初始階段

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

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

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

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

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

2、發(fā)展階段

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

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

當(dāng)然Squid也有更適合的使用場景,選擇Varnish是因為在當(dāng)前場景下更符合我們的需求。

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

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

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

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

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

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

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

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

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

3、現(xiàn)階段

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

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

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

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

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

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

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

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

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

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

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

二、 小結(jié)

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

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

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

目前,攜程圖片服務(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),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

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

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