作者介绍:陈雄军,上海芯昌盛供应链科技有限公司(https://www.x-chance.com)运维负责人,负责集团数据库、IT资产等运维管理工作。拥有多年数据库运维经验,负责集团MySQL、MongoDB、SQL Server、OceanBase 等数据库的运维工作。
一、企业背景
上海芯昌盛供应链科技有限公司,是一家国际供应链管理服务公司,公司业务包括仓储托管、一件代发、定制包装、质量检验、协助选品、退货签收&查验、国际货物运输代理等。目前已与多家知名电商平台合作,包括Shopee、Wish、Tiktok、唯品会等。
二、业务背景
随着近几年公司的快速发展,业务所产生的数据越来越多,之前一直使用的MySQL数据库已经无法支撑业务的快速增长,每天产生的车辆运行轨迹数据、订单物流状态等数据非常庞大,存储在MySQL上已经出现明显问题:
- 单表数据量过大,查询出现明显的性能下降,很多稍微复杂一些的查询就直接卡死;
- MySQL高可用能力差,我们只用了MySQL的主从,主节点出现故障,切换到从节点经常需要补数据;
- 随着数据量越来越大,MySQL这类单体数据库很难实现快速的扩展,只能通过增加主机的配置,成本太高;
- MySQL做了分库分表之后,带来的运维复杂度和维护成本也随之提高。
基于以上几点,我们不得不寻求更好的解决方案。
三、数据库选型
2020年,当时的OceanBase还没有开源,我们对业务进行数据库选型,因为业务原本使用的主要是MySQL数据库,所以在选型中,以兼容MySQL协议为首选条件,然后考察数据库的查询性能、扩展性以及高可用能力,另外开源也是一个重要条件。当时经过一段时间的调研,我们发现市面上有几款比较适合的数据库产品,当时我们选择了TiDB作为我们的选型目标。
选择TiDB数据库主要有以下几点满足我们当前需求:
- 基本完全兼容MySQL协议,业务从MySQL迁移到TiDB基本不需要修改;
- TiDB作为分布式数据库,可以承载更大的数据量;
- 迁移到TiDB之后,相比MySQL查询性能也有一定的提升;
但是,随着我们使用的时间越来越久,问题也逐渐凸显出来。
- TiDB上有的SQL查询时间有时候会突然变的很长,影响业务使用体感;
- 对集群进行扩容比较麻烦,扩容操作经常出现不成功现象;
- 另外TiDB整体组件还是比较多,维护起来也有一定难度,PD存在单节点瓶颈等。
不过,这些都还能够接受。
直到2021年10月份,一次偶然机会,我参加了一个技术大会,在大会上了解到OceanBase数据库,作为淘宝、支付宝内部一直在用,并且完全自主研发的分布式数据库,已经运行了好多年,这确实激发了我很强的好奇心。OceanBase数据库同样在扩展性、性能及高可用方面非常优秀,因此我再次对TiDB和OceanBase数据库进行了对比,当时使用的是OceanBase 3.1.2的版本,TiDB使用的是5.0.1版本。
特性对比 | OceanBase | TiDB |
查询性能 | 比较稳定,快 | 偶尔变慢,有毛刺 |
扩展能力 | 扩展方便,操作简单 | 扩展性一般 |
高可用能力 | 原生具备 | 原生具备 |
架构复杂度 | 架构简单 | 组件多,维护成本高 |
数据压缩率 | 较高 | 较高 |
产品背书 | 支付宝、淘宝、网上银行等 | 无 |
基于以上几点,我们最终选择将数据库切换到OceanBase上,但是因为一些其他原因,这次切换直到2022年11月份才完成。
四、迁移测试
在最终决定用OceanBase数据库替换掉TiDB之后,我们便开启了完成整的测试,以及迁移方案的确定。测试主要包括兼容性测试、性能测试、扩展性测试、高可用测试等。
- 兼容性方面:因为OceanBase也是完全兼容MySQL5.7的语法,我们在测试中发现,基本不需要任何的修改,就可以完全迁移到OceanBase,业务代码所使用的连接驱动直接用MySQL官方驱动就可以;
- 性能方面:最开始我们在使用OceanBase时,并没有注意到需要做分区表,所以在测试过程中,发现SQL查询的性能反而比较差。后来经过OceanBase的工程师指导,我们做了些优化,包括将表创建成分区表,并创建了联合索引之后,性能有了很大提升。
- 扩展性方面:我们尝试给集群中去添加服务器,发现只需要在图形化OCP管理平台上简单的操作下,就可以将新机器加入到集群中,非常方便。
- 高可用方面:我们上线的时候使用OceanBase 3.X版本,高可用方面我们尝试将一台服务器关掉,发现基本对集群没有影响,只有个别请求会失败,不过在几秒之后重新尝试就能成功,这也应证了官方所说的RPO=0,RTO < 30s的指标。
- 数据迁移方面,我们最终由研发人员写了一套工具,不断从TiDB集群select数据,然后在OceanBase数据库中insert写入。经过一段时间的同步,两边数据基本上差不多之后,我们找了一个业务低谷时间段,将数据库集群进行了切换。在切换之前我们已经做了充分准备,包括业务连接用的用户账号、连接性、功能性测试等。
五、性能优化
上面提到,最开始我们在使用OceanBase时,并没有对表进行分区操作。所以在开始测试时,发现查询性能比较差,在测试环境中,有一张表的数据量大概8000多万行,在执行如下查询的时候,用了将近1min57s。
对此,我们明显感觉没有发挥出OceanBase的性能优势,咨询了OceanBase的工程师。根据他们的优化方式进行排查,发现我们一方面没有对表进行分区,另一方面索引创建也有一些可以优化的地方。
因此,我们对表重新创建了分区,使用createtime字段作为一级分区,用id做二级分区:
partition by range(UNIX_TIMESTAMP(createtime)) subpartition by key(id) subpartition template (
subpartition p0,
subpartition p1,
subpartition p2,
subpartition p3,
subpartition p4,
subpartition p5)
(partition p202205 values less than (1654012800),
partition p202206 values less than (1656604800),
partition p202207 values less than (1659283200),
partition p202208 values less than (1661961600),
partition p202209 values less than (1664553600),
partition p202210 values less than (1667232000),
partition p202211 values less than (1669824000),
partition p202212 values less than (1672502400))
在对表执行了分区之后,再次执行相同的操作,发现速度非常快,40ms就返回了结果,这个大超我们预期,比MySQL快非常多,而且比TiDB也要快很多。
所以这里在使用OceanBase的时候一定要注意,因为这种分布式架构,只有对表做了分区之后,数据才会打散到所有的节点上,在做查询计算的时候,才能发挥每个节点的能力。并且在做了分区之后,我对集群进行扩容,集群在新增了服务器之后,数据会以分区的粒度,自动负载均衡到新的节点上,实现真正了线性扩展。
六、取得收益
- 数据库服务更加稳定:在2023年1月份的时候,OceanBase数据库集群中有一台服务器内存条发生了故障,导致机器不可用,当时是凌晨0点多,但是查看业务,并没有发生任何错误请求,因为我们是跨境电商业务,晚上也会有很多业务请求,而我们却没有收到任何业务异常的反馈。这个内存条,到第二天中午更换完成,整个过程我们业务都是无感的,这让我对OceanBase数据库好感度倍升;
- 数据压缩能力更强:之前在TiDB数据库上,我们给每台TiKV服务器配置了10T的磁盘,但是在迁移到OceanBase之前,磁盘空间已经接近告警阈值了,而我们在迁移到OceanBase 数据库上之后,发现每台机器的磁盘使用率只有2T左右,所以看下来,OceanBase数据库的数据压缩能力要好很多。
- 运维成本更低:目前我们只用一套OceanBase数据库,就解决了之前需要维护多套MySQL主从的运维成本问题,并且高可用方面OceanBase原生具备,不需要人为过多干预,节点发生故障也会自动实现切换,我们可以有更多时间聚焦业务。
七、对产品的展望
目前OceanBase使用下来整体感觉还是很丝滑,不过个人觉得还是有些地方可以再优化些,例如OceanBase的错误日志目前还是比较难看懂,日志打印太多了,有用信息有时被淹没在日志里。
未来我们还将对OceanBase做更多的探索,当前我们的AP报表业务数据库用的是SQL Server,OceanBase具备HTAP的能力,一套集群可以同时支撑TP和AP查询,因此未来我们也计划将这个业务切换到OceanBase上。最后希望OceanBase数据库越来越强大。