ren_sky 2020-07-23T03:21:35+00:00 sky_atlantis@sina.com.cn 虚拟化平台的种类 2019-09-24T00:00:00+00:00 ren_sky http://skyatlantis.github.io/虚拟化平台的种类 虚拟化平台常见的种类有如下4类 (1)VMware
(2)Hyper-V
(3)KVM
(4)XEN

]]>
开源协议区别 2019-09-24T00:00:00+00:00 ren_sky http://skyatlantis.github.io/开源协议区别 常见的开源协议有以下几种,排序从宽松到严格

MIT License

MIT许可协议之名源自麻省理工学院(Massachusetts Institute of Technology, MIT),又称“X许可协议”(X License)
或“X11许可协议”(X11 License)

常用的软件: PuTTY与X窗口系统、Expat、Mono、Rails、Lua、atom

BSD License

BSD 许可协议(英语:Berkeley Software Distribution license),是自由软件中使用最广泛的许可协议之一
BSD 包最初所有者是加州大学的董事会,这是由于 BSD 源自加州大学伯克利分校许可证文本被认为遵循公有领域,
所以可以不受限制地修改。为了满足个人或团体的需要,用户可以随意地将’Regents of the University of California’
(加州大学董事会), ‘University of California, Berkeley’(加州大学伯克利分校),以及’Regents’(董事会)替换
成自己的名称。(参考中译附于英文原文后)

常用的软件:
Django、Ruby、Redis等

Apache License

是一个由Apache软件基金会发布的自由软件许可证,最初为Apache http服务器而撰写。Apache许可证要求被授权者保留著作权和放弃权利的声明,但它不是一个反著作权的许可证 Apache 2.0在2004年发布,最新为3.0版本。截至2012年10月,在sourceforge上有8708个项目使用了Apache许可证。

常用的软件:
Android、spark等

Mozilla License

Mozilla公共许可证(英语:Mozilla Public License,简称MPL)是个自由、开源、详细的软件许可证,由Mozilla基金会开发并维护。该协议融合了BSD许可证和GNU通用公共许可协议的特性,追求平衡专有软件和开源软件开发者之间的顾虑。[6] 此协议已有两个版本,[7]最新发布的2.0版以更简洁和更好的兼容其他协议为目标

常用软件:
FIrefox等

LGPL License

GNU宽通用公共许可证(英语:GNU Lesser General Public License,简称:LGPL)是由自由软件基金会公布的自由软件许可证。它允许企业与软件开发者使用,或将LGPL授权的软件集成至他们自己的软件内(即使该软件是私有软件也被允许),同时不会受到Copyleft特性的许可证强制对软件开源的限制。该许可证常被用于一些(但不是全部)GNU程序库。 这个许可证以前被称为GNU程序库通用公共许可证(GNU Library General Public License)。此许可证最新版本为“第3版”,2007年6月29日发布,较早的版本有2.0和2.1版。此种许可之出现,是为了在GPL与许可式许可(如MIT许可证及柏克莱大学的BSD许可证)间获取折衷。

常用软件:
Ceph等

GPL License

GNU通用公共许可协议(英语:GNU General Public License,缩写GNU GPL 或 GPL),是被广泛使用的自由软件许可证, 给予了终端用户运行、学习、共享和修改软件的自由。[6]许可证最初由自由软件基金会的理查德·斯托曼为GNU项目所撰写, 并授予计算机程序的用户自由软件定义(The Free Software Definition)的权利。 [7] GPL是一个Copyleft许可证, 这意味着派生作品只能以相同的许可条款分发。 这与宽松自由软件许可证有所区别 ,如BSD许可证和MIT许可证就是其中被广泛使用的例子。 GPL是第一个普遍使用的Copyleft许可证

常用软件 Linux、samba等

参考

https://www.zhihu.com/question/19568896

]]>
RCU锁机制 2019-06-26T00:00:00+00:00 ren_sky http://skyatlantis.github.io/RCU锁机制 为什么需要RCU锁:

RCU是2.6内核引入的新锁机制,为什么在已经存在自旋锁(spinlock)和读写锁(rwlock)的情况下,还需要引入新的锁机制? 有下面3个原因: (1)这是因为随着CPU的速度越来越快,与访问内存的速度差距也越来越大(访问内存的速度变化较小),这自旋锁和读写锁是基于原
子的访问内存空间,因此加锁的应用在内存访问速度没有变化的情况下,越来越快的CPU,并没有提高加锁应用程序的性能;
(2)另外在大部分非x86操作系统中,获取锁使用的是memory barrier技术,这会导致高速CPU流水线停滞和刷新;
(3)老的锁机制在多核系统下,无法发挥其性能,比如rwlock在2核场景比在单核下要差。
正是在这种情况下,新的RCU锁机制呼之欲出。

RCU锁:

RCU锁首先是一种高性能锁,且有好的扩展性,但它的应用场景比较窄,只适合读多写少的场景。
RCU(Read-Copy-Update)顾名思义读-拷贝修改,被RCU保护的共享数据,读操作不需要获取任何锁就可以访问,但写者在访问它时, 首先会拷贝一个副本,然后对副本进行修改,再使用callback机制在适当的时候,把指向原来数据的部分指向新修改的数据。 这个时机就是所有引用该数据的CPU都退出对共享数据的操作。 可以看到RCU锁的优势是读没有锁开销,因此读的性能很高,但写的开销就比较大,它需要延迟数据结构的释放,复制被修改的数据结构, 它也必须使用某种锁机制同步并行的其它写者的修改操作。读者必须提供一个信号给写者以便写者能够确定数据可以被安全地释放或修改 的时机

RCU与rwlock的区别在于,RCU不但允许多个读者访问共享数据,还允许多个读者和写者同时访问共享数据空间(多写,需要其它锁来保存写是顺序性) 因此读操作不会受到写锁的影响,在一次写多读的情况下,性能会有显著的提示,但是如果有多写的情况下,则RCU的性能会由于写锁开销大,导致 整体性能下降。 rwlock锁的最大特点是排它性,即有写锁时,读锁时阻塞等待的,有读时,不能有写,这样性能比较差,但数据一致性比RCU要好,rwlock的改进锁 seqlock(顺序锁)则是在rwlock的基础上进行改进,它只对写加锁,且写加锁时,读可以继续操作,但存在在写完成后读取会被回滚丢弃,重新读 取新的值,也就是说seqlock仍然是一个顺序读写的屏障,所以叫做顺序锁。因为seqlock只有写操作需要加锁,写操作发生的时候不需要等待读的锁 释放。而rwlock则是读写互斥,当写入发生的时候需要等待读取结束。

参考:

https://www.ibm.com/developerworks/cn/linux/l-rcu/index.html https://zhuanlan.zhihu.com/p/56404913

]]>
文件锁机制 2019-06-26T00:00:00+00:00 ren_sky http://skyatlantis.github.io/文件锁 需要基础知识介绍:

linux支持的文件锁技术主要包括以下2种类型的锁
(1)劝告锁(advisory lock)
内核只提供加锁以及检测文件是否已经加锁的手段,但是内核并不参与锁的控制和协调。也就是说,
如果有进程不遵守“游戏规则”,不检查目标文件是否已经由别的进程加了锁就往其中写入数据,那么
内核是不会加以阻拦的。因此,劝告锁并不能阻止进程对文件的访问,而只能依靠各个进程在访问文
件之前检查该文件是否已经被其他进程加锁来实现并发控制。
(2)强制锁(mandatory lock)
与劝告锁不同,强制锁是一种内核强制采用的文件锁,它是从 System V Release 3 开始引入的。
每当有系统调用 open()、read() 以及write() 发生的时候,内核都要检查并确保这些系统调用
不会违反在所访问文件上加的强制锁约束。也就是说,如果有进程不遵守游戏规则,硬要往加了锁
的文件中写入内容,内核就会加以阻拦:
a> 如果一个文件已经被加上了读锁或者共享锁,那么其他进程再对这个文件进行写操作就会被内核阻止;
b> 被加上了写锁或者排他锁,那么其他进程再对这个文件进行读取或者写操作就会被内核阻止。
c> 访问一个已经加有强制锁的文件,只有在读锁可以正常运行。写锁时,将被阻塞

文件锁类型:

Linux调用文件锁,有以下2种类型,lockf是库函数,是fcntl的封装版本,不单独介绍. (1)flock (2)fcntl

flock:

flock的特性包括以下几个方面:
(1)只能对整个文件进行加锁
(2)flock只能产生劝告性锁
(3)flock可以有共享锁和排它锁 (4)flock和fcntl/lockf的区别主要在fork和dup时候的区别 (5)flock不能在NFS文件系统上使用,如果要在NFS使用文件锁,请使用fcntl。

函数原型:
int flock(int fd,int operation);
operation包括如下4种类型
(1)LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定
(2)LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定
(3)LOCK_UN 解除文件锁定状态
(4)LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。

示例:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/file.h>

int main()
{
    int fd,i;
    char path[]="/home/taoyong/test.txt";
    char s[]="writing.../nwriting....../n";
    extern int errno;
    fd=open(path,O_WRONLY|O_CREAT|O_APPEND);
    if(fd!=-1)
            {
        printf("open file %s ./n",path);

            if(flock(fd,LOCK_EX|LOCK_NB)==0)
            {
            printf("the file was locked by the process./n");    
                if(-1!=write(fd,s,sizeof(s)))
                    {
                printf("write %s to the file %s/n",s,path);
                        }
                else
                       {
                printf("cannot write the file %s/n",path);
                printf("errno:%d/n",errno);
                printf("errMsg:%s/n",strerror(errno));
                    }        
                
            }
        else
            {
            printf("the file was locked by other process.Can't write.../n");
                printf("errno:%d:",errno);
            }
        
        close(fd);


            }
        else
           {
        printf("cannot open file %s/n",path);
        printf("errno:%d/n",errno);
        printf("errMsg:%s",strerror(errno));
            }
}

fcntl:

fcntl括以下几个方面:
(1)可以对文件某一部分加锁
(2) 加读锁(共享锁)文件必须是读打开的,加写锁(排他锁)文件必须是写打开。
(3)进程不能使用F_GETLK命令来测试它自己是否再文件的某一部分持有一把锁。
(4)进程终止时,他所建立的所有文件锁都会被释放(同flock)。
(5)任何时候关闭一个描述符时,则该进程通过这一描述符可以引用的文件上的任何一把锁都被释放(这些锁都是该进程设置的),这一点与flock不同。
(6) fork产生的子进程不继承父进程所设置的锁,这点与flock也不同。(因为flock创建的锁是和文件打开表项(struct file)
相关联的,而不是fd,所以复制出了fd都可以操作这把锁,所以子进程继承了父进程的锁。flock里面要关闭所有复制出的fd,锁才会释放)
(7)在执行exec后,新程序可以继承原程序的锁,这点和flock是相同的。(如果对fd设置了close-on-exec,则exec前会关闭fd,相应文件的锁也会被释放)
(8)支持强制性锁(跟flock不同)。

函数原型:int fcntl(int fd, int cmd, struct flock * lock)
其中第3个参数arg由cmd来控制
cmd的功能包括如下部分:
(1)复制一个现有的描述符(cmd=F_DUPFD/F_DUPFD_CLOEXEC) (2)获得/设置文件描述符标记(cmd=F_GETFD/F_SETFD) (3)获得/设置文件状态标记(cmd=F_GETFL/F_SETFL) (4)获得/设置异步I/O所有权(cmd=F_GETOWN/F_SETOWN) (5)获得/设置记录锁(cmd=F_GETLK/F_SETLK/F_SETLKW)

代码示例:

> #include <unistd.h>   
#include <fcntl.h>   
#include <stdio.h>   
#include <stdlib.h>   
#include <errno.h>    
#include <string.h>   
#define ERR_EXIT(m) \    
    do { \   
        perror(m); \   
        exit(EXIT_FAILURE); \    
    } while(0)    
int main(int argc, char *argv[])   
{   
    int fd;    
    fd = open("test2.txt", O_CREAT | O_RDWR | O_TRUNC, 0664);    
    if (fd == -1)    
        ERR_EXIT("open error");     
    /* 只有对文件有相应的读写权限才能施加对应的文件锁 */    
    struct flock lock;    
    memset(&lock, 0, sizeof(lock));    
    lock.l_type = F_WRLCK; // 排他锁,即不允许其他进程再对其加任何类型的锁,但读锁(共享锁)允许    
    lock.l_whence = SEEK_SET;    
    lock.l_start = 0; //从文件开头开始锁定    
    lock.l_len = 0; // 文件全部内容锁住    
    if (fcntl(fd, F_SETLK, &lock) == 0)    
    {   
        /* 若为F_SETLKW,这时如果锁已经被其他进程占用,则此进程会阻塞直到其他进程释放锁*/   
        printf("lock success\n");   
        printf("press any key to unlock\n");   
        getchar();   
        lock.l_type = F_UNLCK;   
        if (fcntl(fd, F_SETLK, &lock) == 0)    
            printf("unlock success\n");   
        else   
            ERR_EXIT("unlock fail");   
    }   
    else   
        ERR_EXIT("lock fail");   
    return 0; //进程退出会对所有文件解锁    
}  

参考:
https://www.cnblogs.com/charlesblc/p/6287631.html
https://www.ibm.com/developerworks/cn/linux/l-cn-filelock/index.html

]]>
FIO性能测试和调试方式 2019-06-26T00:00:00+00:00 ren_sky http://skyatlantis.github.io/blktrace 使用:

blktrace工具用于分析内核块设备层以及磁盘的性能,也可用于分析在该磁盘上运行的业务IO模型,我们通常用blktrace分析虚拟机里云盘的时延以及业务IO模型。 (1) blktrace 工具安装,blktrace工具包一般会包含在系统的iso中,可以通过yum install 或rpm安装 (2) mount -t debugfs debugfs /sys/kernel/debug (3) 使用blktrace收集IO信息 blktrace -d /dev/vdb -w 30 -d: 表示收集哪个磁盘的IO,可以设置多个 -w: IO收集时间,单位为s,到时间会命令自动退出,如果不设置,可以用ctrl + c 退出 blktrace退出后,会生成多个以磁盘名开头的多个文件。 (4) 使用blkparse工具对收集到信息进行解析。 blkparse -i vdb -d vbd.blktrace.bin -d: 表示将结果输出到文件中 blkparse输出结果: 43,0 15 172150 0.323236306 3043800 M W 21102073 + 1 [kworker/u898:1] 各字段的含义见下表: 字段 含义 43,0 主设备号,次设备号,即主设备号为43,次设备号为0 15 CPU ID,当前动作在哪个CPU上执行 172150 序列号 0.323236306 当前时间发生的时间戳,s.ns 3043800 进程ID M 动作表示,M表示合并操作,其他动作下文会有解释 W R: 读 W: 写 S: 同步 D: 擦除 21102073 + 1 操作起始地址和offset,offset单位为扇区 [kworker/u898:1] 命令或进程的名字 blkparse输出非常多,不利于问题分析,我一般只关注最后这一截,其他用btt工具分析以后再看。

从这个结果可以判断出磁盘读写IO比例 (5) btt 工具分析结果 btt -i vbd.blktrace.bin

一个IO进入块层后,生命周期如下: IO 需求生成 -> IO 请求生成(G) -> 进入设备队列(I) -> 同设备 IO 请求按照文件系统优化策略合并成一个大请求(M) -> 请求交付给硬件设备处理(D) -> IO 读写完成(C) Q2Q:表示2次IO请求的时间间隔。在NetMax单并发性能分析中,我们是根据这个判断磁盘IO不是整个任务的关键路径,因为在NetMax执行单并发任务过程中,该项平均值在380ms, 最大值可能有几十s Q2G :IO 生成开始进入 IO 队列 到为这个 IO 生成一个完整 IO 请求的时间。 G2I : 完整 IO 请求到该请求插入设备队列的时间 Q2M :IO 生成到在设备队列中和其他 IO 请求合并完成的时间 I2D : IO 生成到 IO请求合并完成并开始交由设备处理的时间。如果这个时间很长,可以考虑给磁盘换一个IO调度算法试试 M2D:IO 请求合并完成到开始交由设备处理的时间 D2C : 请求的服务时间,设备真正处理 IO 请求的总时间。对于后端为Ceph的虚拟机场景,这个时间可反应出qemu层和Ceph层总的处理时间。这个时间减去rbd的时间,基本等于qemu的处理时间。 Q2C:块设备层的整体服务时间

btt还可以加一些参数,过滤出自己想要的信息,比如常用的 btt -i vbd.blktrace.bin -B offset 按读写混合生成3个文件,表示每个读写请求时间戳,读写起始地址和offset,我们根据这个输出结果,可判断出磁盘IO是顺序还是随机,每个IO大小大概是多少。 需要注意的是,在纯读和纯写场景,是会生成两个文件。 比如,从下面这个例子中,我们可以看出来,磁盘IO是个顺序的,每个IO大小为64K。

]]>
FIO性能测试和调试方式 2019-06-26T00:00:00+00:00 ren_sky http://skyatlantis.github.io/FIO性能测试和调试方式 网站:

http://oliveryang.net/2016/07/linux-block-driver-basic-2/

home list tags talk user link rss Linux Block Driver - 2
转载时请包含原文或者作者网站链接:http://oliveryang.net

  1. 背景
  2. 准备
  3. 实验与分析 3.1 文件顺序写测试 3.2 文件 IO Pattern 分析 3.2.1 使用 strace 3.2.2 分析 strace 日志 3.2.3 使用 SystemTap 3.2.4 延迟统计 3.3 On CPU Time 分析 3.3.1 使用 perf 3.3.2 使用 Flamegraph
  4. 小结
  5. 延伸阅读
  6. 背景 在 Linux Block Driver - 1 中,我们实现了一个最简块设备驱动 Sampleblk。 这个只有 200 多行源码的块设备驱动利用内存创建了标准的 Linux 磁盘。我们在基于 Linux 4.6.0 内核的环境下,加载该驱动,并在其上创建了 Ext4 文件系统。

本文将继续之前的实验,围绕 Sampleblk 探究 Linux 块设备驱动的运作机制。除非特别指明,本文中所有 Linux 内核源码引用都基于 4.6.0。其它内核版本可能会有较大差异。

  1. 准备 首先,在阅读本文前,请按照 Linux Block Driver - 1 中的步骤准备好实验环境。确保可以做到如下步骤,

编译和加载 Sampleblk Day1 驱动 用 Ext4 格式化 /dev/sampleblk1 mount 文件系统到 /mnt 其次,为了继续后续实验,还需做如下准备工作。

安装 fio 测试软件。

fio 是目前非常流行的 IO 子系统测试工具。作者 Jens Axboe 是 Linux IO 子系统的 maintainer,目前就职于 Facebook。 互联网上 FIO 安装和使用的文章很多,这里就不在赘述。不过最值得细读的还是 fio HOWTO。

安装 blktrace 工具。

也是 Jens Axboe 开发的 IO 子系统追踪和性能调优工具。发行版有安装包。关于该工具的使用可以参考 blktrace man page。

安装 Linux Perf 工具。

Perf 是 Linux 源码树自带工具,运行时动态追踪,性能分析的利器。也可以从发行版找到安装包。 网上的 Perf 使用介绍很多。Perf Wiki 非常值得一看。

下载 perf-tools 脚本。

perf-tools 脚本 是 Brendan Gregg 写的基于 ftrace 和 perf 的工具脚本。全部由 bash 和 awk 写成,无需安装,非常简单易用。 Ftrace: The hidden light switch 这篇文章是 Brendan Gregg 给 LWN 的投稿,推荐阅读。

  1. 实验与分析 3.1 文件顺序写测试 如一般 Linux 测试工具支持命令行参数外,fio 也支持 job file 的方式定义测试参数。 本次实验中使用的 fs_seq_write_sync_001 job file 内容如下,

; – start job file – [global] ; global shared parameters filename=/mnt/test ; location of file in file system rw=write ; sequential write only, no read ioengine=sync ; synchronized, write(2) system call bs=,4k ; fio iounit size, write=4k, read and trim are default(4k) iodepth=1 ; how many in-flight io unit size=2M ; total size of file io in one job loops=1000000 ; number of iterations of one job

[job1] ; job1 specific parameters

[job2] ; job2 specific parameters ; – end job file – 本次实验将在 /dev/sampleblk1 上 mount 的 Ext4 文件系统上进行顺序 IO 写测试。其中 fio 将启动两个测试进程,同时对 /mnt/test 文件进行写操作。

$ sudo fio ./fs_seq_write_sync_001 job1: (g=0): rw=write, bs=4K-4K/4K-4K/4K-4K, ioengine=sync, iodepth=1 job2: (g=0): rw=write, bs=4K-4K/4K-4K/4K-4K, ioengine=sync, iodepth=1 fio-2.1.10 Starting 2 processes ^Cbs: 2 (f=2): [WW] [58.1% done] [0KB/2208MB/0KB /s] [0/565K/0 iops] [eta 13m:27s] …[snipped]… fio: terminating on signal 2

job1: (groupid=0, jobs=1): err= 0: pid=22977: Thu Jul 21 22:10:28 2016 write: io=1134.8GB, bw=1038.2MB/s, iops=265983, runt=1118309msec clat (usec): min=0, max=66777, avg= 1.63, stdev=21.57 lat (usec): min=0, max=66777, avg= 1.68, stdev=21.89 clat percentiles (usec): | 1.00th=[ 0], 5.00th=[ 1], 10.00th=[ 1], 20.00th=[ 1], | 30.00th=[ 1], 40.00th=[ 1], 50.00th=[ 2], 60.00th=[ 2], | 70.00th=[ 2], 80.00th=[ 2], 90.00th=[ 2], 95.00th=[ 3], | 99.00th=[ 4], 99.50th=[ 7], 99.90th=[ 18], 99.95th=[ 25], | 99.99th=[ 111] lat (usec) : 2=49.79%, 4=49.08%, 10=0.71%, 20=0.34%, 50=0.06% lat (usec) : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01% lat (msec) : 100=0.01% cpu : usr=8.44%, sys=69.65%, ctx=1935732, majf=0, minf=9 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=0/w=297451591/d=0, short=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=1 job2: (groupid=0, jobs=1): err= 0: pid=22978: Thu Jul 21 22:10:28 2016 write: io=1137.4GB, bw=1041.5MB/s, iops=266597, runt=1118309msec clat (usec): min=0, max=62132, avg= 1.63, stdev=21.35 lat (usec): min=0, max=62132, avg= 1.68, stdev=21.82

…[snipped]…

Run status group 0 (all jobs): WRITE: io=2271.2GB, aggrb=2080.5MB/s, minb=1038.2MB/s, maxb=1041.5MB/s, mint=1118309msec, maxt=1118309msec

Disk stats (read/write): sda: ios=0/4243062, merge=0/88, ticks=0/1233576, in_queue=1232723, util=37.65% 从 fio 的输出中可以看到 fio 启动了两个 job,并且按照 job file 规定的设置开始做文件系统写测试。 在测试进行到 58.1% 的时候,我们中断程序,得到了上述的输出。从输出中我们得出如下结论,

两个线程总共的写的吞吐量为 2080.5MB/s,在磁盘上的 IPOS 是 4243062。 每个线程的平均完成延迟 (clat) 为 1.63us,方差是 21.57。 每个线程的平均总延迟 (lat) 为 1.68us,方差是 21.89。 磁盘 IO merge 很少,磁盘的利用率也只有 37.65%。 线程所在处理器的时间大部分在内核态:69.65%,用户态时间只有 8.44% 。 3.2 文件 IO Pattern 分析 3.2.1 使用 strace 首先,我们可以先了解一下 fio 测试在系统调用层面看的 IO pattern 是如何的。Linux 的 strace 工具是跟踪应用使用系统调用的常用工具。

在 fio 运行过程中,我们获得 fio 其中一个 job 的 pid 之后,运行了如下的 strace 命令,

$ sudo strace -ttt -T -e trace=desc -C -o ~/strace_fio_fs_seq_write_sync_001.log -p 94302 strace man page 给出了命令的详细用法,这里只对本小节里用到的各个选项做简单的说明,

-ttt 打印出每个系统调用发生的起始时间戳。 -T 则给出了每个系统调用的开销。 -e trace=desc 只记录文件描述符相关系统调用。这样可过滤掉无关信息,因为本实验是文件顺序写测试。 -C 则在 strace 退出前可以给出被跟踪进程的系统调用在 strace 运行期间使用比例和次数的总结。 -o 则指定把 strace 的跟踪结果输出到文件中去。 3.2.2 分析 strace 日志 根据 strace 的跟踪日志,我们可对本次 fio 测试的 IO pattern 做一个简单的分析。 详细日志信息请访问这里,下面只给出其中的关键部分,

1466326568.892873 open(“/mnt/test”, O_RDWR|O_CREAT, 0600) = 3 <0.000013> 1466326568.892904 fadvise64(3, 0, 2097152, POSIX_FADV_DONTNEED) = 0 <0.000813> 1466326568.893731 fadvise64(3, 0, 2097152, POSIX_FADV_SEQUENTIAL) = 0 <0.000004> 1466326568.893744 write(3, “\0\260\35\0\0\0\0\0\0\320\37\0\0\0\0\0\0\300\35\0\0\0\0\0\0\340\37\0\0\0\0\0”…, 4096) = 4096 <0.000020>

[…snipped (512 write system calls)…]

1466326568.901551 write(3, “\0p\27\0\0\0\0\0\0\320\37\0\0\0\0\0\0\300\33\0\0\0\0\0\0\340\37\0\0\0\0\0”…, 4096) = 4096 <0.000006> 1466326568.901566 close(3) = 0 <0.000008>

[…snipped (many iterations of open, fadvise64, write, close)…]

% time seconds usecs/call calls errors syscall —— ———– ———– ——— ——— —————- 72.55 0.192610 2 84992 write 27.04 0.071788 216 332 fadvise64 0.28 0.000732 4 166 open 0.13 0.000355 2 166 close —— ———– ———– ——— ——— —————- 100.00 0.265485 85656 total 根据 strace 日志,我们就可以轻松分析这个 fio 测试的 IO Pattern 是如何的了,

首先调用 open 在 Ext4 上以读写方式打开 /mnt/test 文件,若不存在则创建一个。

因为 fio job file 指定了文件名,filename=/mnt/test

调用 fadvise64,使用 POSIX_FADV_DONTNEED 把 /mnt/test 在 page cache 里的数据 flush 到磁盘。

fio 做文件 IO 前,清除 /mnt/test 文件的 page cache,可以让测试避免受到 page cache 影响。

调用 fadvise64,使用 POSIX_FADV_SEQUENTIAL 提示内核应用要对 /mnt/test 做顺序 IO 操作。

这是因为 fio job file 定义了 rw=write,因此这是顺序写测试。

调用 write 对 /mnt/test 写入 4K 大小的数据。一共 write 512 次,共 2M 数据。

这是因为 fio job file 定义了 ioengine=sync,bs=,4k,size=2M。

最后,调用 close 完成一次 /mnt/test 顺序写测试。重复上述过程,反复迭代。

fio job file 定义了 loops=1000000

另外,根据 strace 日志的系统调用时间和调用次数的总结,我们可以得出如下结论,

系统调用 open,write 和 close 的开销非常小,只有几微秒。 测试中 write 调用次数最多,虽然单次 write 只有几微妙,但积累总时间最高。 测试中 fadvise64 调用次数比 write 少,但 POSIX_FADV_DONTNEED 带来的 flush page cache 的操作可以达到几百微秒。 3.2.3 使用 SystemTap 使用 strace 虽然可以拿到单次系统调用读写的字节数,但对大量的 IO 请求来说,不经过额外的脚本处理,很难得到一个总体的认识和分析。 但是,我们可以通过编写 SystemTap 脚本来对这个测试的 IO 请求大小做一个宏观的统计,并且使用直方图来直观的呈现这个测试的文件 IO 尺寸分布。

启动 fio 测试后,只需要运行如下命令,即可收集到指定 PID 的文件 IO 的统计信息,

$ sudo ./fiohist.stp 94302 starting probe ^C IO Summary:

                                   read     read             write    write
        name     open     read   KB tot    B avg    write   KB tot    B avg
         fio     7917        0        0        0  3698312 14793248     4096

Write I/O size (bytes):

process name: fio value |————————————————– count 1024 | 0 2048 | 0 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3698312 8192 | 0 16384 | 0 可以看到,直方图和统计数据显示,整个跟踪数据收集期间都是 4K 字节的 write 写操作,而没有任何读操作。而且,在此期间,没有任何 read IO 操作。 同时,由于 write 系统调用参数并不提供文件内的偏移量,所以我们无法得知文件的写操作是否是随机还是顺序的。

但是,如果是文件的随机读写 IO,应该可以在 strace 时观测到 lseek + read 或 write 调用。这也从侧面可以推测测试是顺序写 IO。 此外,pread 和 pwrite 系统调用提供了文件内的偏移量,有这个偏移量的数据,即可根据时间轴画出 IO 文件内偏移的 Heatmap。 通过该图,即可直观地判断是否是随机还是顺序 IO 了。

本例中的 SystemTap 脚本 fiohist.stp 是作者个人为分析本测试所编写。 详细代码请参考文中给出的源码链接。此外,在 Linux Perf Tools Tips 这篇文章里收录了关于在自编译内核上运行 SystemTap 脚本的一些常见问题。

3.2.4 延迟统计 fio 的测试结果已经提供了详尽的 IO 延迟数据。因为 fs_seq_write_sync_001 文件定义的是文件 buffer IO,并且是同步写模式。因此,fio 报告的延迟数据就是在文件 IO 层面上的,我们不需要使用其它的工具了。

查看 fio 源码,可以发现,它记录了一次 IO 流程的三个时间,

起始时间 (io_u->start_time) »»» 触发时间 (io_u->issue_time) »»» 完成时间 (icd->time) 其具体含义分别如下,

起始时间

在文件打开的状态下,是读写入文件的缓冲区准备好后的时间。源代码定义:io_u->start_time。

触发时间

同步 IO 时,是读写系统调用发起前的时间。 异步 IO 时,是 IO 请求成功放入请求队列后 (td->io_ops->queue) 返回的时间。 源代码定义:io_u->issue_time。

完成时间

是 IO 完成时的时间。源代码定义:icd->time。

而在 fio 输出里,则存在三种类型的延迟数据,分别为如下含义,

slat (submission latency)

即 IO 提交延迟。其确切含义是 IO 准备好到 IO 真正开始的时间 (即 io_u->issue_time - io_u->start_time)。 需要注意的是,在同步 (SYNC) IO 模式下,slat 并不计算,这是因为同步 IO 的这两个时间非常接近,没有计算意义。

clat (completion latency)

即 IO 完成延迟。其确切含义是 IO 真正开始到 IO 返回的时间 (即 icd->time - io_u->issue_time)。

lat (latency)

即 IO 总延迟,其确切含义是 IO 准备好到 IO 返回的总时间 (即 icd->time - io_u->issue_time)。

有了以上概念,再解读下面的数据就很简单了。

例如,本测试里完成延迟 clat (completion latency) 的结果如下,其中包含了均值 (avg) 和方差 (stdev),

clat (usec): min=0, max=66777, avg= 1.63, stdev=21.57 而总延迟 lat (latency) 结果如下,

lat (usec): min=0, max=66777, avg= 1.68, stdev=21.89 其中,clat percentiles 给出了各种 IO 完成延迟的百分比分布,

clat percentiles (usec): | 1.00th=[ 0], 5.00th=[ 1], 10.00th=[ 1], 20.00th=[ 1], | 30.00th=[ 1], 40.00th=[ 1], 50.00th=[ 2], 60.00th=[ 2], | 70.00th=[ 2], 80.00th=[ 2], 90.00th=[ 2], 95.00th=[ 3], | 99.00th=[ 4], 99.50th=[ 7], 99.90th=[ 18], 99.95th=[ 25], | 99.99th=[ 111] 而总 IO 延迟的百分比分布也包括在输出了,

lat (usec) : 2=49.79%, 4=49.08%, 10=0.71%, 20=0.34%, 50=0.06% lat (usec) : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01% lat (msec) : 100=0.01% 3.3 On CPU Time 分析 运行 fio 测试期间,我们可以利用 Linux perf, 对系统做 ON CPU Time 分析。这样可以进一步获取如下信息,

在测试中,软件栈的哪一部分消耗了主要的 CPU 资源。可以帮助我们确定 CPU 时间优化的主要方向。

通过查看消耗 CPU 资源的软件调用栈,了解函数调用关系。

利用可视化工具,如 Flamgraph,对 Profiling 的大量数据做直观的呈现。方便进一步分析和定位问题。

3.3.1 使用 perf 首先,当 fio 测试进入稳定状态,运行 perf record 命令,

perf record -a -g –call-graph dwarf -F 997 sleep 60

其中主要的命令行选项如下,

-F 选项指定 perf 以 997 次每秒的频率对 CPU 上运行的用户进程或者内核上下文进行采样 (Sampling)。

由于 Linux 内核的时钟中断是以 1000 次每秒的频率周期触发,所以按照 997 频率采样可以避免每次采样都采样到始终中断相关的处理,减少干扰。

-a 选项指定采样系统中所有的 CPU。

-g 选项指定记录下用户进程或者内核的调用栈。

其中,–call-graph dwarf 指定调用栈收集的方式为 dwarf,即 libdwarf 和 libdunwind 的方式。Perf 还支持 fp 和 lbs 方式。

sleep 60 则是通过 perf 指定运行的命令,这个命令起到了让 perf 运行 60 秒然后退出的效果。

在 perf record 之后,运行 perf report 查看采样结果的汇总,

sudo perf report –stdio

[…snipped…]

27.51% 0.10% fio [kernel.kallsyms] [k] __generic_file_write_iter | —__generic_file_write_iter | |–99.95%– ext4_file_write_iter | __vfs_write | vfs_write | sys_write | do_syscall_64 | return_from_SYSCALL_64 | 0x7ff91cd381cd | fio_syncio_queue | td_io_queue | thread_main | run_threads –0.05%– […] […snipped…] 3.3.2 使用 Flamegraph 使用 Flamegraph,可以把前面产生的 perf record 的结果可视化,生成火焰图。 运行如下命令,

perf script | stackcollapse-perf.pl > out.perf-folded

cat out.perf-folded | flamegraph.pl > flamegraph_on_cpu_perf_fs_seq_write_sync_001.svg

然后,即可生成如下火焰图,

该火焰图是 SVG 格式的矢量图,基于 XML 文件定义。在浏览器里右击在新窗口打开图片,即可进入与火焰图的交互模式。该模式下,统计数据信息和缩放功能都可以移动和点击鼠标来完成交互。 通过在交互模式下浏览和缩放火焰图,我们可以得出如下结论,

perf record 共有 119644 个采样数据,将此定义为 100% CPU 时间。 fio 进程共有 91079 个采样数据,占用 76.13% 的 CPU 时间。

fio 的 fio_syncio_queue 用掉了 48.53% 的 CPU,其中绝大部分时间在内核态,sys_write 系统调用就消耗了 45.78%。

fio 的 file_invalidate_cache 函数占用了 20.88% 的 CPU,其中大部分都在内核态,sys_fadvise64 系统调用消耗了 20.81%。

在这里我们注意到,sys_write 和 sys_fadvise64 系统调用 CPU 占用资源的比例是 2:1。而之前 strace 得出的两个系统调用消耗时间的比例是 3:1。 这就意味着,sys_write 花费了很多时间在睡眠态。

在 Ext4 文件系统的写路径,存在热点锁。

ext4_file_write_iter 函数里的 inode mutex 的 mutex 自旋等待时间,占用了 16.93% 的 CPU。与 sys_write 系统调用相比,CPU 消耗占比达到三分之一强。

swapper 为内核上下文,包含如下部分,

native_safe_halt 代表 CPU 处于 IDEL 状态,共有两次,9.04% 和 9.18%。

smp_reschedule_interrupt 代表 CPU 处理调度器的 IPI 中断,用于处理器间调度的负载均衡。共有两次,1.66% 和 1.61%。这部分需要方大矢量图移动鼠标到相关函数才能看到。

kblockd 工作队列线程。

由 block_run_queue_async 触发,最终调用 __blk_run_queue 把 IO 发送到下层的 sampleblk 块驱动。共有两部份,合计 0.88%。

rcu_gp_kthread 处理 RCU 的内核线程,占用 0.04 % 的 CPU 时间。 综合以上分析,我们可以看到,火焰图不但可以帮助我们理解 CPU 全局资源的占用情况,而且还能进一步分析到微观和细节。例如局部的热锁,父子函数的调用关系,和所占 CPU 时间比例。

关于进一步的 Flamegraph 的介绍和资料,请参考 Brenden Gregg 的 Flamegraph 相关资源。

  1. 小结 本文通过使用 Linux 下的各种追踪工具 Strace,Systemtap,Perf,Ftrace,来分析 fio 测试的运行情况。实际上,利用 Linux 下的动态追踪工具我们达到了以下目的,

掌握了本文中 fio 测试的主要特征,文件 IO size,IO 时间分布。这是性能分析里 workload analysis 方法的一部分。 了解了 fio 测试 On CPU 时间的分析方法。这是性能分析里 resource analysis 方法的一部分。 关于 Linux 动态追踪工具的更多信息,请参考延伸阅读章节里的链接。

  1. 延伸阅读 Linux Block Driver - 1 Linux Perf Tools Tips Using Linux Trace Tools - for diagnosis, analysis, learning and fun Flamegraph 相关资源 Ftrace: The hidden light switch Oliver Yang / 2016-07-10 Published under (CC) BY-NC-SA in categories Chinese Software Hardware tagged with driver perf trace file system kernel linux storage
Powered by Jekyll and Github Copyright 2014 - 2018 by Oliver Yang 2018-03-04 08:12:28 UTC
]]>
cephfs与glusterfs性能对比 2019-06-26T00:00:00+00:00 ren_sky http://skyatlantis.github.io/cephfs和glusterfs性能对比 测试结果
测试模型 GlusterFS(iops/lat) CephFS-Fuse(iops/lat) CephFS Re-export NFS(v4)(iops/lat) CephFS-kernel(iops/lat)
4K 10G顺序读 5579/1.431 6155/1.297 7368/1.08 6823/1.170
4K 10G顺序写 1297/6.161 471/ 16.210 1246/ 6.41 2254/3.55
4K 10G随机读 2601/3.071 1321/6.050 798/9.99 723/11.046
4K 10G随机写 2118/3.772 457/17.45 1141/7.00 2143/3.73
4M 10G顺序读 27/289 36/ 219.19 27/289 27/290.04
4M 10G顺序写 8/910 5/1412.13 12/615.67 13/614.03
4M 10G随机读 27/288 27/292.63 23/341.66 25/312.58
4M 10G随机写 8/924 4/1552.01 10/764.82 12/616.67

注:lat单位为ms毫秒

]]>
ceph-performance 2019-06-20T00:00:00+00:00 ren_sky http://skyatlantis.github.io/ceph-performance ceph-performance

[global] fsid = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx mon_host = xxx.xxx.xxx.xxx cluster_network = xxx.xxx.xxx.xxx/xx public_network = xxx.xxx.xxx.xxx/xx mon_max_pg_per_osd = 400 objecter_inflight_ops = 10240 objecter_inflight_op_bytes = 2147483648 osd_op_num_shards = 6 osd_op_num_threads_per_shard = 4 ms_async_op_threads = 6 ms_async_max_op_threads = 6 ms_crc_data = false throttler_perf_counter = false debug_none = 0/0 debug_lockdep = 0/0 debug_context = 0/0 debug_crush = 0/0 debug_mds = 0/0 debug_mds_balancer = 0/0 debug_mds_locker = 0/0 debug_mds_log = 0/0 debug_mds_log_expire = 0/0 debug_mds_migrator = 0/0 debug_buffer = 0/0 debug_timer = 0/0 debug_filer = 0/0 debug_striper = 0/0 debug_objecter = 0/0 debug_rados = 0/0 debug_rbd = 0/0 debug_rbd_mirror = 0/0 debug_rbd_replay = 0/0 debug_journaler = 0/0 debug_objectcacher = 0/0 debug_client = 0/0 debug_osd = 0/0 debug_optracker = 0/0 debug_objclass = 0/0 debug_filestore = 0/0 debug_journal = 0/0 debug_ms = 0/0 debug_mon = 0/0 debug_monc = 0/0 debug_paxos = 0/0 debug_tp = 0/0 debug_auth = 0/0 debug_crypto = 0/0 debug_finisher = 0/0 debug_reserver = 0/0 debug_heartbeatmap = 0/0 debug_perfcounter = 0/0 debug_rgw = 0/0 debug_civetweb = 0/0 debug_javaclient = 0/0 debug_asok = 0/0 debug_throttle = 0/0 debug_refs = 0/0 debug_xio = 0/0 debug_compressor = 0/0 debug_bluestore = 0/0 debug_bluefs = 0/0 debug_bdev = 0/0 debug_kstore = 0/0 debug_rocksdb = 0/0 debug_leveldb = 0/0 debug_memdb = 0/0 debug_kinetic = 0/0 debug_fuse = 0/0 debug_mgr = 0/0 debug_mgrc = 0/0 debug_dpdk = 0/0 debug_eventtrace = 0/0

[mon] mon_allow_pool_delete = true mgr_initial_modules = restful status dashboard balancer mon_health_preluminous_compat_warning = false

[mgr] mgr_op_latency_sample_interval = 300 mon_pg_warn_min_per_osd = 0 mon_warn_on_pool_no_app = false rbd_perf_report_enabled = false

[osd] osd_journal_size = 0 bluestore_block_db_size = 0 bluestore_block_wal_size = 0 osd_objectstore = bluestore bluestore_throttle_bytes = 134217728 bluestore_csum_type = none bluestore_cache_size = 1073741824 osd_client_message_cap = 1024 bluestore_rocksdb_options = compression=kNoCompression,max_write_buffer_number=8,min_write_buffer_number_to_merge=2,recycle_log_file_num=4,compaction_style=kCompactionStyleLevel,write_buffer_size=536870912,target_file_size_base=67108864,max_background_compactions=28,max_background_flushes=4,level0_file_num_compaction_trigger=8,level0_slowdown_writes_trigger=32,level0_stop_writes_trigger=64,num_levels=7,max_bytes_for_level_base=536870912,max_bytes_for_level_multiplier=4,compaction_readahead_size=2097152,compaction_threads=32,flusher_threads=8,rate_limiter_bytes_per_sec=10485760 osd_class_update_on_start = false osd_scrub_max_interval = 0 osd_scrub_begin_hour = 50 osd_scrub_end_hour = 100 osd_max_backfills = 100 osd_recovery_sleep_hdd = 0 osd_recovery_sleep_hybrid = 0 bluestore_max_blob_size = 4194304 osd_client_message_size_cap = 2147483648 bluestore_prefetch_blob = true bluestore_meta_fixed_length = 65536

async recovery

osd_async_recovery = true osd_async_recovery_min_cost = 0 osd_force_auth_primary_missing_objects = 0

]]>
NAS延时调用 2019-05-28T00:00:00+00:00 ren_sky http://skyatlantis.github.io/NAS延时调用 nfs-client性能指标

命令:mountstats [ options ] options:

       --version    display the version of this command    
       --nfs        display only the NFS statistics     
       --rpc        display only the RPC statistics     

输出:
mountstats –rpc /nfs/

命令:nfsiostat [ [ ] ] [ ] [ ] Options:

         --version             show program's version number and exit    
         -h, --help            show this help message and exit       

 Statistics Options:
         File I/O is displayed unless one of the following is specified:    

         -a, --attr            displays statistics related to the attribute cache  
         -d, --dir             displays statistics related to directory operations   
         -p, --page            displays statistics related to the page cache   

 Display Options:    
 Options affecting display format:    

         -s, --sort            Sort NFS mount points by ops/second   
         -l LIST, --list=LIST  only print stats for first LIST mount points   
                               count> ] ] [ <options> ] [ <mount point> ]    

命令:nfsstat [OPTION]…
OPTION:

          -m, --mounts          Show statistics on mounted NFS filesystems         
          -c, --client          Show NFS client statistics        
          -s, --server          Show NFS server statistics      
          -2                    Show NFS version 2 statistics       
          -3                    Show NFS version 3 statistics     
          -4                    Show NFS version 4 statistics      
          -o [facility]         Show statistics on particular facilities          
          nfs                   NFS protocol information    
          rpc                   General RPC information    
          net                   Network layer statistics   
          fh                    Usage information on the server's file handle cache   
          rc                    Usage information on the server's request reply cache   
          all                   Select all of the above    
          -v, --verbose, --all  Same as '-o all'   
          -r, --rpc             Show RPC statistics    
          -n, --nfs             Show NFS statistics   
          -Z[#], --sleep[=#]    Collects stats until interrupted        
                                Cumulative stats are then printed    
                                If # is provided, stats will be output every    
                                # seconds         
          -S, --since file      Shows difference between current stats and those in 'file'    
          -l, --list            Prints stats in list format    
          --version             Show program version   
          --help                What you just did   

nfs-ganesha

命令:dbus-send [–help] [–system | –session | –address=ADDRESS] [–dest=NAME] [–type=TYPE] [–print-reply[=literal]] [–reply-timeout=MSEC] [contents ...] 参见:https://github.com/nfs-ganesha/nfs-ganesha/wiki/Dbusinterface

(1)查询有哪些客户端连接
dbus-send –print-reply –system –dest=org.ganesha.nfsd /org/ganesha/nfsd/ClientMgr org.ganesha.nfsd.clientmgr.ShowClients

(2)读取该客户端的统计
dbus-send –print-reply –system –dest=org.ganesha.nfsd /org/ganesha/nfsd/ClientMgr org.ganesha.nfsd.clientstats.GetNFSv3IO string:::ffff:19.19.19.137

(3)读取export路径
dbus-send –print-reply –system –dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.ShowExports

(4)根据export路径读取该export路径统计信息
dbus-send –print-reply –system –dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportstats.GetNFSv3IO uint16:1

libcephfs

在/var/run/ceph-client下有asok文件,通过这个文件来查看其性能数据
比如:ceph daemon ./client.1954118.asok perf dump查看libcephfs的时延统计。
输出:

[root@ceph104 ceph]# ceph daemon ./client.1954118.asok perf dump
{

}

reply:
从libcephfs发出元数据请求,到收到mds会应答平均时延。
wrlat:
libceph写请求平均处理时延,从libcephfs write接口开始计算,到return之前的平均时延。
rdlat:
Libceph读请求平均处理时延,从libcephfs read接口开始计算,到return之前的平均时延。
fssync:
Libceph sync请求平均处理时延,从libcephfs sync接口开始计算,到return之前的平均时延。
msgr_running_recv_time:
msgr线程接收IO总时间。
msgr_running_send_time:
msgr线程发送IO总时间。

OSD

命令: ceph daemon osd.X perf dump

相关统计信息:
op_before_queue_op_lat:
messages线程接收到OP到OP入 shardwq队列之前的时延(包括message线程将IO数据从内核读上来的时间间隔)。
op_before_dequeue_op_lat:
messages线程接收到OP 到 从shardwq 队列出队,并且获取到PG Lock的时延。
op_r_latency/op_w_latency:
OSD 读/写 OP总的执行时间,即从messages线程接收到OP到OSD处理完成,给客户端应答之前的时间间隔。
op_r_process_latency/op_w_process_latency:
OSD 读/写OP的执行时间,即从OP出队到OSD处理完成,给客户端应答之前的时间间隔。
op_r_prepare_latency:
PG处理读 OP 时间,在数据备份策略为副本的情况下,表示从OP出队到提交IO给磁盘的时间。
op_w_prepare_latency:
PG处理写 OP 时间,即从OP出队到完成bluestore本地事务准备工作的时间。

ceph daemon osd.X perf dump bluestore
read_lat:
从bluestore 接收到读请求到完成读请求的时间。
commit_lat:
从bluestore接收到写请求到完成写请求的时间。
read_wait_aio_lat:
磁盘处理读请求时间。
read_onode_meta_lat:
读取onode元数据时间。
csum_lat:
计算checksum花费的时间。
state_prepare_lat:
bluestore准备事务上下文等花费的时间。
state_aio_wait_lat:
磁盘处理写请求的时间。
state_done_lat:
磁盘处理写请求完成后,等待事务进入done状态的时间(因为后提交到磁盘的IO可能先完成,为了防止乱序,后提交到磁盘的IO需要等待先提交磁盘的IO完成后才能进入done状态)。
kv_commit_lat:
kv提交时间。
kv_lat:
kv完成时间。
state_kv_queued_lat:
kv排队时间。

MDS

ceph daemon mds.ceph101 perf dump

]]>
Ceph-tool 2019-05-28T00:00:00+00:00 ren_sky http://skyatlantis.github.io/ceph-tool ceph-dencoder

贯穿整个osd数据处理的核心结构为ObjectStore::Transaction,所有操作关联的数据都会封装到Transaction的bufferlist中。 bufferlist中存储的数据是经过encode序列号的二进制流。在到实际Transaction的后端存储处理时,则通过对bufferlist进行 decode反序列。ceph-dencoder工具可以提供encode、dencode和dump ceph相关的数据结果,也可以做兼容性的测试。

工具使用 (1)查看支持的结构体
ceph-dencoder list_types
(2)查看object_info示例 在/var/lib/ceph/osd/ceph-x/current/ 下找到一个有数据的对象文件 12版本后增加了bluefs的机制,无法直接看到对象文件 使用attr –l命令查看其中的内容
示例: attr -l 1000000000d.00000000_head_6C753797__15 Attribute “cephos.spill_out” has a 2 byte value for 1000000000d.00000000__head_6C753797__15 Attribute “ceph._scan_ceiling” has a 22 byte value for 1000000000d.00000000__head_6C753797__15 Attribute “ceph._scan_max_mtime” has a 8 byte value for 1000000000d.00000000__head_6C753797__15 Attribute “ceph._scan_max_size” has a 8 byte value for 1000000000d.00000000__head_6C753797__15 Attribute “ceph.” has a 250 byte value for 1000000000d.00000000_head_6C753797__15 Attribute “ceph.@1” has a 5 byte value for 1000000000d.00000000_head_6C753797__15 Attribute “ceph.snapset” has a 31 byte value for 1000000000d.00000000__head_6C753797__15 说明: “cephos.spill_out”是一个两个字节的字符数组,用于记录文件的扩展属性是否溢 出到了Omap里; “ceph.“和”ceph.@1”应该算是一部分,因为ceph._超出了XFS扩展属性的长度 限制,所以拆成了两个 (3)将扩展属性导出到文件 attr -q -g file
示例:
attr -q -g “ceph.
” 1000000000d.00000000_head_6C753797__15 > abc.txt
attr -q -g “ceph.
@1” 1000000000d.00000000__head_6C753797__15 » abc.txt
(4)使用ceph-dencoder导出文件
ceph-dencoder import abc.txt type object_info_t decode dump_json 示例:
[root@cephfs102 21.17_head]# ceph-dencoder import abc.txt type object_info_t decode dump_json
{ “oid”: {
“oid”: “1000000000d.00000000”,
“key”: “”,
“snapid”: -2,
“hash”: 1819621271,
“max”: 0,
“pool”: 21,
“namespace”: “”
}, “version”: “2797’2”,
“prior_version”: “2655’1”,
“last_reqid”: “client.3204248.0:135”,
“user_version”: 2,
“size”: 557132,
“mtime”: “0.000000”,
“local_mtime”: “0.000000”,
“lost”: 0,
“flags”: 52,
“snaps”: [],
“truncate_seq”: 0,
“truncate_size”: 0,
“data_digest”: 557693221,
“omap_digest”: 4294967295,
“watchers”: {}
}

]]>