From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id C3BE76738F for ; Tue, 12 Jan 2021 11:22:33 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id AF5BA22C54 for ; Tue, 12 Jan 2021 11:22:03 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 32E6422BA3 for ; Tue, 12 Jan 2021 11:21:59 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id F181145D2D for ; Tue, 12 Jan 2021 11:21:58 +0100 (CET) From: Alwin Antreich To: pve-devel@lists.proxmox.com Date: Tue, 12 Jan 2021 11:21:48 +0100 Message-Id: <20210112102153.3215121-6-a.antreich@proxmox.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210112102153.3215121-1-a.antreich@proxmox.com> References: <20210112102153.3215121-1-a.antreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.018 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [pveceph.pm, pools.pm] Subject: [pve-devel] [PATCH manager v3 05/10] ceph: add autoscale_status to api calls X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2021 10:22:33 -0000 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 --- 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.29.2