ivanjobs.github.io - Ceph故障解析-filestore_merge_threshold









Search Preview

Ceph故障解析-filestore_merge_threshold | Ivan的博客

ivanjobs.github.io
最近参与了一项Ceph新老集群数据迁移的工作,在解决Block Requests故障领域,积累了第一份经验。本篇博客,旨在介绍 这次故障的现象以及原理分析。
.io > ivanjobs.github.io

SEO audit: Content analysis

Language Error! No language localisation is found.
Title Ceph故障解析-filestore_merge_threshold | Ivan的博客
Text / HTML ratio 38 %
Frame Excellent! The website does not use iFrame solutions.
Flash Excellent! The website does not have any flash contents.
Keywords cloud = ret Ceph return int Python Mesos < mesos vector return_code OpenStack include iter path struct info expected_num_objs dir result
Keywords consistency
Keyword Content Title Description Headings
= 22
ret 15
Ceph 14
return 13
int 9
Python 7
Headings
H1 H2 H3 H4 H5 H6
1 0 4 0 2 0
Images We found 1 images on this web page.

SEO Keywords (Single)

Keyword Occurrence Density
= 22 1.10 %
ret 15 0.75 %
Ceph 14 0.70 %
return 13 0.65 %
int 9 0.45 %
Python 7 0.35 %
Mesos 7 0.35 %
< 6 0.30 %
mesos 5 0.25 %
vector 5 0.25 %
return_code 5 0.25 %
OpenStack 4 0.20 %
include 4 0.20 %
iter 4 0.20 %
path 4 0.20 %
struct 4 0.20 %
info 4 0.20 %
expected_num_objs 4 0.20 %
dir 4 0.20 %
result 4 0.20 %

SEO Keywords (Two Word)

Keyword Occurrence Density
< return 6 0.30 %
ret = 5 0.25 %
return ret 5 0.25 %
ret < 5 0.25 %
if ret 5 0.25 %
number of 3 0.15 %
return_code = 3 0.15 %
struct dirent 3 0.15 %
DIR dir 2 0.10 %
if dir 2 0.10 %
entry result 2 0.10 %
iter = 2 0.10 %
need to 2 0.10 %
the number 2 0.10 %
split if 2 0.10 %
Ceph RGW 2 0.10 %
readdir_rdir entry 2 0.10 %
= readdir_rdir 2 0.10 %
closedirdir return 2 0.10 %
dir = 2 0.10 %

SEO Keywords (Three Word)

Keyword Occurrence Density Possible Spam
< return ret 5 0.25 % No
ret < return 5 0.25 % No
if ret < 5 0.25 % No
the number of 2 0.10 % No
readdir_rdir entry result 2 0.10 % No
= readdir_rdir entry 2 0.10 % No
return_code = readdir_rdir 2 0.10 % No
最新文章 dev ops 1 0.05 % No
ret subdir_info_s info 1 0.05 % No
subdir_info_s info infosubdirs 1 0.05 % No
info infosubdirs = 1 0.05 % No
infosubdirs = subdirssize 1 0.05 % No
= subdirssize infohash_level 1 0.05 % No
infohash_level = hash_level 1 0.05 % No
subdirssize infohash_level = 1 0.05 % No
subdirs if ret 1 0.05 % No
= hash_level ret 1 0.05 % No
hash_level ret = 1 0.05 % No
ret = set_infopath 1 0.05 % No
= set_infopath info 1 0.05 % No

SEO Keywords (Four Word)

Keyword Occurrence Density Possible Spam
ret < return ret 5 0.25 % No
if ret < return 5 0.25 % No
= readdir_rdir entry result 2 0.10 % No
return_code = readdir_rdir entry 2 0.10 % No
hash_level ret = set_infopath 1 0.05 % No
info infosubdirs = subdirssize 1 0.05 % No
infosubdirs = subdirssize infohash_level 1 0.05 % No
= subdirssize infohash_level = 1 0.05 % No
subdirssize infohash_level = hash_level 1 0.05 % No
infohash_level = hash_level ret 1 0.05 % No
= hash_level ret = 1 0.05 % No
最新文章 dev ops math 1 0.05 % No
ret subdir_info_s info infosubdirs 1 0.05 % No
ret = set_infopath info 1 0.05 % No
= set_infopath info if 1 0.05 % No
set_infopath info if ret 1 0.05 % No
info if ret < 1 0.05 % No
< return ret ret 1 0.05 % No
return ret ret = 1 0.05 % No
ret ret = fsync_dirpath 1 0.05 % No

Internal links in - ivanjobs.github.io

开始使用gtest
开始使用gtest | Ivan的博客
寻找正确的语义[比赛总结]
寻找正确的语义[比赛总结] | Ivan的博客
score_thresholder服务开发总结
score_thresholder服务开发总结 | Ivan的博客
Debug CPP Program On Ubuntu
Debug CPP Program On Ubuntu | Ivan的博客
Modern CPP Developer Need To Know
Modern CPP Developer Need To Know | Ivan的博客
汇编语言学习笔记
汇编语言学习笔记 | Ivan的博客
Mesos Quota 和 Reservation
Mesos Quota 和 Reservation | Ivan的博客
libprocess学习笔记
libprocess学习笔记 | Ivan的博客
Consul使用笔记
Consul使用笔记 | Ivan的博客
SSH重新学习
SSH重新学习 | Ivan的博客
Protocol buffers 代码入门
Protocol buffers 代码入门 | Ivan的博客
Mesos Slave 如何上报资源?
Mesos Slave 如何上报资源? | Ivan的博客
Object Locator (Ceph) 探究笔记
Object Locator (Ceph) 探究笔记 | Ivan的博客
librados接口使用
librados接口使用 | Ivan的博客
Ceph RGW Pools 浅析
Ceph RGW Pools 浅析 | Ivan的博客
在单机上搭建多Ceph集群
在单机上搭建多Ceph集群 | Ivan的博客
Dockerfile中RUN/CMD/ENTRYPOINT的区分
Dockerfile中RUN/CMD/ENTRYPOINT的区分 | Ivan的博客
strace使用入门
strace使用入门 | Ivan的博客
Haystack论文学习笔记
Haystack论文学习笔记 | Ivan的博客
Mesos关联配置
Mesos关联配置 | Ivan的博客
ZooKeeper概览
ZooKeeper概览 | Ivan的博客
Ceph故障解析-filestore_merge_threshold
Ceph故障解析-filestore_merge_threshold | Ivan的博客
基于laravel+mysql的容器化DAL方案
基于laravel+mysql的容器化DAL方案 | Ivan的博客
vuejs使用小结1
vuejs使用小结1 | Ivan的博客
Ceph新技能Get
Ceph新技能Get | Ivan的博客
Ceph v10.2.3 RGW源码解析2
Ceph v10.2.3 RGW源码解析2 | Ivan的博客
Ceph v10.2.3 RGW源码解析1
Ceph v10.2.3 RGW源码解析1 | Ivan的博客
s3cmd使用说明
s3cmd使用说明 | Ivan的博客
vuejs工具链简介
vuejs工具链简介 | Ivan的博客
requirejs简介
requirejs简介 | Ivan的博客
可编程自动化输入方案(Mac下)
可编程自动化输入方案(Mac下) | Ivan的博客
Mesos Supress/Revive Offers测试
Mesos Supress/Revive Offers测试 | Ivan的博客
Mesos Offer生命周期杂记
Mesos Offer生命周期杂记 | Ivan的博客
Mesos Agent Containerizer分析
Mesos Agent Containerizer分析 | Ivan的博客
get started with createjs chapter 1 notes
get started with createjs chapter 1 notes | Ivan的博客
mesos agent /monitor/statistics返回数据业务意义
mesos agent /monitor/statistics返回数据业务意义 | Ivan的博客
mesos master/messages_deactivate_frameworks 不生效?
mesos master/messages_deactivate_frameworks 不生效? | Ivan的博客
KMP算法杂谈
KMP算法杂谈 | Ivan的博客
Mesos配置项深入分析
Mesos配置项深入分析 | Ivan的博客
mesos-master replicated_log存的是什么?
mesos-master replicated_log存的是什么? | Ivan的博客
mesos disk usage vs df 结果不一致问题
mesos disk usage vs df 结果不一致问题 | Ivan的博客
Mesos GC原理解析
Mesos GC原理解析 | Ivan的博客
准备mesos单机版开发测试环境
准备mesos单机版开发测试环境 | Ivan的博客
Mesos 1.0.0 源码解析杂记
Mesos 1.0.0 源码解析杂记 | Ivan的博客
stout学习笔记
stout学习笔记 | Ivan的博客
gflags学习笔记
gflags学习笔记 | Ivan的博客
ceph fuse挂载cephfs, ls不出文件列表问题,调试记录
ceph fuse挂载cephfs, ls不出文件列表问题,调试记录 | Ivan的博客
Ceph源码解析(3)-rados put过程探究
Ceph源码解析(3)-rados put过程探究 | Ivan的博客
Hub,Bridge,Switch和Gateway是什么?
Hub,Bridge,Switch和Gateway是什么? | Ivan的博客
数论学习笔记
数论学习笔记 | Ivan的博客
二分图专题解析
二分图专题解析 | Ivan的博客
Ceph Cluster调优日志
Ceph Cluster调优日志 | Ivan的博客
boost库的智能指针
boost库的智能指针 | Ivan的博客
Linux命令使用记录
Linux命令使用记录 | Ivan的博客
Vim Cheat Sheet
Vim Cheat Sheet | Ivan的博客
原码、反码、补码笔记
原码、反码、补码笔记 | Ivan的博客
ceph-deploy 配置文件比较 BUG
ceph-deploy 配置文件比较 BUG | Ivan的博客
Ceph源码解析(2)-rados put过程探究
Ceph源码解析(2)-rados put过程探究 | Ivan的博客
Ceph Release 概述
Ceph Release 概述 | Ivan的博客
Ceph CRUSH Map 维护详解
Ceph CRUSH Map 维护详解 | Ivan的博客
题解[第二周]
题解[第二周] | Ivan的博客
MathQuill Math Equation Cheatsheet
MathQuill Math Equation Cheatsheet | Ivan的博客
题解[第一周]
题解[第一周] | Ivan的博客
Ceph集群运维问题记录
Ceph集群运维问题记录 | Ivan的博客
linux man高级技巧
linux man高级技巧 | Ivan的博客
Git 我错了!
Git 我错了! | Ivan的博客
Ceph源码解析(1)-Create Pool过程探究
Ceph源码解析(1)-Create Pool过程探究 | Ivan的博客
准备Ceph开发环境
准备Ceph开发环境 | Ivan的博客
Ceph:Too Many PGs Per OSD
Ceph:Too Many PGs Per OSD | Ivan的博客
UVA 11292 题解
UVA 11292 题解 | Ivan的博客
Ceph RBD 文件映射实验笔记
Ceph RBD 文件映射实验笔记 | Ivan的博客
硬盘分区
硬盘分区 | Ivan的博客
硬盘模型
硬盘模型 | Ivan的博客
Ceph配置项
Ceph配置项 | Ivan的博客
OSTEP 文件系统实现
OSTEP 文件系统实现 | Ivan的博客
在Ceph底层xfs上找到你上传的文件
在Ceph底层xfs上找到你上传的文件 | Ivan的博客
使用s3cmd操作ceph rgw
使用s3cmd操作ceph rgw | Ivan的博客
Ceph核心概念备忘录
Ceph核心概念备忘录 | Ivan的博客
COSBench使用笔记
COSBench使用笔记 | Ivan的博客
使用saltstack部署运维ceph集群笔记
使用saltstack部署运维ceph集群笔记 | Ivan的博客
如何使用salt states?
如何使用salt states? | Ivan的博客
ceph-deploy命令详解
ceph-deploy命令详解 | Ivan的博客
dd笔记
dd笔记 | Ivan的博客
DTrace是什么?
DTrace是什么? | Ivan的博客
Ceph Cache Tier笔记
Ceph Cache Tier笔记 | Ivan的博客
Linux下理解filesystem/device/mount等概念
Linux下理解filesystem/device/mount等概念 | Ivan的博客
Base64编码详解与应用
Base64编码详解与应用 | Ivan的博客
URLEncoder学习笔记
URLEncoder学习笔记 | Ivan的博客
Ceph论文阅读笔记
Ceph论文阅读笔记 | Ivan的博客
使用Python inotify监控文件变化
使用Python inotify监控文件变化 | Ivan的博客
Git命令Snippets
Git命令Snippets | Ivan的博客

Ivanjobs.github.io Spined HTML


Ceph故障解析-filestore_merge_threshold | Ivan的博客 最新文章 dev ops math algorithm personal 开始使用gtest 2018书单课单 2017年总结/2018年展望 寻找正确的语义[比赛总结] score_thresholder服务开发总结 Debug CPP Program On Ubuntu Modern CPP Developer Need To Know 汇编语言学习笔记 Mesos Quota 和 Reservation libprocess学习笔记 Consul使用笔记 SSH重新学习 Protocol buffers 代码入门 Mesos Slave 如何上报资源? Object Locator (Ceph) 探究笔记 librados接口使用 Ceph RGW Pools 浅析 在单机上搭建多Ceph集群 2016年总结/2017年展望 Dockerfile中RUN/CMD/ENTRYPOINT的区分 strace使用入门 Haystack论文学习笔记 Mesos关联配置 ZooKeeper概览 Ceph故障解析-filestore_merge_threshold 基于laravel+mysql的容器化DAL方案 vuejs使用小结1 Ceph新技能Get Ceph v10.2.3 RGW源码解析2 Ceph v10.2.3 RGW源码解析1 s3cmd使用说明 vuejs工具链简介 requirejs简介 mesos maintenance深度解析 可编程自动化输入方案(Mac下) Mesos Supress/Revive Offers测试 Mesos Offer生命周期杂记 MesosWage-earnerContainerizer分析 get started with createjs installment 1 notes mesos wage-earner /monitor/statistics返回数据业务意义 mesos master/messages_deactivate_frameworks 不生效? mesos /flags 403 forbidden? KMP算法杂谈 Mesos配置项深入分析 mesos-master replicated_log存的是什么? mesos disk usage vs df 结果不一致问题 Mesos GC原理解析 准备mesos单机版开发测试环境 Mesos 1.0.0 源码解析杂记 stout学习笔记 gflags学习笔记 ceph fuse挂载cephfs, ls不出文件列表问题,调试记录 Ceph源码解析(3)-rados put过程探究 Hub,Bridge,Switch和Gateway是什么? 数论学习笔记 二分图专题解析 Ceph Cluster调优日志 boost库的智能指针 Linux命令使用记录 Vim Cheat Sheet 原码、反码、补码笔记 ceph-deploy 配置文件比较 BUG Ceph源码解析(2)-rados put过程探究 Ceph Release 概述 Ceph CRUSH Map 维护详解 题解[第二周] MathQuill Math Equation Cheatsheet 题解[第一周] Ceph集群运维问题记录 linux man高级技巧 Git 我错了! Ceph源码解析(1)-Create Pool过程探究 准备Ceph开发环境 Ceph:Too Many PGs Per OSD UVA 11292 题解 Docker Private Registry(Ceph Swift) 搭建笔记 Ceph RBD 文件映射实验笔记 硬盘分区 硬盘模型 Ceph配置项 OSTEP 文件系统实现 在Ceph底层xfs上找到你上传的文件 使用s3cmd操作ceph rgw Ceph核心概念备忘录 COSBench使用笔记 GCJ2015 Qualification Round-B题解 使用saltstack部署运维ceph集群笔记 如何使用salt states? ceph-deploy命令详解 dd笔记 DTrace是什么? Ceph Cache Tier笔记 Linux下理解filesystem/device/mount等概念 Base64编码详解与应用 URLEncoder学习笔记 Ceph论文阅读笔记 使用Python inotify监控文件变化 Git命令Snippets 使用Nginx做LB MathQuill学习笔记 Docker化Laravel开发环境 Ceph Pool PG配置说明 Ceph 笔记 Ceph源码分析 Latex数学符号 为Ceph OSS服务搭建LB Ceph RGW S3接口测试:诡异的403 AccessDenied问题 访问Ceph RGW失败 403 Forbidden问题 解决历程 Ceph RADOS论文研读笔记 Ceph源码分析:从一个REST请求,到OSD存储。 各种开源代码协议简述 OpenStack Projects简述 OpenStack Ceilometer 笔记 RabbitMQ 和 oslo.messaging Ceph Rest API 身份验证方式(S3) tcpdump笔记 Ceph集群部署笔记 Python PEP8规范笔记 Python Decorator(装饰器)模式 笔记 libvirt笔记 OpenStack oslo 概览 OpenStack KeyStone API http://localhost:5000/ 源码追踪 Python pdb笔记 zero length variety in a struct Jenkins' Hash Functions NTP部署笔记 Linux iptables笔记 Python Paste笔记 Python PasteDeploy笔记 Python eventlet笔记 使用curl测试RESTful接口 ubuntu14.04下安装devstack devstack 安装指南【最简单】 Docker操作记录 git merge 详解 Python 包管理详解 阿里云服务器设置swapfile的方法 shell脚本编写向导 搭建Laravel全栈开发环境 2016 December 08 Ceph故障解析-filestore_merge_threshold 最近参与了一项Ceph新老集群数据迁移的工作,在解决Block Requests故障领域,积累了第一份经验。本篇博客,旨在介绍 这次故障的现象以及原理分析。 背景描述 ceph老集群有大概3亿的对象需要迁移,于是基于S3接口,一方面从老集群GET,另一方面向新集群PUT。 代码实现上,有一些核心细节:session复用,并发节流。 在迁移过程中,我们发现:迁移一定量数据之后,新Ceph集群就会出现大量Block Requests,并且伴有OSD的Down,fs_apply_latency奇高(几十秒级别)。 迁移速度根本无法接受。之后,我们尝试了各种方法,包括调优Ceph参数、调优文件系统参数、map alphabetize pool到SSD、使用SSD journal等,都未能解决本质问题。同样的问题,还是一再的重现。 问题解决 小伙伴们在“尸体”上进行观察,注意到一个现象,PG目录下的文件数,几乎都达到了5K级别。于是,自然的想到了单目录下文件个数不能太多,否则fs性能影响很大。 于是,照着这个靠谱的思路,重建集群、修改Ceph相关的配置参数,最终解决了问题。 原理解析 filestore_merge_threshold和filestore_split_multiple 这两个参数,决定了split的上限: abs(filestore_merge_threshold) * 16 * filestore_split_multiple。 filestore_merge_threshold决定了merge的下限。 // Do the folder splitting first ret = pre_split_folder(pg_num, expected_num_objs); if (ret < 0) return ret; // Initialize the folder info starting from root return init_split_folder(path, 0); } int HashIndex::pre_split_folder(uint32_t pg_num, uint64_t expected_num_objs) { // If folder merging is enabled (by setting the threshold positive), // no need to split if (merge_threshold > 0) return 0; const coll_t c = coll(); // Do not split if the expected number of objects in this hodgepodge is zero (by default) if (expected_num_objs == 0) return 0; // Calculate the number of leaf folders (which unquestionably store files) // need to be created const uint64_t objs_per_folder = (uint64_t)(abs(merge_threshold)) * (uint64_t)split_multiplier * 16; uint64_t leavies = expected_num_objs / objs_per_folder ; pre_split_folder用于对split做准备工作,init_split_folder: int HashIndex::init_split_folder(vector<string> &path, uint32_t hash_level) { // Get the number of sub directories for the current path vector<string> subdirs; int ret = list_subdirs(path, &subdirs); if (ret < 0) return ret; subdir_info_s info; info.subdirs = subdirs.size(); info.hash_level = hash_level; ret = set_info(path, info); if (ret < 0) return ret; ret = fsync_dir(path); if (ret < 0) return ret; // Do the same for subdirs vector<string>::const_iterator iter; for (iter = subdirs.begin(); iter != subdirs.end(); ++iter) { path.push_back(*iter); ret = init_split_folder(path, hash_level + 1); if (ret < 0) return ret; path.pop_back(); } return 0; } 递归遍历子目录,list_subdirs是干什么的? int LFNIndex::list_subdirs(const vector<string> &to_list, vector<string> *out) { string to_list_path = get_full_path_subdir(to_list); DIR *dir = ::opendir(to_list_path.c_str()); char buf[offsetof(struct dirent, d_name) + PATH_MAX + 1]; if (!dir) return -errno; struct dirent *de; while (!::readdir_r(dir, reinterpret_cast<struct dirent*>(buf), &de)) { if (!de) { break; } string short_name(de->d_name); string demangled_name; if (lfn_is_subdir(short_name, &demangled_name)) { out->push_back(demangled_name); } } ::closedir(dir); return 0; } 仅仅是递归遍历了目录,不是split核心逻辑所在。 int HashIndex::complete_split(const vector<string> &path, subdir_info_s info) { int level = info.hash_level; map<string, ghobject_t> objects; vector<string> dst = path; int r; dst.push_back(""); r = list_objects(path, 0, 0, &objects); if (r < 0) return r; complete_split时会list_objects。 以上大概列举了一些关键代码片段,具体的逻辑还需要深入研读源码。但有一点可以判断出来,就是在split的时候,确实会list_objects, 而且底层使用的是readdir_r。 XFS目录下文件个数,到底对性能影响有多大? 测试代码: #include <sys/types.h> #include <dirent.h> #include <errno.h> #include <stdio.h> int main() { int return_code; DIR *dir; struct dirent entry; struct dirent *result; if ((dir = opendir("./tmp")) == NULL) perror("opendir() error"); else { for (return_code = readdir_r(dir, &entry, &result); result != NULL && return_code == 0; return_code = readdir_r(dir, &entry, &result)) ;//do nothing if (return_code != 0) perror("readdir_r() error"); closedir(dir); } return 0; } 测试结果: 100: 0.001s 200: 0.001s 400: 0.001s 800: 0.001s 1600: 0.001s 3200: 0.001s 6400: 0.001s 12800: 0.002s 25600: 0.002s 50000: 0.004s 100000: 0.007s … 这个测试结果,可能看不出什么。因为测试脚本遍历每个对象,什么事也没做。如果把这部分加上,目录下文件个数,对整体性能的影响可见一斑。 总结 不可以不加测试的应用第三方的调优参数。 写入和重启OSD都会触发split check。 commit是写日志、apply是写数据。 短暂的低性能和block requests属于正常现象。 Please enable JavaScript to view the comments powered by Disqus. All content is licensed under CC BY-NC-SA Buit with Jekyll and 3-Jekyll theme • Hosted on Github Table of Contents