Add support for configurable OSD DB ratios
The default of 0.05 (5%) is likely ideal in the initial implementation, but allow this to be set explicitly for maximum flexibility in space-constrained or performance-critical use-cases.
This commit is contained in:
parent
eba142f470
commit
44491dd988
|
@ -3751,6 +3751,7 @@ class API_Storage_Ceph_OSD_Root(Resource):
|
||||||
{'name': 'device', 'required': True, 'helptext': "A valid device must be specified."},
|
{'name': 'device', 'required': True, 'helptext': "A valid device must be specified."},
|
||||||
{'name': 'weight', 'required': True, 'helptext': "An OSD weight must be specified."},
|
{'name': 'weight', 'required': True, 'helptext': "An OSD weight must be specified."},
|
||||||
{'name': 'ext_db', 'required': False, 'helptext': "Whether to use an external OSD DB LV device."},
|
{'name': 'ext_db', 'required': False, 'helptext': "Whether to use an external OSD DB LV device."},
|
||||||
|
{'name': 'ext_db_ratio', 'required': False, 'helptext': "Decimal size ratio of the external OSD DB LV device."},
|
||||||
])
|
])
|
||||||
@Authenticator
|
@Authenticator
|
||||||
def post(self, reqargs):
|
def post(self, reqargs):
|
||||||
|
@ -3781,6 +3782,11 @@ class API_Storage_Ceph_OSD_Root(Resource):
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
description: Whether to use an external OSD DB LV device
|
description: Whether to use an external OSD DB LV device
|
||||||
|
- in: query
|
||||||
|
name: ext_db_ratio
|
||||||
|
type: float
|
||||||
|
required: false
|
||||||
|
description: Decimal ratio of total OSD size for the external OSD DB LV device, default 0.05 (5%)
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: OK
|
description: OK
|
||||||
|
@ -3798,6 +3804,7 @@ class API_Storage_Ceph_OSD_Root(Resource):
|
||||||
reqargs.get('device', None),
|
reqargs.get('device', None),
|
||||||
reqargs.get('weight', None),
|
reqargs.get('weight', None),
|
||||||
reqargs.get('ext_db', False),
|
reqargs.get('ext_db', False),
|
||||||
|
float(reqargs.get('ext_db_ratio', 0.05)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1292,11 +1292,11 @@ def ceph_osd_db_vg_add(zkhandler, node, device):
|
||||||
|
|
||||||
|
|
||||||
@ZKConnection(config)
|
@ZKConnection(config)
|
||||||
def ceph_osd_add(zkhandler, node, device, weight, ext_db_flag=False):
|
def ceph_osd_add(zkhandler, node, device, weight, ext_db_flag=False, ext_db_ratio=0.05):
|
||||||
"""
|
"""
|
||||||
Add a Ceph OSD to the PVC Ceph storage cluster.
|
Add a Ceph OSD to the PVC Ceph storage cluster.
|
||||||
"""
|
"""
|
||||||
retflag, retdata = pvc_ceph.add_osd(zkhandler, node, device, weight, ext_db_flag)
|
retflag, retdata = pvc_ceph.add_osd(zkhandler, node, device, weight, ext_db_flag, ext_db_ratio)
|
||||||
|
|
||||||
if retflag:
|
if retflag:
|
||||||
retcode = 200
|
retcode = 200
|
||||||
|
|
|
@ -222,19 +222,20 @@ def ceph_osd_list(config, limit):
|
||||||
return False, response.json().get('message', '')
|
return False, response.json().get('message', '')
|
||||||
|
|
||||||
|
|
||||||
def ceph_osd_add(config, node, device, weight, ext_db_flag):
|
def ceph_osd_add(config, node, device, weight, ext_db_flag, ext_db_ratio):
|
||||||
"""
|
"""
|
||||||
Add new Ceph OSD
|
Add new Ceph OSD
|
||||||
|
|
||||||
API endpoint: POST /api/v1/storage/ceph/osd
|
API endpoint: POST /api/v1/storage/ceph/osd
|
||||||
API arguments: node={node}, device={device}, weight={weight}, ext_db={ext_db_flag}
|
API arguments: node={node}, device={device}, weight={weight}, ext_db={ext_db_flag}, ext_db_ratio={ext_db_ratio}
|
||||||
API schema: {"message":"{data}"}
|
API schema: {"message":"{data}"}
|
||||||
"""
|
"""
|
||||||
params = {
|
params = {
|
||||||
'node': node,
|
'node': node,
|
||||||
'device': device,
|
'device': device,
|
||||||
'weight': weight,
|
'weight': weight,
|
||||||
'ext_db': ext_db_flag
|
'ext_db': ext_db_flag,
|
||||||
|
'ext_db_ratio': ext_db_ratio
|
||||||
}
|
}
|
||||||
response = call_api(config, 'post', '/storage/ceph/osd', params=params)
|
response = call_api(config, 'post', '/storage/ceph/osd', params=params)
|
||||||
|
|
||||||
|
|
|
@ -2635,17 +2635,24 @@ def ceph_osd_create_db_vg(node, device, confirm_flag):
|
||||||
is_flag=True, default=False,
|
is_flag=True, default=False,
|
||||||
help='Use an external database logical volume for this OSD.'
|
help='Use an external database logical volume for this OSD.'
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
'-r', '--ext-db-ratio', 'ext_db_ratio',
|
||||||
|
default=0.05, show_default=True, type=float,
|
||||||
|
help='Decimal ratio of the external database logical volume to the OSD size.'
|
||||||
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
'-y', '--yes', 'confirm_flag',
|
'-y', '--yes', 'confirm_flag',
|
||||||
is_flag=True, default=False,
|
is_flag=True, default=False,
|
||||||
help='Confirm the creation'
|
help='Confirm the creation'
|
||||||
)
|
)
|
||||||
@cluster_req
|
@cluster_req
|
||||||
def ceph_osd_add(node, device, weight, ext_db_flag, confirm_flag):
|
def ceph_osd_add(node, device, weight, ext_db_flag, ext_db_ratio, confirm_flag):
|
||||||
"""
|
"""
|
||||||
Add a new Ceph OSD on node NODE with block device DEVICE.
|
Add a new Ceph OSD on node NODE with block device DEVICE.
|
||||||
|
|
||||||
If '--ext-db' is specified, the existing OSD database volume group on NODE will be used; it must exist first or OSD creation will fail. See the 'pvc storage osd create-db-vg' command for more details.
|
If '--ext-db' is specified, the existing OSD database volume group on NODE will be used; it must exist first or OSD creation will fail. See the 'pvc storage osd create-db-vg' command for more details.
|
||||||
|
|
||||||
|
The default '--ext-db-ratio' of 0.05 (5%) is sufficient for most RBD workloads and OSD sizes, though this can be adjusted based on the sizes of the OSD(s) and the underlying database device. Ceph documentation recommends at least 0.02 (2%) for RBD use-cases, and higher values may improve WAL performance under write-heavy workloads with fewer OSDs per node.
|
||||||
"""
|
"""
|
||||||
if not confirm_flag and not config['unsafe']:
|
if not confirm_flag and not config['unsafe']:
|
||||||
try:
|
try:
|
||||||
|
@ -2653,7 +2660,7 @@ def ceph_osd_add(node, device, weight, ext_db_flag, confirm_flag):
|
||||||
except Exception:
|
except Exception:
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
retcode, retmsg = pvc_ceph.ceph_osd_add(config, node, device, weight, ext_db_flag)
|
retcode, retmsg = pvc_ceph.ceph_osd_add(config, node, device, weight, ext_db_flag, ext_db_ratio)
|
||||||
cleanup(retcode, retmsg)
|
cleanup(retcode, retmsg)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -236,7 +236,7 @@ def add_osd_db_vg(zkhandler, node, device):
|
||||||
|
|
||||||
# OSD addition and removal uses the /cmd/ceph pipe
|
# OSD addition and removal uses the /cmd/ceph pipe
|
||||||
# These actions must occur on the specific node they reference
|
# These actions must occur on the specific node they reference
|
||||||
def add_osd(zkhandler, node, device, weight, ext_db_flag=False):
|
def add_osd(zkhandler, node, device, weight, ext_db_flag=False, ext_db_ratio=0.05):
|
||||||
# Verify the target node exists
|
# Verify the target node exists
|
||||||
if not common.verifyNode(zkhandler, node):
|
if not common.verifyNode(zkhandler, node):
|
||||||
return False, 'ERROR: No node named "{}" is present in the cluster.'.format(node)
|
return False, 'ERROR: No node named "{}" is present in the cluster.'.format(node)
|
||||||
|
@ -247,7 +247,7 @@ def add_osd(zkhandler, node, device, weight, ext_db_flag=False):
|
||||||
return False, 'ERROR: Block device "{}" on node "{}" is used by OSD "{}"'.format(device, node, block_osd)
|
return False, 'ERROR: Block device "{}" on node "{}" is used by OSD "{}"'.format(device, node, block_osd)
|
||||||
|
|
||||||
# Tell the cluster to create a new OSD for the host
|
# Tell the cluster to create a new OSD for the host
|
||||||
add_osd_string = 'osd_add {},{},{},{}'.format(node, device, weight, ext_db_flag)
|
add_osd_string = 'osd_add {},{},{},{},{}'.format(node, device, weight, ext_db_flag, ext_db_ratio)
|
||||||
zkhandler.write([
|
zkhandler.write([
|
||||||
('base.cmd.ceph', add_osd_string)
|
('base.cmd.ceph', add_osd_string)
|
||||||
])
|
])
|
||||||
|
|
|
@ -5026,6 +5026,13 @@
|
||||||
"name": "ext_db",
|
"name": "ext_db",
|
||||||
"required": false,
|
"required": false,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Decimal ratio of total OSD size for the external OSD DB LV device, default 0.05 (5%)",
|
||||||
|
"in": "query",
|
||||||
|
"name": "ext_db_ratio",
|
||||||
|
"required": false,
|
||||||
|
"type": "float"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
|
@ -68,7 +68,7 @@ class CephOSDInstance(object):
|
||||||
self.stats = json.loads(data)
|
self.stats = json.loads(data)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_osd(zkhandler, logger, node, device, weight, ext_db_flag=False):
|
def add_osd(zkhandler, logger, node, device, weight, ext_db_flag=False, ext_db_ratio=0.05):
|
||||||
# We are ready to create a new OSD on this node
|
# We are ready to create a new OSD on this node
|
||||||
logger.out('Creating new OSD disk on block device {}'.format(device), state='i')
|
logger.out('Creating new OSD disk on block device {}'.format(device), state='i')
|
||||||
try:
|
try:
|
||||||
|
@ -104,7 +104,7 @@ class CephOSDInstance(object):
|
||||||
if ext_db_flag:
|
if ext_db_flag:
|
||||||
_, osd_size_bytes, _ = common.run_os_command('blockdev --getsize64 {}'.format(device))
|
_, osd_size_bytes, _ = common.run_os_command('blockdev --getsize64 {}'.format(device))
|
||||||
osd_size_bytes = int(osd_size_bytes)
|
osd_size_bytes = int(osd_size_bytes)
|
||||||
result = CephOSDInstance.create_osd_db_lv(zkhandler, logger, osd_id, osd_size_bytes)
|
result = CephOSDInstance.create_osd_db_lv(zkhandler, logger, osd_id, ext_db_ratio, osd_size_bytes)
|
||||||
if not result:
|
if not result:
|
||||||
raise
|
raise
|
||||||
db_device = "osd-db/osd-{}".format(osd_id)
|
db_device = "osd-db/osd-{}".format(osd_id)
|
||||||
|
@ -359,7 +359,7 @@ class CephOSDInstance(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_osd_db_lv(zkhandler, logger, osd_id, osd_size_bytes):
|
def create_osd_db_lv(zkhandler, logger, osd_id, ext_db_ratio, osd_size_bytes):
|
||||||
logger.out('Creating new OSD database logical volume for OSD ID {}'.format(osd_id), state='i')
|
logger.out('Creating new OSD database logical volume for OSD ID {}'.format(osd_id), state='i')
|
||||||
try:
|
try:
|
||||||
# 0. Check if an existsing logical volume exists
|
# 0. Check if an existsing logical volume exists
|
||||||
|
@ -370,11 +370,11 @@ class CephOSDInstance(object):
|
||||||
logger.out('Ceph OSD database LV "osd-db/osd{}" already exists'.format(osd_id), state='e')
|
logger.out('Ceph OSD database LV "osd-db/osd{}" already exists'.format(osd_id), state='e')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 1. Determine LV sizing (5% of OSD size, in MB)
|
# 1. Determine LV sizing
|
||||||
osd_db_size = int(osd_size_bytes * 0.05 / 1024 / 1024)
|
osd_db_size = int(osd_size_bytes * ext_db_ratio / 1024 / 1024)
|
||||||
|
|
||||||
# 2. Create the LV
|
# 2. Create the LV
|
||||||
logger.out('Creating LV "osd-db/osd-{}"'.format(osd_id), state='i')
|
logger.out('Creating DB LV "osd-db/osd-{}" of {}M ({} * {})'.format(osd_id, osd_db_size, osd_size_bytes, ext_db_ratio), state='i')
|
||||||
retcode, stdout, stderr = common.run_os_command(
|
retcode, stdout, stderr = common.run_os_command(
|
||||||
'lvcreate --yes --name osd-{} --size {} osd-db'.format(osd_id, osd_db_size)
|
'lvcreate --yes --name osd-{} --size {} osd-db'.format(osd_id, osd_db_size)
|
||||||
)
|
)
|
||||||
|
@ -489,14 +489,15 @@ def ceph_command(zkhandler, logger, this_node, data, d_osd):
|
||||||
|
|
||||||
# Adding a new OSD
|
# Adding a new OSD
|
||||||
if command == 'osd_add':
|
if command == 'osd_add':
|
||||||
node, device, weight, ext_db_flag = args.split(',')
|
node, device, weight, ext_db_flag, ext_db_ratio = args.split(',')
|
||||||
ext_db_flag = bool(strtobool(ext_db_flag))
|
ext_db_flag = bool(strtobool(ext_db_flag))
|
||||||
|
ext_db_ratio = float(ext_db_ratio)
|
||||||
if node == this_node.name:
|
if node == this_node.name:
|
||||||
# Lock the command queue
|
# Lock the command queue
|
||||||
zk_lock = zkhandler.writelock('base.cmd.ceph')
|
zk_lock = zkhandler.writelock('base.cmd.ceph')
|
||||||
with zk_lock:
|
with zk_lock:
|
||||||
# Add the OSD
|
# Add the OSD
|
||||||
result = CephOSDInstance.add_osd(zkhandler, logger, node, device, weight, ext_db_flag)
|
result = CephOSDInstance.add_osd(zkhandler, logger, node, device, weight, ext_db_flag, ext_db_ratio)
|
||||||
# Command succeeded
|
# Command succeeded
|
||||||
if result:
|
if result:
|
||||||
# Update the command queue
|
# Update the command queue
|
||||||
|
|
Loading…
Reference in New Issue