作者简介:吴其朋,滴滴分布式存储运维负责人
滴滴出行作为涵盖网约车、出租车、顺风车、代驾等业务的一站式多元化出行平台,拥有全球客户6.5亿。在平台出行种类十余种且服务如此体量的用户时,滴滴出行的底层数据库主要采用MySQL,且拥有上万套集群。其中单实例超2TB的集群为400+套,最大的集群规模为几十分片,数据总量已超百TB。还有数十套非Innodb引擎的MySQL服务如RocksDB、TokuDB等。
然而,底层数据库矩阵随着业务的高速增长逐渐在性能、效率,成本,一致性这四个方面显露瓶颈。
首先,某业务在访问MySQL百亿大表时,延迟高达上百毫秒,造成业务SQL超时,影响业务流程。同时,因为该表有事务依赖,所以无法通过拆表的方式提升其访问性能。
其次,由于审计和业务需求,核心归档服务中需要保留大量历史数据,导致服务存储量高达几十T甚至上百T,每次业务有新增表字段等DDL需求时,DDL过程都会持续数天或数周。严重影响业务上线时间,降低产品迭代效率。
再次,某些业务既需要TP能力,又需要AP能力。因此由MySQL提供TP能力,然后通过链路把数据同步到大数据平台,业务同学再进行AP访问。这不仅使运维成本增加,还带来了业务同学的学习和改造成本。因此,我们希望TP场景和AP类场景可以在内部闭环,降低成本,加速业务迭代效率。
最后,滴滴出行的金融服务对数据一致性有强依赖,无法接受MySQL主从上百毫秒级延迟,导致所有的金融服务只能依靠强制读写主库的方式。当业务流量上涨时,我们只能通过不断地拆分主库提升性能,这不仅浪费从库资源,还会造成业务成本翻倍增长。
面对上述MySQL痛点和业务挑战,我们把选型和调研工作投入到分布式数据库领域,没想到也是一波三折。
引入分布式数据库某DB无法满足业务需求
根据业务需求,我们确定引入分布式数据库必须满足三个条件。
一是能够解决当前性能差、效率低、成本高,以及数据一致性方面的问题。根据上文所述,我们希望数据库有秒级的在线DDL功能、更便捷的横向扩缩容能力、天然的强一致性、更低的学习与运维成本,同时,能够对下游链路提供支持。
二是要足够稳定,稳定性即我们对业务同学承诺的SLA标准,包含可恢复性、Lantency、限流模型、容量模型。这也是我们选型时的基础要求。
三是要符合滴滴出行的未来业务规划,其中最重要的是双活需求。
在2021年初,我们调研了几款发展较为成熟的分布式数据库,并在2021年中引入当时的选型结果——某DB,开始搭建测试集群,学习分布式数据库的基础知识。
后续,从测试到正式上线历经四个阶段。
第一阶段:2022年初,对某DB进行Sysbench压力测试、兼容性测试,以及验证高可用场景、周边工具可用性、DDL和扩缩容能力。
第二阶段:2022年8月,我们搭建了非核心归档库,用于积累线上运维经验,让组内同学都能在真实环境中进行实战演练,同时锻炼大家解决问题的能力。
第三阶段:2022年9月,我们在某DB接入公司级监控,编写运维手册,期望当我们遇到故障时可以根据预案SOP轻松解决线上问题,并经过长期实践能更好地接入自动化平台。
第四阶段,2023年初,我们在某DB接入线上归档库和在线集群。
在某DB上线后,解决了部分MySQL的使用问题。比如,除索引以外的其它DDL操作基本都秒级完成;再比如横向一键扩容的功能非常实用。但是,我们在日常运维以及和业务同学平时的沟通中,发现了一些线上问题。
第一个问题是在进行日常集群扩容、索引添加的整个过程中,业务延迟基本会上涨近40%。
第二个问题在于日常的抖动,在业务流量、业务模型不变的前提下,某DB会出现间接性的延迟抖动,抖动范围在40%-100%不等。 因为业务对延迟数据库的响应延迟非常敏感,当出现延迟变长的情况时,整体响应超过业务阈值,造成大量SQL执行失败,对客户产生极大影响。
第三个问题来自于业务的下游同步需求,比如是否可以依赖当前的Canal链路,把数据同步到MQ、Kafka以供其他业务方使用,用最小的代价达到业务需求。
针对这三个问题,我们做了一些优化和调整,比如参数优化、调小并发度、增加存储节点数量等,可仍不能达到业务侧对延迟的要求。因此,我们开始再次调研是否有更适合的分布式数据库方案。
转角遇到分布式数据库OceanBase
在调研分布式数据库的过程中,我们通过技术文章认识到OceanBase的能力,比如稳定、性能较高、可灵活扩展、降本表现不错等,结合对OceanBase社区论坛动态的观察,初步分析其可能满足我们的业务需求,于是展开了进一步的测试验证。
基于上一次分布式数据库选型失败的经验和教训,我们并没有对OceanBase进行常规的测试流程,而是针对线上问题进行定向压测和场景演练。我们认为,只有满足线上需求,才能进行更深的探索。
首先,测试日常抖动。低峰期业务配合100%模拟线上流量直接发压,我们进行了4次压力测试,每次持续3小时以上。在压力测试的过程中,业务同学还会不断变化压力模型,比如1:1的读写、2:1的读写、3:1的读写等。在测试结束后,DBA同学根据业务同学提供的SQL访问模型,自己编写接口模拟业务场景,再通过滴滴出行压测平台进行一周持续发压测试。 经过两轮这样的压力测试,OceanBase在延迟方面表现平稳,整体压测期间没有出现明显的延迟抖动,CPU负载也很稳定,业务端也没有像之前线上一样因延迟问题出现大量报错的情况,完全满足我们业务方的需求。
其次,验证常规业务流量下,扩容、缩容对业务Latency的影响。基于OceanBase运维平台OCP便捷的API接口,我们通过简单调用几十分钟内就实现了之前需要长达数天的自动扩、缩容操作。不断地观察切换过程Latency的情况。结果显示,在切换过程中会产生20s左右的延迟上涨(满足业务诉求),其余时间段均平稳度过,没有产生扩容期间延迟上涨的问题。
最后,我们基于业务流量对1T大表进行多达几十次的加索引操作,观察延迟情况。结果显示,一直到索引添加结束,都无明显延迟上涨。
在经过上述基于业务场景的测试后,OceanBase的性能满足业务需求。在接下来的一个月,我们开始为上线做准备。
我们验证了OceanBase与MySQL的兼容性,对1000个CASE进行回放,发现有22个函数变量未通过验证,但经过比对,这22个函数均未在滴滴出行线上业务使用。因此,OceanBase 100%兼容线上业务。
在上线任何存储方案或功能前,我们都会对故障预案进行验证,涵盖网络、磁盘、内存、CPU、节点故障等。我们此次故障预案基于OCP运维平台,这是一个白屏化的操作平台,即便是刚接触OceanBase的同学,根据预案也能达到线上及时止损的效果。顺便一提,除OCP外,OceanBase的其他工具如OMS迁移工具、binlog_service、obdiag巡检也都符合要求。
为避免疏漏,我们仍然对OceanBase进行了高可用验证、磁盘I/O性能测试、基准压力测试。
高可用验证:2.5W/s QPS压力下进行单点故障测试,1T集群15秒内可以完成自动切换,15秒后集群整体运行稳定. 。
磁盘I/O性能测试:模拟OceanBase顺序写、随机读的文件访问方式对磁盘进行性能测试,以判断机型的使用极限。
基准压力测试结果如下图所示:
OceanBase在滴滴出行的落地效果
滴滴出行在OceanBase上线的第一个业务是特征库,其特点是对接业务广泛,公司内很多业务依赖特征库做数据聚合与数据分析。因此,当特征库在线上出现问题时,影响范围较大。在OceanBase上线初期,业务同学采用双写随机读的方式验证其性能,这样能保证问题发生时可以随时回滚,还能更直观地对比上线前后的性能变化。
从下图可见, OceanBase上线后,性能提升明显,其稳定性表现也得到了业务同学的一致认可。
OceanBase在滴滴出行上线后,我们开始完善基于 OceanBase的上下游生态。上文提到,我们需要解决下游数据链路支持的问题,滴滴出行的大多数业务都需要把上游的MySQL或OceanBase的数据同步到下游的MQ或Kafka,以供不同业务线或业务场景进行分析。因此,一些业务强依赖于binlog同步链路。
OceanBase的Binlog Service在MySQL 兼容模式下,可以将 OceanBase 的日志转换成 MySQL Binlog 文件,且全面兼容 Binlog 能力,更方便接入下游生态。当前工具基本无需改造就可以直接使用,避免了重复造轮子。可问题是,Binlog Service目前为单机模式,无法满足高可用需求。我们的解决方案是:将多个binlog server部署在不同的proxy节点上,实现共同消费模式;Canal通过文件名+时间戳的形式,实现单个binlog server故障时,自主切换到另外一个server上,实现高可用。
OceanBase应用经验总结与未来规划
上线OceanBase之后,不仅解决了此前线上的问题,还让整体延迟缩短了近10倍。并且在执行DDL、扩缩容、日常流量中,延迟整体表现平稳,没有产生间接性抖动。完全满足我们业务对延迟的要求,保证了线上业务的稳定运行。
在使用 OceanBase 过程中,让我们留下了三个深刻的印象。
第一,分区表设计,是超级大表性能稳定的保障。OceanBase分区表的设计是它的一大亮点,使我们可以根据不同的维度对表进行分区。例如,我们有一张大表,既可以根据订单进行分区,也可以根据司机进行分区,还可以根据乘客进行分区。不仅满足业务不同维度的查询需求,而且性能有保障。
第二,日志、数据分盘存储,防止资源抢占以影响性能。起初滴滴出行由于MySQL历史架构导致日志和数据放在一块磁盘里,带来的问题是当上游业务量特别大,在OceanBase进行转储时,日志和数据会相互抢占资源,进而影响性能。将日志和数据分盘存储,就能避免这个问题,达到OceanBase的最 佳应用效果。
第三,MySQL Shard 到 OceanBase 的多表合并问题。当我们把上游MySQL的多表合并到下游OceanBase的一张表时,我们不仅要关心迁移效率和成本,还要关心链路问题。例如,我们把MySQL 20个库的分表合并到一个OceanBase库时,可能这20个分库是由20个链路提供消费,但合并到下游时只能有一个binlog server提供链路服务。这时,我们需要评估这个binlog server和Canel能否支持这么大的流量。
未来,我们计划扩大OceanBase使用规模。首先替换数十套非InnoDB引擎;其次逐渐承接线上的核心归档服务;最后将OceanBase作为分布式数据库方案,并将MySQL超大规模核心集群逐步迁移至OceanBase。
另外,在运维方面,核心业务场景如多活场景、强一致场景开始接入OceanBase,同时,将OceanBase运维管控平台接入滴滴出行平台,加强运维人员的问题定位、故障排查等能力。
目前,OceanBase在滴滴出行上线的表现满足预期。在使用过程中,我们积累了三个期望或建议,希望官方能够支持。
期望实现全局自适应限流。因为业务方有时候简单粗暴,会出现大量自动重试操作,基于我们的SLA标准,期望OceanBase在未来具备全局自适应限流能力,,自动对每种类型的SQL 限制并发度,,防止重试SQL瞬间激增,,导致数据库Load 激增。这样一来,当我们设置全局SQL执行的并发度在10或20的时候,无论历史SQL还是新SQL都会自动统一,无需运维手动操作,当出现故障时即可快速止损。目前OCP具备单独对SQL限流的能力,但不能全局限流。
期望增加核心字段校验,增快迁移速度。在OceanBase 上线期间,OMS的迁移只是基于全量的迁移与数据验证(OceanBase 社区响应迅速,,最新版OMS 已支持该功能.),但在大表迁移场景下,大表中有一些备注信息、大字段等,业务同学在数据校验时更侧重于核心字段校验。我们希望OMS拥有校验部分核心字段的能力,分担业务同学的校验工作,提高OMS的迁移速度。同时希望OMS支持多表的旁路导入,替代目前多表合并采用的SQL方式。
期望更方便的多租户拆分能力。在数据使用初期,业务的规模可能都比较小。大家为了节省资源希望把多个租户或多个业务线放在一个大的集群中,但这会遗留什么问题呢?随着业务的发展,该集群将由非核心变为核心,想把业务从核心集群中迁移出去,为了保证数据一致性,采用主备库模式,且相同的Proxy兼容主库和备库。在主备库搭建过程中,让备库的延迟与主库完全齐平后,Proxy进行主备库的切换,业务几乎是无感知的。备库完全迁移出来后,我们可以通过切换Proxy,再把业务流量迁移出来。目前据OceanBase 社区反馈,,下一个OBProxy 版本将支持透明切换,,帮助用户完成无感迁移。