内存刷脏机制触发的系统故障案例一则

2024-02-05 21:52

本文主要是介绍内存刷脏机制触发的系统故障案例一则,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  关键词

  • linux、centos
  • cpu load、cpu iowait、sar监控、大页内存
  • vm.dirty_background_ratio、vm.dirty_ratio、vm.min_free_kbytes

     There are many things that can not be broken!

     如果觉得本文对你有帮助,欢迎点赞、收藏、评论!

一、问题现象

某数据库主机接连在几天里出现莫名hang死现象,造成业务中断,故障时间段,出现数据库连接数升高,cpu有陡增,cpu iowait time陡增,从监控曲线看cpu load负载过高,并伴随有大量的IO操作、事务等待会话、tps以及慢SQL,由于负载升高导致数据库自动主从切换失败,造成业务一定的中断影响。

二、问题分析

1、在集中复盘这几次故障中,发现故障主机几次故障之前出现过剩余内存严重不足情况,主机内存:377G,几乎耗尽,将故障原因怀疑的方向定位在是zone内存剩余达到min水位线导致直接内存回收,用户申请内存被阻塞,只有内核态可以正常申请剩余内存。

这种情况下,系统中剩余的内存极少,少到可能连回收内存操作本身需要的内存都不够,当 free 内存降到了 min 水线以下,此时如果操作系统忽然需要通过伙伴系统为用户进程分配一大块内存,或者需要创建一个很大的缓冲区,而当时系统中的内存没有办法提供足够多的物理内存以满足这种内存请求,这时候,操作系统就必须尽快进行页面回收操作,以便释放出一些内存空间从而满足上述的内存请求,这种页面回收方式也被称作"直接页面回收",这个过程会阻塞申请内存的进程,被阻塞进程的内存分配延迟就会提高,从而感受到卡顿。

随后检查操作系统内存回收上的参数配置情况,发现此时的脏页vm.dirty_ratio过小,在此过程中很多应用进程可能会因为系统转而处理文件IO而阻塞。

2、同时发现主机pagetables达到70G以上,建议数据库配置大页。使用大页(huge page)能够缩小page tables,减少cpu在内存管理上的的系统开销,提高性能。 

三、处理过程

1、调整刷脏配置
vm.dirty_background_ratio = 50 
vm.dirty_ratio = 80
vm.min_free_kbytes 为4G


2、配置大页,降低pagetables占用内存。

四、知识拓展

1、sysctl中的那些参数控制页高速缓存的参数

  • vm.vfs_cache_pressure (默认值 = 100)
    • 默认值vfs_cache_pressure=100,在回收页高速缓存(page cache)和交换缓存(swap cache)时,内核会以"相对公平"的比例回收dentries和inodes。
    • 调整内核更趋向于回收内存中保存的目录项缓存(dentry)和索引节点对象 (inode objects)。
    • 减少vfs_cache_pressure值,会使内核更倾向于保留目录项对象(dentry)以及索引节点缓存(inode caches); 增加vfs_cache_pressure 超过100 会使内核更倾向于释放目录项对象(dentry)以及索引节点缓存(inode caches)。
    • 可以通过增加vfs_cache_pressure的值,来使内核更倾向于释放上述缓存,从而限制页高速缓存(page cache)的大小。
  • vm.dirty_background_ratio (默认值 = 10)
    • 此参数的值代表脏页占总内存的百分比, 当系统中脏页数量达到此值时,内核线程pdflush开始把脏页数据写入存储。
    • 可以通过减少此值,来使pdflush进程更早把脏页写入存储,从而限制页高速缓存的大小。
  • vm.dirty_ratio (默认值 = 20)
    • 这个参数则指定了当文件系统缓存脏页数量达到系统内存百分之多少时(默认值20%),系统不得不开始处理缓存脏页(因为此时脏页数量已经比较多,为了避免数据丢失需要将一定脏页刷入外部存储);在此过程中很多应用进程可能会因为系统转而处理文件IO而阻塞。
    • 减少此值可使 系统更早来处理内存中的脏页,从而限制页高速缓存的大小。
  • vm.dirty_writeback_centisecs (Red Hat Enterprise Linux 4 & 5: 默认值 = 499, Red Hat Enterprise Linux 6 and 7: 默认值 = 500)
    • pdflush进程会定时被唤醒,把脏页中的数据写入硬盘。单位是 1/100 秒。缺省数值是500,也就是pdflush进程5秒钟会被唤醒一次。
    • 减少此值可以更频繁的唤醒pdflush进程来处理脏页, 从而限制页高速缓存的大小。
  • vm.dirty_expire_centisecs (Red Hat Enterprise Linux 4 and 5: 默认值= 2999, Red Hat Enterprise Linux 6 and 7: 默认值 = 3000)
    • 这个参数声明Linux内核写缓冲区里面的数据多“旧”了之后,被唤醒的pdflush进程就开始考虑写到磁盘中去。单位是 1/100秒。缺省是 30000,也就是 30 秒的数据就算旧了,pdflush进程被唤醒后,将会把“旧”的数据写入磁盘。
    • 减少此值意味着脏页会更快变“旧”,并被pdflush进程写入磁盘,从而限制页高速缓存的大小。
  • vm.swappiness (RHEL 5 and 6:默认值 = 60, RHEL 7:默认值 = 30)
    • 此参数控制内核是否更趋向于交换非活动内存页页至交换分区(此值越高,代表非活动内存页越可能被交换至交换分区)。
    • 减少此值使内核更倾向于保持非活动内存页在物理内存中,从而释放页高速缓存中的页, 从而限制页高速缓存的大小。

2、如何查看你的脏页刷脏情况

使用sar命令,重点关注pgscank指标,格式

sar  -B  1 5        

pgpgin/s:表示每秒从磁盘或SWAP置换到内存的字节数(KB)
pgpgout/s:表示每秒从内存置换到磁盘或SWAP的字节数(KB)
fault/s:每秒钟系统产生的缺页数,即主缺页与次缺页之和(major + minor)
majflt/s:每秒钟产生的主缺页数 pgfree/s:每秒被放入空闲队列中的页个数
pgscank/s:每秒被 kswapd 扫描的页个数
pgscand/s:每秒直接被扫描的页个数
pgsteal/s:每秒钟从 cache 中被清除来满足内存需要的页个数
%vmeff:每秒清除的页(pgsteal)占总扫描页(pgscank + pgscand)的百分比

这篇关于内存刷脏机制触发的系统故障案例一则的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/682277

相关文章

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class

MySQL中实现多表查询的操作方法(配sql+实操图+案例巩固 通俗易懂版)

《MySQL中实现多表查询的操作方法(配sql+实操图+案例巩固通俗易懂版)》本文主要讲解了MySQL中的多表查询,包括子查询、笛卡尔积、自连接、多表查询的实现方法以及多列子查询等,通过实际例子和操... 目录复合查询1. 回顾查询基本操作group by 分组having1. 显示部门号为10的部门名,员

如何关闭 Mac 触发角功能或设置修饰键? mac电脑防止误触设置技巧

《如何关闭Mac触发角功能或设置修饰键?mac电脑防止误触设置技巧》从Windows换到iOS大半年来,触发角是我觉得值得吹爆的MacBook效率神器,成为一大说服理由,下面我们就来看看mac电... MAC 的「触发角」功能虽然提高了效率,但过于灵敏也让不少用户感到头疼。特别是在关键时刻,一不小心就可能触

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

Golang基于内存的键值存储缓存库go-cache

《Golang基于内存的键值存储缓存库go-cache》go-cache是一个内存中的key:valuestore/cache库,适用于单机应用程序,本文主要介绍了Golang基于内存的键值存储缓存库... 目录文档安装方法示例1示例2使用注意点优点缺点go-cache 和 Redis 缓存对比1)功能特性

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

Nginx之upstream被动式重试机制的实现

《Nginx之upstream被动式重试机制的实现》本文主要介绍了Nginx之upstream被动式重试机制的实现,可以通过proxy_next_upstream来自定义配置,具有一定的参考价值,感兴... 目录默认错误选择定义错误指令配置proxy_next_upstreamproxy_next_upst

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图