Linux 4.1内核热补丁成功实践
副标题[/!--empirenews.page--]
最开始公司运维同学反馈,个别宿主机上存在进程CPU峰值使用率异常的现象。而数万台机器中只出现了几例,也就是说万分之几的概率。监控产生的些小误差,不会造成宕机等严重后果,很容易就此被忽略了。 但我们考虑到这个异常转瞬即逝、并不易被察觉,可能还存在更多这样的机器,又或者现在正常将来又不正常,内核研发本能的好奇心让我们感到:此事必有蹊跷!于是追查下去。 现象一:CPU监控非0即100% 该问题现象表现在Redis进程CPU监控的峰值时而100% 时而为0,有的甚至是几十分钟都为0,突发1秒100%后又变为0,如下图。 而从大量机器的统计规律看,这个现象在2.6.32 内核不存在,在4.1内核存在几例。2.6.32是我们较早期采用的版本,为平台的稳定发展做了有力支撑,4.1 可以满足很多新技术需求,如新款CPU、新板卡、RDMA、NVMe和binlog2.0等。后台无缝维护着两个版本,并为了能力提升和优化而逐步向4.1及更高版本过渡。 现象二:top显示非0即300% 登录到机器上执行top -b -d 1 –p <pid> | grep<pid> , 可以看到进程的CPU利用率每隔几分钟到几十分钟出现一次300%,这意味着该进程3个线程占用的3个CPU都跑满了,跟监控程序呈现同样的异常。 上述异常程序使用的是同样的数据源:/proc/pid/stat中进程运行占用的用户态时间utime和内核态时间stime。我们抓取utime和stime更新情况后,发现utime或者stime每隔几分钟或者几十分钟才更新,更新的步进值达到几百到1000+,而正常进程看到的是每几秒更新,步进值是几十。 定位到异常点后,还要找出原因。排除了监控逻辑、IO负载、调用瓶颈等可能后,确认是4.1内核的CPU时间统计有 bug。 cputime统计逻辑 检查/proc/pid/stat中utime和stime被更新的代码执行路径,在cputime_adjust()发现了一处可疑的地方: 当utime+stime>=rtime的时候就直接跳出了,也就是不更新utime和stime了!这里的rtime是runtime,代表进程运行占用的所有CPU时长,正常应该等于或近似进程用户态时间+内核态时间。 但内核配置了CONFIG_VIRT_CPU_ACCOUNTING_GEN选项,这会让utime和stime分别单调增长。而runtime是调度器里统计到的进程真正运行总时长。 内核每次更新/proc/pid/stat的utime和stime的时候,都会跟rtime对比。如果utime+stime很长一段时间都大于rtime,那代码直接goto out了, /proc/pid/stat就不更新了。只有当rtime持续更新追上utime+stime后,才更新utime和stime。 第一回合:冷补丁 出现问题的代码位置已经找到,那就先去内核社区看看有没有成熟补丁可用,看一下kernel/sched/cputime.c的 changelog,看到一个patch:确保stime+utime=rtime。再看描述:像top这样的工具,会出现超过100%的利用率,之后又一段时间为0,这不就是我们遇到的问题吗?真是踏破铁鞋无觅处,得来全不费工夫!(patch链接:https://lore.kernel.org/patchwork/patch/609410/)
该补丁在4.3内核及以后版本才提交, 却并未提交到4.1稳定版分支,于是移植到4.1内核。打上该补丁后进行压测,再没出现cputime时而100%时而0%的现象,而是0-100%之间平滑波动的值。 至此,你可能觉得问题已经解决了。但是,问题才解决了一半。而往往“但是”后边才是重点。 第二回合:热补丁 给内核代码打上该冷补丁只能解决新增服务器的问题,但公司还有数万存量服务器是无法升级内核后重启的。 如果没有其它好选择,那存量更新将被迫采用如下的妥协方案:监控程序修改统计方式进行规避,不再使用utime和stime,而是通过runtime来统计进程的执行时间。 虽然该方案快速可行,但也有很大的缺点: 1. 很多业务部门都要修改统计程序,研发成本较高; 2. /proc/pid/stat的utime和stime是标准统计方式,一些第三方组件并不容易修改; 3. 并没有根本解决utime和stime不准的问题,用户、研发、运维使用ps、top命令时还会产生困惑,产生额外的沟通协调成本。 幸好,我们还可以依靠UCloud已多次成功应用的技术:热补丁技术。 所谓热补丁技术,是指在有缺陷的服务器内核或进程正在运行时,对已经加载到内存的程序二进制打上补丁,使得程序实时在线状态下执行新的正确逻辑。可以简单理解为像关二爷那样不打麻药在清醒状态下刮骨疗伤。当然,对内核刮骨疗伤内核是不会痛的,但刮不好内核就会直接死给你看,没有丝毫犹豫,非常干脆利索又耿直。 (编辑:温州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |