本文翻译自How Twitter Handles 3,000 Images Per Second,作者是Todd Hoff,翻译已获得本人授权。
今天的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
写入路径
读取路径
新法 - 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)
|