引言:自2021年起,翼鸥教育便开始应用OceanBase社区版,两年间,先后部署了总计12套生产集群,其中核心集群占比超过四分之三,所承载的数据量已突破30TB。自2022年10月,OceanBase 社区发布了4.2.x 版本,其单机效能、数据压缩实力及AP分析能力等核心功能进行了整体升级,深深吸引了我们的目光。于是,在4.2.1 LTS版正式面世后,我们立刻启动了升级计划,目前已经从最初的OceanBase 3.1.4升级到4.2.1 版本。
本文分享我们在版本升级过程中积累的一些经验,供大家参考。
家里有孩子的朋友或许对翼鸥教育的核心产品“ClassIn在线教室”比较熟悉。作为应用于150多个国家的全球教与学一体化平台,ClassIn 为学生提供从课前到课后的智慧服务,以及从软件到硬件的配套设施。此外,翼鸥教育旗下还有TeacherIn、NOBOOK 等众多优质的教育科技产品。
翼鸥教育应用OceanBase的起因是想解决MySQL带来的问题。众所周知,MySQL读出现瓶颈时,可以通过扩展从库轻松解决,但遇到写瓶颈的时候就比较难办了。尤其是单机数据增长到2TB以上,写能力愈发受限,数据处理效率也逐渐变低。这时我们会想到分库分表方案,但分库分表无法从根本解决问题。业务连续性也是一个问题,MySQL的高可用能力依赖外部组件,需要投入专门的人力去维护。因此,当我们了解到OceanBase多分区的灵活扩展能力、高数据压缩率以及金融级高可用后,我们怎么会不选择它呢?
我们为什么选择将OceanBase从 3.1.4版本升级到4.2.1版本?
在上线OceanBase 3.1.4版本后,我们陆续部署了12套生产集群,其中超过3/4的集群是核心集群,数据量超30TB。上线之后,OceanBase 3.1.4的确为我们解决了不少难题,在灵活扩展、数据库压缩和高可用等方面的表现优异。
OceanBase在翼鸥教育的应用场景如下图所示,翼鸥教育的应用通过访问SLB(服务器负载均衡)再连接到OceanBase生产集群。在大数据场景下,由于OceanBase 3.1.4版本AP性能较弱,我们将上游数据通过OMS工具同步至OceanBase集群,在实时场景使用OMS将数据同步至Kafka,在离线场景使用Data X将数据抽取到大数据的数仓系统中进行分析。
俗话说没有一款产品是万金油,OceanBase 3.1.4在我们的业务场景中逐渐显现出一些不足。
1. DDL支持不完善。OceanBase的DDL速度非常快,但在3.x版本支持不够完善,比如向上兼容不支持text-> medium text,再比如不支持int -> varchar的列类型修改。
2. 字符集支持不完善。由于历史原因,我们使用的字符集没有用OceanBase 支持的 utf8mb4_general_ci,而是 utf8mb4_bin字符集,导致我们使用OMS在上游加字段时,下游的大数据集群就会发生数据迁移任务的中断。
3. 大IN支持不友好。例如在MySQL中 IN 包含 80万个值,查询只需10ms,而在OceanBase 3.1.4版本中需要5s,是因为时间主要消耗在查询解析方面。OceanBase 4.2版本后对这方面做了优化,性能提升明显。
4. 分区数太多影响性能。当分区数超过30000后,响应时间下降明显。
5. 数据膨胀问题。OceanBase的降本增效的效果非常显著,原来MySQL集群中6TB数据迁移到OceanBase后缩减到了1TB。但我们发现集群使用一段时间后,数据存在空间放大的问题。比如本来一年增长1.5TB,但集群膨胀了4T。
6. 物理备份不支持S3。S3是可以充分利用网络带宽且价格优惠的存储方式,但OceanBase 3.1.4版本仅支持nfs,未支持S3。
基于上述使用方面的不足,我们决定升级到OceanBase 4.x版本。
升级至OceanBase 4.2.1版本的流程和效果
从版本选型到版本升级,我们历经四个阶段:版本选型、功能和性能测试、组件升级、集群升级。
第一阶段:版本选型。
选择版本时我们主要考虑五个因素。
- 功能:新版本能否满足当前业务需求?
- 性能:新版本性能相较于旧版本性能提升多少?
- 稳定性:新版本是否足够稳定,有没有bug?
- 兼容性:迁移后与旧的集群是否兼容?
- 产品生命周期:新版本是否为官方长期支持版本?
针对上述问题,我们结合应用场景需求,对OceanBase 4.x版本特性与升级点进行了分析,认为新版本相较于旧版本性能有显著的提升,能够更好地满足当前场景的需求。且OceanBase 4.2版本是长期支持版本。长期支持版本经过多次迭代,遇到的问题较少;创新版本经过几个版本的迭代和修复,也会渐趋稳定。兼容性方面,因为我们是从OceanBase低版本升级到高版本,所以兼容性良好。
第二阶段:功能和性能测试。
在MySQL环境中,我们可以使用tcpcopy进行流量回放来进行业务验证。然而,在OceanBase中,业务是以租户为单位的,如果直接采集流量,会涉及多个租户。为了方便实现,我们自己开发了一个代理(Agent),实时将SQL_audit中的SQL同步到Kafka。在目标端,可以启动多个Agent读取select语句来并行进行回放,并观察目标端是否受到影响。
我们基于gopacket抓包。再进行mysql ps数据解析,经过解析的PS协议及其参数的结果存在Redis,最后通过Agent读取Redis回放。这样可以让我们提前发现业务迁移中可能存在的问题,比如执行计划是否变慢、是否有不兼容问题等。
在迁移前,我们通过sysbench压测观察OceanBase新版本相较于旧版本的性能提升度。我们的服务器规格都是64C/512G,但此处仅基于16C/96G的业务租户配置进行压测。从下图可见,OceanBase 4.2.1版本较OceanBase 3.1.4版本性能提升3倍左右,即使在读写比7:3的场景下,新版本的性能更优,也更为稳定。
此外,保险起见,我们基于JMeter,使用CSV动态生成参数的方式对生产线接口进行压测(线上租户配置为3节点16C/96G )。结果如下图所示,OceanBase 4.2.1版本较OceanBase 3.1.4性能提升2倍左右。
第三阶段:组件升级。
在确定版本升级后,我们先对组件进行升级,以下是我们在升级过程中的一些经验总结,供大家借鉴:
1. 如何解决长期未使用的Agent导致升级OCP时报错的问题:
具体而言,显示ocp-server-ce:check_operation_task未通过,The Server have running task。这是因为我们升级OCP时使用的Agent经久未用导致无法回滚,所以我们在它的原数据库中更新状态就可以了:update task_instance set state='SUCCESSFUL' where id in (父任务id);
2. 如何针对OMS Store 进行性能调优:
作为OMS的重度用户,OMS store可以理解为一个binlogservice的webservice,并且store内部有OB CDC模块。该模块包括数据消费模块和拉取日志模块。消费日志线程(cdc)会从多个OBServer中拉取clog并排序,存储到内存中。此时,CDC拉取日志模块会消费内存中数据,并将其落盘。然而,由于最初使用的是机械硬盘,默认的storage即机械盘,导致落盘速度较慢。为了进行性能调优,我们将参数storage调整为内存,并且将OB CDC使用的内存限额从20G调整为40G。此外,为了及时更新心跳时间,我们还将DDL当前拉取日志的上限(progress_limit_sec_for_ddl)从3600秒调整为60秒。
3. 如何解决OMS迁移和同步任务延迟问题:
在OMS的迁移流程中,首先会启动OMS store,以保证后续DBA能成功取到增量数据。然后,全量迁移流程随之启动,待全量迁移和全量校验完成后,再启动增量数据迁移和校验流程。在这个流程中,我们经常遇到数据迁移慢、校验时间长的问题,以及数据同步到Kafka
延迟的问题。究其原因,不同场景采用默认参数,速度不及预期,我们可以通过调整参数来解决上述问题。
在数据迁移和校验场景,速度慢的时候我们通常会想到调整线程数或切片大小,以读取更多数据。但是读取更多数据就意味着内存需要更大的承载量,所以我们要把JVM参数调高。
常用调参:
• workerNum | limitator.platform.threads.number
• sliceBatchSize | limitator.select.batch.max
• connectorJvmParam | task.checker_jvm_param
应用场景调参:
• sliceByMinMax: false(id不连续)
• sliceByMinMax: true(id连续)
在数据同步sink到Kafka场景下,如果速度较慢,可能是由于分片算法的影响,导致OBServer的I/O较高。这是slicebyminmax的原因,通常情况下,我们的跑批操作类似数据库工具pt和ghost,它们基于范围100~~10000不断向前滚动。然而,有时我们的自身ID包括业务使用的UUID,它可能是不连续的,这会导致读取I/O较高。在这种情况下,需要关闭切片的slicebyminmax设置,这样可以提高数据同步速度。如果仍然无法满足预期,在机器的支持能力足够的情况下,还可以调整批处理的大小,每次读取更多的数据。
另外还需要调整JVM的内存。在这个场景下,开发人员都知道,对于插入操作,可以很容易地进行批量处理。但对于更新和删除操作,就不那么容易进行批量处理。因此,需要根据上游的情况如是否有大事务等,动态调整参数,尤其是针对insert和update的比例。首先消除最重要的瓶颈,然后再调整其它常用的参数,特别是在OMS中将增量同步到大数据库的情况下。我们采取了大数据库的lock_time默认值,并将OceanBase的ob_query_time参数设置得比较大,因为锁的释放时间根据ob_query_time来确定,可能会导致长时间被锁住的情况,进而使jdbc的writer的点位不更新。实际上,数据仍然会持续写入目标端。
常用调参
• workerNum
• maxRecordCapacity
• connectorJvmParam
应用场景调参
• splitThreshold(insert攥批效率高;update和delete不能批量,拆开效果好)
4.如何解决4018错误码报错:
在使用OceanBase的过程中,让我们最困扰的问题是4018错误码,这也是版本升级的直接原因。当出现4018错误码的时候,一个zone中两个机器只有一个机器节点报错,无法请求,导致业务报错。短期解决方法是重启报错的机器节点,而从长远来看,升级版本才能彻底解决问题。我们升级到OceanBase 4.2.1.3 版本后,再没有遇到过4018问题。
第四阶段:集群升级。
在集群升级的过程中,我们仍然保持谨慎的态度,分为准备、生产上线、整体回归、收尾操作四个步骤,升级成功后整体效果满足预期:
- 新版本的DDL支持完善,解决了旧版本的DDL问题,且性能得到较大提升;
- 数据被进一步压缩,比如300GB数据迁移到新版本后压缩至200GB,存储空间得到释放;
- 新版本的备份支持S3,使我们可以充分利用网络带宽;
- 数据从OMS同步到Kafka,性能提升7倍。
至于上文提到的字符集支持问题,可能是OB server带来的,在OMS迁移的部分场景中仍会出现任务中断的现象。
总结与规划
目前,我们把8套核心集群都升级到了OceanBase 4.2.1版本,升级经验总结如上。而在我们从上线到使用OceanBase期间,有五点应用经验可供大家参考。
第一, 在我们使用OceanBase的过程中,跑批是业务经常做的工作。经验指出,跑批或数据更新时,尽量指定分区,避免跨节点分布式事务。
第二, 尽可能使用本地索引以节省开销,因为全局索引更新需要分布式事务,所以在唯一性或者多维场景下使用全局索引。
第三, 针对副本切主,OBServer事务查杀有重试逻辑,业务同学要能够及时捕获异常,利用分布式特性和发挥分区并行的优势,避免业务报错。
第四, 在OLAP环境下可以充分利用并行提升查询速度,建议单个分区小于50GB。
第五, 此前人工排查问题时速度比较慢,obdiag推出后,问题定位和日志分析都变得方便、简单,在此推荐大家充分利用这个工具。
后续,我们会把剩余OceanBase集群都升级到4.2.1版本。同时,随着OceanBase 4.3版本AP能力的提升,我们也考虑将大数据集群升级到该版本。
OceanBase 云数据库现已支持免费试用,现在申请,体验分布式数据库带来全新体验吧 ~