• 查询osd上的pg数


    本文中的命令的第一版来源于国外的一个博客,后面的版本为我自己修改的版本

    查询的命令如下:

    ceph pg dump | awk '
     /^pg_stat/ { col=1; while($col!="up") {col++}; col++ }
     /^[0-9a-f]+.[0-9a-f]+/ { match($0,/^[0-9a-f]+/); pool=substr($0, RSTART, RLENGTH); poollist[pool]=0;
     up=$col; i=0; RSTART=0; RLENGTH=0; delete osds; while(match(up,/[0-9]+/)>0) { osds[++i]=substr(up,RSTART,RLENGTH); up = substr(up, RSTART+RLENGTH) }
     for(i in osds) {array[osds[i],pool]++; osdlist[osds[i]];}
    }
    END {
     printf("
    ");
     printf("pool :	"); for (i in poollist) printf("%s	",i); printf("| SUM 
    ");
     for (i in poollist) printf("--------"); printf("----------------
    ");
     for (i in osdlist) { printf("osd.%i	", i); sum=0;
     for (j in poollist) { printf("%i	", array[i,j]); sum+=array[i,j]; poollist[j]+=array[i,j] }; printf("| %i
    ",sum) }
     for (i in poollist) printf("--------"); printf("----------------
    ");
     printf("SUM :	"); for (i in poollist) printf("%s	",poollist[i]); printf("|
    ");
    }'
    

    默认的输出如下:

    
    pool :	0	1	2	| SUM 
    ----------------------------------------
    osd.4	54	133	79	| 266
    osd.5	57	104	88	| 249
    osd.6	61	132	86	| 279
    osd.7	54	114	85	| 253
    osd.8	63	123	85	| 271
    osd.0	62	120	87	| 269
    osd.1	52	126	81	| 259
    osd.2	52	103	88	| 243
    osd.3	57	125	89	| 271
    ----------------------------------------
    SUM :	512	1080	768	|
    
    

    这个有个问题就是osd是乱序的,并且对于一个存储池来说不清楚哪个osd的pg是最多的

    重构第一版:

    跟上面的相比按顺序来排列

    ceph pg dump | awk '
     /^pg_stat/ { col=1; while($col!="up") {col++}; col++ }
     /^[0-9a-f]+.[0-9a-f]+/ { match($0,/^[0-9a-f]+/); pool=substr($0, RSTART, RLENGTH); poollist[pool]=0;
     up=$col; i=0; RSTART=0; RLENGTH=0; delete osds; while(match(up,/[0-9]+/)>0) { osds[++i]=substr(up,RSTART,RLENGTH); up = substr(up, RSTART+RLENGTH) }
     for(i in osds) {array[osds[i],pool]++; osdlist[osds[i]];}
    }
    END {
     printf("
    ");
     slen=asorti(poollist,newpoollist);
     printf("pool :	");for (i=1;i<=slen;i++) {printf("%s	", newpoollist[i])}; printf("| SUM 
    ");
     for (i in poollist) printf("--------"); printf("----------------
    ");
     slen1=asorti(osdlist,newosdlist)
     delete poollist;
     for (i=1;i<=slen1;i++) { printf("osd.%i	", newosdlist[i]); sum=0; 
     for (j=1;j<=slen;j++)  { printf("%i	", array[newosdlist[i],newpoollist[j]]); sum+=array[newosdlist[i],newpoollist[j]]; poollist[j]+=array[newosdlist[i],newpoollist[j]] }; printf("| %i
    ",sum)
    } 
    for (i in poollist) printf("--------"); printf("----------------
    ");
     printf("SUM :	"); for (i=1;i<=slen;i++) printf("%s	",poollist[i]); printf("|
    ");
    }'
    

    输出结果为下面的,可以看到现在是按顺序来的,存储池是顺序的,osd编号也是顺序的

    
    pool :	0	1	2	| SUM 
    ----------------------------------------
    osd.0	62	120	87	| 269
    osd.1	52	126	81	| 259
    osd.2	52	103	88	| 243
    osd.3	57	125	89	| 271
    osd.4	54	133	79	| 266
    osd.5	57	104	88	| 249
    osd.6	61	132	86	| 279
    osd.7	54	114	85	| 253
    osd.8	63	123	85	| 271
    ----------------------------------------
    SUM :	512	1080	768	|
    

    重构第二版:

    包含osd pool的排序,包含osd的排序,输出平均pg数目,输出最大的osd编号,输出超过平均值的百分比

    ceph pg dump | awk '
     /^pg_stat/ { col=1; while($col!="up") {col++}; col++ }
     /^[0-9a-f]+.[0-9a-f]+/ { match($0,/^[0-9a-f]+/); pool=substr($0, RSTART, RLENGTH); poollist[pool]=0;
     up=$col; i=0; RSTART=0; RLENGTH=0; delete osds; while(match(up,/[0-9]+/)>0) { osds[++i]=substr(up,RSTART,RLENGTH); up = substr(up, RSTART+RLENGTH) }
     for(i in osds) {array[osds[i],pool]++; osdlist[osds[i]];}
    }
    END {
     printf("
    ");
     slen=asorti(poollist,newpoollist);
     printf("pool :	");for (i=1;i<=slen;i++) {printf("%s	", newpoollist[i])}; printf("| SUM 
    ");
     for (i in poollist) printf("--------"); printf("----------------
    ");
     slen1=asorti(osdlist,newosdlist)
     delete poollist;
     for (i=1;i<=slen1;i++) { printf("osd.%i	", newosdlist[i]); sum=0; 
     for (j=1;j<=slen;j++)  { printf("%i	", array[newosdlist[i],newpoollist[j]]); sum+=array[newosdlist[i],newpoollist[j]]; poollist[j]+=array[newosdlist[i],newpoollist[j]];if(array[newosdlist[i],newpoollist[j]] != 0){poolhasid[j]+=1 };if(array[newosdlist[i],newpoollist[j]]>maxpoolosd[j]){maxpoolosd[j]=array[newosdlist[i],newpoollist[j]];maxosdid[j]=newosdlist[i]}}; printf("| %i
    ",sum)} 
    for (i in poollist) printf("--------"); printf("----------------
    ");
     printf("SUM :	"); for (i=1;i<=slen;i++) printf("%s	",poollist[i]); printf("|
    ");
     printf("AVE :	"); for (i=1;i<=slen;i++) printf("%d	",poollist[i]/poolhasid[i]); printf("|
    ");
     printf("max :	"); for (i=1;i<=slen;i++) printf("%s	",maxpoolosd[i]); printf("|
    ");
     printf("osdid :	"); for (i=1;i<=slen;i++) printf("osd.%s	",maxosdid[i]); printf("|
    ");
     printf("per:	"); for (i=1;i<=slen;i++) printf("%.1f%	",100*(maxpoolosd[i]-poollist[i]/poolhasid[i])/(poollist[i]/poolhasid[i])); printf("|
    ");
    }'
    

    输出如下:

    pool :	0	1	2	| SUM 
    ----------------------------------------
    osd.0	62	120	87	| 269
    osd.1	52	126	81	| 259
    osd.2	52	103	88	| 243
    osd.3	57	125	89	| 271
    osd.4	54	133	79	| 266
    osd.5	57	104	88	| 249
    osd.6	61	132	86	| 279
    osd.7	54	114	85	| 253
    osd.8	63	123	85	| 271
    ----------------------------------------
    SUM :	512	1080	768	|
    AVE :	56	120	85	|
    max :	63	133	89	|
    osdid :	osd.8	osd.4	osd.3	|
    per:	10.7%	10.8%	4.3%	|
    

    重构第三版:

    包含osd pool的排序,包含osd的排序,输出平均pg数目,输出最大的osd编号,输出最大超过平均值的百分比,输出最少pg的osd编号,输出最小低于平均值的百分比

    ceph pg dump | awk '
     /^pg_stat/ { col=1; while($col!="up") {col++}; col++ }
     /^[0-9a-f]+.[0-9a-f]+/ { match($0,/^[0-9a-f]+/); pool=substr($0, RSTART, RLENGTH); poollist[pool]=0;
     up=$col; i=0; RSTART=0; RLENGTH=0; delete osds; while(match(up,/[0-9]+/)>0) { osds[++i]=substr(up,RSTART,RLENGTH); up = substr(up, RSTART+RLENGTH) }
     for(i in osds) {array[osds[i],pool]++; osdlist[osds[i]];}
    }
    END {
     printf("
    ");
     slen=asorti(poollist,newpoollist);
     printf("pool :	");for (i=1;i<=slen;i++) {printf("%s	", newpoollist[i])}; printf("| SUM 
    ");
     for (i in poollist) printf("--------"); printf("----------------
    ");
     slen1=asorti(osdlist,newosdlist)
     delete poollist;
     for (j=1;j<=slen;j++) {maxpoolosd[j]=0};
     for (j=1;j<=slen;j++) {for (i=1;i<=slen1;i++){if (array[newosdlist[i],newpoollist[j]] >0  ){minpoolosd[j]=array[newosdlist[i],newpoollist[j]] ;break } }};	
     for (i=1;i<=slen1;i++) { printf("osd.%i	", newosdlist[i]); sum=0; 
     for (j=1;j<=slen;j++)  { printf("%i	", array[newosdlist[i],newpoollist[j]]); sum+=array[newosdlist[i],newpoollist[j]]; poollist[j]+=array[newosdlist[i],newpoollist[j]];if(array[newosdlist[i],newpoollist[j]] != 0){poolhasid[j]+=1 };if(array[newosdlist[i],newpoollist[j]]>maxpoolosd[j]){maxpoolosd[j]=array[newosdlist[i],newpoollist[j]];maxosdid[j]=newosdlist[i]};if(array[newosdlist[i],newpoollist[j]] != 0){if(array[newosdlist[i],newpoollist[j]]<=minpoolosd[j]){minpoolosd[j]=array[newosdlist[i],newpoollist[j]];minosdid[j]=newosdlist[i]}}}; printf("| %i
    ",sum)} for (i in poollist) printf("--------"); printf("----------------
    ");
     slen2=asorti(poollist,newpoollist);
     printf("SUM :	"); for (i=1;i<=slen;i++) printf("%s	",poollist[i]); printf("|
    ");
     printf("Osd :	"); for (i=1;i<=slen;i++) printf("%s	",poolhasid[i]); printf("|
    ");
     printf("AVE :	"); for (i=1;i<=slen;i++) printf("%.2f	",poollist[i]/poolhasid[i]); printf("|
    ");
     printf("Max :	"); for (i=1;i<=slen;i++) printf("%s	",maxpoolosd[i]); printf("|
    ");
     printf("Osdid :	"); for (i=1;i<=slen;i++) printf("osd.%s	",maxosdid[i]); printf("|
    ");
     printf("per:	"); for (i=1;i<=slen;i++) printf("%.1f%	",100*(maxpoolosd[i]-poollist[i]/poolhasid[i])/(poollist[i]/poolhasid[i])); printf("|
    ");
     for (i=1;i<=slen2;i++) printf("--------");printf("----------------
    ");
     printf("min :	"); for (i=1;i<=slen;i++) printf("%s	",minpoolosd[i]); printf("|
    ");
     printf("osdid :	"); for (i=1;i<=slen;i++) printf("osd.%s	",minosdid[i]); printf("|
    ");
     printf("per:	"); for (i=1;i<=slen;i++) printf("%.1f%	",100*(minpoolosd[i]-poollist[i]/poolhasid[i])/(poollist[i]/poolhasid[i])); printf("|
    ");
    }'
    

    输出如下:

    dumped all in format plain
    
    pool :	0	1	2	| SUM 
    ----------------------------------------
    osd.0	206	206	53	| 465
    osd.1	22	19	5	| 46
    osd.2	202	196	49	| 447
    osd.3	19	25	6	| 50
    osd.4	29	35	9	| 73
    osd.5	34	31	6	| 71
    ----------------------------------------
    SUM :	512	512	128	|
    AVE :	85	85	21	|
    max :	206	206	53	|
    osdid :	osd.0	osd.0	osd.0	|
    per:	141.4%	141.4%	148.4%	|
    ---------------------------------------
    min :	19	19	5	|
    osdid :	osd.3	osd.1	osd.1	|
    per:	-77.7%	-77.7%	-76.6%	|
    

    Luminous以及之后的版本

    ceph pg dump | awk '
     /^PG_STAT/ { col=1; while($col!="UP") {col++}; col++ }
     /^[0-9a-f]+.[0-9a-f]+/ { match($0,/^[0-9a-f]+/); pool=substr($0, RSTART, RLENGTH); poollist[pool]=0;
     up=$col; i=0; RSTART=0; RLENGTH=0; delete osds; while(match(up,/[0-9]+/)>0) { osds[++i]=substr(up,RSTART,RLENGTH); up = substr(up, RSTART+RLENGTH) }
     for(i in osds) {array[osds[i],pool]++; osdlist[osds[i]];}
    }
    END {
     printf("
    ");
     slen=asorti(poollist,newpoollist);
     printf("pool :	");for (i=1;i<=slen;i++) {printf("%s	", newpoollist[i])}; printf("| SUM 
    ");
     for (i in poollist) printf("--------"); printf("----------------
    ");
     slen1=asorti(osdlist,newosdlist)
     delete poollist;
     for (j=1;j<=slen;j++) {maxpoolosd[j]=0};
     for (j=1;j<=slen;j++) {for (i=1;i<=slen1;i++){if (array[newosdlist[i],newpoollist[j]] >0  ){minpoolosd[j]=array[newosdlist[i],newpoollist[j]] ;break } }}; 
     for (i=1;i<=slen1;i++) { printf("osd.%i	", newosdlist[i]); sum=0; 
     for (j=1;j<=slen;j++)  { printf("%i	", array[newosdlist[i],newpoollist[j]]); sum+=array[newosdlist[i],newpoollist[j]]; poollist[j]+=array[newosdlist[i],newpoollist[j]];if(array[newosdlist[i],newpoollist[j]] != 0){poolhasid[j]+=1 };if(array[newosdlist[i],newpoollist[j]]>maxpoolosd[j]){maxpoolosd[j]=array[newosdlist[i],newpoollist[j]];maxosdid[j]=newosdlist[i]};if(array[newosdlist[i],newpoollist[j]] != 0){if(array[newosdlist[i],newpoollist[j]]<=minpoolosd[j]){minpoolosd[j]=array[newosdlist[i],newpoollist[j]];minosdid[j]=newosdlist[i]}}}; printf("| %i
    ",sum)} for (i in poollist) printf("--------"); printf("----------------
    ");
     slen2=asorti(poollist,newpoollist);
     printf("SUM :	"); for (i=1;i<=slen;i++) printf("%s	",poollist[i]); printf("|
    ");
     printf("Osd :	"); for (i=1;i<=slen;i++) printf("%s	",poolhasid[i]); printf("|
    ");
     printf("AVE :	"); for (i=1;i<=slen;i++) printf("%.2f	",poollist[i]/poolhasid[i]); printf("|
    ");
     printf("Max :	"); for (i=1;i<=slen;i++) printf("%s	",maxpoolosd[i]); printf("|
    ");
     printf("Osdid :	"); for (i=1;i<=slen;i++) printf("osd.%s	",maxosdid[i]); printf("|
    ");
     printf("per:	"); for (i=1;i<=slen;i++) printf("%.1f%	",100*(maxpoolosd[i]-poollist[i]/poolhasid[i])/(poollist[i]/poolhasid[i])); printf("|
    ");
     for (i=1;i<=slen2;i++) printf("--------");printf("----------------
    ");
     printf("min :	"); for (i=1;i<=slen;i++) printf("%s	",minpoolosd[i]); printf("|
    ");
     printf("osdid :	"); for (i=1;i<=slen;i++) printf("osd.%s	",minosdid[i]); printf("|
    ");
     printf("per:	"); for (i=1;i<=slen;i++) printf("%.1f%	",100*(minpoolosd[i]-poollist[i]/poolhasid[i])/(poollist[i]/poolhasid[i])); printf("|
    ");
    }'
    

    luminous之后的版本json的输出小写改成大写了,需要替换几个字段,上面的已经增加了

    上面的处理使用的是awk处理,开始的时候看不懂什么意思,然后就去看了这本书《The AWK Programming Language》

    语法的解释

    /^pg_stat/ { col=1; while($col!="up") {col++}; col++ }

    这个是匹配pg dump 的输出结果里面pg_stat那个字段,开始计数为1,不是up值就将col的值加1,这个匹配到的就是我们经常看到的[1,10]这个值最后的col++是将col值+1,因为字段里面有up,up_primary,我们需要的是up_primary

    /[1]+.[0-9a-f]+/ { match($0,/[2]+/); pool=substr($0, RSTART, RLENGTH); poollist[pool]=0;

    这个是匹配前面的 1.17a pg号 ,使用自带的match函数 做字符串的过滤统计匹配.号前面的存储池ID, 并得到 RSTART, RLENGTH 值,这个是取到前面的存储池ID,使用substr 函数,就可以得到pool的值了,poollist[pool]=0,是将数组的值置为0

    up=$col; i=0; RSTART=0; RLENGTH=0; delete osds; while(match(up,/[0-9]+/)>0) { osds[++i]=substr(up,RSTART,RLENGTH); up = substr(up, RSTART+RLENGTH) }

    先将变量置0,然后将osd编号一个个输入到osds[i]的数组当中去

    for(i in osds) {array[osds[i],pool]++; osdlist[osds[i]];}

    将osds数组中的值输入到数组当中去,并且记录成osdlist,和数组array[osd[i],pool]

    printf(" ");
    printf("pool : "); for (i in poollist) printf("%s ",i); printf("| SUM ");

    打印osd pool的编号

    for (i in poollist) printf("--------"); printf("---------------- ");

    根据osd pool的长度打印----

    for (i in osdlist) { printf("osd.%i ", i); sum=0;

    打印osd的编号

    for (j in poollist) { printf("%i ", array[i,j]); sum+=array[i,j]; poollist[j]+=array[i,j] }; printf("| %i ",sum) }
    打印对应的osd的pg数目,并做求和的统计

    for (i in poollist) printf("--------"); printf("---------------- ");
    printf("SUM : "); for (i in poollist) printf("%s ",poollist[i]); printf("| ");

    打印新的poollist里面的求和的值

    修改版本里面用到的函数

    slen1=asorti(osdlist,newosdlist)

    这个是将数组里面的下标进行排序,这里是对osd和poollist的编号进行排序 slen1是拿到数组的长度,使用for进行遍历输出

    脚本的逻辑

    • 匹配到pg的id和pg对应的osd,
    • 使用数组的方式,将统计到的osd id存储起来,
    • 然后打印数组

    其他资源:
    pg设置的计算器:
    http://ceph.com/pgcalc/
    pg的查询和设置:
    http://ceph.com/docs/master/rados/operations/placement-groups/

    变更记录

    Why Who When
    创建 武汉-运维-磨渣 2015-10-04
    修改 武汉-运维-磨渣 2016-08-24
    修改有0的统计BUG 武汉-运维-磨渣 2016-09-08
    增加luminous版本脚本 武汉-运维-磨渣 2020-06-17

    引用博客地址如下:

    http://cephnotes.ksperis.com/blog/2015/02/23/get-the-number-of-placement-groups-per-osd/


    1. 0-9a-f ↩︎

    2. 0-9a-f ↩︎

  • 相关阅读:
    POJ1741 Tree(树分治)
    codeforces713D Animals and Puzzle(二维倍增)
    codeforces713C Sonya and Problem Wihtout a Legend(dp)
    codeforces724E Goods transportation(最小割——dp)
    codeforces710E Generate a String(dp)
    codeforces Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) 题解(A-D)
    BNUOJ52317 As Easy As Possible(树上倍增)
    hihocoder1386 Pick Your Players(dp)
    常用函数
    vector总结(更新中。。。)
  • 原文地址:https://www.cnblogs.com/zphj1987/p/13575311.html
Copyright © 2020-2023  润新知