图片空间是淘宝智能图片中心面向商家提供的免费图片存储管理服务,由于淘宝、天猫主站上累积的用户图片数据量非常大(想想淘宝/天猫的商家和消费者每天要上传多少图片!),并且增长量惊人,图片空间业务面临着非常巨大的存储空间和写入性能压力。尤其每年双11之前,商家大量更新商品库存保有单位SKU(Stock keeping Unit),此时数据会急剧增长。
淘宝/天猫每日新增大量商品、评论图片某年双十一前夕,当时阿里大部分数据库系统还使用的是InnoDB存储引擎,图片空间的研发同学梳理双十一线上风险时,咨询到DB磁盘及水位的容量是否足够,我们曾信誓旦旦地说:“没有问题,四个月前我们刚扩了一倍机器”。可是没过多久就被现实打脸了:不到5个月的时间,业务数据累积了过去6-7年的量,每日增量急剧上升,扩容的磁盘很快也将不够了。
最简单粗暴的方法当然是扩容,这样做风险最小,但却只能解决眼前的问题。以现在数据的膨胀速度,未来难免多次扩容。仅仅因为空间不足的问题,导致成本翻好几倍,这是难以接受的。另外一个方法是换引擎,当时阿里主打高性能低成本的自研存储引擎X-Engine刚刚成熟(TODO:X-ENGINE架构超链接),相较于基于B+-Tree的存储引擎(例如InnoDB)数据页存在较多空间浪费,基于LSM-Tree的X-Engine数据完全紧凑排列,空间利用率更高。而紧凑排列的数据施以前缀压缩技术,空间使用进一步减少。
X-Engine的Data Block无需原地更新,可以方便使用通用压缩算法(zlib,zstd,snapy等)压缩。所有位于LSM-tree低层次的数据都会默认压缩。经过大量对比测试,X-Engine默认选用了ZSTD压缩算法,但同时也保留了对其他算法的支持。此外后台compaction会持续删除无效记录(LSM-Tree更新和删除都是写入新记录,旧版本记录不再被需要时,视为无效),持续释放冗余的空间。因为上述技术特点,X-Engine对存储空间的节省几乎到达了“变态”的程度,以至于当图片空间库的数据全部从InnoDB转移到X-Engine后,空间节省了7倍,如下图所示
为什么数据从InnoDB迁移至X-Engine后,取得了如此巨大的成本收益?
此外,由于图片空间是一个高频使用的应用,如果X-Engine的性能不满足要求,也无法落地。得益于LSM轻量化写机制,X-Engine写入操作本就是优势,何况还引入了group commit和事务处理流水线机制,大大增加了写入处理的并发度。读请求本是LSM的弱项,分层的结构和追加写产生的多版本数据,会增加读请求查询路径的长度,X-Engine为此做了大量的优化,诸如:多粒度Cache(memtable,Block Cache和Row Cache)、bloomfilter和range scan filter(Surf, SIGMOD'18)有效减少点查询和范围扫描的次数、异步I/O预取等,尽力把它打造成读写性能均衡,成本优势突出的存储引擎。关于X-Engine读写优化,可以参考这篇文章(TODO:超链接)。
经过DBA和业务开发同学的验证,X-Engine的读写性能及延时完全满足业务需求。很快,淘宝图片空间库全部切换为X-Engine引擎,节省了大量的存储成本。
X-Engine分层存储的架构,特别适合具有如下业务负载特征的业务: