手淘圖片庫新特性解析

雲移 淘系技術

手淘圖片庫新特性解析

隨著手淘拉新和用戶體量的增加,CDN圖片資源的訪問量也隨之增加。我們知道訪問量增加,會帶來帶寬的增加,服務器成本也隨之增加。同時新增的用戶,喜好各不相同,為了滿足不同用戶的喜好,商家會修改主圖樣式來吸引消費者。如何緩解用戶增長帶來的帶寬壓力和滿足商家和用戶的多樣化需求呢?針對這兩個問題,圖片庫和圖片空間同學對客戶端和服務端做了相應的改造來解決這些問題,主要的做法是H5HEIC化以及圖片庫磁盤緩存標準化。




HEIC的應用


▐ HEIC是什麼


HEIF是一種圖像容器格式,它所生成的圖像文件相對較小,且圖像質量也高於較早的JPEG標準。HEIF這種新的圖像格式基於高效視頻壓縮格式(也稱為HEVC或H.265),它通過使用更先進的壓縮算法來實現圖片的壓縮存儲。


  • 感興趣的同學可以看下https://nokiatech.github.io/heif/examples.html
  • H.265一般是用在視頻上的一種編碼標準,這個標準會有不同的實現。
  • 引用https://www.sysgeek.cn/heif/



手淘NativeHEIC化


從2018年開始手淘的native頁面已經全面支持HEIC,為CDN側節省了大量流
量,優化了用戶的圖片體驗。native頁面可以HEIC化需要滿足兩個條件:


  1. 業務的圖片是存放在手淘圖片空間,才能夠使用圖片空間的圖片處理能力。
  2. 業務需要使用圖片庫的適配庫來對原始url進行適配,然後再借助圖片庫的能力完成圖片的加載。


目前從統計來看淘內的圖片40%已經使用了HEIC,為什麼只有40%的量?一方面是因為手淘部分業務的圖片不是放在圖片空間做處理,比如有的業務使用TFS來做存儲,另一方面是手淘使用的H5內核目前無法解碼HEIC圖片。說到這裡需要簡單介紹下手淘的圖片的業務流程:


手淘圖片庫新特性解析


以上只是簡單的示意,大體展現圖片如何從商家流動到用戶的,主要的中轉便是圖片空間它可以對圖片進行處理和轉化。用戶使用手淘客戶端訪問頁面時,業務會將商品圖片url傳遞給圖片庫,圖片庫會對傳入的url做處理,按照圖片空間的規則拼接上HEIC後綴,這樣當url到達CDN時,如果有HEIC圖片緩存直接返回,如果沒有會請求圖片空間的服務將原始圖片轉碼成heic圖片。以上是native的流程,我們還忽略了另一個流量來源H5,目前手淘H5容器無法使用HEIC解碼器,所以沒有進行HEIC化。



H5頁面HEIC化


為什麼今年可以做H5頁面HEIC化了呢?主要是以下兩個方面:


  1. 內核提供了外接三方解碼器的能力
  2. 手淘支持遠程下載so


有同學可能會好奇,之前提到的圖片空間是什麼?圖片空間可以看作是提供強大圖片處理能力的服務。從上一小節的流程圖可以看出CDN後面是圖片空間,這裡簡單介紹下圖片空間和CDN之間的關係。當有圖片請求訪問到CDN時,CDN會查找當前緩存中有沒有這個請求需要的圖片,如果有直接從CDN中返回,如果沒有CDN會去請求圖片空間處理原圖給出符合要求的圖片,然後再返回給CDN,同時CDN會對這張圖片做緩存,當下次有相同的請求過來時就直接返回緩存的圖片,不再回源到圖片空間,縮短請求響應時間。


首先介紹下UC內核外接三方解碼器能力,這個能力是如何實現的呢?簡單來說就是提供實現UC規定接口的so文件(保證規定的函數符號會被正確導出),UC內核會使用dlopen打開so,同時獲取接口函數的函數指針,當需要解碼時直接使用函數指針直接調用即可。下面是大體的調用流程以及相關的接口定義:



簡短介紹下上圖藍框的流程:


手淘圖片庫新特性解析


  1. Init:初始化圖片解碼器,並將相應的數據結構透傳到UC
  2. Decode:UC會透傳相應的數據到解碼器,解碼器解碼完成後將相應的RGBA數據給到UC,UC最終將解碼後的數據給到渲染層
  3. Close:回收初始化過程中創建的系統資源


之前從事過PC開發的同學可能會熟悉這這種做法,PC插件化大多是利用dll(可以理解為Linux下的so)來實現,這在PC時代是常用做法,Python調用C++/C代碼也可以通過封裝為so進行調用。針對UC提供的這種能力,圖片庫對原有的HEIC解碼器做了封裝,實現了上面的接口規範,提供給UC調用,這樣H5解碼HEIC的問題就解決掉了。


真的這麼順利麼?答案是No。手淘目前對so集成時的大小有限制,剛好HEIC的32位和64位so加起來將近4.5MB,這已經是嚴重超標了,是不可以接受的。


那該如何解決呢?架構組提供了遠程加載so組件(上圖中的遠程下載),可以將so放在遠程,不需要打進apk包,當需要的時候從遠程下載,同時HEIC解碼so是獨立的沒有依賴,直接dlopen打開就可以使用。這樣我們的解碼功能就順利完成了,剩下的工作就需要Windvane同學添加相應的降級邏輯和監控邏輯提供必要的穩定性保障,到這裡這個H5支持HEIC功能就完成了。



說了這麼多從native支持HEIC到H5支持HEIC,收益是什麼呢?有兩個方面,一個是端上的收益,一個是服務端收益:


客戶端


目前端上的計算能力已不是瓶頸,主要是網絡的通信時間,圖片體積越小,網絡耗時越少,同時網絡耗時的減少可以抵消端上解碼耗時的增加,總體而言圖片的加載性能會提高。同理對於H5頁面也一樣,網絡耗時越少,頁面性能也會有所提高。


服務端


對於服務端而言,圖片的體積更小,佔用的帶寬也更小,單位時間內處理的請求增加,簡單來說就是提高了QPS。



H5支持HEIC這個功能已經灰度了幾個版本,後續會逐步全量,對於H5頁而而言,頁面性能也會得到提升。


我們可以先參考下native頁面下HEIC圖片和WEBP圖片的下載時間和解碼時間的對比數據:


Format

網絡時間(ms)

解碼時間(msHE)

HEIC

141

27.5

WEBP

645

30


手淘圖片庫新特性解析


數據說明:樣本數在幾十萬級別,基本可以抹平圖片尺寸帶來的統計差異。


從上面的數據也可以表明,網絡時間的優化可以抵消部分解碼時間的增加,有的同學看到數據會有疑問,解碼時間並沒有增加反而有所優化,這主要是多媒體算法團隊對HEIC解碼做了優化,同時圖片空間空間同學對HEIC的封裝做了優化(優化的後的封裝,仍然是符合HEIF文件標準的)。


圖片庫緩存標準化


▐ 圖片庫磁盤緩存標準化


用過Phenix圖片庫或者三方開源圖片庫的同學都知道,圖片庫會有三層緩存(內存、磁盤、網絡),磁盤緩存一般是持久化的,除非超過磁盤緩存大小被LRU淘汰掉,為了滿足圖片空間的需求,圖片庫對磁盤緩存做了改造。大體流程如下:



手淘圖片庫新特性解析


簡單來說圖片庫的磁盤緩存可以指定過期時間,過期後圖片請求會打到後端。圖片空間會在圖片響應頭裡添加過期字段來控制本次請求到的圖片在磁盤緩存中存在的時長。目前實現的緩存控制是在原先LRU基礎上實現的,即首先會判斷這張圖片有沒有被LRU淘汰掉,如果沒有被淘汰掉會走到緩存控制邏輯,如果已經被LRU淘汰,保持原有邏輯。



有同學可能會疑惑這麼做有什麼意義的呢?之前LRU策略圖片更新時間是不確定的,有可能很快就過期了也有可能要等幾十小時才能過期,完全取決於用戶訪問的頻次以及用戶的操作習慣,過期時間字段可以精確到小時級別,讓圖片及時過期,請求到最新的圖片。


▐ URL不變更新圖片


看到這個標題很多同學可能會有疑惑,URL不變更新圖片是什麼意思?簡單來說就是訪問相同的圖片url圖片的內容可能不同,經過這麼一解釋有的同學可能更加疑惑,為什麼要這麼做?


帶著這個疑問我們來解釋為什麼會有這樣的功能,促銷對手淘來說比較常見,商家也會抓住這個機會盡可能吸引消費者去下單,提高成交量。圖片作為手淘商品的主要信息載體,有活動的時候商家為了能夠傳遞更多的信息給消費者,商家會頻繁修改商品主圖的促銷樣式和信息來吸引消費者去點擊,更多的點擊意味這更高的流量,從而帶來更高的成交量。商家通過圖片空間修改商品主圖,圖片空間會將修改後的主圖URL更新到商品服務,但是這給商品服務帶來了挑戰,手淘承載著成千上萬商家,如果促銷期間大量商家去更新商品主圖URL,對商品服務帶來的壓力不可小覷(不止主圖更新會調用商品服務,其他業務也會去調用),因此在大促期間為了保證商品服務的穩定性,會進行必要的限流。大體流程如下圖:



手淘圖片庫新特性解析


這樣商家在特定的時間是不能及時修改商品圖的,這會導商家和消費者的體驗下降,因為主圖的促銷信息不能及時更新,導致主圖顯示的優惠信息和實際購買的優惠信息有可能會有偏差。這該如何解決呢?活動期間商家改圖後商品主圖URL不變,圖片空間會將修改的圖片更新到CDN,不再去頻繁刷商品服務,商品服務的壓力也會減小,消費者的體驗也得到了保障。修改後的流程如下圖:



手淘圖片庫新特性解析


有同學可能會有疑問,為什麼不是提升商品服務的性能呢?以下是我簡單的分析,不一定準確:數據庫的寫性能是有限的,無論再怎麼優化再怎麼加機器,大量的併發過來總會達到瓶頸。有的同學可能會說,分佈式、分庫、一致性哈希,或許可以做也可以解決問題,可是大促是短期行為,做這麼大的改造耗費大量的人力成本,但是對非大促,這樣的改造沒有收益,同時也會增加系統的複雜度。


通過這樣小成本的改造,將一部分流量轉移到CDN側,減輕了商品服務的壓力同時也能提升商家和消費者的體驗,商家也可以隨時更新商品主圖。


說了這麼多圖片庫做了什麼?一開始介紹的圖片庫磁盤緩存標準化,大促期間圖片空間會在下發圖片的Response中帶上過期時間字段,設置一個合理的過期時間,便於大促期間商品主圖的磁盤緩存隔一段時間過期一次,過期後請求新的圖片,這樣用戶看到的圖片始終是最新的,雖做不到實時但也可以達到小時級,能夠滿足業務的訴求。



總結


今年圖片庫的主要改動有兩個方面:H5支持HEIC化以及圖片庫磁盤緩存標準化,這兩個改造從本質上來說是將服務端的優化通過端上整合觸達到用戶。HEIC圖片native端在2018年就已經開始支持,但是由於H5容器UC內核當時沒有HEIC解碼能力,所以H5頁面沒有使用HEIC,今年隨著UC對外提供了三方解碼插件的功能,利用這個契機將H5頁面進行HEIC化。圖片庫磁盤緩存標準化。


分享到:


相關文章: