☰
信创环境下数据中台落地实践:麒麟+海光+OceanBase适配全记录
2026/10/17 5:28:37 网站建设 项目流程

1. 项目背景与价值:为什么AllData要啃信创这块硬骨头

做数据中台这行的人,这些年应该都感受到了一个明显趋势:信创不再是什么“将来时”,而是实打实的“现在时”。尤其对于政府、金融、能源这些行业客户,国产化替代已经从单点试点走向全面铺开。我接手AllData数据中台的信创落地,核心任务就是在麒麟操作系统、海光CPU、OceanBase数据库这套国产技术栈上,让整个中台跑得稳、跑得顺。

先说结论:这套组合拳打下来,踩坑不少,但最终效果超出预期。AllData数据中台包含了数据采集、数据开发、数据服务、数据治理等核心模块,之前跑在CentOS、MySQL、Oracle这套传统栈上,迁移到信创环境后,不是简单的“换个操作系统重装一遍”,而是从底层驱动到上层应用,从数据库方言到调度策略,全都得重新审视一遍。

为什么要做这件事?最直接的原因是客户侧的需求。很多单位采购时已经写明“必须支持国产化环境”,如果中台产品不支持,连投标资格都没有。更深层的原因是,国产化不只是政策驱动,海光CPU的性能在特定负载下并不输给x86主流芯片,OceanBase在分布式事务和扩展性上也有自己的优势。这意味着,只要适配得当,信创环境不背“性能差”的锅。

这篇分享,我尽量把一个数据中台在麒麟V10(基于CentOS生态兼容)+ 海光7000系列CPU + OceanBase 4.x的落地过程讲透,包括环境选型、编译适配、数据库迁移、性能调优、常见坑和排查思路。不管你是在做类似的中台项目,还是只是要把某个业务系统迁移到国产环境,这些经验应该都能复用。

2. 环境选型与方案设计:先想清楚再动手

2.1 为什么选定麒麟、海光、OceanBase这套组合

信创环境里,操作系统、芯片、数据库的可选项其实挺多的。操作系统有麒麟、统信UOS,芯片有海光、鲲鹏、飞腾,数据库有OceanBase、达梦、人大金仓、GaussDB等。我们最终选了麒麟V10 + 海光7000系列 + OceanBase,不是拍脑袋,而是经过了几轮权衡。

先说操作系统。麒麟V10的服务器版有两个分支:一个是基于CentOS的(兼容模式),一个是基于欧拉(openEuler)的。考虑到AllData中台涉及的组件多、依赖杂,我们选的是兼容CentOS 7.7的分支版本。为什么?因为很多开源组件(比如Hadoop生态、Flink、Spark)官方只做了CentOS/RHEL的二进制兼容测试,选兼容模式能最大程度减少“底层库不兼容”带来的问题。

再说芯片。海光7000系列是x86架构(指令集兼容),这在中台场景里是个巨大的优势。中台会跑大量Java服务、大数据组件,这些组件大多是x86编译的二进制包,海光CPU可以直接跑,不需要重新编译。对比之下,鲲鹏和飞腾是ARM架构,很多组件得交叉编译,工作量翻倍。所以,如果条件允许,“Intel/AMD的x86迁移到海光x86”几乎是成本最低的国产化路径。

最后是数据库。OceanBase我选了4.2.x社区版。选择原因有三:第一,OceanBase兼容MySQL协议,而AllData中台的元数据存储原本就是MySQL,迁移成本低;第二,OceanBase的分布式能力对于中台这种“多租户、海量元数据”的场景很匹配;第三,社区版免费,功能上对中台场景足够。

2.2 整体架构与部署拓扑设计

AllData数据中台本身是个微服务架构,包含以下核心服务:

  • 采集通道:基于Canal、Flume、DataX的数据同步
  • 计算引擎:Flink、Spark、Hive(Yarn调度)
  • 数据服务:统一SQL查询、API封装、数据权限
  • 治理能力:元数据管理、数据质量、数据血缘、数据标准

信创适配后的物理部署拓扑大致如下:

角色配置操作系统备注
中台应用节点 x3海光7390/16C/64G麒麟V10K8s worker + 微服务
大数据计算节点 x5海光7390/32C/128G麒麟V10Yarn NodeManager + HDFS DataNode
数据库节点 x3海光7390/16C/64G麒麟V10OceanBase OBServer
管理节点 x2海光7390/16C/64G麒麟V10K8s master + 中台管理端

这里说明一点:OceanBase虽然分布式架构,但AllData中台的元数据体量(几十GB级别)其实单节点也能扛住。我们上三节点主要是为了高可用,顺便演练一下分布式运维。

2.3 迁移策略:不是“重装”,而是“分五步走”

我的迁移策略总结为五个阶段:基线梳理、组件适配、数据迁移、性能调优、双跑验证。每个阶段里都有关键决策,下面拆开细讲。

3. 适配过程中的核心难点与关键操作

3.1 麒麟操作系统上的基础环境初始化

拿到海光服务器后,第一步不是装中台,而是把基础环境整干净。麒麟V10装在海光CPU上很顺利,但是有几个细节需要注意:

系统源替换。麒麟兼容CentOS版本默认的yum源是麒麟官方的,但有些包(比如某些开发库)还是从CentOS源拉更全。我们的做法是保留麒麟源为主,同时挂载一个CentOS 7.7的镜像源为备用。操作时要注意优先级,别让两个源打架。

内核参数调优。大数据组件对内核参数敏感,比如vm.max_map_count、net.core.somaxconn、file-max这些必须调。还有透明大页(THP),建议直接关闭,否则HBase、Flink的内存管理会被大页机制拖累。我在/etc/rc.local里加了关闭THP的命令:

echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag

如果内核里有/sys/kernel/mm/transparent_hugepage/目录,说明THP启用中,必须关。

JDK选择。中台本身是Java写的,大数据生态也要JDK。我们统一用的是OpenJDK 8(麒麟源里有),同时额外装了JDK 11给某些组件用(比如近新版的Flink要求JDK 11)。这里有个坑:麒麟默认的OpenJDK是java-1.8.0-openjdk,但版本号可能停留在8u232左右,而Flink 1.13+要求8u201以上,一般没问题,但如果你遇到“Unsupported class file major version”这类报错,就是JDK版本太旧。

3.2 海光CPU环境下的组件编译与运行适配

海光虽然是x86兼容,但也不是完全无脑跑。我遇到的实际问题有三个:

指令集差异。海光7000系列支持AVX2、AVX512(部分型号),但某些老版本的C++编译组件(比如PyTorch、OpenBLAS)在编译时默认的-march参数不匹配,会导致非法指令错误。解决方案是:重新编译时显式指定-march=znver2或者保守一点-march=x86-64-v2。但好消息是,我们中台用到的组件里,只有一小部分C/C++扩展需要重新编译,纯Java和Go的组件基本没这个问题。

BIOS与NUMA。海光CPU是典型的NUMA架构,多路环境下,如果BIOS里NUMA没开或者内存插法不对,性能会大打折扣。我在部署前专门检查了numactl --hardware的输出,确认node间距和CPU绑定正常。对于Flink和Yarn这类计算组件,建议开启NUMA感知调度,宁可牺牲一点调度灵活性,也要保证内存访问带宽。

Hadoop生态验证。HDFS的DataNode和Yarn的NodeManager在麒麟+海光上跑,目前没有遇到任何兼容性问题。HDFS的libhdfs原生库依然能用,但某些老版本(Hadoop 2.x)在编译时检测CPU特性可能会报“**Illegal instruction (core dumped)”。如果遇到,找到hadoop安装目录下的lib/native/libhadoop.so,用ldd查一下依赖,基本能定位是不是底层库的指令集问题。

3.3 OceanBase替换MySQL:DDL差异与SQL方言改造

这是整个项目里工作量最大、也是最容易出问题的地方。

AllData中台原本的元数据库是MySQL 5.7,里面有几百张表,大部分是建表语句、索引、外键。OceanBase 4.x虽然兼容MySQL协议,但有两个问题我必须提醒:

第一,DDL语法不是100%兼容。OceanBase的建表语句大体兼容MySQL,但有一些细节差异:

  • 不支持ENGINE=InnoDB这种显式指定(OceanBase有自己的存储引擎概念,不需要也不能指定)
  • 字段注释、表注释语法兼容
  • AUTO_INCREMENT支持,但必须是主键或唯一键的一部分,这个和MySQL一致
  • DATETIME默认值方面,DEFAULT CURRENT_TIMESTAMP基本兼容

我写了一个自动化脚本,把原MySQL的SHOW CREATE TABLE结果批量导出,然后做正则替换,去掉ENGINE=、ROW_FORMAT=这些OceanBase不认识的参数,再逐表导入。整个过程跑下来,几百张表没出大错。

第二,SQL函数的兼容性差异。中台代码里有不少MySQL专属函数或写法,比如:

  • GROUP_CONCAT在OceanBase支持,但返回长度限制需要配置max_group_concat_len
  • 分页查询LIMIT offset, count兼容没问题
  • 某些DATE_FORMAT格式化符号有细微差异
  • JSON_EXTRACT在OceanBase中需要确认版本是否支持

我们的策略是:先把中台的DAO层SQL全部过一遍,找出所有不走普通SELECT/INSERT/UPDATE/DELETE的语句,单独建一个“方言适配清单”,手动改写不兼容的部分。

3.4 中台应用层JDBC驱动切换

中台服务和OceanBase之间用的是JDBC。很多人以为OceanBase兼容MySQL,直接拿MySQL JDBC驱动连就行——确实是,但没那么简单。

OceanBase 4.x官方推荐的驱动有两种:一个是用MySQL Connector/J(需指定useSSL=false和allowMultiQueries=true等参数),另一个是OceanBase自己的驱动oceanbase-client。我建议直接用OceanBase官方驱动,因为它在协议兼容和事务处理上做了更多适配。

我在中台的application.yml里做了这样的配置:

spring: datasource: url: jdbc:oceanbase://127.0.0.1:2881/all_data?useUnicode=true&characterEncoding=utf8&useSSL=false driver-class-name: com.oceanbase.jdbc.Driver username: all_data_user password: xxxxxx

注意:OceanBase通过OBProxy访问时,监听端口默认是2883;直接连接OBServer时,端口是2881。我们生产环境用了OBProxy做接入,所以URL里用的2883。如果是直连模式,端口要改成2881。

3.5 大数据组件对接OceanBase:数据同步与实时采集

AllData中台里的数据采集模块支持从业务库抽数据到数仓,其中有一类任务是把数据从其他MySQL库同步到中台的OceanBase存储。这块我们用了DataX和Canal两条链路。

DataX同步。DataX官方支持MySQL Reader/Writer,对OceanBase来说,Writer可以复用MySQL Writer,但有几个参数要调。我用的是一个自定义的DataX插件,核心配置如下:

{ "job": { "content": [ { "writer": { "name": "oceanbasewriter", "parameter": { "username": "all_data_writer", "password": "xxxx", "column": ["*"], "preSql": [], "connection": [ { "jdbcUrl": "jdbc:oceanbase://192.168.1.10:2883/all_data", "table": ["target_table"] } ] } } } ] } }

DataX同步1千万行数据到OceanBase,速度在5万行/秒左右(并行度调高后),比之前MySQL 5.7的写入性能还要好一点,这可能是因为OceanBase的并行写入能力确实强。

Canal实时同步。Canal要把binlog解析后的数据写到OceanBase时,我遇到过一个坑:Canal默认的parse线程会读取MySQL binlog的GTID模式,而OceanBase作为目标端时,它是通过JDBC批量写入的,和源端binlog没关系。所以问题不是同步失败,而是Canal在解析源端MySQL的binlog时,如果源端开了GTID,而Canal配置里没开gtidEnable,就会不断报错。解决办法是在Canal实例配置里加上:

canal.instance.gtid=false canal.instance.mysql.slaveId=12345

4. 项目实施全记录:从零开始的真实落地过程

4.1 阶段一:基线盘点与兼容性预研(第1-2周)

动手之前,我花了两周时间做“基线盘点”。这一步很多人会跳过,但我建议一定不要省。具体包括三个动作:

  1. 组件清单建立。把AllData中台涉及的所有组件列出来,逐个查官方文档或社区Issue,确认其是否声明支持ARM/x86、CentOS/RHEL、特定CPU指令集。我们的组件清单大概有六十多项,一部分是自研微服务,一部分是开源中间件。

  2. JDK与基础库版本统一。大数据组件之间依赖经常冲突,比如Hive要guava14,Spark要guava27。我提前定好一个“依赖基线版本表”,后续所有组件的依赖都朝这个表对齐。遇到确实无法兼容的,单独封装隔离。

  3. 网络端口与安全策略梳理。国产化环境下客户的安全扫描特别严格,我把中台涉及的所有端口、协议都列成一张表,提前交给客户的安全团队确认。

4.2 阶段二:底层系统与基础组件部署(第3-4周)

麒麟+海光服务器的RAID和系统部署不在我代码层面范围,但基础组件我来弄。这个阶段我没急着装大数据组件,而是先装了两个“前置依赖”:Docker(中台部分组件需要用容器化)和K8s集群。麒麟V10的Docker安装用官方源里的docker-ce包,没问题;但容器运行时,我建议用containerd而不是Docker daemon,因为K8s用containerd更稳。

然后在K8s上部署了中台的基础服务:Nacos(注册中心)、Gateway(网关)、Redis、MinIO(对象存储)。这些组件都是Java或Go的,在海光x86上跑得很平稳,几乎没有适配工作。

4.3 阶段三:OceanBase集群安装与初始化(第5-6周)

OceanBase的部署比MySQL复杂一个量级,因为它天生是分布式形态。我的节点规划是3台OBServer + 1台OBProxy(也可以每台都部署OBProxy做负载均衡)。

安装OceanBase 4.2.x我用了官方提供的obd(OceanBase Deployer)工具,可以自动检测目标机并推送rpm包。关键配置参数如下:

oceanbase-ce: servers: - 192.168.1.11 - 192.168.1.12 - 192.168.1.13 global: devname: eth0 memory_limit: 40G system_memory: 10G datafile_size: 50G log_disk_size: 60G cpu_count: 16 production_mode: true

这里有几个参数必须注意:

  • memory_limit需要预留物理内存给OS和其他进程,不然会遇到“Cannot allocate memory”的坑
  • datafile_size不能大于磁盘剩余空间,否则初始化会失败
  • production_mode生产模式会启动更严谨的参数校验,建议一开始就打开

初始化完成后,用obclient连接验证:

obclient -h192.168.1.11 -P2881 -uroot -p

能进去执行SQL,集群就起来了。

4.4 阶段四:AllData中台服务迁移与注册对接(第7-9周)

中台微服务本身用的是Spring Boot,迁移到K8s之后,关键点在于配置驱动化。把原先写在application.yml里的数据库地址、Redis地址、Kafka地址等全部抽象到K8s的ConfigMap里,让服务在启动时从环境变量读取。这样做的好处是:万一OceanBase的OBProxy地址变了,不用重新构建镜像,改个ConfigMap重启服务就行。

在服务对接OceanBase时,我额外做了一层“轻量级DAO适配”:在中台的Mapper层(用的是MyBatis)用@Profile("oceanbase")注解区分MySQL方言和OceanBase方言。这样同一个Mapper接口,可以在不同环境跑不同SQL,不用改业务代码。这个做法很关键,因为客户后来要求我们在测试环境保留MySQL(方便对比),生产切OceanBase,只有分开配置才能两边都跑。

4.5 阶段五:数据迁移与全链路验证(第10-12周)

数据迁移是客户最关心的一件事,毕竟影响的是“真金白银”。我们的方式是用DataX做全量迁移,然后用Canal做增量同步。全量迁移跑了大概3天,总共迁移了2TB左右的业务数据,校验行数完全一致(校验方式是逐表COUNT(*)加抽样对比)。

全量结束后,开启Canal增量同步,追平到迁移开始的时间点之后,再切流量到中台新环境。这个“双跑”阶段持续了两周,一边跑新中台,一边旧中台继续运行,每天对比两侧跑出的报表结果是否一致。

验证通过后,旧环境下线。整个切换过程对最终用户是透明的,没有出现“业务中断”“数据对不上”的投诉。

5. 一路上踩过的坑与排查方法

5.1 海光CPU上的“Illegal instruction”问题

如果你用海光跑某些老版本的大数据组件(尤其是Hadoop 2.x、Spark 2.x),然后突然出现进程crash,日志只有一行Illegal instruction (core dumped),大概率是CPU指令集不兼容。

排查方法:用gdb挂住core dump,看crash的调用栈,定位到具体so库;然后用objdump查看该so的动态依赖里有没有对SSE/AVX这类指令集的强依赖。解决方式有两个:换更新版本(官方做了更多x86兼容优化),或者重新编译该原生库并指定保守的-march参数。

5.2 OceanBase初始化报“Nested table capacity exceeded”

我遇到过OceanBase在执行批量写入时报Nested table capacity exceeded,这是内存中嵌套表容量超限导致的。解决方法是调大内存参数,或者分批次写入。这个错误在MySQL下永远不会出现,算是OceanBase特有的一个限制。

5.3 麒麟V10上无法启动某些systemd服务

麒麟V10基于CentOS的systemd版本是219(较老),新版本软件(如containerd)可能默认依赖systemd的某些新特性。如果你在麒麟上启动containerd报“Unit containerd.service entered failed state”,别急着重装,先查systemctl status containerd -l的输出,一般能看到“Unknown lvalue 'TasksMax' in section 'Service'”之类的提示。解决方法是:编辑/etc/systemd/system/containerd.service,把不认识的参数注释掉,然后systemctl daemon-reload && systemctl restart containerd。

5.4 OceanBase的时区与MySQL不一致导致调度任务延迟

中台里的定时调度(比如每天凌晨跑数)是依赖数据库时间判断的。原来的MySQL用的CST时区(UTC+8),而OceanBase默认是+08:00,按理一致。但注意:OceanBase的TIMESTAMP类型底层存的是UTC值,读出来时会按session时区转换。如果客户端没设置time_zone,默认可能是+00:00,导致所有查询结果少了8小时。

解决方法是:在建立连接时,JDBC URL里加个参数:

url: jdbc:oceanbase://...?serverTimezone=Asia/Shanghai

或者在每个应用启动时执行一次SQL:

SET time_zone = '+08:00';

5.5 常见问题速查表

现象可能原因处理建议
组件启动时Illegal instructionCPU指令集不兼容更新版本或重新编译原生库,指定-march=x86-64-v2
OceanBase连接超时OBProxy未配置连接池大小调大client_max_connections
DataX写入OceanBase很慢batchSize过小调大batchSize到10000左右,开多通道
Canal一直断连重连源端MySQL开了GTID但Canal未开启canal.instance.gtid=false
麒麟yum源安装包不全麒麟源包缺失挂载CentOS 7.7镜像源,注意优先级

6. 性能对比与调优实录:不比不知道

项目尾声,我做了一轮“新旧环境性能对比”,用客户真实跑批任务来验证。结果比较有意思:

任务类型原环境(CentOS+MySQL+物理机)新环境(麒麟+海光+OceanBase)结论
日批跑数(T+1)2小时10分1小时48分新环境略快
即席查询(单表过滤)1.8秒1.6秒持平略快
数据同步(1000万行)4分30秒3分50秒快15%
并发接口调用(100并发)320 QPS340 QPS略优

这个结果说明什么?海光CPU的单核性能确实比同级别Intel弱一些,但OceanBase的并行执行和存储引擎在某些场景下弥补了CPU劣势。更重要的是,中台本身是IO密集+网络密集的分布式架构,单机CPU性能并不是瓶颈。

性能调优方面,我做了三件事:

  1. 调整JVM堆大小。把中台微服务的JVM堆从默认的1/4物理内存调到了1/2物理内存(同时设置-XX:MaxRAMPercentage=70.0),减少了GC停顿。

  2. 开启OceanBase的并行查询。在OceanBase里设置parallel_servers_target,让大查询自动走并行执行计划。注意要针对具体大表加PARALLEL(4)hint,否则默认并行度可能不生效。

  3. HDFS的EC(Erasure Coding)容错策略。原来HDFS副本数3的存储开销太大,改成EC RS-6-3模式,存储效率提升50%,读写性能略有下降但中台场景可接受。

7. 信创适配中的一些关键经验与后续扩展方向

折腾完这个项目,回头看,有几条经验特别想分享给同行。

第一条:x86路线的信创,不要自己吓自己。海光CPU对x86软件生态的兼容性极好,大多数Java、Go、Python组件直接跑,真正要动手改的地方不多。项目里我大概只花了两到三周的精力在“纯粹的信创适配”上,其余时间都在处理中台自身的业务迁移问题。

第二条:数据库替换是核心工作量所在。如果原来的中台深度绑定MySQL的存储过程、自定义函数、特定JSON处理,那么改成OceanBase(或其他分布式数据库)一定会踩到方言墙。唯一的缓解办法是:提前把数据库访问层抽象出来,让SQL尽量标准化,避免用太高级的数据库特性。这一点我希望做中台产品的同行能记住——今天你不抽象,明天信创环境会教你抽象。

第三条:国产化不等于性能打折。我在项目交付时给客户的数据是实打实的对比报告。在合理的架构设计和参数调优下,国产化环境在某些维度反而能超越旧环境。关键是不要拿“新环境”和“旧环境的巅峰状态”比较,而是沉下心做一轮系统性压测和调优。

至于后续扩展方向,目前我计划做两件事:一是把中台的计算引擎从纯Hadoop生态往Flink+Iceberg方向演进,这样在信创环境下存储和计算分离更彻底,OceanBase只做数据服务层;二是把中台的数据质量模块做得更智能化,自动通过OceanBase的分布式能力做数据比对和校验。信创不只是“换个底座”,底座变了,上面的应用也要顺势升级。

8. 写在最后:我就说一句心里话

干完这个项目,我最深的体会是:信创落地没有想象中那么可怕,但也没有捷径。每个组件都得认认真真地过一遍兼容性验证,每个坑都得一笔一笔地记下来。如果你现在正要做同类的事情,我可以给你的建议是——先把基础环境的兼容性验证做到位,再去碰业务迁移。底层栈不稳,上层业务全是空中楼阁。另一个建议是,所有SQL写标准SQL,所有连接串走配置中心,所有组件版本锁基线,这三件事做到,你的信创项目就成功了一半。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询