[pve-devel] [PATCH manager v4 1/9] ceph: add autoscale_status to api calls

Dominik Csapak d.csapak at proxmox.com
Tue Apr 20 10:15:15 CEST 2021


From: Alwin Antreich <a.antreich at proxmox.com>

the properties target_size_ratio, target_size_bytes and pg_num_min are
used to fine-tune the pg_autoscaler and are set on a pool. The updated
pool list shows now autoscale settings & status. Including the new
(optimal) target PGs. To make it easier for new users to get/set the
correct amount of PGs.

Signed-off-by: Alwin Antreich <a.antreich at proxmox.com>
Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 PVE/API2/Ceph/Pools.pm | 96 +++++++++++++++++++++++++++++++++++++-----
 PVE/CLI/pveceph.pm     |  4 ++
 2 files changed, 90 insertions(+), 10 deletions(-)

diff --git a/PVE/API2/Ceph/Pools.pm b/PVE/API2/Ceph/Pools.pm
index 01c11100..014e6be7 100644
--- a/PVE/API2/Ceph/Pools.pm
+++ b/PVE/API2/Ceph/Pools.pm
@@ -16,6 +16,24 @@ use PVE::API2::Storage::Config;
 
 use base qw(PVE::RESTHandler);
 
+my $get_autoscale_status = sub {
+    my ($rados) = shift;
+
+    $rados = PVE::RADOS->new() if !defined($rados);
+
+    my $autoscale = $rados->mon_command({
+	    prefix => 'osd pool autoscale-status'});
+
+    my $data;
+    foreach my $p (@$autoscale) {
+	$p->{would_adjust} = "$p->{would_adjust}"; # boolean
+	$data->{$p->{pool_name}} = $p;
+    }
+
+    return $data;
+};
+
+
 __PACKAGE__->register_method ({
     name => 'lspools',
     path => '',
@@ -37,16 +55,21 @@ __PACKAGE__->register_method ({
 	items => {
 	    type => "object",
 	    properties => {
-		pool => { type => 'integer', title => 'ID' },
-		pool_name => { type => 'string', title => 'Name' },
-		size => { type => 'integer', title => 'Size' },
-		min_size => { type => 'integer', title => 'Min Size' },
-		pg_num => { type => 'integer', title => 'PG Num' },
-		pg_autoscale_mode => { type => 'string', optional => 1, title => 'PG Autoscale Mode' },
-		crush_rule => { type => 'integer', title => 'Crush Rule' },
-		crush_rule_name => { type => 'string', title => 'Crush Rule Name' },
-		percent_used => { type => 'number', title => '%-Used' },
-		bytes_used => { type => 'integer', title => 'Used' },
+		pool              => { type => 'integer', title => 'ID' },
+		pool_name         => { type => 'string',  title => 'Name' },
+		size              => { type => 'integer', title => 'Size' },
+		min_size          => { type => 'integer', title => 'Min Size' },
+		pg_num            => { type => 'integer', title => 'PG Num' },
+		pg_num_min        => { type => 'integer', title => 'min. PG Num', optional => 1, },
+		pg_num_final      => { type => 'integer', title => 'Optimal PG Num', optional => 1, },
+		pg_autoscale_mode => { type => 'string',  title => 'PG Autoscale Mode', optional => 1, },
+		crush_rule        => { type => 'integer', title => 'Crush Rule' },
+		crush_rule_name   => { type => 'string',  title => 'Crush Rule Name' },
+		percent_used      => { type => 'number',  title => '%-Used' },
+		bytes_used        => { type => 'integer', title => 'Used' },
+		target_size       => { type => 'integer', title => 'PG Autoscale Target Size', optional => 1 },
+		target_size_ratio => { type => 'number',  title => 'PG Autoscale Target Ratio',optional => 1, },
+		autoscale_status  => { type => 'object',  title => 'Autoscale Status', optional => 1 },
 	    },
 	},
 	links => [ { rel => 'child', href => "{pool_name}" } ],
@@ -86,12 +109,24 @@ __PACKAGE__->register_method ({
 	    'pg_autoscale_mode',
 	];
 
+	# pg_autoscaler module is not enabled in Nautilus
+	my $autoscale = eval { $get_autoscale_status->($rados) };
+
 	foreach my $e (@{$res->{pools}}) {
 	    my $d = {};
 	    foreach my $attr (@$attr_list) {
 		$d->{$attr} = $e->{$attr} if defined($e->{$attr});
 	    }
 
+	    if ($autoscale) {
+		$d->{autoscale_status} = $autoscale->{$d->{pool_name}};
+		$d->{pg_num_final} = $d->{autoscale_status}->{pg_num_final};
+		# some info is nested under options instead
+		$d->{pg_num_min} = $e->{options}->{pg_num_min};
+		$d->{target_size} = $e->{options}->{target_size_bytes};
+		$d->{target_size_ratio} = $e->{options}->{target_size_ratio};
+	    }
+
 	    if (defined($d->{crush_rule}) && defined($rules->{$d->{crush_rule}})) {
 		$d->{crush_rule_name} = $rules->{$d->{crush_rule}};
 	    }
@@ -143,6 +178,13 @@ my $ceph_pool_common_options = sub {
 	    minimum => 8,
 	    maximum => 32768,
 	},
+	pg_num_min => {
+	    title => 'min. PG Num',
+	    description => "Minimal number of placement groups.",
+	    type => 'integer',
+	    optional => 1,
+	    maximum => 32768,
+	},
 	crush_rule => {
 	    title => 'Crush Rule Name',
 	    description => "The rule to use for mapping object placement in the cluster.",
@@ -165,6 +207,19 @@ my $ceph_pool_common_options = sub {
 	    default => 'warn',
 	    optional => 1,
 	},
+	target_size => {
+	    description => "The estimated target size of the pool for the PG autoscaler.",
+	    title => 'PG Autoscale Target Size',
+	    type => 'string',
+	    pattern => '^(\d+(\.\d+)?)([KMGT])?$',
+	    optional => 1,
+	},
+	target_size_ratio => {
+	    description => "The estimated target ratio of the pool for the PG autoscaler.",
+	    title => 'PG Autoscale Target Ratio',
+	    type => 'number',
+	    optional => 1,
+	},
     };
 
     if ($nodefault) {
@@ -241,6 +296,12 @@ __PACKAGE__->register_method ({
 	my $rpcenv = PVE::RPCEnvironment::get();
 	my $user = $rpcenv->get_user();
 
+	# Ceph uses target_size_bytes
+	if (defined($param->{'target_size'})) {
+	    my $target_sizestr = extract_param($param, 'target_size');
+	    $param->{target_size_bytes} = PVE::JSONSchema::parse_size($target_sizestr);
+	}
+
 	if ($add_storages) {
 	    $rpcenv->check($user, '/storage', ['Datastore.Allocate']);
 	    die "pool name contains characters which are illegal for storage naming\n"
@@ -387,6 +448,12 @@ __PACKAGE__->register_method ({
 	my $pool = extract_param($param, 'name');
 	my $node = extract_param($param, 'node');
 
+	# Ceph uses target_size_bytes
+	if (defined($param->{'target_size'})) {
+	    my $target_sizestr = extract_param($param, 'target_size');
+	    $param->{target_size_bytes} = PVE::JSONSchema::parse_size($target_sizestr);
+	}
+
 	my $worker = sub {
 	    PVE::Ceph::Tools::set_pool($pool, $param);
 	};
@@ -438,6 +505,7 @@ __PACKAGE__->register_method ({
 	    fast_read              => { type => 'boolean', title => 'Fast Read' },
 	    application_list       => { type => 'array', title => 'Application', optional => 1 },
 	    statistics             => { type => 'object', title => 'Statistics', optional => 1 },
+	    autoscale_status       => { type => 'object',  title => 'Autoscale Status', optional => 1 },
 	    %{ $ceph_pool_common_options->() },
 	},
     },
@@ -462,6 +530,7 @@ __PACKAGE__->register_method ({
 	    size                   => $res->{size},
 	    min_size               => $res->{min_size},
 	    pg_num                 => $res->{pg_num},
+	    pg_num_min             => $res->{pg_num_min},
 	    pgp_num                => $res->{pgp_num},
 	    crush_rule             => $res->{crush_rule},
 	    pg_autoscale_mode      => $res->{pg_autoscale_mode},
@@ -474,12 +543,19 @@ __PACKAGE__->register_method ({
 	    hashpspool             => "$res->{hashpspool}",
 	    use_gmt_hitset         => "$res->{use_gmt_hitset}",
 	    fast_read              => "$res->{fast_read}",
+	    target_size            => $res->{target_size_bytes},
+	    target_size_ratio      => $res->{target_size_ratio},
 	};
 
 	if ($verbose) {
 	    my $stats;
 	    my $res = $rados->mon_command({ prefix => 'df' });
 
+	    # pg_autoscaler module is not enabled in Nautilus
+	    # avoid partial read further down, use new rados instance
+	    my $autoscale_status = eval { $get_autoscale_status->() };
+	    $data->{autoscale_status} = $autoscale_status->{$pool};
+
 	    foreach my $d (@{$res->{pools}}) {
 		next if !$d->{stats};
 		next if !defined($d->{name}) && !$d->{name} ne "$pool";
diff --git a/PVE/CLI/pveceph.pm b/PVE/CLI/pveceph.pm
index ba5067b1..4c000881 100755
--- a/PVE/CLI/pveceph.pm
+++ b/PVE/CLI/pveceph.pm
@@ -207,7 +207,11 @@ our $cmddef = {
 		    'size',
 		    'min_size',
 		    'pg_num',
+		    'pg_num_min',
+		    'pg_num_final',
 		    'pg_autoscale_mode',
+		    'target_size',
+		    'target_size_ratio',
 		    'crush_rule_name',
 		    'percent_used',
 		    'bytes_used',
-- 
2.20.1





More information about the pve-devel mailing list