基于X-Engine引擎的PolarDB-X集群支撑了淘宝历史订单数据库业务,解决了使用HBase数据库遗留的问题,降低存储成本的同时,满足了用户随时查询订单的需求。
背景信息
阿里巴巴旗下的淘宝是中国著名的在线购物平台,活跃用户数量超过数亿人。
在如此体量巨大的平台上,每天的实物和虚拟商品交易达到亿级别。每次交易会涉及到会员信息验证、商品库信息查询、订单创建、库存扣减、优惠扣减、订单支付、物流信息更新和确认支付等,每个环节都涉及到数据库记录创建和状态更新,整个流程可能涉及到数百次数据库事务操作,整个数据库集群每天会执行数百亿次事务读写。数据库团队不仅要保证数据库系统性能稳定,还需要考虑每日递增海量数据带来的巨大存储成本压力。
交易订单是整个交易过程最为关键的信息,由于可能涉及到交易纠纷处理,需要随时提供用户查询,必须永久记录在数据库中。淘宝成立至今,与订单相关的数据库记录总量达到了万亿级别,所占用磁盘空间也早已超过PB级。
下文将为您详细介绍淘宝是如何做到既满足用户随时查询订单的低延时需求,又控制存储成本。
架构演进历史
淘宝从2003年成立至今,近17年时间,随着流量不断增加,交易订单数据库架构也经历过数次演进:
第一阶段
淘宝起步阶段由于流量较小,使用Oracle数据库存储所有订单信息,订单创建和历史订单查询都在同一数据库进行。
第二阶段
由于历史订单数据量越来越大,单一数据库已经不能同时满足性能和容量需求,于是对交易订单库进行拆分,分为在线库和历史库,将三个月之前的历史订单迁移进历史库,但是由于数据量巨大,不能满足查询需求,因此当时的用户只能查询三个月之内的历史订单信息。
第三阶段
为了解决存储成本和历史订单查询问题,淘宝将历史订单迁移到HBase数据库。
整体方案是使用主表结合索引表,查询订单详细信息通过主表完成,通过买家或者卖家ID查询订单,则需要借助索引表先得到订单号。这个方案遗留一个问题,订单不一定按照时间顺序迁移到历史订单库,很多类型订单并不迁移到历史订单库,所以会导致订单列表不是严格按照时间排序,用户可能会发现自己的近期订单出现在不正确的位置。
第四阶段
历史订单数据库采用基于X-Engine引擎的PolarDB-X集群,既降低了存储成本,也解决了乱序问题。
业务痛点
回顾淘宝交易订单数据库演进历史,自拆分出历史订单数据库,在后续十年时间里,业务团队和数据库团队一直在应对几个核心挑战:
存储成本
由于每日写入数据量巨大,必须保证存储成本极低。
查询功能
提供丰富查询功能,例如按时间排序、按订单类型查找等,因此底层数据库需要支持二级索引,且二级索引需要保证一致性和性能。
查询延时
保证较低查询延时,不影响用户体验。虽然90天前的历史订单查询量比90天内少很多,但仍然需要保证延时在一定范围内。
基于X-Engine引擎的历史订单数据库方案
交易订单系统在在线库和历史库分离的架构下迭代了十年时间,很多业务代码对这套分离架构做了兼容,考虑到对业务代码改造以及迁移的风险,我们在初期延续了分离架构,只是将原有HBase集群替换成PolarDB-X集群(X-Engine引擎)。详细方案如下:
在线库依然沿用之前MySQL集群(InnoDB引擎),但是只保存最近90天订单,数据量少,可以保证较高的缓存命中率,确保读写延时。
通过数据同步将在线库中超过90天的订单迁移到历史库中,并从在线库中删除。
历史库存储引擎切换为X-Engine,保存超过90天的所有交易订单数据,超过90天的订单读写,直接操作历史库。
使用新方案后,历史库存储成本相比使用HBase时没有上升;历史库和在线库互相兼容,可以创建完全一样的索引,解决了排序异常问题;历史库的冷热分离保证了读取延时。
总结
淘宝交易订单记录流水型的访问特征是最近写入的记录会被大量访问,随着时间推移,记录访问频次急剧衰减。X-Engine引擎的冷热分离机制能很好地处理这种流水型业务,单一X-Engine数据库集群完全可以解决此类需求。
对于新开业务或者有大量流水型记录存储需求的现有业务,如果业务层面还未做冷热分离,建议您直接使用X-Engine引擎,基于X-Engine引擎的分布式数据库PolarDB-X可以同时解决扩展问题和存储成本问题。
目前X-Engine引擎已经在阿里云上线, 需要的用户可以购买使用。详情请参见创建RDS MySQL实例。