Ceph automatic reweight script
The data distribution of Ceph is determined by CRUSH Map, while the CRUSH algorithm is pseudo-HASH, so the data will be skewed within a certain period of time, which requires us to use scripts to reweight periodically:
# author jesse.js.lyu@gmail.com
# reweight for ceph osds
Import hashlib
Import commands
Import threading
Import sys
From time import ctime,sleep
Import urllib2
Import json
Def doReweight (osdMaxUtilId, osdTargetReweight):
Print 'ceph osd reweight' + str (osdMaxUtilId) +''+ str (osdTargetReweight)
(status,output) = commands.getstatusoutput ('ceph osd reweight' + str (osdMaxUtilId) +''+ str (osdTargetReweight))
Print status,output
Def canOSDReweight ():
#
CanDoReweight = False
PgStateIsOk = False
OsdUtilDiffEnough = False
# determine pg status
(status,output) = commands.getstatusoutput ('ceph-s-- format=json-pretty')
PgMapJson = json.loads (output)
# print pgMapJson ['pgmap'] [' pgs_by_state']
NumPGS = pgMapJson ['pgmap'] [' num_pgs']
For pgState in pgMapJson ['pgmap'] [' pgs_by_state']:
If pgState ['state_name'] = =' active+clean' and pgState ['count'] = = numPGS:
PgStateIsOk = True
If pgStateIsOk = = False:
Print "pg is reweighting or can't do reweight right now...."
Exit
# determine OSD util diff
(status,output) = commands.getstatusoutput ('ceph osd df-- format=json-pretty')
# print status,output
OsdMaxUtil=0
OsdMaxUtilId=-1
OsdMaxReweight=1
OsdMinUtil=100
OsdMinUtilId=-1
OsdReweightStep=0.01
If status = = 0:
OsdDictJson = json.loads (output)
For node in osdDictJson ['nodes']:
If node ['utilization'] > osdMaxUtil:
OsdMaxUtilId = node ['id']
OsdMaxUtil = node ['utilization']
OsdMaxReweight = node ['reweight']
If node ['utilization']
< osdMinUtil: osdMinUtilId = node['id'] osdMinUtil = node['utilization'] osdTargetReweight = osdMaxReweight - osdReweightStep osdUtilDiff = (osdMaxUtil - osdMinUtil)/osdMinUtil*100 if osdUtilDiff >10:
OsdUtilDiffEnough = True
Print "Max and Min OSD's utilization diff is" + str (osdUtilDiff)
Else:
Print "Max and Min OSD's utilization diff is" + str (osdUtilDiff) + ", less then 10%, give up..."
Exit
If pgStateIsOk = = True and osdUtilDiffEnough = = True and osdTargetReweight > 0:
Print "= doing reweight ="
Print osdMaxUtilId,osdMaxUtil,osdMaxReweight
Print osdMinUtilId,osdMinUtil
DoReweight (osdMaxUtilId, osdTargetReweight)
Def invokeOSDReweight ():
While True:
Sleep (30)
CanOSDReweight ()
If _ _ name__ = ='_ _ main__':
InvokeOSDReweight ()