mds元信息缓存不释放问题
时间:2022-07-22
本文章向大家介绍mds元信息缓存不释放问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1. 问题:
ceph集群警告信息如下:
ceph -s
health HEALTH_WARN
mds0: Client xxx-online00.gz01 failing to respond to cache pressure
2. 分析问题过程
2.1 官方解释
类型 |
描述 |
---|---|
消息: |
“Client name failing to respond to cache pressure” |
代码: |
MDS_HEALTH_CLIENT_RECALL,MDS_HEALTH_CLIENT_RECALL_MANY |
描述: |
客户端有各自的元数据缓存,客户端缓存中的条目(比如索引节点)也会存在于 MDS 缓存中,所以当 MDS 需要削减其缓存时(保持在 mds_cache_size 以下),它也会发消息给客户端让它们削减自己的缓存。如果有客户端没响应或者有缺陷,就会妨碍 MDS 将缓存保持在 mds_cache_size 以下, MDS 就有可能耗尽内存而后崩溃。如果某个客户端的响应时间超过了 mds_recall_state_timeout (默认为 60s ),这条消息就会出现。 |
2.2 查看客户端session
$ ceph daemon mds.ceph-epnfs-mds01.gz01 session ls
[
{
"id": 4746087,
"num_leases": 9,
"num_caps": 57368,
"state": "open",
"replay_requests": 0,
"completed_requests": 1,
"reconnecting": false,
"inst": "client.4746087 10.1.7.1:0/1700679012",
"client_metadata": {
"entity_id": "admin",
"hostname": "test-hostname00",
"kernel_version": "3.10.0-514.16.1.el7.x86_64"
}
}
]
2.3 查看客户端inode
跟踪代码发现num_caps就是统计的客户端的inode数量, 大概统计了下已经打开的inode数量。
2.4 尝试mds主从切换
2.4.1 执行过程如下
主从切换流程:
- handle_mds_map state change up:boot --> up:replay
- handle_mds_map state change up:replay --> up:reconnect
- handle_mds_map state change up:reconnect --> up:rejoin
- handle_mds_map state change up:rejoin --> up:active
2.5. 主从mds切换结论
成功切换主从角色
2.6. 主从mds切换问题
- mds在切换过程中,导致繁忙cpu很高,在mds_beacon_grace(默认15s)时间内没有向monitor注册,没有及时汇报心跳给mon,导致mds自杀。
- mds主从切换open inode并没有释放
3. 深入问题分析
3.1 mds切换过程导致mds自杀
问题:mds在切换过程中,导致繁忙cpu很高,在mds_beacon_grace(默认15s)时间内没有向monitor注册,没有及时汇报心跳给mon,导致mds自杀。
mds存储:
- 元数据的内存缓存,为了加快元数据的访问。
- 保存了文件系统的元数据(对象里保存了子目录和子文件的名称和inode编号)
- 还保存cephfs日志journal,日志是用来恢复mds里的元数据缓存
- 重启mds的时候会通过replay的方式从osd上加载之前缓存的元数据
mds冷备/热备:
- 冷备就是备份的mds,只起到一个进程备份的作用,并不备份lru元数据。主备进程保持心跳关系,一旦主的mds挂了,备份mds replay()元数据到缓存,当然这需要消耗一点时间。
- 热备除了进程备份,元数据缓存还时时刻刻的与主mds保持同步,当 active mds挂掉后,热备的mds直接变成主mds,并且没有replay()的操作,元数据缓存大小和主mds保持一致。
说明:
- rejoin把客户端的inode加载到mds cache
- replay把从cephfs的journal恢复内存
mds主备切换策略:
- 默认每个standby都一样
- 指定后补
- mds standby for name指定一 MDS 守护进程的名字,此进程将作为它的候补
- mds standby for rank此 MDS 将作为本机架上 MDS 守护进程的候补
- 优先级最高standby replay
节点失效机制:
- 一个活跃的MDS定期向monitor发送交互信息,如果一个MDS在mds_beacon_grace(默认15s)时间内没有向monitor注册,则认为该MDS失效。
恢复过程:
- 失效节点的相关日志被读入内存;
- 处理有争议的子树分配问题和涉及多个MDS的transaction;
- 与client重新建立会话并重新保存打开文件的状态;
- 接替失效节点的MDS加入到MDS集群的分布式缓存中
resolve阶段的事件:
- 恢复节点向所有MDS发送一个resolve信息,该信息中包含了当前恢复节点管理的子树、在迁移过程中出现故障的子树;
- 其他正常运行的MDS也要将这些信息发送给正在恢复的MDS;
- 恢复中的MDS根据收到的子树信息重建自己缓存中的子树层次结构。
重建分布式缓存和锁状态:
- 恢复节点向所有MDS发送一个rejoin信息,该信息包含了恢复节点所知道的接受节点拥有的元数据副本信息并宣称自己没有管理的恢复文件;
- 原来有效的节点向恢复节点发送信息,告诉恢复节点自己拥有的元数据副本,并且向恢复节点加入锁状态
- 恢复节点将自己原本不知道的副本信息加入到自己的缓存中
为啥mds切换导致cpu高?
- 分析日志(发现执行rejoin_start动作只会就超时)
2018-04-27 19:12:21.909280 7f8268805700 1 mds.0.2665 rejoin_start
2018-04-27 19:12:37.294438 7f826a809700 1 heartbeat_map is_healthy 'MDSRank' had timed out after 15
2018-04-27 19:12:40.961787 7f82656fe700 1 heartbeat_map is_healthy 'MDSRank' had timed out after 15
2018-04-27 19:12:40.961796 7f82656fe700 1 mds.beacon.ceph-xxx-mds01.gz01 _send skipping beacon, heartbeat map not healthy
2018-04-27 19:12:42.294507 7f826a809700 1 heartbeat_map is_healthy 'MDSRank' had timed out after 15
- 2.跟踪代码分析(在执行process_imported_caps超时了, 这个函数主要是打开inodes 加载到cache中)
-
- 跟踪官方bug列表发现补丁(解决主从mds切换超时自杀, 以及merge到目标版本13.0.0) https://github.com/ceph/ceph/pull/21144
- 4.跟踪补丁代码分析(inode到了1000个,mds 心跳reset, 禁止自杀行为)
3.2 mds主从切换open inode没有释放
问题:mds主从切换open inode没有释放,mds集群显示mds0: Client xxx-online00.gz01 failing to respond to cache pressure 解决方式:(由于inode都缓存在client端,所以必须的想办法释放inode)
- 方案1:evict client(主动踢出有问题的客户端)
- 方案2:client remount(有问题的客户端重新mount挂载)
- 方案3:drop_cache(官方提供的mds 主动删除cache,补丁在review过程中个,目标版本是ceph-14.0.0) https://github.com/ceph/ceph/pull/21566
- 写一只具有识别能力的图片爬虫
- 【今日问题】变量未初始化引起的崩溃
- 前端特效开发 | 点击查看大图相册效果
- 开发 | 星际争霸2人工智能研究环境 SC2LE 初体验
- 开发 | 我做了12万条的影评分析,告诉你《战狼Ⅱ》都在说些啥
- JavaScript | 函数定义的两种方法;预编译与执行
- jQuery特效 | 导航底部横线跟随鼠标缓动
- JavaScript | 选中并获取多行文本框内容的效果
- JavaScript | 动画显示比例的投票效果
- 原生JS | 作用域
- 腾讯、网易、新浪新闻网站爬虫编写记录及评论格式分析
- 原生JS | 随机抽取不重复的数组元素 —— 有没有更好的方法?
- 原生JS | 逻辑操作符的短路问题
- 数字识别,从KNN,LR,SVM,RF到深度学习
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 没内鬼,来点干货!SQL优化和诊断
- 好像很厉害的生成器!一秒钟搞定一个项目
- 【一起学系列】之策略模式:好多鸭子啊
- 没内鬼,来点干货!volatile和synchronized
- 【一起学系列】之观察者模式:我没有在监控你啊
- Celery 4 初体验及踩坑
- MySQL 最佳实践:gh-ost 工具使用详解
- 如何将 Hexo 博客部署到云开发静态网站托管
- WordPress 静态化部署到云开发网站托管
- 如何用云应用快速部署一个nodebb的开源论坛
- 【一起学系列】之装饰器模式:不改代码增强功能?
- Hello!GitHub 好用好玩值得收藏的开源项目集合~
- 【一起学系列】之工厂模式:产品?产品族?
- 再见,Navicat!同事安利的这个IDEA的兄弟,真香!
- 【一起学系列】之单例模式:只推荐三种~