mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-08-13 21:24:01 +00:00
ceph: add autoscale_status to api calls
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@proxmox.com> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
d7518964d9
commit
5a3d794242
@ -16,6 +16,24 @@ use PVE::API2::Storage::Config;
|
|||||||
|
|
||||||
use base qw(PVE::RESTHandler);
|
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 ({
|
__PACKAGE__->register_method ({
|
||||||
name => 'lspools',
|
name => 'lspools',
|
||||||
path => '',
|
path => '',
|
||||||
@ -37,16 +55,21 @@ __PACKAGE__->register_method ({
|
|||||||
items => {
|
items => {
|
||||||
type => "object",
|
type => "object",
|
||||||
properties => {
|
properties => {
|
||||||
pool => { type => 'integer', title => 'ID' },
|
pool => { type => 'integer', title => 'ID' },
|
||||||
pool_name => { type => 'string', title => 'Name' },
|
pool_name => { type => 'string', title => 'Name' },
|
||||||
size => { type => 'integer', title => 'Size' },
|
size => { type => 'integer', title => 'Size' },
|
||||||
min_size => { type => 'integer', title => 'Min Size' },
|
min_size => { type => 'integer', title => 'Min Size' },
|
||||||
pg_num => { type => 'integer', title => 'PG Num' },
|
pg_num => { type => 'integer', title => 'PG Num' },
|
||||||
pg_autoscale_mode => { type => 'string', optional => 1, title => 'PG Autoscale Mode' },
|
pg_num_min => { type => 'integer', title => 'min. PG Num', optional => 1, },
|
||||||
crush_rule => { type => 'integer', title => 'Crush Rule' },
|
pg_num_final => { type => 'integer', title => 'Optimal PG Num', optional => 1, },
|
||||||
crush_rule_name => { type => 'string', title => 'Crush Rule Name' },
|
pg_autoscale_mode => { type => 'string', title => 'PG Autoscale Mode', optional => 1, },
|
||||||
percent_used => { type => 'number', title => '%-Used' },
|
crush_rule => { type => 'integer', title => 'Crush Rule' },
|
||||||
bytes_used => { type => 'integer', title => 'Used' },
|
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}" } ],
|
links => [ { rel => 'child', href => "{pool_name}" } ],
|
||||||
@ -86,12 +109,24 @@ __PACKAGE__->register_method ({
|
|||||||
'pg_autoscale_mode',
|
'pg_autoscale_mode',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# pg_autoscaler module is not enabled in Nautilus
|
||||||
|
my $autoscale = eval { $get_autoscale_status->($rados) };
|
||||||
|
|
||||||
foreach my $e (@{$res->{pools}}) {
|
foreach my $e (@{$res->{pools}}) {
|
||||||
my $d = {};
|
my $d = {};
|
||||||
foreach my $attr (@$attr_list) {
|
foreach my $attr (@$attr_list) {
|
||||||
$d->{$attr} = $e->{$attr} if defined($e->{$attr});
|
$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}})) {
|
if (defined($d->{crush_rule}) && defined($rules->{$d->{crush_rule}})) {
|
||||||
$d->{crush_rule_name} = $rules->{$d->{crush_rule}};
|
$d->{crush_rule_name} = $rules->{$d->{crush_rule}};
|
||||||
}
|
}
|
||||||
@ -143,6 +178,13 @@ my $ceph_pool_common_options = sub {
|
|||||||
minimum => 8,
|
minimum => 8,
|
||||||
maximum => 32768,
|
maximum => 32768,
|
||||||
},
|
},
|
||||||
|
pg_num_min => {
|
||||||
|
title => 'min. PG Num',
|
||||||
|
description => "Minimal number of placement groups.",
|
||||||
|
type => 'integer',
|
||||||
|
optional => 1,
|
||||||
|
maximum => 32768,
|
||||||
|
},
|
||||||
crush_rule => {
|
crush_rule => {
|
||||||
title => 'Crush Rule Name',
|
title => 'Crush Rule Name',
|
||||||
description => "The rule to use for mapping object placement in the cluster.",
|
description => "The rule to use for mapping object placement in the cluster.",
|
||||||
@ -165,6 +207,19 @@ my $ceph_pool_common_options = sub {
|
|||||||
default => 'warn',
|
default => 'warn',
|
||||||
optional => 1,
|
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) {
|
if ($nodefault) {
|
||||||
@ -241,6 +296,12 @@ __PACKAGE__->register_method ({
|
|||||||
my $rpcenv = PVE::RPCEnvironment::get();
|
my $rpcenv = PVE::RPCEnvironment::get();
|
||||||
my $user = $rpcenv->get_user();
|
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) {
|
if ($add_storages) {
|
||||||
$rpcenv->check($user, '/storage', ['Datastore.Allocate']);
|
$rpcenv->check($user, '/storage', ['Datastore.Allocate']);
|
||||||
die "pool name contains characters which are illegal for storage naming\n"
|
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 $pool = extract_param($param, 'name');
|
||||||
my $node = extract_param($param, 'node');
|
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 {
|
my $worker = sub {
|
||||||
PVE::Ceph::Tools::set_pool($pool, $param);
|
PVE::Ceph::Tools::set_pool($pool, $param);
|
||||||
};
|
};
|
||||||
@ -438,6 +505,7 @@ __PACKAGE__->register_method ({
|
|||||||
fast_read => { type => 'boolean', title => 'Fast Read' },
|
fast_read => { type => 'boolean', title => 'Fast Read' },
|
||||||
application_list => { type => 'array', title => 'Application', optional => 1 },
|
application_list => { type => 'array', title => 'Application', optional => 1 },
|
||||||
statistics => { type => 'object', title => 'Statistics', optional => 1 },
|
statistics => { type => 'object', title => 'Statistics', optional => 1 },
|
||||||
|
autoscale_status => { type => 'object', title => 'Autoscale Status', optional => 1 },
|
||||||
%{ $ceph_pool_common_options->() },
|
%{ $ceph_pool_common_options->() },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -462,6 +530,7 @@ __PACKAGE__->register_method ({
|
|||||||
size => $res->{size},
|
size => $res->{size},
|
||||||
min_size => $res->{min_size},
|
min_size => $res->{min_size},
|
||||||
pg_num => $res->{pg_num},
|
pg_num => $res->{pg_num},
|
||||||
|
pg_num_min => $res->{pg_num_min},
|
||||||
pgp_num => $res->{pgp_num},
|
pgp_num => $res->{pgp_num},
|
||||||
crush_rule => $res->{crush_rule},
|
crush_rule => $res->{crush_rule},
|
||||||
pg_autoscale_mode => $res->{pg_autoscale_mode},
|
pg_autoscale_mode => $res->{pg_autoscale_mode},
|
||||||
@ -474,12 +543,19 @@ __PACKAGE__->register_method ({
|
|||||||
hashpspool => "$res->{hashpspool}",
|
hashpspool => "$res->{hashpspool}",
|
||||||
use_gmt_hitset => "$res->{use_gmt_hitset}",
|
use_gmt_hitset => "$res->{use_gmt_hitset}",
|
||||||
fast_read => "$res->{fast_read}",
|
fast_read => "$res->{fast_read}",
|
||||||
|
target_size => $res->{target_size_bytes},
|
||||||
|
target_size_ratio => $res->{target_size_ratio},
|
||||||
};
|
};
|
||||||
|
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
my $stats;
|
my $stats;
|
||||||
my $res = $rados->mon_command({ prefix => 'df' });
|
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}}) {
|
foreach my $d (@{$res->{pools}}) {
|
||||||
next if !$d->{stats};
|
next if !$d->{stats};
|
||||||
next if !defined($d->{name}) && !$d->{name} ne "$pool";
|
next if !defined($d->{name}) && !$d->{name} ne "$pool";
|
||||||
|
@ -207,7 +207,11 @@ our $cmddef = {
|
|||||||
'size',
|
'size',
|
||||||
'min_size',
|
'min_size',
|
||||||
'pg_num',
|
'pg_num',
|
||||||
|
'pg_num_min',
|
||||||
|
'pg_num_final',
|
||||||
'pg_autoscale_mode',
|
'pg_autoscale_mode',
|
||||||
|
'target_size',
|
||||||
|
'target_size_ratio',
|
||||||
'crush_rule_name',
|
'crush_rule_name',
|
||||||
'percent_used',
|
'percent_used',
|
||||||
'bytes_used',
|
'bytes_used',
|
||||||
|
Loading…
Reference in New Issue
Block a user