Ceph OSDs 間的數據均衡

背景

Ceph 集羣在運行一段時間後常會碰到OSD 數據不均衡的時候,有的OSD 使用率超過的80%,有的甚至不足60%。一般有兩種方法去均衡各個OSDs 間的數據

OSD Reweight

其實就是給各個OSDs 設置均衡權重(區別OSD weight 是根據容量設置的固定權重)

調整數據量超過閥值的OSD的權重,閥值默認值爲120%。

ceph osd reweight-by-utilization [threshold]

若要預覽效果,則可以使用以下命令:

ceph osd test-reweight-by-utilization [threshold]

當然,也可以根據每個OSD上的PG數量來調整,閥值默認值也是120%。

ceph osd reweight-by-pg [threshold]

若要預覽效果,則可以使用以下命令:

ceph osd test-reweight-by-pg [threshold]

Ceph Balancer

從Luminous 開始,Ceph 新增的了balancer ,可以將PG 在各個OSD上自動遷移,已達到均衡的效果。推薦使用。

1)查看balancer 模塊狀態

ceph mgr module ls # 查看各個模塊的狀態
ceph balancer status

2)啓用balancer 模塊(默認enable)

ceph mgr module enable balancer

3)啓用均衡(默認active 是false)

ceph balancer on

4)設置模式(修改PG mapping)

ceph balancer mode upmap

或設置模式(修改weight)

ceph balancer mode crush-compat

其中upmap 模式設置兼容版本

ceph osd set-require-min-compat-client luminous

Luminous 需要手動設置均衡計劃?

ceph balancer eval #對集羣所有pool進行權重調整計算,針對特定pool 採用 ceph balancer eval <POOL_NAME>
ceph balancer optimize plan2 #生成一個調優配置,或指定存儲池 ceph balancer optimize plan2 default.rgw.buckets.data
ceph balancer eval plan2 #執行調優計算
ceph balancer show plan2 #查看調優計算最終的結果
ceph balancer execute plan2 #根據上面模擬計算的結果,執行最終的權重調整

5)查看調整結果

ceph osd df

6)關閉自動調整

ceph balancer off
ceph balancer status

OSD PG 數統計腳本:包含osd pool的排序,包含osd的排序,輸出平均pg數目,輸出最大的osd編號,輸出最大超過平均值的百分比,輸出最少pg的osd編號,輸出最小低於平均值的百分比,
用於輔助查看集羣各個OSD 的PG 分佈情況,參考武漢-磨渣的博客《查詢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("\n");
 slen=asorti(poollist,newpoollist);
 printf("pool :\t");for (i=1;i<=slen;i++) {printf("%s\t", newpoollist[i])}; printf("| SUM \n");
 for (i in poollist) printf("--------"); printf("----------------\n");
 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\t", newosdlist[i]); sum=0;
 for (j=1;j<=slen;j++)  { printf("%i\t", 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\n",sum)} for (i in poollist) printf("--------"); printf("----------------\n");
 slen2=asorti(poollist,newpoollist);
 printf("SUM :\t"); for (i=1;i<=slen;i++) printf("%s\t",poollist[i]); printf("|\n");
 printf("Osd :\t"); for (i=1;i<=slen;i++) printf("%s\t",poolhasid[i]); printf("|\n");
 printf("AVE :\t"); for (i=1;i<=slen;i++) printf("%.2f\t",poollist[i]/poolhasid[i]); printf("|\n");
 printf("Max :\t"); for (i=1;i<=slen;i++) printf("%s\t",maxpoolosd[i]); printf("|\n");
 printf("Osdid :\t"); for (i=1;i<=slen;i++) printf("osd.%s\t",maxosdid[i]); printf("|\n");
 printf("per:\t"); for (i=1;i<=slen;i++) printf("%.1f%\t",100*(maxpoolosd[i]-poollist[i]/poolhasid[i])/(poollist[i]/poolhasid[i])); printf("|\n");
 for (i=1;i<=slen2;i++) printf("--------");printf("----------------\n");
 printf("min :\t"); for (i=1;i<=slen;i++) printf("%s\t",minpoolosd[i]); printf("|\n");
 printf("osdid :\t"); for (i=1;i<=slen;i++) printf("osd.%s\t",minosdid[i]); printf("|\n");
 printf("per:\t"); for (i=1;i<=slen;i++) printf("%.1f%\t",100*(minpoolosd[i]-poollist[i]/poolhasid[i])/(poollist[i]/poolhasid[i])); printf("|\n");
}'
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章