服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-08-28 简米科技 4,590 字 11 分钟阅读

电子病历系统并发写入对磁盘IO的压力分析

导读电子病历系统并发写入卡顿,根子多半在磁盘IO,解决思路不是无脑加硬件,而是先定位IO瓶颈类型,再针对性地优化数据库、文件系统和存储选型,电子病历系统并发写入慢,磁盘IO到底卡在哪医院门诊早高峰的场景,相信HIS工程师都不陌生,医生开完医嘱点击保存,护士站批量录入生命体征,药房同时发起发药确认,几百个会话在同一秒……

电子病历系统并发写入卡顿,根子多半在磁盘IO,解决思路不是无脑加硬件,而是先定位IO瓶颈类型,再针对性地优化数据库、文件系统和存储选型。

电子病历系统并发写入慢,磁盘IO到底卡在哪

医院门诊早高峰的场景,相信HIS工程师都不陌生,医生开完医嘱点击保存,护士站批量录入生命体征,药房同时发起发药确认,几百个会话在同一秒内涌向数据库,这个时候,电子病历系统的响应时间从平时的几百毫秒飙升到几秒甚至几十秒,多数情况下,问题不出在CPU,也不出在内存,而是磁盘IO扛不住了。

并发写入和顺序读写的本质区别

数据库的写入操作和读操作有本质区别,读操作可以靠内存缓存大幅加速,命中缓存后根本不需要碰磁盘,但写入操作不一样,为了保证事务的持久性,数据库必须把redo log刷到磁盘上,事务才能提交成功,这个动作叫做fsync,每一个提交的事务,哪怕只改了一行数据,也要等待一次磁盘写入完成。

当并发量上来以后,大量事务同时提交,磁盘就要处理一个又一个的随机小IO请求,机械硬盘的寻道时间大约在几毫秒到十几毫秒之间,每秒能处理的IOPS也就一两百,面对几十个并发写请求,磁盘队列直接被打满,后续请求只能排队等待,这就是电子病历系统并发写入慢最常见的原因。

数据库层的写放大效应

问题还不止于此,PostgreSQL的MVCC机制,Oracle的回滚段,MySQL的Change Buffer,这些机制在带来并发控制能力的同时,也放大了写入量,一条UPDATE语句,可能产生新的数据版本、回滚日志、索引更新、WAL日志,算下来,逻辑上一条写入,物理上可能要写2到3个地方。

行业共识认为,数据库层的写放大系数通常在2到4倍之间,这就意味着,业务上每秒1000次写入,磁盘实际承受的可能是每秒3000次IO请求,如果索引建得过多,或者表结构设计不合理,这个放大系数还会更高。

一个典型的门诊高峰场景还原

想象一下这样的场景:上午十点,某三甲医院的内科诊区,200个诊室同时开诊,每个医生每5分钟开出一张处方,每张处方涉及主表、明细表、药品表、收费表等多个表的写入,加上护士站的操作,整个医院的写入TPS大概在500左右,如果数据库服务器用的是两块SATA SSD组成的RAID 1,理论IOPS大概在几千,表面上看够用了,但实际运行中,由于写放大、索引维护、后台检查点等因素,磁盘利用率经常冲到90%以上。

这个时候,电子病历系统的操作响应就会变得非常不稳定,医生点保存,转圈好几秒,然后整个诊区开始抱怨系统卡,这是医院信息化建设中相当有代表性的一个场景。

医院HIS系统磁盘IO压力测试怎么做

既然要解决问题,先得把问题量化,很多医院的运维团队面对卡顿的第一反应是加内存、加CPU,但加完之后效果不明显,正确的做法是先做压力测试,搞清楚磁盘IO的真实水位。

用系统命令快速定位IO瓶颈

登录数据库服务器,先用iostat -x 1看看磁盘的实时状态,重点看几个指标:

  • %util:磁盘忙绿百分比,持续超过80%说明磁盘是瓶颈
  • svctm:平均服务时间,机械盘一般在5到10毫秒,SSD应该低于1毫秒
  • await:平均等待时间,这个值如果远大于svctm,说明请求在排队
  • aqu-sz:平均队列长度,持续大于2说明负载偏高

再看iostat -x 1输出的wr_s和wKB/s,如果每秒写入次数只有几百,但%util已经100%,说明单次写入的代价很大,问题可能出在写入模式上,如果wr_s本身就很高,比如超过2000,那确实是并发量太大。

跟踪数据库等待事件

操作系统层面的指标只能告诉我们磁盘忙不忙,要弄清楚谁在等磁盘,还得看数据库的等待事件。

Oracle数据库可以查v$system_event视图,重点看log file synclog file parallel write两个事件。log file sync的平均等待时间如果超过20毫秒,说明提交事务时写redo log太慢,MySQL可以用SHOW ENGINE INNODB STATUS,看Log flush相关的状态,PostgreSQL则查pg_stat_database里的xact_commitblks_written

如果等待事件集中在日志写入上,优化方向应该是提升日志盘的性能,如果集中在数据文件的写操作上,那就要考虑数据文件布局和缓冲池设置。

医院信息科能做的三个压测动作

停诊后压测,晚上门诊结束后,在测试库上模拟第二天的并发写入,用sysbench或者pgbench这类工具,按医院实际业务的写入比例构造混合负载,从100并发开始,逐步往上加,每档跑10分钟,记录TPS和延迟的拐点。

抓取真实SQL,打开数据库的慢查询日志,把白天高峰时段的TOP 20写入SQL抓出来,分析这些SQL涉及哪些表,索引是否合理,有没有跨事务的多表更新,往往能发现某个SQL有全表扫描,写操作被放大。

对比测试,把同样的压测脚本跑在当前的机械盘阵列上,再跑在一块临时挂载的NVMe SSD上,对比两次的TPS和平均延迟,差值就是存储硬件提升带来的收益,这个数据可以作为后续采购预算的依据。

电子病历系统选型时磁盘IO该怎么看

很多医院在选型电子病历系统时,注意力都在功能列表上:有没有临床路径、有没有单病种质控、病历编辑器好不好用,但磁盘IO的支撑能力同样重要,它决定了系统在高并发时能不能保持稳定的体验。

共享存储和本地盘的选择

医院核心业务系统一般用共享存储,方便做双机热备和RAC,共享存储的性能取决于存储设备的控制器能力和后端磁盘配置,全闪存阵列的性能很好,但价格也不低,混闪阵列如果缓存命中率高,大部分读操作可以在缓存中完成,写入压力则集中在后端磁盘。

选择共享存储时,重点关注控制器的写缓存策略,如果写缓存带电池保护,写入可以先落缓存再异步刷盘,性能会好很多,如果没有电池保护,每次写入都要穿透到后端磁盘,IOPS会大打折扣。

SSD的选型要看两个指标

第一是耐久度,电子病历系统的写入量虽然比不上互联网业务,但数据库的redo log每天都在持续写入,选SSD时要看DWPD(每天全盘写入次数),企业级SSD一般是1到3,消费级只有0.1到0.3,长期用下来,消费级SSD很容易提前报废。

第二是稳态性能,SSD刚拿到手时性能很好,但写满一部分后,垃圾回收机制会让写入性能明显下降,选型时不要看峰值IOPS,要看持续写入状态下的稳定IOPS,这个数据在厂商的规格书里一般叫"稳态随机写入IOPS"。

国产数据库替换过程中的IO性能变化

近年来,不少医院在推进国产数据库替换,从Oracle迁移到国产数据库,SQL语法兼容性是一方面,IO行为的变化同样不能忽视。

国产数据库大多基于PostgreSQL或MySQL内核演进而来,以PostgreSQL内核的国产数据库为例,它的WAL写入机制和Oracle的redo log有明显差异,PG的每个事务提交都要写WAL,而Oracle有group commit优化,迁移之后,同样的业务量下,磁盘的写入次数可能会上升。在迁移前一定要做IO压测对比,不要只比功能

还有一个容易被忽略的点:国产数据库的默认参数和Oracle不同,比如checkpoint间隔、WAL缓冲区大小、commit延迟设置,这些参数对磁盘IO影响很大,需要按照医院的硬件配置做针对性调整。

磁盘IO优化的四个实战方向

诊断清楚瓶颈之后,优化可以从四个方向入手,不需要一次性全部做完,按投入产出比排序,逐项推进。

减少数据库层的写放大

  • 精简冗余索引,每多一个二级索引,每次INSERT和UPDATE就要多写一棵B+树,把长期未使用的索引删掉,写放大立刻下降
  • 调整WAL/redo log的group commit参数,让多个事务的提交合并成一次日志刷盘,大幅降低fsync次数
  • 对电子病历系统中频繁更新状态的表,考虑将热点字段拆分到独立的表中,避免整行更新导致的大字段重写

优化文件系统层

  • 挂载参数中开启noatime,避免每次访问都更新atime
  • 如果使用PostgreSQL,WAL日志建议放在独立的磁盘分区上,避免和数据文件争抢IO
  • XFS和ext4在并发写入场景下表现有差异,XFS对多线程并发写入的扩展性更好,新部署的系统可以考虑

升级存储硬件

这是最直接见效也最费钱的方式,升级路径一般是:

现状 升级方案 预期收益
机械盘RAID 10 换成SATA SSD IOPS提升5到10倍
SATA SSD 换成NVMe SSD 延迟降低一半以上
NVMe SSD 换成带掉电保护的NVMe 稳定性提升,寿命更长
单机本地盘 换成全闪存阵列 性能和可靠性同时提升

应用层削峰填谷

有些写入操作可以延后处理,不需要实时落库,比如电子病历的自动保存功能,可以让前端每30秒自动保存一次,但如果后台每30秒就发起一次真实的数据库写入,压力还是很大,合理的做法是前端把自动保存的内容放在本地内存或localStorage,只有用户手动保存或切换页面时才真正写入数据库。

类似的,护理记录单的批量录入,可以先在前端汇总,一次性提交,减少数据库的往返次数,对降低IO压力有明显帮助。

磁盘IO监控的日常巡检建议

优化不是一次性的事情,磁盘IO的压力会随着业务量的增长而变化,建立日常巡检机制,把问题扼杀在萌芽期。

  • 每周检查一次数据库服务器的iostat输出,关注磁盘利用率趋势是否在逐步上升
  • 每月分析一次数据库的AWR或类似报告,看TOP等待事件有没有变化
  • 每季度做一次IO压测,对比当季的性能基线和上季度是否有明显下降
  • 关注存储告警:SSD的剩余寿命、RAID组的降级状态、存储控制器的缓存命中率

相关问答

问:电子病历系统并发写入慢,加内存有用吗?
数据库缓冲池扩大确实能提升读操作的缓存命中率,但写入操作必须落盘才能保证持久性,如果磁盘本身已经是瓶颈,加内存只会让更多的脏块积压在内存里,最终还是要刷到磁盘上,效果有限,应先确认磁盘利用率,再决定是加内存还是换存储。

问:医院HIS系统磁盘IO压力测试需要停机吗?
测试分两档,在测试库上做压力测试不需要停机,可以随时进行,如果想测试生产环境的真实承载能力,建议在门诊结束后的夜间窗口期进行,控制并发数,避免影响住院部的夜间业务,测试前做好数据库备份,测试过程中持续监控CPU、内存和IO指标,异常时立即停止。

问:NVMe SSD和SATA SSD在医院业务系统里的实际差距有多大?
顺序读写场景下差距不大,SATA SSD的500MB/s已经够用,差距主要体现在随机小IO和并发写入上,NVMe的低延迟优势明显,对于电子病历系统这种频繁小事务写入的场景,NVMe的体验提升相当可观,不过共享存储架构下,瓶颈可能在存储控制器,单独换服务器内的NVMe盘不一定能发挥全部性能。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱