云计算百科
云计算领域专业知识百科平台

生产复盘:国产化服务器 IO 瓶颈导致数据库性能雪崩优化实录(政务项目落地)

摘要

政务系统信创改造,数据库从 x86 物理机迁移到鲲鹏 920 国产服务器 + 全闪存储,本以为性能会持平,结果上线高峰期直接雪崩:TPS 从 2000 掉到 700,写入延迟翻 10 倍,政务申报接口大面积超时。团队一开始死磕数据库参数、优化 SQL,折腾三天没起色,最后定位到底层 IO 栈全是默认配置,国产存储 + ARM 架构的适配坑一个没踩全。

本文基于一线政务项目真实优化实录,完整还原故障排查全流程,拆解国产化服务器 5 大特有 IO 坑,从系统层、存储层、数据库层、架构层四层输出全链路优化方案,覆盖人大金仓 V9、达梦 DM9 双库专属参数,附优化前后实测对比、可直接复制的调优命令。照着做,国产化环境数据库 IO 性能可提升 2~3 倍,延迟降低 80% 以上。

政务选金仓,金融选达梦;MySQL 迁移选金仓,Oracle 迁移选达梦。全文无空泛理论,所有参数均经过国产 ARM 服务器 + 全闪存储生产压测验证。


一、生产惊魂:迁到国产服务器,数据库性能直接腰斩

📌 故障背景:某地市政务服务系统信创改造,数据库从 x86 Intel 服务器 + SAS 存储,迁移至鲲鹏 920 国产服务器 + 国产全闪 SSD 存储,数据库为人大金仓 V9,数据量约 800G,日常 TPS 峰值 2000 左右。

1.1 完整故障时间线

时间点事件排查操作
上线当天 低峰期运行正常,响应略慢但可接受 认为是适配期正常现象,未深究
次日早高峰 业务申报量上涨,TPS 从预期 2000 掉到 700,接口平均延迟从 30ms 涨到 300ms 排查 SQL、索引,未见明显慢 SQL
高峰持续期 写入接口大面积超时,99 分位延迟超 1 秒 调大数据库缓冲区、优化检查点,收效甚微
第二天 团队死磕数据库参数、加索引、优化 SQL,性能无本质提升 怀疑国产数据库性能不行,准备回退 x86
第三天 转向底层排查,iostat 发现 IO await 高达 8ms,% util 常年打满 定位核心瓶颈在存储 IO 栈,数据库背了锅
优化窗口期 逐层优化 IO 调度、存储缓存、文件系统、数据库参数 优化完成后性能反超 x86 原环境

1.2 核心故障现象

  • 写入延迟飙升:读操作基本正常,写入延迟翻 10 倍,TPS 上不去
  • CPU 不高 IO 满:数据库 CPU 使用率不到 30%,但磁盘 % util 长期 100%,IO 等待占比极高
  • 参数优化无效:调大内存、改检查点、优化 SQL,都只能轻微改善,解决不了根本问题
  • 低峰正常高峰崩:并发低的时候一切正常,一上量就雪崩,典型的 IO 吞吐量瓶颈
  • 1.3 最大的误区

    很多团队迁信创,遇到性能问题第一反应是「国产数据库不行」「ARM 性能差」,实际上 80% 的场景都是底层 IO 栈没做适配,还在用机械盘的默认配置跑全闪 SSD,数据库和 CPU 纯纯背锅。


    二、排查全流程:从应用到底层,一步步定位 IO 瓶颈

    遇到性能问题别上来就改数据库,按从上到下的顺序排查,10 分钟就能定位是不是 IO 的锅。

    第一步:先排除应用与数据库层面

  • 查慢 SQL:看是不是突然出现大量慢 SQL 导致 IO 升高,确认 SQL 执行计划正常、索引有效
  • 查等待事件:数据库层面看是不是 IO 等待占主导

    — 金仓:查看等待事件,IO类等待占比高就是IO瓶颈
    SELECT event, count(*) FROM sys_stat_activity WHERE wait_event_type = 'IO' GROUP BY event;

    — 达梦:查看系统等待事件
    SELECT class, wait_time FROM v$system_wait_class WHERE class LIKE '%IO%';

  • 查缓存命中率:命中率正常说明内存够,问题不在缓冲区

    — 金仓缓存命中率
    SELECT sum(blks_hit)*100/sum(blks_hit+blks_read) FROM sys_stat_database;

  • 第二步:系统层确认 IO 瓶颈

    用 iostat -x 1 一眼就能确认,重点看这四个指标:

    bash

    iostat -x 1

    指标正常 SSD 值故障值说明
    %util <30% 90%~100% 磁盘利用率,长期满就是瓶颈
    await <0.5ms 5~20ms 平均 IO 等待时间,SSD 超过 1ms 就异常
    r_await/w_await <0.3ms 数毫秒 读写单独等待时间,写入高重点看写缓存
    avgqu-sz <5 几十 IO 队列深度,排队严重说明处理不过来

    ✅ 确诊标准:% util 长期接近 100%,await 远超 SSD 正常水平,同时数据库 IO 等待占比最高,就是纯 IO 瓶颈。

    第三步:定位 IO 瓶颈在哪一层

    IO 是整条链路,从数据库→文件系统→操作系统→RAID 卡→硬盘,逐层排除:

  • 先测裸盘性能:用 fio 测裸盘最大 IOPS、延迟,确认硬件本身性能达标
  • 再测文件系统:测挂载文件系统后的性能,看损耗有多大
  • 最后看数据库:对比数据库实际 IO 和硬件上限,差太多就是上层参数有问题
  • 💡 本次故障排查结果:裸盘 fio 测随机写 IOPS 能到 3 万,数据库实际跑起来只有 3000,差了 10 倍,明显是软件栈配置拖了后腿。


    三、根因深挖:国产化服务器 5 个特有 IO 坑,x86 根本遇不到

    坑 1:IO 调度器默认用 CFQ,完全不适合 SSD

    很多国产服务器系统默认 IO 调度器还是cfq(完全公平队列),这是给机械硬盘设计的,SSD 场景下调度开销极大,IOPS 直接砍半。

    • x86 新系统很多默认已经切了,国产定制化系统反而保留了旧默认
    • ARM 平台 IO 调度适配本身就不如 x86 成熟,错配后性能损耗更严重

    坑 2:RAID 卡默认写通模式,没开写回缓存

    国产 RAID 卡默认策略保守,默认Write Through(写通),每次写都直接落盘,完全不用缓存,写入延迟直接翻几倍。

    • x86 服务器很多出厂就开了写回,国产服务器为了数据安全默认保守配置
    • 没有备电的情况下开写回有断电丢数据风险,很多运维不敢开

    坑 3:文件系统默认挂载参数,日志开销吃掉一半性能

    默认 ext4/xfs 挂载参数都是通用配置,开启了 atime、日志完整模式,每一次 IO 都附带元数据、日志写入,SSD 场景下纯纯浪费性能。

    • 数据库场景有自己的 WAL/REDO 日志,文件系统日志完全可以调弱
    • 国产化文件系统驱动适配不如 x86 成熟,额外开销更大

    坑 4:队列深度不匹配,高并发下 IO 拥堵

    国产 SSD 固件、驱动对队列深度的适配和 x86 平台有差异,默认队列深度要么太小发挥不出 SSD 性能,要么太大导致拥堵延迟飙升。

    • 很多团队照搬 x86 的队列深度参数,结果要么性能上不去,要么延迟爆炸
    • ARM 平台中断处理和 x86 有差异,IO 亲和性没配好也会导致性能损耗

    坑 5:数据库参数照搬 x86,检查点刷盘太猛

    很多团队迁移数据库,参数直接从老环境抄过来,检查点间隔短、刷盘策略激进,在 IO 本来就弱的国产化环境下,直接把 IO 打满,业务写入全排队。

    • 金仓、达梦在 ARM 平台的 IO 行为和 x86 有细微差异,刷盘频率需要重新适配
    • 国产存储写放大比一线 SSD 高,频繁小 IO 写入性能衰减更明显

    四、第一层:系统层 IO 极致调优(命令直接抄)

    这一步优化成本为零,改完性能就能提升 50% 以上,是性价比最高的优化。

    4.1 IO 调度器切换为 SSD 专属

    所有 SSD 盘全部改成mq-deadline调度器,机械盘用bfq,数据库场景性能最优。

    # 临时生效(替换sdX为实际磁盘名)
    echo mq-deadline > /sys/block/sdX/queue/scheduler

    # 永久生效(CentOS/麒麟系统)
    echo 'ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/scheduler}="mq-deadline"' > /etc/udev/rules.d/60-scheduler.rules
    udevadm control –reload-rules && udevadm trigger

    4.2 调整队列深度与 IO 亲和性

    根据 SSD 规格调整队列深度,平衡吞吐量与延迟:

    # 调整队列深度,全闪SSD建议256~512
    echo 256 > /sys/block/sdX/queue/nr_requests

    # 开启IO合并,减少小IO数量
    echo 1 > /sys/block/sdX/queue/merges

    # 优化SSD预读,数据库随机读场景不需要太大预读
    echo 8 > /sys/block/sdX/queue/read_ahead_kb

    4.3 文件系统挂载参数优化

    ext4/xfs 都适用,重点减少元数据写入、降低日志开销:

    # 挂载参数优化,写入/etc/fstab
    /dev/sdX1 /data ext4 defaults,noatime,nodiratime,data=writeback,barrier=0 0 0

    • noatime,nodiratime:关闭访问时间记录,减少元数据写入
    • data=writeback:数据写入不等待日志落盘,数据库自有 WAL 保证一致性
    • barrier=0:关闭磁盘屏障,依赖 RAID 卡缓存备电保证一致性

    ⚠️ 注意:开 writeback 和关 barrier 必须确保 RAID 卡有备电保护,否则异常断电可能丢数据。

    4.4 内核参数整体调优

    # 写入/etc/sysctl.conf,执行sysctl -p生效
    # 页面刷盘优化,避免集中刷盘导致IO尖刺
    vm.dirty_ratio = 10
    vm.dirty_background_ratio = 5
    vm.dirty_expire_centisecs = 3000
    vm.dirty_writeback_centisecs = 100

    # 提升系统最大IO队列数
    kernel.sem = 5010 641280 5010 1280
    fs.aio-max-nr = 1048576
    fs.file-max = 6815744

    4.5 关闭透明大页

    数据库场景透明大页会导致 IO 抖动、延迟忽高忽低,必须永久关闭:

    # 临时关闭
    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    echo never > /sys/kernel/mm/transparent_hugepage/defrag

    # 永久关闭,写入rc.local或grub


    五、第二层:存储硬件层优化,释放 SSD 全部性能

    硬件层优化是天花板,配置对了性能直接翻倍。

    5.1 RAID 卡开启写回缓存

    这是写入性能提升最大的一项,前提是 RAID 卡有 BBU 备电模块:

    # 以LSI RAID卡为例,查看当前缓存策略
    storcli64 /c0 show all | grep WriteCache

    # 开启写回模式
    storcli64 /c0/v0 set wrcache=wb
    # 开启预读
    storcli64 /c0/v0 set rdcache=ra

    ✅ 效果:写入延迟可从毫秒级降到百微秒级,随机写 IOPS 提升 2~3 倍。

    5.2 RAID 条带大小适配数据库

    数据库场景推荐条带大小 256K~512K,匹配数据库页大小(金仓 8K、达梦页大小可配置),减少条带穿越:

    # 新建RAID时指定条带大小
    storcli64 /c0 add vd type=raid5 drives=0:0-3 strip=256

    5.3 SSD 固件升级与磨损均衡

    国产 SSD 早期固件普遍存在性能 bug、写放大高的问题,升级到最新稳定版固件,开启全局磨损均衡,长期运行性能不衰减。

    5.4 数据盘与日志盘物理分离

    重做日志(WAL/REDO)是顺序写,数据文件是随机写,物理分离到不同 RAID 组:

    • 日志盘:高 IOPS、低延迟的 SSD,专门扛顺序写入
    • 数据盘:大容量 SSD,承载随机读写 避免日志刷盘和数据读写争抢 IO 资源,这是数据库存储的标准最佳实践。

    六、第三层:数据库层 IO 适配(金仓 / 达梦双库专属参数)

    底层 IO 优化完,数据库参数也要跟着适配,把硬件性能充分用起来。

    6.1 人大金仓 V9 IO 专属优化

    写入 kingbase.conf:

    # ========== 内存缓冲,减少物理IO ==========
    shared_buffers = 8GB # 总内存的25%,尽量缓存热点数据
    effective_cache_size = 24GB # 预估系统缓存,影响执行计划
    work_mem = 32MB # 单操作内存,减少磁盘排序
    maintenance_work_mem = 1GB # 维护操作内存

    # ========== WAL/检查点 平滑IO ==========
    wal_buffers = 64MB # WAL缓冲区
    max_wal_size = 16GB # WAL上限,延长检查点间隔
    checkpoint_timeout = 60min # 检查点间隔,减少频繁刷盘
    checkpoint_completion_target = 0.9 # 平滑刷盘,避免IO尖刺
    wal_writer_delay = 10ms # WAL写入频率
    commit_delay = 10 # 提交延迟,合并小事务写入

    # ========== 后台刷盘优化 ==========
    bgwriter_delay = 10ms # 后台写进程间隔
    bgwriter_lru_maxpages = 200 # 单次刷脏页数
    effective_io_concurrency = 200 # 并发IO数,适配SSD性能
    random_page_cost = 1.1 # SSD随机读成本接近顺序读,优化执行计划
    seq_page_cost = 1.0

    6.2 达梦 DM9 IO 专属优化

    写入 dm.ini:

    # ========== 缓冲区优化 ==========
    BUFFER = 8192 # 数据缓冲区,单位MB
    MAX_BUFFER = 12288 # 最大缓冲区
    LOG_BUFFER = 512 # 日志缓冲区

    # ========== 检查点与刷盘 ==========
    CHECKPOINT_INTERVAL = 3600 # 检查点间隔,单位秒
    CHECKPOINT_COMPLETED_TARGET = 0.9 # 平滑完成比例
    LOG_FILE_SIZE = 1024 # 单个日志文件大小,单位MB
    LOG_SPACE_LIMIT = 81920 # 日志总空间

    # ========== IO适配 ==========
    IO_THREADS = 8 # IO线程数
    DIRECT_IO = 1 # 开启DIRECT IO,绕过系统缓存双缓存
    PAGE_SIZE = 8192 # 页大小匹配存储条带
    FAST_ROLLBACK = 1 # 快速回滚,减少IO峰值

    6.3 数据库层优化核心原则

  • 能走内存不走磁盘:缓冲区尽量给足,热点数据全放内存,从根源减少物理 IO
  • 刷盘要平滑不要尖刺:延长检查点间隔、调大完成目标,把集中 IO 摊平,避免瞬间打满
  • 小 IO 合并写入:通过提交延迟、缓冲区合并,把零散小 IO 合并成大 IO,提升 SSD 效率

  • 七、第四层:架构层 IO 削峰,从根源降低 IO 压力

    硬件优化有天花板,架构层面优化才能从根本降低 IO 需求。

    7.1 读写分离

    备库承担所有查询、报表、统计类请求,主库只负责写入和核心查询,主库 IO 压力直接降低 50% 以上。

    • 金仓 / 达梦原生支持物理备库只读查询,改连接串就能用
    • 报表、批量查询全部走备库,不占用主库 IO 资源

    7.2 冷热数据分离

    历史冷数据归档到低速存储,热数据留在高性能 SSD:

    • 按时间分区,超过 3 个月的历史数据迁移到归档库
    • 冷数据只查询不更新,对 IO 性能要求低
    • 热数据量小了,缓存命中率更高,物理 IO 更少

    7.3 批量操作削峰

    • 批量更新、数据导入分批提交,每批休眠间隔,避免瞬间打满 IO
    • 批量任务统一安排在业务低峰期执行,不和高峰期抢 IO
    • 大表建索引、vacuum、统计信息收集等 IO 密集操作,全部放在低峰期

    八、实测对比:优化前后性能数据对照表

    📊 测试环境:鲲鹏 920 2 颗 / 64 核、256G 内存、国产全闪 SSD RAID5、人大金仓 V9、sysbench 压测、100 并发 OLTP 混合场景。

    性能指标优化前(默认配置)优化后(全链路调优)提升幅度原 x86 环境参考
    峰值 TPS 720 2680 272% 2050
    平均响应延迟 138ms 29ms 降低 79% 35ms
    99 分位延迟 1260ms 118ms 降低 91% 150ms
    随机写 IOPS 3200 28500 790% 21000
    写入平均延迟 8.2ms 0.28ms 降低 97% 0.4ms
    磁盘 % util 峰值 98% 32% 下降 67% 45%
    数据库缓存命中率 89% 98.6% 提升 9.6% 97%

    💡 结论:全链路优化后,国产服务器 + 国产存储的数据库性能,不仅追上了原 x86 环境,还反超了 30% 左右,完全满足生产要求。之前觉得性能差,本质都是默认配置没适配,白白浪费了硬件能力。


    九、避坑红线:10 个国产化 IO 最容易踩的致命错误

    ⚠️ 红线 1:默认 IO 调度器不换,用 CFQ 跑 SSD

    • 后果:IOPS 直接砍半,延迟飙升,白白浪费 SSD 性能
    • 整改:SSD 全部切 mq-deadline,这是第一步必须做的

    ⚠️ 红线 2:RAID 卡写通模式硬扛,不敢开写回

    • 后果:写入延迟翻几倍,IOPS 上不去,性能直接腰斩
    • 整改:有备电就开写回,这是写入性能提升最大的一项

    ⚠️ 红线 3:文件系统默认参数不优化

    • 后果:元数据、日志额外 IO 吃掉 30% 以上性能
    • 整改:关 atime、优化日志模式,数据库场景完全没问题

    ⚠️ 红线 4:数据日志混在一个盘里

    • 后果:日志刷盘和数据读写抢 IO,高峰期互相阻塞
    • 整改:物理分离日志盘和数据盘,顺序写和随机写分开

    ⚠️ 红线 5:数据库参数直接照搬 x86

    • 后果:检查点频繁刷盘,IO 尖刺严重,适配度差
    • 整改:根据国产存储特性重新调整缓冲、检查点参数

    ⚠️ 红线 6:透明大页不关

    • 后果:IO 延迟忽高忽低,周期性卡顿,排查不到根因
    • 整改:数据库场景必须永久关闭透明大页

    ⚠️ 红线 7:不升级 SSD 固件

    • 后果:国产 SSD 早期固件 bug 多,写放大高、越用越慢
    • 整改:上线前升级到最新稳定版固件,避免踩已知坑

    ⚠️ 红线 8:队列深度乱调

    • 后果:调太小性能上不去,调太大延迟爆炸
    • 整改:压测找到最佳值,兼顾吞吐量和延迟

    ⚠️ 红线 9:为了安全全关缓存、开最强校验

    • 后果:安全性拉满,性能直接砍到膝盖,完全没法用
    • 整改:在有硬件备电、冗余保护的前提下,合理开启缓存

    ⚠️ 红线 10:只优化数据库,不看底层

    • 后果:数据库参数调来调去收效甚微,根因在底下一层
    • 整改:性能问题从上到下排查,定位到瓶颈层再优化

    十、监控预警:IO 瓶颈提前发现,别等雪崩再救火

    把 IO 指标纳入核心监控,异常提前告警,根本不会发展成性能雪崩。

    10.1 必加 IO 监控项

    监控指标告警阈值告警级别
    磁盘 % util >70% 持续 5 分钟 一般告警
    磁盘 % util >90% 持续 2 分钟 严重告警
    IO 平均 await >1ms 持续 5 分钟 严重告警
    写入延迟 >0.5ms 持续 5 分钟 一般告警
    IO 队列长度 >32 持续 5 分钟 一般告警
    数据库 IO 等待占比 >30% 严重告警

    10.2 定期巡检项

  • 每月用 fio 压测一次裸盘性能,对比基线,发现性能衰减及时处理
  • 每季度检查 SSD 磨损度、剩余寿命,提前更换预警盘
  • 每月检查 RAID 卡缓存策略、固件版本,保持配置一致

  • 总结

    国产化服务器数据库性能雪崩,很多时候不是硬件不行、也不是数据库不行,而是从系统到存储到数据库的整条 IO 栈,都还在用默认的通用配置,完全没适配 SSD 和 ARM 架构。从系统层改调度、调参数,到存储层开缓存、做分离,再到数据库层适配优化、架构层削峰,全链路调下来,国产平台的性能完全可以追上甚至超过 x86。

    信创优化从来不是「凑合用」,而是把每一层的潜力都释放出来,做到既自主可控,又性能够打。

    政务选金仓,金融选达梦;MySQL 迁移选金仓,Oracle 迁移选达梦。

    📚 专栏推荐:专注 SpringBoot3 + 人大金仓 + 达梦信创实战,持续输出生产级部署、性能调优、故障排查、避坑指南干货,关注不迷路。

    觉得文章有用的话,欢迎点赞、收藏、关注三连,后续更新更多信创数据库性能优化的硬核内容。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 生产复盘:国产化服务器 IO 瓶颈导致数据库性能雪崩优化实录(政务项目落地)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!