业务痛点及选型背景
在游戏业务发展阶段早期,我们考虑到迭代迅速、运维简单、架构轻量,使后端数据库均采用了AWS上的MySQL单实例,承担游戏运行、运营分析等各项业务。
运营分析业务主要面向公司内部员工,用于观察生产业务运营情况、追踪异常用户数据,针对游戏日志进行分析计算,处理生成BI报表。该业务几乎24小时都有数据写入,大部分数据量集中在几张日志表、流水表中,且21:00-24:00点的数据量会是其他时段的1-2倍。随着业务的发展,我们发现,运营分析业务使用MySQL数据库的弊端越来越凸显。
弊端1:性能瓶颈。随着多张表一天产生的数据量由百万级增长到亿级,原来的MySQL实例在读场景的性能出现明显下滑,例如,针对单天的统计计算从原来的10s延迟至300+s才能出结果;在写场景下,由于80%以上的数据集中在几张日志表、流水表中,且24小时不间断写,造成写热点、数据入库慢等问题。
弊端2:分析瓶颈。写热点场景下,数据入库慢,叠加读性能下滑的影响,导致运营分析的数据一直有延迟,仅能获取准实时报表。
弊端3:扩展瓶颈。数据量突增的情况下,出现上述性能、分析瓶颈后,暂时只能升级MySQL配置,但随着业务的进一步扩展,升无可升。同时,由于MySQL的局限性,难以采用线性扩展方案,即使想用分库分表,前期的应用适配改造及后期的运维工作量也很大,无法短时间解决问题。
基于上述三个弊端,我们在制定解决方案时想到了关注已久的原生分布式数据库 OceanBase。早在OceanBase开源(2021年6月)前与CloudCanal的合作直播中,让我们了解到这款数据库产品。当我们再度想起OceanBase时,它已经开源并计划发布OceanBase 4.0版本。在我们从OceanBase官网及社区深入了解相关信息时,观察到OceanBase的文档比较完善,其写性能、AP能力、扩展性、迁移成本都符合我们对新方案的预期。当即展开小规模调研。即搭建低配测试环境观察基本的语法兼容和业务适配。
测试与部署
在小规模测试过程中,用户数据突增,数据从原来的日增百万级别,直接跳跃到日增1.2亿左右,公司内部报表业务接近瘫痪,更新替换迫在眉睫。我们迅速搭建了测试环境,测试公司基本的业务流程、兼容情况,为正式部署做准备。测试过程中主要考量以下几个因素。
1、高性能
抽取MySQL中多张日志、流水表的部分数据至OceanBase 4.0单节点中,测试各类分析SQL的查询性能,如分组求和、总数统计等。
对比示例:模拟单表2600w的数据量,OceanBase中全表count(1)毫秒级响应,而在MySQL中执行是分钟级。
2、低成本
数据存储方面,原来千万级别的数据在MySQL中大概占用超400 GB的存储量,迁移到OceanBase中亿级别的数据仅需260 GB。
MySQL 5.7迁移至OceanBase4.0时,使用了MySQL dump导出MySQL 5.7数据,再使用OBLOADER 4.0导入OceanBase 4.0,方便快捷。
迁移至OceanBase4.0以后,少部分存储过程存在不兼容的情况,在代码层面做了修改,相较于分库分表的改造、运维方案,这块的人力投入比较可控。
3、易用性
采用OBD方式部署单节点实例简单快捷,另外自带的ODC开发者工具和以前习惯使用的Navicat都能方便的测试OceanBase。
基于上述测试数据,我们决定部署OceanBase 4.0,生产环境部署信息如下。
OceanBase:4.0.0_CE_BP1OBD:1.6.2
|
|
|
OceanBase:单节点OBServer+OBProxy
|
|
而在实际的测试到生产过程中,线上业务飞速发展,单表日增数据量到上亿级别,导致在生产环境实际跑业务分析SQL时,效率不佳。因此,我们针对几张核心表的查询也做了一定的优化措施。下面以SQL为例展开说明,以供参考。
比如这是一张游戏的流水表,拿到用户的流水记录以后,我们在内部会统计最近几天,不同游戏、不同渠道用户的各类消费情况,根据统计的各游戏的运营信息及时调整游戏的活动策略。
CREATE TABLE `games_play_flow` (
`event_time` int(11) DEFAULT NULL COMMENT,
`game_id` int(5) DEFAULT NULL COMMENT,
`account_id` bigint(20) DEFAULT NULL,
`uid` bigint(20) DEFAULT NULL,
`channel_id` varchar(20) DEFAULT NULL,
`play_id` varchar(100) DEFAULT NULL,
`mfr_id` int(11) DEFAULT NULL,
`money_type` tinyint(4) DEFAULT NULL,
`output` bigint(20) DEFAULT NULL,
`consume` bigint(20) DEFAULT NULL,
KEY `idx_ix_event_time_63917445` (`event_time`) BLOCK_SIZE 16384 LOCAL,
KEY `idx_ix_account_id_1050842020` (`account_id`) BLOCK_SIZE 16384 LOCAL
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0
SELECT /*+ parallel(10)*/ "2022-12-09" date,
game_id,
channel_id,
sum(output) as pay_output,
sum(consume) as pay_consume
from games_play_flow
where money_type = 2
and event_time between 1670515200 and 1670601600
group by game_id ,channel_id
在测试此类业务SQL的过程中,也出现了一些意料之外的问题,在日增数据量突增的情况下,OceanBase4.0中单表分组统计SQL性能表现没有在测试环境的表现好。并且因为业务24小时均匀写入的特点,业务没有明显的高低峰期,导致当天最新数据入库时,统计信息未更新,统计最近三天运营数据时,SQL执行计划不走索引。
我们也和OceanBase社区的同学一起商量了解决方案,做了三方面的工作,最终保证了业务SQL的性能满足运营需求。第一,重新规划运营数据的保留周期,计划仅保留1-2个月数据,并且将多张核心的单表(几亿行数据)改造为分区表,按天分区;第二,根据CPU占用增加SQL执行的并行度,利用分区裁剪+event_time索引提升查询效率;第三,针对统计信息未及时更新的问题,定时任务触发手动收集统计信息。
实践总结
从整体来看,选用OceanBase 4.0对公司业务性能的提升还是很大的,也为公司节约了很多成本。
首先,解决了MySQL的性能瓶颈问题,依据生产环境实际运行情况,分区表的改造加上OceanBase准内存架构,解决了热点表写的问题,OceaanBase 4.0单机写性能是之前MySQL的5-6倍。其次,针对两条业务线(MySQL与OceeanBase)在游戏正式服的查询性能表现,对于分组聚合查询业务,我们按天进行数据分区,MySQL对单天的数据进行统计计算需要130s,而OceanBase 仅需18s,且OceanBase业务线日增数据是MySQL业务线的2倍左右。按这样的比例来算,同配置下,在我们的业务场景下OceanBase的分组查询性能是MySQL的12倍左右。性能得到了巨大的提升。
当然,在业务切换到OceanBase 4.0的过程中,我们也遇到了一些问题,比如上文提到的刚开始启用生产环境发现按天分区的分区表查询性能和测试环境相差较大,后来同OceanBase社区的同学一起快速定位到了问题。原来是当天的分区统计信息未收集到,导致查询语句走的全表扫描,通过手动触发收集分区信息后,查询性能就立马上来了,据了解,OceanBase 4.1版本将提供在线收集统计信息功能,解决这个问题。
除此以外,我们还反馈了一些关于兼容性、功能等问题,OceanBase社区的同学也一一做了解答,可参考如下:
cpu_count不实时生效:
mySQL迁移到ob遇到兼容问题:
未来畅想
总的来说,在本次业务解决方案替换过程中,我们重点关注于AP场景下的性能优化,期间遇到的一些问题都已解决,但还有些未来可能遇到的问题,我们也做了一些规划。
未来会将OceanBase4.0BP1升级至正式版本。
为支持业务发展,后续可能会继续扩展实例节点数,针对大表优化,可能进一步做二级分区。
在运维管理方面,试用OCP Express,简化集群管理的操作。
这次试用OceanBase 4.0,整体而言比较惊喜,短时间内的调研、测试、替换上线,既解决了我们的业务痛点,又不用担心扩展问题。未来,我也会积极参与OceanBase的社区,和大家共迎更好的OceanBase。