推ter是如何做到每秒處理3000張圖片的?
如今,推ter 每秒可以創建并保存 3000 張(20GB)的圖片。2015 年,推ter 甚至從對媒體存儲策略的優化中節省出了 600 萬美元。
但并非一開始就是這樣的,2012 年 推ter 還主要是基于文本的,就像《哈利波特》中的霍格沃茨魔法學校沒有了那些懸掛在墻上的炫酷活動照片一樣。如今已經是 2016 年,推ter 已進入了富媒體未來時代。在新媒體平臺發展的過程中,推ter 可以支持照片預覽、多張照片、gif 圖、Vine 短片以及在線視頻。
推ter 的軟件開發工程師 Henna Kermani 在 Mobile @Scale London 的談話中提及,這個媒體平臺每秒能夠處理 3000 張圖片。雖然這次談話的主要話題是討論圖片管道,但她表示其中的大多細節也適用于其他的媒體類型。
這次談話所總結的心得中,一些最有趣的內容摘錄如下:
- 按照可能奏效的最簡單方式來執行,結果真的會讓你大吃一驚: 發送一條帶圖片的推特是一個要么全有要么全無的操作,最簡單的方式就是鎖定。由于無法很好地擴展,尤其是網絡狀況不佳的情況下,推ter 很難再增加新功能。
- 分離處理: 將發推與發送媒體分離,通過解耦的方式來處理,推ter 便可分別優化各個途徑,同時還能大幅增進操作靈活性。
- 移動 handle(句柄),而不要移動 blob(二進制大對象): 不要在系統中執行大塊的數據移動,這樣會消耗掉帶寬,并導致接觸到數據的各個服務有性能上的問題。請存儲數據,并使用 handle 來引用。
- 改用分段的、可恢復的上傳操作能夠大幅降低媒體上傳的失敗率。
- 實驗與研究: 推ter 在研究中發現:將各類圖片變體(縮略圖、小圖、大圖等)的 TTL(存活時間)設為 20 天可以讓存儲與計算達到最有效、最優秀的平衡。圖片在 20 天之后的訪問概率很低,刪除后每天能節省下來的存儲空間幾乎有 4TB——達到計算服務器需要數值的近乎一半,這樣做之后每年能節省數百萬美元。
- 按需操作: 我們可以刪除舊圖片的變體,是因為它們能在瞬間完成重建,而無需預計算。根據需求來執行服務能夠增加靈活性,并在任務執行的方式上更為智能,控制時也更集中化。
- 漸進式 JPEG(Progressive JPEG)是標準圖片格式的真正優勝者:不但前端和后端對其支持都很優秀,在速度較慢的網絡中,這類圖片的效果也很好。
- 在 推ter 發展為富媒體未來的過程中,有許許多多好事發生,讓我們來一一解讀。
過去——2012 年的 推ter
寫入方式
用戶在應用中編輯一條推文,或許再附上一張圖片。
客戶端將這條帶圖推文發送給單一整體式端點。上傳時,推文中的圖片和其他元數據是捆綁在一起,發送給過程中所涉及的單體服務的。
在舊式設計中,端點就是諸多問題產生的根源。
問題一: 浪費大量帶寬
創建一條推文與上傳媒體,兩者在一個操作中緊密耦合。
上傳的動作是一個整體,要么全部成功,要么全部失敗。無論失敗的原因是什么——網絡臨時中斷、暫時出錯等等,都需要將整個過程從頭來過,包括要重新上傳媒體。如果在上傳到 95% 的時候出現故障而導致失敗,就必須重新再次上傳。
問題二: 對較大的新型媒體來說,缺乏良好的擴展
這種辦法缺乏針對大型媒體,比如視頻的擴展性。媒體越大,失敗的可能性也越大,特別是在 IT 業的新興市場,比如巴西、印度、印尼等地,由于網速慢、網絡可靠性差,這個問題更加嚴重,確實很需要增加上傳的成功率。
問題三: 內部帶寬的使用效率低下
終端與 TFE(推ter 前端)相連,而 TFE 則負責用戶身份驗證,并將用戶分配到不同圖片服務器(Image Service)。
圖片服務器與圖片變體生成器(Variant Generator )會話,并生成不同大小的圖片實例(比如小圖、中圖、大圖、縮略圖)。圖片變體存儲在 BlobStore 中,這是一個針對類似圖片和視頻等大型有效載荷而優化的 key-value 存儲系統,存儲在其中的圖片是永久性的。
創建及保存推文的過程中,還涉及了許多其他服務。由于終端是單一整體式的,媒體與推文的元數據結合在一起,也會流經所有的服務。這個大型有效載荷被發送給直接負責圖片的服務,這些服務并不屬于媒體管道,但仍被強制執行大型有效載荷的優化。這種辦法在內部帶寬中效率非常低。
問題四: 臃腫的存儲空間
推文中的圖片在數月或數年后已經不再會被調用了,但仍存于 BloStore 中占用空間。有時甚至在推文被刪除后,圖片仍存在于 BlobStore 中,缺乏垃圾回收機制。
讀取方式
引入了名為 MinaBird 的 CDN 源服務器(Origin Server )。
- MinaBird 可以與 ImageBird、VideoBird 對話,因此如果沒有的話,可以立即生成相應大小的圖片及視頻格式。
- MinaBird 在執行客戶端請求時,更為動態也更為流暢。比如因為版權問題而需要將某個內容屏蔽,使用 MinaBird 可以很容易地對特定某條媒體執行屏蔽及恢復的操作。
- 能夠實時生成需求大小的圖片與視頻格式轉碼,推ter 在存儲上的智能性也更高了。
按需生成要求的媒體變體意味著無需在 BlobStore 中存儲所有的變體。這是一個巨大的勝利。
原始媒體直到刪除前都存儲在 BlobStore 中,而變體只保存 20 天。媒體平臺團隊做了很多關于最佳保存時限的研究,所有請求的圖片中,大約 50% 只保存 15 天,按收益率遞減結果,刪除較早的圖片。很舊的媒體很可能沒有人會發起相應的請求,在 15 天后會有很長的長尾期。
如果不設定 TTL(存活時間)和過期時間,每天增加的媒體存儲量有 6TB。懶辦法就是按需生成所有媒體變體,導致媒體存儲增長為 1.5TB。20 天 TTL 所使用的存儲空間比懶辦法多不了多少,因此不會占用太大的存儲空間,但在計算上這是一個巨大的勝利。使用懶辦法來計算,讀取所有變體需要在每個數據中心設置 150 個 ImageBird,而使用 20 天 TTL 的話,只需要 75 個 ImageBird。因此 20 天 TTL 是令計算和存儲達到最有效、最平衡的時間點。
由于節省存儲空間和計算資源就是節省金錢,引入 20 天 TTL 之后,在 2015 年 推ter 節省下了 600 萬美元。
客戶端優化(安卓)
在使用 WebP(谷歌創建的一種圖片格式)進行了 6 個月的實驗之后,
這種圖片比相應的 PNG 或 JPEG 圖片要小 25%。
這樣一來,特別是在新興市場,由于較小的圖片對網絡壓力也較小,因而用戶參與度也更高。
由于不支持 iOS 系統,并且只支持安卓 4.0 以上的系統,缺少平臺的支持使得 WebP 格式花費巨大。
于是 推ter 嘗試了另一個選項,漸進式 JPEG 格式。由于通過連續掃描的形式來渲染,首次掃描可能是塊狀的,但在連續掃描的過程中會逐漸自我完善。
這種格式的性能更佳。
后端很容易支持。
這種格式比傳統 JPEG 格式的編碼速度慢了 60%,由于一次編碼,多次服務,因此這不算大問題。
漸進式 JPEG 圖片不支持透明圖片,因此保留了透明的 PNG 圖片,除此之外其它都使用了漸進式 JPEG。
客戶端由 非死book 的 Fresco 庫提供支持,Fresco 的優點很多。在 2G 網絡下,效果令人印象深刻。第一次掃描 PJPEG 圖片只用了 10kb 流量,因此加載時間不長,在本地管道還等待加載,什么都沒顯示的時候,PJPEG 已經顯示出了可識別的圖像。
有正在進行的實現結果顯示,負載細節如下:減少了9% 的 P50 加載時間,減少了 27% 的 P95 加載時間,減少了 74% 的失敗率,慢速連接的用戶確實能獲得極大改善。
來自:iteye