我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

异构算力与国产数据库:技术选型与性能优化实战

异构算力与国产数据库:技术选型与性能优化实战 开头干了快十年基础架构这两年最深的感受是技术选型这件事已经不是简单的“哪个好用选哪个”而是“哪个能在约束条件下最稳地跑起来”。尤其是信创项目一上来就是“异构算力 国产数据库”的组合拳——底层CPU可能是x86、鲲鹏、飞腾混着来数据库要从海外商业产品换成国产集中式或分布式产品上层应用还得保持原有功能不变、性能不滑坡。这篇文章不聊虚的就围绕“异构算力国产数据库”这个组合把我在多个信创项目中实际用到的技术选型思路、适配踩坑过程、性能优化方法一次讲透适合正在做或准备做国产化替换的架构师、DBA、后端研发同学参考。1. 异构算力与国产数据库的组合逻辑1.1 先搞懂“异构”到底是异构在哪很多人一听“异构算力”第一反应是“CPUGPU”但放到信创语境下异构的含义要宽得多。我见过的一个典型生产环境长这样机房里既有海光x86架构的服务器在跑业务系统又有鲲鹏ARM架构的服务器在跑大数据组件还配了少量国产加速卡做AI推理底层存储则是分布式软件定义存储。这就是典型的“异构算力”——不是某一种芯片撑全场而是多种指令集架构、多种算力类型混布在同一套业务体系里。为什么会出现这种局面原因不复杂一是信创名录里的芯片本身就有多路可选x86生态成熟但供货周期长ARM架构的单核算力密度有优势项目工期紧的时候哪个能到货就用哪个二是业务系统负载特征差异很大交易类系统吃单核主频并发查询类系统吃多核并行AI推理场景则需要向量指令和专用加速单元。单一架构很难在所有场景里都拿最优解于是异构混布成为必然。但异构带来的麻烦也很直接不同指令集对编译产物、运行时行为、数据库内部执行计划的影响是完全不同的。同一个SQL在x86上走哈希连接是3毫秒到了ARM上可能因为内存带宽特性不同优化器选错了连接顺序直接放大到30毫秒。这种差异不是玄学是芯片微架构、缓存层级、内存控制器通道数、NUMA拓扑共同作用的结果。1.2 国产数据库在异构环境里的特殊角色国产数据库和开源数据库、商业数据库最大的不同在于它不只是“存数据的软件”而是整个信创技术栈里的“承重墙”。应用要改中间件要改底层芯片也在变数据库作为数据落地的核心必须同时兼容上层的SQL语义和下层的硬件差异。目前国产数据库大致分两派一派是集中式事务型数据库架构上兼容传统商业数据库的语法和交互协议主打强一致、高可靠适合承载核心交易系统、账务系统另一派是分布式数据库底层存储与计算分离、多副本强一致适合承载海量数据、高并发查询的互联网化业务。选哪一派不完全取决于性能更多取决于业务改造的容忍度和运维团队的能力边界——选集中式应用改造量相对小但未来扩展性受限选分布式扩展性拉满但SQL语法限制、分布式事务开销、运维复杂度都会显著上升。在异构算力环境下国产数据库还多了一层“跨芯片适配”的要求。同一个数据库集群可能一半节点跑在x86上一半节点跑在ARM上这就要求数据库产品本身具备多架构构建能力同时在节点间做性能调平时不能简单按“核数平均分配”而要按实测算力权重调度。提示如果你所在的团队第一次做信创替换不要一上来就追求“一步到位上分布式”。很多核心业务系统其实数据量不大但事务一致性要求极高集中式国产数据库反而更容易平滑切换。1.3 架构师视角选型不只看性能榜单我做选型的时候习惯先列一个“约束条件清单”而不是直接看跑分。约束条件包括几类政策与目录约束核心芯片、操作系统、数据库是否都在采购名录范围内版本是否齐备。硬件供应约束项目要求的交付时间内哪些架构的服务器能稳定供货有没有存储和网络的配套保障。应用兼容性约束现有应用是否为纯Java体系是否依赖特定的数据库私有SQL语法有没有存储过程、自定义函数等深度绑定。团队能力约束现有DBA团队熟悉什么类型的数据库运维是否能接受分布式的分片键设计、全局索引维护等新技能。跑分、TPCC、TPCH这些指标当然也要看但它们是“理想条件下的参考上限”不是“请购依据”。真实项目里最稳的组合往往不是单项跑分最高的组合而是所有约束条件都满足、团队已有技能覆盖度最高的组合。2. 技术选型的关键决策点与方案比选2.1 算力侧的选型不唯芯片论看业务负载算力选型的核心是先把业务负载按特征分成两类第一类叫“延迟敏感型”典型代表是联机交易、账务处理、门户鉴权。这类负载的单笔请求计算量不大但要求响应时间稳定通常几十毫秒到一两百毫秒就得返回不能接受抖动。对芯片的要求是单核性能和内存访问延迟要优秀。在国产芯片里某些x86路线的海光、兆芯处理器在单核主频和缓存延迟上更接近原厂水平适合这类业务。第二类叫“吞吐消耗型”典型代表是数据分析、批量跑批、日志检索、AI模型推理。这类负载可以接受几百毫秒甚至秒级延迟但要求在单位时间内处理尽可能多的任务。对芯片的要求是多核并行能力、内存带宽、向量指令集支持。ARM架构的鲲鹏、飞腾在多核扩展性上有天然优势搭配高带宽内存跑这类业务很合适。实际项目中我还做过一种折中方案用同一款数据库集群把交易型节点部署在x86服务器上把分析型节点部署在ARM服务器上通过数据库的读写分离或副本调度能力把两类负载物理隔离到不同算力池。这样一来x86池保证了交易链路的低延迟ARM池保证了分析查询的高吞吐互相不干扰。2.2 数据库侧的选型集中式与分布式的取舍前面提到集中式和分布式这里给出我常用的几个判断标准判断维度选集中式选分布式数据规模单表亿级以内总体数据量百GB到数TB单表十亿级以上总体数据量数十TB以上事务特征强事务、多表关联、复杂约束简单主键查询为主分布式事务极少扩展方式垂直扩容换更强主机为主水平扩节点为主运维能力DBA团队熟悉传统数据库能接受半自动化运维有自动化运维平台能接受更复杂的集群管理改造预算低希望应用几乎不动高愿意为扩展性重构数据访问层这个表不是死教条但大方向不会错。我踩过一个项目某个业务系统实际数据量只有十几GB但决策层听说“分布式能无限扩展”就选了一款分布式数据库。结果上线后运维团队天天被分片键选择、全局二级索引、跨节点JOIN这些问题折磨完全得不偿失。回过头看当时用一款主打高兼容的集中式国产库一个月的改造量就能搞定。反过来我也见过数据量上百TB的日志分析平台硬要用单机集中式数据库最后只能不停地清数据保空间查询窗口越缩越短。选型不是追求技术“最先进”而是匹配业务“最合适”。2.3 选型验证跑一个“最小可用原型”再决策我的经验是选型阶段所有PPT和参数对比都只能作为初筛真正决策靠“最小可用原型”验证。做法如下第一步挑出业务中SQL复杂度排名前20的语句加上数据模型中最核心的5张表作为验证样本。第二步在目标算力服务器上安装候选数据库产品至少两款导入与生产数据特征相似的数据集。第三步逐一执行样本SQL记录执行计划、响应时间、资源消耗CPU、内存、IO。第四步观察硬件指标是否均衡——比如某个SQL把单核跑满但其他核闲着说明优化器并行度设计有问题内存持续上涨不回落说明缓存管理存在隐患。做完这个原型验证基本就能看出哪款数据库在这个特定算力环境下更顺手。注意不要拿厂商的测试报告代替自己跑因为厂商调优过的环境参数和生产环境差异太大参考价值有限。3. 异构算力下的数据库部署与参数调优实战3.1 部署拓扑同集群、跨架构的注意事项如果条件允许我建议异构算力环境下的数据库集群尽量做到“同架构节点划分集群”也就是不要让同一个数据分片同时落在x86和ARM节点上。原因很简单数据库的Raft或Paxos共识协议对网络延迟和节点性能一致性有隐含假设异构节点混在同一分片里慢节点会拖慢整个分片的提交延迟反而发挥不出异构算力的优势。更好的做法是按业务单元拆库拆集群核心交易库跑纯x86集群分析查询库跑纯ARM集群中间用数据同步工具做准实时同步。如果非要一套集群跨架构那就在资源调度上做权重隔离让高负载业务只调度到算力强的架构节点上同时关闭跨架构的自动迁移。网络规划上数据库节点的网络延迟建议控制在1毫秒以内存储网络与业务网络分离。3.2 操作系统和硬件层的基准调优数据库部署前的操作系统层调优比数据库参数调优更容易被忽视但收益往往更明显。我每次在新环境装国产数据库都会按下面顺序做一轮基础设置首先是BIOS和固件层。确认CPU开启最大性能模式关闭节能降频选项这对延迟敏感型业务很关键。开启足够的内存通道尽量插满所有内存通道而不是集中插在部分通道上保证内存带宽满载。如果服务器支持NUMA就要做NUMA感知配置——数据库实例尽量绑死在某个NUMA节点的CPU和内存上避免跨NUMA访问的远程内存延迟。然后是操作系统层。透明大页THP建议关闭改用标准大页或让数据库自行管理内存因为THP在内存回收时的卡顿对数据库极不友好。IO调度器建议改成none或noop交给底层存储设备自行调度。vm.swappiness建议设置为10以下避免系统过早地把数据库缓存页换出到磁盘。注意这些设置在不同架构上的表现有差异。我在ARM架构上遇到过THP开启时数据库性能抖动非常明显的情况关闭后立即稳定x86架构上虽然也有问题但没有这么夸张。换架构后不要沿用旧经验重新做一轮基准测试最稳。3.3 数据库参数调优的几个重点方向国产数据库产品大多从内核层面支持参数调优但默认参数往往偏保守适合“保证不出错”不适合“跑出性能”。我调优时重点看这几个方向3.3.1 缓冲池与内存划分数据库的缓冲池大小直接决定热数据能有多少留在内存里。原则是在给操作系统留足余量的前提下一般至少留16GB或总内存的20%给OS和文件缓存把尽可能多的内存分给缓冲池。我在一个128GB内存的ARM服务器上把缓冲池从默认的8GB调到96GBTPC-H查询性能提升超过两倍。不过要警惕“内存过分配置”。特别是Java写的数据库部分国产库的内核有Java组件内存的堆内、堆外、直接内存都需要单独配置某块配太大可能导致整机OOM。改内存参数时务必小步调整观察24小时稳定再继续。3.3.2 并行度参数分析型查询场景很依赖并行执行。参数上主要的开关有两个一个是CPU并行度决定单个查询最多能用几个CPU核另一个是跨节点并行度决定一个查询可以在多少个节点上同时跑。在x86架构上我通常把CPU并行度设置为物理核数的一半留出余量给并发事务在ARM架构上由于单核性能相对弱可以适当增加并行度但要小心内存带宽成为瓶颈。调优的方法是固定数据集从并行度1开始逐步翻倍观测查询响应时间和系统吞吐的拐点一般会出现“并行度达到某值后性能不升反降”的现象拐点前一个值就是当前环境的最优值。3.3.3 IO路径参数数据库的日志刷盘策略是IO调优的关键。默认的“每次提交都刷盘”策略最安全但高并发下会成为瓶颈。可选方案是“批量刷盘”将多个提交聚合成一次刷盘能大幅提升吞吐代价是极端断电场景可能丢极少量的已提交事务。在信创项目里如果底层存储本身有电池保护或双副本强一致我会选择批量刷盘模式实测TPS能提升约30%~50%。3.4 性能测试方法先定基线再谈优化调优的每一步都要有数据支撑。我习惯做一个“三级测试法”第一级是硬件基准测试确认整机的CPU、内存、存储性能是否达到预期并把结果作为后续对比的物理上限。第二级是数据库基准测试用标准测试工具跑一套固定的读多写少负载记录得到这条基线前的所有参数配置后续每次改动只允许动一个参数重新跑测试看结果。第三级是业务仿真测试用生产脱敏数据回放业务高峰时段的流量验证整个集群在真实负载下的端到端表现。每次跑测试的时候都记录一个“测试快照”包含参数配置全文、服务器规格信息、网络拓扑、测试工具版本、并发线程数、数据量大小。没有快照的性能测试等于白测因为以后不会知道这个结果是怎么跑出来的。这点非常重要我因为没记录快照曾经出现过调优两个月后发现改错一个参数、全部重跑的情况。4. 应用侧适配与SQL性能优化实操4.1 异构切换后最常踩的SQL兼容性坑换了国产数据库之后应用侧最常见的问题不是“跑不动”而是“跑不了”。SQL语法兼容性是个大坑尤其是从商业数据库迁移过来的应用。我踩过的高频问题有几类第一类是分页查询语法差异。很多商业数据库支持专用的分页扩展语法而国产数据库部分支持MySQL风格的分页、部分支持PostgreSQL风格迁移时如果不改直接语法报错。第二类是字符串拼接风格差异。某些商用库用双竖线拼接字符串而国产库可能只支持concat函数简单替换即可但批量替换时容易漏。第三类是隐式类型转换的差异。国产库普遍对隐式转换更严格比如字符串列和数字列比较时如果字符串列上有索引旧库可能走索引新库会走全表扫描性能瞬间掉一个量级。处理这些问题我建议在迁移前做一个“SQL静态扫描”把应用里的所有SQL提取出来在国产库上逐一执行并用EXPLAIN看执行计划。扫描工作看起来很笨重但能提前暴露80%以上的兼容性问题比上线后炸了再排查效率高得多。4.2 让SQL走对索引异构算力下的优化器差异同样的SQL在x86和ARM两个架构上的执行计划可能完全不同一个走索引快速返回一个全表扫描慢到不可接受。原因在于国产数据库的优化器从内核层面通过代价模型估算执行成本而代价模型严重依赖底层硬件参数——CPU的整数运算速度、内存的随机访问延迟、磁盘IO的传输带宽。这些参数在不同架构上有明显差异优化器等不了那么准。所以跨架构切换后必须重新分析慢查询重建统计信息。重点是重新执行全库ANALYZE收集更新后的统计信息让优化器能看到真实的数据分布。对高频查询逐个EXPLAIN重点看有没有全表扫描和索引失效的迹象。对索引设计做一次全面审视——特别是“过宽索引”问题在ARM架构下因为内存带宽差异多列复合索引的效率可能明显低于x86环境拆成窄索引反而更快。我印象最深的一个案例某个查询在x86环境跑200毫秒迁移到ARM环境后跑到了6秒。排查后发现优化器在ARM环境下放弃了一个核心列的等值索引改选了另一个选择性极差的索引。解决办法很简单——删除低选择性索引强制走正确索引查询恢复到300毫秒。性能优化有时候就是“做减法”。4.3 分页、聚合、连接三类查询的手工改写技巧除了依赖优化器手工改SQL也是提升异构算力下查询性能的常用手段。关于分页查询深分页是性能杀手一个“limit 100000, 20”的查询要扫描前面十万行才能返回20行结果。优化方法是改成“基于上一页最大ID的游标分页”——应用记录上一页最后一条数据的ID下一页用where id 上一页ID配合limit 20取数。这个改写对国产数据库效果极好因为避免了大量无效扫描。关于聚合查询多个小聚合可以合并成一次扫描减少对表的重复读取。比如统计多个维度的数据原本可能要扫五次表合并成一次扫描后用case when在查询中做多条件聚合只读一遍数据耗时几乎只取决于表本身的大小。关于连接查询小表驱动大表通常是好策略但在异构环境下要关注被驱动表是否有匹配索引。没有索引的连接会触发嵌套循环全扫描这种查询在ARM架构下因为主频相对低会放大耗时。最有效的办法是给连接列建索引或者把部分连接场景拆成两步查询先缩小结果集再关联。心得SQL改写不是一步到位的每改一次都要看执行计划。我在项目里形成了一条规律——任何SQL改动必须跑一次前后对比。执行计划不变就说明没改到点子上改了执行计划但耗时没降下来就说明改错了方向。4.4 利用分区表与并行查询消化异构算力分区表在国产数据库里是一个“低投入高回报”的优化手段。尤其是按时间分区的表对典型的交易流水、日志记录类业务非常友好。查询时通过分区裁剪只扫描相关分区而不是全表可以指数级降低IO量。我经手的一个月度流水报表原来全表扫描要90秒按月份分区后只扫一个月的数据耗时降到4秒。分区表设计要注意分区键必须和主要查询条件匹配否则裁剪不了分区数量不要过于碎片化每个分区数据量尽量均匀跨分区查询时如果SQL没用上分区键性能可能反而比普通表更差。配合分区并行查询是另一个利器。在一个64核的ARM服务器上跑一个百万级分区的聚合查询开启8路并行响应时间可以从40秒降到5秒。但要设好并行度上限否则并发线程过多会把内存带宽打满拖垮整个节点上的其他业务。5. 迁移实施与数据一致性保障5.1 迁移方案的三种路径及适用场景国产数据库替换迁移我常用的路径有三类第一类是逻辑导出导入。用数据库自带的迁移工具或第三方数据同步工具把数据和对象定义从源库导出来再导入到目标库。适合数据量小、停机窗口长的系统。优点是对源端影响小缺点是迁移过程慢大表导入耗时不可控。第二类是双写同步过渡。应用改造为同时写入新旧两套库通过数据同步工具保持双库数据一致观察一段时间确认目标库稳定后再把读流量切换到新库最后下线旧库。适合不允许长时间停机的核心业务但应用要同时适配两套库的语法改造量比较大。第三类是备份恢复式迁移。如果目标数据库支持从源库的备份文件直接恢复这是效率最高的方式。但通常限制于同品牌或生态兼容的数据库之间跨厂商场景不太适用。5.2 避免数据不一致的几个关键动作数据迁移最容易出的问题不是“丢数据”而是“不一致”——源库里有的数据迁移过去之后逻辑上不对等。我总结了几条硬经验第一迁移前做“源端数据体检”查有没有主键冲突、外键悬挂、孤儿数据、编码不合法等脏数据。脏数据一定要在源端清理完再迁移否则到目标库排错非常痛苦。第二迁移过程中要记录每一个批次的迁移时间、行数、校验和出了问题能定位是哪个批次、哪张表、哪一行。第三迁移完成后做全量校验不能只比对行数——行数一致不代表数据一致必须抽样比对字段值重点覆盖边界值、空值、特殊字符、浮点数精度。我遇到过一个案例迁移完成后行数完全一致但业务跑了一天发现金额对不上。排查后发现源库的一个金额字段是字符型存着100.00目标库自动转成了数值型100本来没问题但某些行存的是1,000.00带千分位转换时解析错误。这类问题靠行数校验根本发现不了只能靠字段级抽样比对。5.3 回滚方案迁移必须有退路任何迁移都要设计回滚方案信创项目尤其如此。我的做法是保留源库环境直到新库稳定运行至少一个业务周期通常是两到四周期间源库只读不写确保随时可以切回。同时回滚方案里要考虑数据反向同步的问题。切换后新库产生的新数据如果回滚到源库这些增量数据需要能回到源库。所以稳妥的做法是切换后不立即停掉数据同步任务而是改为反向同步直到确认无需回滚再彻底断开。5.4 迁移工具选型与性能经验市面上的迁移工具有几类数据库厂商自带的迁移工具、第三方商业迁移工具、开源的数据同步框架。我的经验是第一选择是用目标数据库厂商自带的迁移工具它们对目标端的优化和兼容性问题处理最到位第二选择是成熟的开源同步框架灵活度高但需要自己处理很多细节不建议用通用ETL工具直接做全量迁移因为大批量插入的性能和事务控制通常不如专业迁移工具。全量迁移阶段性能瓶颈往往在目标端的写入能力。优化手段包括迁移期间关闭目标库的自动统计信息收集导入完成后统一收集调整批量提交的大小通常每个事务包含几千行数据的批量提交比单行提交快数十倍临时关闭约束和索引导入完再重建避免每插入一行都维护索引结构。6. 上线后的压测、监控与持续优化6.1 压力测试要压到什么程度才算合格很多项目上线前做了压测但压测方法不对。最常见的问题是压测工具生成的请求太规整和真实业务差距太大压测时间太短只跑几分钟看不出内存泄漏和慢SQL累积问题。我建议压测至少做到四点一是压测模型用真实业务日志回放而不是用压测工具自带的随机请求。我用生产网关的脱敏访问日志回放工具做压测效果明显比合成流量真实得多。二是压测时间要覆盖一个完整业务周期至少持续4小时以上期间包括数据同步任务、定时批量任务等都在运行。三是逐步加压从30%的预估峰值开始每10分钟提升10%直到系统达到预期峰值的1.2倍为止这样才能确认系统有余量。四是在压测过程中实时监控数据库的关键指标出现问题当场定位现场不能压完再分析。6.2 建立基于现象的性能监控体系上线后的日常运维我建议建立一套分层的监控体系基础设施层CPU使用率、内存水位、磁盘IO延迟、网络带宽和丢包率。在异构环境下还要按节点架构分别设置告警阈值因为ARM和x86的合理水位不同。数据库实例层活跃会话数、事务提交延迟、锁等待时长、缓冲池命中率、慢查询数量。业务链路层接口响应时间P99、错误率、依赖的数据库操作耗时分布。这三层必须打通一个业务慢请求要能从“客户端超时”追踪到“某条SQL阻塞”再到“底层磁盘IO延迟升高”否则排查效率极低。我见过不少团队监控面板很漂亮但告警都是孤岛式的数据库告警了没人知道影响到了哪个业务这种监控其实是摆设——没有终结链路就没法定位根因。6.3 一个真实的线上性能问题排查实录分享一个典型的排查过程某个核心系统在业务高峰时段出现大量超时应用层看到的现象是数据库活跃会话数飙升CPU使用率接近90%。第一轮排查先看基础设施层指标存储延迟正常网络无丢包CPU虽然高但没有到硬瓶颈。第二轮看数据库层指标缓冲池命中率99%以上说明不是IO问题但锁等待时长显著上升很多事务在等同一个热点表的行锁。第三轮抓取阻塞源头通过数据库的会话视图找到持锁会话发现是一条批量更新语句正在更新一张超大表的某分区锁范围过大把后面几十个事务全部堵住。根因定位后解决方案是把大事务拆分为小批次提交每批次处理几千行后快速释放锁同时调整该业务的更新顺序和分片逻辑避免多个并发事务同时更新相邻数据。改造后同样时段的活跃会话数从300降到80接口P99从2.5秒回到400毫秒。这个案例说明很多“性能问题”其实就是事务粒度和锁机制设计的问题不一定是算力不够。6.4 持续优化的闭环机制上线不是终点性能优化是持续性的工作。我建议每两周做一次“慢查询复盘”把数据库慢查询日志里的Top SQL捞出来逐条分析执行计划、索引使用情况、资源消耗趋势。每季度做一次“容量评估”结合业务增长曲线评估当前算力和存储是否能支撑未来半年的峰值提前规划扩容不做“救火队员”。闭环的核心是“有变化就有对比”。任何一次SQL改动、参数调整、架构变更都记录前后性能指标和执行计划。时间长了这些记录就成了团队自己的性能基线知识库比任何外部资料都有价值。实操心得我把所有性能相关参数、SQL改写记录、压测结果都维护在一个文档里按日期和系统名归档。遇到线上问题直接查这个文档定位是不是最近改动引起的。效果很好强烈建议。7. 几条值得记住的经验总结最后分享几条个人经验算是这些年做信创项目攒下来的心得第一点异构算力不是“硬件杂糅”的代名词而是一种主动的设计策略。通过不同芯片各司其职可以在满足合规要求的前提下达到接近商业方案的整体性能和利用率。关键是节点按业务特征归堆不强行混布。第二点国产数据库的选型不能被“分布式一定先进”的观念带偏。技术在向上走但业务复杂度是向下的——能用集中式低成本解决的就不要自找麻烦上分布式。技术方案的优雅程度不是以复杂度为度量而是以匹配度为标准。第三点性能优化永远从业务负载出发而不是从参数清单出发。先搞清楚业务是读多还是写多、查询是点查还是范围扫、事务是短还是长再决定调什么、怎么调。没有业务输入的技术调优就是瞎调。第四点团队技术栈的平滑过渡是项目成功的重要变量。再好的数据库如果运维团队不熟不敢动参数、不会看监控出了问题只能干瞪眼。选型时把团队的学习曲线算进去比堆参数调优重要得多。异构算力加国产数据库这组组合短时间不会过时。只要架构师能沉住气把“为什么这么选”想透把“上线后怎么管”做实这条路是完全走得通的。
返回列表