天天看點

Twitter如何做到每秒鐘處理3000張圖檔上傳

今天的twitter每秒鐘能夠建立并儲存3000張(200gb)圖檔。甚至早在2015年,twitter就通過改進媒體存儲政策節約了6百萬美元。

以前并不是這樣的。twitter在2012年主要以提供文字資訊為主,當時的使用者也很少釋出各種炫酷的動态圖檔。到現在2016年,twitter開始提供富媒體功能。這樣的轉變是通過twitter自行開發的全新媒體平台(media platform)實作的,這個平台可以支援照片預覽、多張照片發送、動态gif圖檔、vine視訊,以及内嵌視訊等功能。

twitter軟體開發工程師henna kermani在mobile @scale london活動中,通過一場名為每秒3000張圖檔的有趣演講介紹了twitter的媒體平台。演講主要側重于圖像處理方面,但她講的大部分細節也同樣适用于其他形式的媒體。

演講中一些比較有趣的重點包括:

因陋就簡的處理方法注定将會失敗。在原本不支援的情況下,不假思索通過簡單的手段支援上傳帶圖檔的推文,這樣的做法會造成某種形式的“套牢”。并且這種方式缺乏縮放能力,尤其是在網絡狀況不佳的時候,這使得twitter很難增加新的功能。 去耦合。通過将推文與所包含的媒體去耦合,twitter可以分别針對每個途徑進行優化,在營運方面獲得更大程度的靈活性。 移動句柄,而非存儲塊。不要在您的系統内部移動過大的資料塊。這種做法将消耗大量帶寬,會導緻所有需要通路這些資料的服務遭遇性能問題。更好的方法是單獨存儲資料,并通過句柄的方式進行引用。 使用分塊可續傳方式上傳可大幅降低媒體檔案的上傳失敗率。 持續的實驗和研究。twitter研究發現,對于圖檔的不同變體(例如縮略圖、小圖、大圖等),20天的存活時間(time to live, ttl)是最佳甜區,這個值可以在存儲和計算之間實作良好的平衡。圖檔内容釋出20天之後的通路機率會大幅降低,是以可以删除圖檔的各種變體,這樣的做法每天可以幫助twitter節約4tb資料存儲空間,并将需要的計算伺服器數量減少幾乎一半,同時每年可節約數百萬美元。 按需。老圖檔的不同變體可以放心删除,并在需要時重建,而無須預先建立好。這種按需執行服務的做法可改善靈活性,讓您更清楚任務的執行方式,并對其進行集中的控制。 漸顯式jpeg(progressive jpeg)作為一種标準圖檔格式無疑是真正的赢家。這種格式在前端和後端都有良好的支援,在速度不快的網絡中也能提供不錯的表現。

twitter開發富媒體功能的過程中還發生了一些很棒的故事,一起來學學他們是如何做到的...

舊途 - 2012年的twitter寫入路徑

使用者在某個應用中撰寫了一條推文,并可能在推文中附加了一張圖檔。

用戶端将該推文發送至一個單體端點(monolithic endpoint)。圖檔會作為附帶内容與推文的所有其他中繼資料一起上傳,并傳遞至這一過程涉及到的每個服務。 在原本的設計下,這個端點是造成很多問題的根源。

問題1:浪費大量網絡帶寬

推文的建立和媒體的上傳緊密耦合為一個操作。

相關廠商内容

                  滴滴出行ios用戶端架構演進之路!                                  微信用戶端如何應對弱網絡!                                  函數式程式設計中的swift與swift中的函數式程式設計!                                  你離成為一位合格的技術上司者還有多遠?                                  國際範 最前沿 不容錯過的容器技術盛會                

相關贊助商

  gmtc全球移動技術大會2016年6月24日-25日,北京,點選了解詳情!

上傳過程充滿不确定性,或者完全成功或者徹底失敗。失敗可能出于任何原因,例如網絡卡頓或傳輸錯誤等,如果失敗就隻能從頭開始重新執行整個上傳過程,包括上傳圖檔。例如,假設上傳操作在進行到95%後出錯,也需要将所有内容重新上傳一遍。

問題2:面對新出現更大體積的媒體無法很好地縮放

這種方式無法通過縮放支援視訊等更大體積的媒體檔案。體積的增大會導緻出錯機率增加,尤其是在諸如巴西、印度、印度尼西亞這樣網絡速度慢并且不可靠的新興市場,而twitter非常迫切地希望提高這些地區使用者上傳推文的成功率。

問題3:内部帶寬使用效率低下

端點需要連接配接至負責處理使用者身份驗證和路由的twitter前端(tfe),随後使用者會被路由至某個圖檔服務(image service)。

圖檔服務聯系變體生成器(variant generator),用不同尺寸(例如小、中、大、縮略圖)為圖檔生成不同執行個體。這些變體會存儲在blobstore中,這是一種專為圖檔和視訊等大型載荷進行過優化的鍵值(key-value)類型存儲。随後圖檔将永遠存儲在這裡。

在建立和儲存推文的過程中,還涉及到很多其他服務。因為端點是單體的,如果将媒體與推文中繼資料結合在一起,就需要在所有服務之間傳輸這種綁定在一起的資料。這樣的大型載荷甚至會傳遞到原本在設計上并不用于直接處理圖檔的服務,這些服務甚至并不是媒體傳遞管道的一部分,但依然需要針對大型載荷的處理進行優化。這樣的做法導緻内部帶寬使用效率嚴重降低。

問題4:存儲容量極度膨脹

數月甚至數年前釋出的推文中所包含的圖檔已無人問津,但依然需要永遠存儲在blobstore中,這些内容耗費了寶貴的存儲空間。因為沒有垃圾回收機制,有時甚至在推文被删除後,圖檔依然會儲存在blobstore中。讀取路徑

使用者看到一條包含圖檔的推文。圖檔來自哪裡?

用戶端從cdn請求圖檔的變體。cdn可能需要從原始位置或tfe處檢索該圖檔。這一過程最終導緻需要通直接查詢blobstore的方式,使用url請求某一特定尺寸的圖檔。

問題5:無法引入新的變體

這種設計不是非常靈活。如果需要添加新的變體,也就是說需要為圖檔建立一個新的尺寸,此時必須為blobstore中的每個圖檔建立一個新尺寸的版本。這種方式缺乏按需建立變體的便利機制。

缺乏靈活性意味着twitter很難為用戶端添加新的功能。

新法 - 2016年的twitter寫入路徑

将上傳的媒體與推文去耦合。

上傳操作至此成為“一等公民”,并建立了專門用于将原始圖檔存儲至blobstore的上傳端點。

這種方法為上傳操作的處理提供了極大的靈活性。

用戶端聯系tfe,tfe随後聯系圖檔服務,圖檔服務将圖檔儲存至blobstore并将相關資料添加至一個中繼資料存儲。僅此而已。這一過程不會涉及任何隐藏的服務,不需要處理媒體,也不需要四處傳遞圖檔。

随後圖檔服務會傳回一個代表該媒體的唯一辨別符,即mediaid。當用戶端需要建立推文,釋出私信,或更新自己的頭像照片時,将使用這個mediaid作為引用該媒體的句柄,而不需要提供媒體的原始檔案。

假設使用者想要使用剛上傳的圖檔釋出推文,過程将會是這樣:

用戶端聯系更新端點,在推文中包含mediaid,該請求将發送至twitter前端,随後tfe會将請求路由至對于所建立内容來說最為恰當的服務。對推文本身,最适宜的服務是tweetypie,私信和使用者資料資訊的處理也由不同服務進行,所有這些服務都能與圖檔服務通信,圖檔伺服器中包含處理面孔檢測、兒童色情内容檢測等功能所需的推文處理隊列,當這些任務執行完畢後,圖檔服務會與處理圖檔的imagebird或處理視訊的videobird服務通信。imagebird負責生成變體,videobird則對視訊進行一定的轉碼,最終處理生成的媒體内容将儲存至blobstore。

不再需要将媒體内容四處傳輸,借此可節約大量本被浪費的帶寬。

分塊可續傳的上傳。

進入地鐵站,10分鐘後出來,上傳過程可從上次中斷的地方恢複進行。對使用者來說該過程是完全無縫的。

用戶端使用上傳api發起上傳會話,後端會為使用者提供一個mediaid,這個mediaid将在整個上傳會話中充當辨別符。

圖檔被拆分為多個小塊,例如拆分成三塊。這些檔案塊可使用api附加到一起,每次調用的附加操作可提供必要的片段索引,所有附加操作都可作用于同一個mediaid。上傳完成後對上傳内容進行“定稿”,随後這個媒體就可以使用了。

這種方法更容易适應網絡故障。每個獨立小塊可以重試,如果網絡因為任何原因中斷,使用者可以暫停并在網絡恢複後從暫停的位置繼續上傳。

方法簡單,效益巨大。對于體積超過50kb的檔案,上文提到的三個國家中圖檔上傳失敗率降低幅度分别為:巴西,33%;印度,30%;印度尼西亞,19%。

讀取路徑

此處用到了一種名為minabird的cdn源伺服器。

minabird可與imagebird和videobird通信,這樣就算不存在,也可以即時生成不同尺寸圖檔和不同格式視訊的變體。

在處理用戶端請求方面,minabird更流暢也更動态。舉例來說,假設有内容由于dmca(數字千年版權法)的要求需要删除,此時很容易便可阻止對相關内容的通路,或重新允許對媒體特定片段的通路。

按需即時生成變體和轉碼的方式使得twitter在存儲容量的使用方面更為高效。

按需生成變體,意味着不需要将所有變體都存儲在blobstore中,這是一個巨大的進步。

原始圖檔在删除前将一直保留,而變體隻保留20天。媒體平台團隊針對最佳過期時限進行了大量研究,發現在所有請求的圖檔中,有大約50%的圖檔都是在最多15天(左右)的時間内上傳的。繼續保留更早前上傳的圖檔可以獲得的收益在逐漸下降。更老的媒體檔案也有可能就此無人問津。15天後存在一條很長的長尾。

不設定存活時間(ttl)并且不過期的情況下,媒體檔案的存儲導緻資料存儲總量每天增加6tb,按需生成所有變體的“偷懶”做法會讓資料存儲總量每天增加1.5tb。20天存活時間所用的存儲空間并不像“偷懶”做法那麼多,是以在存儲方面的成本并不高,但對計算的要求更高了。對于“偷懶”的做法,在讀取的同時生成所有變體,需要為每個資料中心提供150台imagebird伺服器,而20天存活時間的做法隻需要投入75台。是以20天存活時間是一個甜區,可以在存儲和計算方面實作平衡。

由于節約存儲和計算資源等同于省錢,通過采取20天存活時間的做法,twitter在2015年節約了6百萬美元。

用戶端的改進(android)

針對google建立的圖像格式webp執行了為期6個月的實驗。

相比png或jpeg圖檔,這種格式的圖檔體積平均減小25%。

使用者參與積極性有所提高,尤其是在減小圖檔體積可以幫助網絡減壓的新興市場。

ios 不支援該格式。

僅 android 4.0 以上系統可支援。

平台支援的缺乏使得webp的支援代價不菲。

twitter還嘗試過漸顯式jpeg。這種格式可以使用逐行掃描的方式進行渲染,首次掃描的圖檔可能顯得斑駁不勻,但可通過逐行掃描的方式逐漸進行完善。

性能更好。

後端易于支援。

相比傳統jpeg編碼速度慢60%。但由于編碼工作隻需要進行一次,随後所有使用者都可從中受益,是以這不算什麼大問題。

不支援透明,是以還需保留透明png,但漸顯式jpeg其他方面都很出色。

用戶端對該格式的支援是通過facebook的fresco庫實作的。fresco庫的價值很值得大書特書,就算在2g網絡中也能實作讓人印象深刻的效果。pjpeg的首次掃描隻産生10kb流量,是以很快就可以加載完成。當原生管道還在等待加載,無法顯示任何内容的時候,pjpeg已經可以提供可分辨的圖檔。

通過對推文詳細資訊視圖的加載進行持續的實驗發現,p50加載時間降低9%,p95加載時間降低27%,出錯率降低了74%。網絡速度緩慢的使用者無疑能從中獲得不菲的收益。

本文轉自d1net(轉載)

繼續閱讀