1. 程式人生 > >Twitter 是如何做到每秒處理 3000 張圖片的?

Twitter 是如何做到每秒處理 3000 張圖片的?

如今,Twitter每秒可以建立並儲存3000張(20GB)的圖片。2015年,Twitter甚至從對媒體儲存策略的優化中節省出了600萬美元。

但並非一開始就是這樣的,2012年Twitter還主要是基於文字的,就像《哈利波特》中的霍格沃茨魔法學校沒有了那些懸掛在牆上的炫酷活動照片一樣。如今已經是2016年,Twitter已進入了富媒體未來時代。在新媒體平臺發展的過程中,Twitter可以支援照片預覽、多張照片、gif圖、Vine短片以及線上視訊。

Twitter的軟體開發工程師Henna Kermani在Mobile @Scale London的談話中提及,這個媒體平臺每秒能夠處理3000張圖片。雖然這次談話的主要話題是討論圖片管道,但她表示其中的大多細節也適用於其他的媒體型別。

這次談話所總結的心得中,一些最有趣的內容摘錄如下:

  • 按照可能奏效的最簡單方式來執行,結果真的會讓你大吃一驚: 傳送一條帶圖片的推特是一個要麼全有要麼全無的操作,最簡單的方式就是鎖定。由於無法很好地擴充套件,尤其是網路狀況不佳的情況下,Twitter很難再增加新功能。
  • 分離處理: 將發推與傳送媒體分離,通過解耦的方式來處理,Twitter便可分別優化各個途徑,同時還能大幅增進操作靈活性。
  • 移動handle(控制代碼),而不要移動blob(二進位制大物件): 不要在系統中執行大塊的資料移動,這樣會消耗掉頻寬,並導致接觸到資料的各個服務有效能上的問題。請儲存資料,並使用handle來引用。
  • 改用分段的、可恢復的上傳操作能夠大幅降低媒體上傳的失敗率。
  • 實驗與研究: Twitter在研究中發現:將各類圖片變體(縮圖、小圖、大圖等)的TTL(存活時間)設為20天可以讓儲存與計算達到最有效、最優秀的平衡。圖片在20天之後的訪問概率很低,刪除後每天能節省下來的儲存空間幾乎有4TB——達到計算伺服器需要數值的近乎一半,這樣做之後每年能節省數百萬美元。
  • 按需操作: 我們可以刪除舊圖片的變體,是因為它們能在瞬間完成重建,而無需預計算。根據需求來執行服務能夠增加靈活性,並在任務執行的方式上更為智慧,控制時也更集中化。
  • 漸進式JPEG(Progressive JPEG)是標準圖片格式的真正優勝者:不但前端和後端對其支援都很優秀,在速度較慢的網路中,這類圖片的效果也很好。
  • 在Twitter發展為富媒體未來的過程中,有許許多多好事發生,讓我們來一一解讀。

過去——2012年的Twitter

寫入方式

使用者在應用中編輯一條推文,或許再附上一張圖片。

客戶端將這條帶圖推文傳送給單一整體式端點。上傳時,推文中的圖片和其他元資料是捆綁在一起,傳送給過程中所涉及的單體服務的。

在舊式設計中,端點就是諸多問題產生的根源。

問題一: 浪費大量頻寬

建立一條推文與上傳媒體,兩者在一個操作中緊密耦合。

上傳的動作是一個整體,要麼全部成功,要麼全部失敗。無論失敗的原因是什麼——網路臨時中斷、暫時出錯等等,都需要將整個過程從頭來過,包括要重新上傳媒體。如果在上傳到95%的時候出現故障而導致失敗,就必須重新再次上傳。

問題二: 對較大的新型媒體來說,缺乏良好的擴充套件

這種辦法缺乏針對大型媒體,比如視訊的擴充套件性。媒體越大,失敗的可能性也越大,特別是在IT業的新興市場,比如巴西、印度、印尼等地,由於網速慢、網路可靠性差,這個問題更加嚴重,確實很需要增加上傳的成功率。

問題三: 內部頻寬的使用效率低下

終端與TFE(Twitter前端)相連,而TFE則負責使用者身份驗證,並將使用者分配到不同圖片伺服器(Image Service)。

圖片伺服器與圖片變體生成器(Variant Generator )會話,並生成不同大小的圖片例項(比如小圖、中圖、大圖、縮圖)。圖片變體儲存在BlobStore中,這是一個針對類似圖片和視訊等大型有效載荷而優化的key-value儲存系統,儲存在其中的圖片是永久性的。

建立及儲存推文的過程中,還涉及了許多其他服務。由於終端是單一整體式的,媒體與推文的元資料結合在一起,也會流經所有的服務。這個大型有效載荷被髮送給直接負責圖片的服務,這些服務並不屬於媒體管道,但仍被強制執行大型有效載荷的優化。這種辦法在內部頻寬中效率非常低。

問題四: 臃腫的儲存空間

推文中的圖片在數月或數年後已經不再會被呼叫了,但仍存於BloStore中佔用空間。有時甚至在推文被刪除後,圖片仍存在於BlobStore中,缺乏垃圾回收機制。

讀取方式

引入了名為MinaBird的CDN源伺服器(Origin Server )。

  • MinaBird可以與ImageBird、VideoBird對話,因此如果沒有的話,可以立即生成相應大小的圖片及視訊格式。
  • MinaBird在執行客戶端請求時,更為動態也更為流暢。比如因為版權問題而需要將某個內容遮蔽,使用MinaBird可以很容易地對特定某條媒體執行遮蔽及恢復的操作。
  • 能夠實時生成需求大小的圖片與視訊格式轉碼,Twitter在儲存上的智慧性也更高了。

按需生成要求的媒體變體意味著無需在BlobStore中儲存所有的變體。這是一個巨大的勝利。

原始媒體直到刪除前都儲存在BlobStore中,而變體只儲存20天。媒體平臺團隊做了很多關於最佳儲存時限的研究,所有請求的圖片中,大約50%只儲存15天,按收益率遞減結果,刪除較早的圖片。很舊的媒體很可能沒有人會發起相應的請求,在15天后會有很長的長尾期。

如果不設定TTL(存活時間)和過期時間,每天增加的媒體儲存量有6TB。懶辦法就是按需生成所有媒體變體,導致媒體儲存增長為1.5TB。20天TTL所使用的儲存空間比懶辦法多不了多少,因此不會佔用太大的儲存空間,但在計算上這是一個巨大的勝利。使用懶辦法來計算,讀取所有變體需要在每個資料中心設定150個ImageBird,而使用20天TTL的話,只需要75個ImageBird。因此20天TTL是令計算和儲存達到最有效、最平衡的時間點。

由於節省儲存空間和計算資源就是節省金錢,引入20天TTL之後,在2015年Twitter節省下了600萬美元。

客戶端優化(安卓)

這種圖片比相應的PNG或JPEG圖片要小25%。

這樣一來,特別是在新興市場,由於較小的圖片對網路壓力也較小,因而使用者參與度也更高。

由於不支援iOS系統,並且只支援安卓4.0以上的系統,缺少平臺的支援使得WebP格式花費巨大。

於是Twitter嘗試了另一個選項,漸進式JPEG格式。由於通過連續掃描的形式來渲染,首次掃描可能是塊狀的,但在連續掃描的過程中會逐漸自我完善。

這種格式的效能更佳。

後端很容易支援。

這種格式比傳統JPEG格式的編碼速度慢了60%,由於一次編碼,多次服務,因此這不算大問題。

漸進式JPEG圖片不支援透明圖片,因此保留了透明的PNG圖片,除此之外其它都使用了漸進式JPEG。

客戶端由Facebook的Fresco庫提供支援,Fresco的優點很多。在2G網路下,效果令人印象深刻。第一次掃描PJPEG圖片只用了10kb流量,因此載入時間不長,在本地管道還等待載入,什麼都沒顯示的時候,PJPEG已經顯示出了可識別的影象。

有正在進行的實現結果顯示,負載細節如下:減少了9%的P50載入時間,減少了27%的P95載入時間,減少了74%的失敗率,慢速連線的使用者確實能獲得極大改善。