速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

OceanBase 在科大讯飞三大场景下的应用实践

  • 2024-12-02
    北京
  • 本文字数:6409 字

    阅读完需:约 21 分钟

大小:3.36M时长:19:32
OceanBase在科大讯飞三大场景下的应用实践

作者|李梦嘉,科大讯飞技术中心数据库方向负责人。


作为亚太地区知名的智能语音和人工智能上市企业(股票代码:002230),科大讯飞自成立以来一直从事智能语音、自然语言理解、计算机视觉等核心技术研究并保持了国际前沿技术水平。2023 年,我们的某个 AP 业务进行数据库方案替换,上线了 OceanBase 数据库。本文分享这一年来 OceanBase 在科大讯飞的应用场景和运维经验。

数据库选型需求


2023 年,我们上线了一个全新的业务,短短几月,数据增长就远远超出了上线初的预测,以至于底层数据库 MySQL 支撑出现瓶颈。对此,运维侧和业务侧提出了不同的诉求。


首先,业务侧希望数据库具备 HTAP 能力和多模能力。


HTAP 能力。MySQL 数据库在我们生产环境中被广泛使用,既支持 TP 类在线业务,又处理 AP 类业务的数据统计与分析。众所周知,MySQL 对复杂 SQL 的优化能力较弱,当数据达到一定规模时就会出现性能瓶颈,这时开发人员需要找到一款性能更强的数据库,经过改造让其适配 MySQL。为了减少改造成本,我们希望有一款数据库既兼容 MySQL 协议,又能支持 HTAP 混合负载,最好一套系统代替 TP+AP 两套系统,无需分库分表,同时支持列存和行列混存及查询优化,以保障良好的查询性能。


多模能力。随着科大讯飞业务的多元化与复杂化,我们使用的数据库类型也越来越多,对开发、运维都是一种挑战。我们希望有一款数据库能够统一接口处理结构化、非结构化数据,简化我们的技术栈。另外,最好支持 NoSQL 功能,比如 HBase、Redis、向量等产品形态。


其次在运维侧,我们对数据库的诉求主要包括两方面:数据迁移、白屏运维。


数据迁移。由于我们使用的数据库类型较多,DBA 日常工作涉及在各个数据库集群中迁移、同步数据的操作,而使用的迁移工具、迁移方案也多种多样,因此,我们希望能有一款数据库支持 MySQL、HBase、Redis 、PostgreSQL 等多种数据库的数据迁移、同步,同时具备数据校验能力。


白屏运维。我们的运维工作也涉及平台化建设,在该平台尚未完成数据流转生命周期的覆盖时,就无可避免通过命令行黑屏去操作。进而产生误操作,给业务带来稳定性风险。我们希望通过白屏化运维包括安装部署、升级、备份恢复,以及集群巡检、故障分析、SQL 优化建议等功能,实现数据流转全生命周期的覆盖。


在做产品调研时,OceanBase 作为单机分布式一体化、TP 与 AP 一体化的数据库吸引到了我们,其兼容 MySQL 协议和部分语法,稳定性与性能已经过市场验证,近年来也拥有了多模能力。同时,OceanBase 拥有丰富的生态工具,在数据迁移和白屏运维方面页满足我们的要求。因此,我们决定引入 OceanBase(对选型和测试、上线过程感兴趣的朋友可以查看博文:亿级规模大表数据,查询性能快 40 倍|科大讯飞 HTAP 探索实践)。

OceanBase 落地场景


在业务上线 OceanBase 后,主要的应用情况体现在三类场景中。

场景一:海量数据统计

起初业务数据量很小,在线业务和统计业务共用一套 MySQL 集群,没想到上线不久后业务量猛增,增速远超产品侧的预测。



该业务有三个典型特点。第一,数据量大,核心表上亿级,最大的表超百亿规模;第二,增长快,核心表每天新增千万级数据,每年数据的存储量增加 5TB 以上,且不能删除,产品策略要求永久保存数据;第三,基于海量数据进行实时的多维度统计分析,要求秒级返回,并通过大屏进行实时展示(涉及报表 40+)。


这三个业务特性使 MySQL 面临两个支撑难点,一是大规模数据的迅速增长已经超出 MySQL 的承载力,二是 MySQL 在统计查询方面较弱,无法满足业务需求。为了解决这两个问题,我们对系统进行改造和拆分。


首先,为了解决 MySQL 单集群的容量问题,我们将与核心业务关联较低的表拆分到单独的 MySQL 集群中,再把纯用户文本类的大字段的表单独拆分到 MongoDB 集群,相当于缓解了 MySQL 容量瓶颈和水平扩展问题。


其次,把数据拆分到多个集群后,出于统计分析的需求,业务侧仍然需要将数据进行汇总,一种可行的办法是将数据抽取到大数据平台,通过平台进行查询。但是,这种方法的缺陷在于查询是异步进行,无法满足秒级查询和展示的需求,同时,数据流向大数据平台,也需要经过开发和改造。


为了减少开发改造的工作量,同时更好地解决问题,我们找到了兼容 MySQL 协议的单机分布式一体化数据库 OceanBase,并在 2023 年将其应用于海量数据统计场景。因为 OceanBase 支持水平横向扩容,所以容量不会成为业务发展的阻碍。同时,OceanBase 的 HTAP 特性,无论是 TP 场景的性能还是 AP 场景的统计分析都能够满足业务秒级查询的要求,在不同的统计 SQL 场景,相比 MySQL,OceanBase 的 OLAP 性能提升 7~40 倍。



最终,我们通过数据同步工具将 MongoDB 和 MySQL 多个集群的数据统一汇总到 OceanBase,在不改变业务逻辑的情况下,满足了业务统计查询报表的需求。

场景二:分库分表数据汇聚

对于一些规模较大的集群,我们在前期使用分库分表方案进行水平拆分,实际是将数据打散在多个分片上。比如将最大的表分成 16 个分库共 256 个分片。



在这样的架构下,做统计查询就比较困难。因为分库分表中间件对跨分片的关联和汇聚查询能力较弱,所以无法直接在中间件查询。如果采用人工查询和汇聚的方式,面对单表 256 个分片,耗时较长。另外,在进行 SQL 统计分析时,涉及亿级数量的表扫描,可能导致集群性能抖动,影响业务稳定性。


基于上述背景,我们将多个经过分片的数据汇聚到同一个查询库里进行统计,这是一个过渡方案,本质是使用 MySQL 多元复制的能力将多个分片的数据汇聚到一个 MySQL 汇总查询库,可以暂时满足业务需求。



但是,这个方案的数据同步链路非常复杂,因为我们业务环境中使用的是 MySQL 5.5,复制能力较弱,一些业务原因导致数据库版本无法升级和改造,所以数据必须经过一个临时的中转库,再结合 MySQL 5.7 的多元复制及 replicate DB 功能,把多个分片汇聚到一张表中。同时,每个分片都需要一个单独的同步链路,任何一个链路有问题,中转库及最终的数据查询汇聚库都要进行数据修复,导致整体链路出故障时难以修复。尤其是当线上需要变更表结构时。经过的每一个分片都要执行变更操作,致使汇聚链路中断,此时只能依靠人工修复链路。


更让人头疼的是,我们采用 MySQL 的源生同步,不支持数据校验,缺乏对已汇聚数据和源库原表的完整性校验的机制。如果同步链路中出错,我们只能选择忽略错误,继续保持链路的进度。因此,我们无法判定汇聚后的数据一致性和准确性,如果发现问题,只能重建同步链路,整个过程耗时又耗人。


为了解决上述痛点,我们使用了 OceanBase 的数据同步工具 OMS,代替中转库的方案。



OMS 对 MySQL 各版本兼容良好,可以让我们将数据从 MySQL 一步汇聚到 OceanBase,同步链路被极大地简化。由于 OMS 的监控和数据校验功能完善,可以监控各种数据延迟,便于我们及时获取同步动态,当数据出现冲突或丢失时,我们也可以借助工具快速进行修复。另外,上文提到每一个分片都是单独的链路,我们可以复制链路原子化,如果单一链路出现问题,也不会影响其他链路的数据同步。


下图是 MySQL 源生复制和 OMS 同步的功能对比,可以看到 OMS 占据很大的优势。比如支持断点续传、数据同步校验、同步延迟监控,以及当数据发生冲突时可以根据配置选择跳过还是覆盖。同时 OMS 也支持同步链路重建,当出现同步故障时,我们可以通过数据抽取快速恢复链路。



场景三:NoSQL 及多模

这是一个在线爬虫类业务,需要下载客户请求端的网页,并返回数据。该业务的并发很高,生产端和消费端的并发量均为 1.5 万个进程,同时业务对应用请求响应的时延要求是毫秒级,因此我们最初选择使用 Redis 去解耦生产端和消费端,使二者互不影响。


  • 通过 lpush 和 rpush 把待下载网页的 URL 数据存入 redis 的 list key。

  • 通过 lpop 和 rpop 来获取待下载的网页 URL。



由于爬虫的数据量特别大,整个 Redis 集群使用三台服务器,共 42 个实例,最大的单实例内存约 60GB,整个集群规模占内存约 2TB,这为系统埋下了隐患。


第一,Redis 主从复制是基于内存中的复制积压缓冲区,如果业务爬虫的瞬时写流量大,会把积压缓冲区的内存覆盖,导致内存不足,进而 Redis 主从复制中断,重建频繁失败。这时只能人工介入。


第二,由于爬虫数据的分布不均,整个集群中会存在热 key,业务对部分 key 请求频率过高时(>2w/s),会使集群负载不均。而且因为业务逻辑,我们没办法针对热 key 进行拆分。


第三,无论是生产还是消费,业务的并发量都很高,但 Redis 本身是单线程的,如果业务出现偶发 o(n) 操作就会导致单线程阻塞 :如 hgetall,scan, lrange 0-1 等。


因此,我们需要重新选型数据处理方案以解决上述难题。


OBKV 是构建在分布式存储引擎上的 NoSQL 产品,继承了 OceanBase 的分布式、多租户、高性能、高可靠等基础能力。其分为 OBKV-HBase 和 OBKV-Redis,后者正是我们当前选择的新方案,原因是:


  • OBKV-Redis 完全兼容 Redis 协议,业务侧不需要修改。

  • OBKV-Redis 持久化 key 到磁盘,解决内存不足或使用过多的问题。

  • OBKV-Redis 针对热 key 底层通过表分片进行了优化。

  • OBKV-Redis 利用 OBServer 多线程处理,无单线程阻塞问题。

  • OBKV-Redis 无特殊运维,只需运维 OceanBase 集群。

  • OBKV-Redis 的 P99 在 10 ms 以内,满足业务需求。


在上线前,我们针对 OBKV 和 Redis 进行了读写方面的压测,为了保证公平性,规格统一限定为 12 核 20GB。从下图可见,在读场景,二者的性能、延时相近。而在写场景,OBKV 写性能与 Redis 存在一定差距,但满足业务负载;OBKV 写延迟比 Redis 略高,但都在 10ms 以内,满足业务需求。



使用 OBKV-Redis 后,虽然性能与延时并未提升,但解决了此前 Redis 主从复制容易中断,产生热 key、单线程阻塞等问题。

OceanBase 白屏运维

除了上述应用场景外,OceanBase 丰富的工具体系为我们提供了极大便利。


本文开头提到复杂的运维操作促使我们寻找一个白屏化的运维平台,以管理数据库全生命周期。OceanBase 运维平台——OCP 基于 Web 的可视化白屏管理,将黑屏运维管理工作标准化、自动化,我们可以通过页面操作进行数据库运维,提升运维效率。


OCP 具有几项典型功能:

  • 资源管理。提供 OceanBase 集群,租户,主机等资源对象的全生命周期管理,包括管理,安装、运维、 性能监控、配置、升级等功能。

  • 监控告警。全局监控及告警设置,支持所有资源对象不同维度,实时、准确地监控告警需求,支持自定义告警。

  • 备份恢复。支持集群和租户表级全量备份、增量备份及日志备份,支持在备份周期内任意时间点的恢复,支持多种云平台介质的备份恢复。

  • 自治服务。自动化处理 “发现-诊断-定位-优化/应急”链路,极大地降低用户运维的成本。


从下面 OCP 平台的截图可以看到,无论是集群管理还是租户管理,我们部可以通过白屏化进行操作。在很大程度上简化了运维工作,降低了我们的运维投入。


OceanBase 运维经验

OceanBase 成功解决了我们在业务侧和运维侧的难题,在运维 OceanBase 一年后,我们也积累了一些运维经验,供大家借鉴。

1、产品版本选择

当我们在业务侧推广 OceanBase 时,通常业务侧会关心应该使用哪个版本,这时我们需要对各版本有较为全面的了解。OceanBase 的版本号通常有三类:


  • Va.b.c_CE,如 V4.2.1_CE;

  • Va.b.c_CE_BP1,如 V4.2.1_CE_BP1;

  • Va.b.c_CE_BP1_HF1,如 V4.2.1_CE_BP1_HF1。


在上述版本号中:

  • a 表示主要的大版本,一般会有架构升级或较大的新功能发布。

  • b 表示计划迭代版本,含有重要功能或特性更新和提升。

  • c 表示发布更新版本,对已知问题进行修复,一般无功能或特性变更。

  • BP:表示是第 X 个 Bugfix 版本,通常每个月发布一次,用于修复一些重大的 bug,引入一些小功能特性。

  • HF:表示是第 X 个 Bugfix 版本的第 Y 个 Hotfix,如果在 BP 发布期间发现了重大的 bug,就通过 HF 来修复。


目前,OceanBase 4.x 的长期支持版本有 OceanBase 4.2.1 和 OceanBase 4.2.5,我们使用的是 OceanBase 4.2.1。对于初次选择 OceanBase 的企业,我们推荐使用长期支持版本的最新 BP 或最新 HF 版本。

2、DDL 分类

在 MySQL 的日常运维工作中,Online DDL 操作或大表 DDL 操作对我们来说是一大痛点。OceanBase 对 Online DDL 操作进行了增强,目前 MySQL 中大表分钟级的 DDL 操作,在 OceanBase 中秒级完成,且不锁表,完全不会阻塞业务。不过,对于秒级完成的 Offline DDL :操作,其原理是新建一张临时隐藏表,后台将原表的数据补全到隐藏表,最后重命名临时表为原表并删除旧表,在这个过程需要锁表,对业务有损。

下图是 OceanBase 目前已经支持的 DDL 操作,相信随着版本的快速演进,Online DDL 操作会越来越多,Offline DDL:操作会越来越少。



此外,值得一提的是,为了解决 Offline DDL 锁表的问题,OceanBase 提供了一个功能——ODC 无锁结构变更。其本质是依赖 OMS、OCP 解决问题,首先创建临时表并改变表结构,其次全量拷贝数据并做增量同步和校验,最终切换新旧表。


下图是 ODC 无锁结构变更支持的变更范围。



在进行无锁结构变更操作时,我们需要注意:


  • 表必须有主键或非空唯一键;

  • 需要操作对象至少 2 倍的磁盘空间;

  • 无锁结构变更期间,其它关于该表的 DDL 变更将导致任务失败。


根据我们的实测数据,线网 5 亿单表(200GB)修改列类型耗时约 5 小时,但经过我们和官方技术人员分析,耗时较长的原因是 ODC 依赖的 OMS 同步效率慢,可以通过参数调优实现加速。

3、善用 Hint

优化器是数据库 SQL 执行的关键,但往往无法正确选择准确的执行时间。当优化器选择了错误的执行计划时,就需要通过 Hint 指定执行计划。Hint 是一种 SQL 语句注释,用于将指令传递给数据库优化器,使优化器生成指定的执行计划。一般情况下,优化器会为用户查询选择最佳的执行计划,不需要用户使用 Hint 指定。


下面来看一个简单的 SQL 在是否增加 Hint 的执行效率对比。该表的全量数据为 600 万行。虽然有围绕条件,但过滤条件不是很好,没有办法走索引。经过扫描,结果集也是 600 万,可以判定为全局扫描。

数据量:


obclient [oceanbase]> select count(1) from chat_req_uid_doctype_daily;

count(1)|

--------+

6097816

obclient [oceanbase]> select count(1) from chat_req_uid_doctype_daily where doctype in ('0', '1', '2', '3', '1100');

count(1)|

--------+

6025383


在不用 Hint 的情况下,初始 SQL 执行需要 6s,为了优化性能,我们为该 SQL 加入 Hint,执行效率提升至了 1s,效果较为显著。我们线网一般是把 OceanBase 作为一个 AP 类的场景去使用。所以说它的并发不是特别高。所以说在为了提升查询效率的情况下,我们一般会建议业务适当增加 Hint,因为 Hint 并不是越多越好,达到一定并行量后,性能提升效果会受限。


原 SQL(6s):


obclient [oceanbase]> select count(distinct uid) as uidcnts

from  chat_req_uid_doctype_daily

where doctype in ('0', '1', '2', '3', '1100');


添加 Hint 的 SQL(1s):


obclient [oceanbase]> select /*+ parallel(4) */

count(distinct uid) as uidcnts

from chat_req_uid_doctype_daily

where doctype in ('0', '1', '2', '3', '1100');

4、优化器版本对 SQL 的影响

不同版本的优化器,对 SQL 性能会产生不同的影响。举个例子,某 SQL 的条件列中是一个条件中的一个非相关子查询,最初我们使用 OceanBase 4.1.0 版本时,该 SQL 的执行时间为 0.3s,当我们升级为 OceanBase 4.2.1 版本后。执行时间退化到了 50s。


经过测试,发现问题在于条件列的子查询,如果把这个子查询换成子查询返回的固定日期,它的查询时间会恢复到 0.3s。这是由于数据库版本之间优化器的变化导致的,最终我们通过添加 Hint 并修改执行计划,使该 SQL 的执行效率重回 0.3s。


OceanBase 的优化器是基于规则优化和代价优化相结合,在一般情况下通过代价进行查询优化,可能会产生错误的执行计划,这时就需要通过 Hint 基于规则进行“修剪”实现优化。


目前 OceanBase 还在不断演进,其研发人员无法神通广大地覆盖所有 SQL 场景,还是要依赖于用户在生产场景不断发现问题、反馈问题,而官方的响应和改进也非常快速。期待 OceanBase 能够越做越好。


作者简介:


李梦嘉,科大讯飞技术中心数据库方向负责人。10 年以上 DBA 经验,对数据库的架构设计、优化、问题诊断、故障处理、数据恢复等有深刻地理解和实战经验。推动了讯飞数据库标准化、自动化运维、运维流程规范体系、高可用架构设计等建设。

2024-12-02 18:325434
用户头像
李冬梅 加V:busulishang4668

发布了 960 篇内容, 共 557.7 次阅读, 收获喜欢 1119 次。

关注

评论 1 条评论

发布
用户头像
感觉TiDB才是最合适的选择
2024-12-03 13:55 · 四川
回复
没有更多了
发现更多内容

疫情宅家4个月苦修,“不负年华“终斩阿里Java岗4面,分享下心路历程

Java 程序员 后端

直播阿里远程面(钉钉部门),三面坐上“直通车

Java 程序员 后端

看了这篇文章后,面试官再也不敢问你非结构化存储的原理了

Java 程序员 后端

知道这些面试技巧,让你的测试求职少走弯路

Java 程序员 后端

玩转互联网公司面试!快手、爱奇艺、小红书等14家互联网企业面经分享!

Java 程序员 后端

男默女泪!全网疯传的华为内部网络协议神仙笔记究竟有何魅力?

Java 程序员 后端

看一遍就理解:动态规划详解

Java 程序员 后端

看看AQS阻塞队列和条件队列

Java 程序员 后端

看透了 Redis 源码之后,我总结出来的几点心得

Java 程序员 后端

真是绝了!git标星19

Java 程序员 后端

牛逼,这2招,彻底让你和 null say 拜拜

Java 程序员 后端

用时17天完成4面阿里,已斩获offer,总结下个人面经心得体会

Java 程序员 后端

盘点郭德纲那些“催人奋进”的经典语录 -- 致被我们浪费的时光

Java 程序员 后端

盘点阿里巴巴 34 个牛逼 GitHub 项目

Java 程序员 后端

电商中的SPU与SKU

Java 程序员 后端

牛!阿里巴巴首推的《Java进阶必备宝典》,从理论到实战

Java 程序员 后端

看懂这篇文章就够了!什么是Redis缓存雪崩、缓存穿透和缓存击穿-五分钟统统搞定

Java 程序员 后端

真香!面试题库泄漏,在Github一夜爆火的面试题库,被各大厂要求直接下架

Java 程序员 后端

看完这套Java笔记,才明白笔者同时斩获7份大厂offer是有原因的!

Java 程序员 后端

看完这篇还不懂HashMap的扩容机制,那我要哭了~

Java 程序员 后端

知乎热问:国家何时整治程序员的高薪现象?太可怕了!

Java 程序员 后端

牛皮!华为工程师总结的Java生态知识体系面试必看笔记,太秀了

Java 程序员 后端

独角兽余额宝(Java现场面试48题):性能调优+索引+Mysql+缓存

Java 程序员 后端

生产环境JVM内存溢出案例分析

Java 程序员 后端

用好这几个技巧,解决Maven-Jar包冲突易如反掌

Java 程序员 后端

白嫖!白嫖!【尚学堂】高淇Java300集全套学习资料

Java 程序员 后端

盘点那些进行“网络编程”必须要知道的基础知识!

Java 程序员 后端

看阿里P8用5个核心技术和200个案例带你解密阿里亿级流量核心架构

Java 程序员 后端

知道这些线程池底层源码的知识,你也能和面试官扯半小时

Java 程序员 后端

用 Java 爬美女图片,这个厉害了!

Java 程序员 后端

直呼内行!阿里大佬离职带出内网专属“高并发系统设计”学习笔记

Java 程序员 后端

OceanBase在科大讯飞三大场景下的应用实践_数据库_李梦嘉_InfoQ精选文章