Skip to content

Commit

Permalink
24-3: Add scale recommender for autoscaling (#12425)
Browse files Browse the repository at this point in the history
  • Loading branch information
pixcc authored Dec 10, 2024
1 parent ccb1ed1 commit ad9481c
Show file tree
Hide file tree
Showing 37 changed files with 1,698 additions and 23 deletions.
23 changes: 23 additions & 0 deletions ydb/core/base/hive.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ namespace NKikimr {
EvUpdateTabletsObject,
EvUpdateDomain,
EvRequestTabletDistribution,
EvRequestScaleRecommendation,
EvConfigureScaleRecommender,

// replies
EvBootTabletReply = EvBootTablet + 512,
Expand Down Expand Up @@ -84,6 +86,8 @@ namespace NKikimr {
EvUpdateTabletsObjectReply,
EvUpdateDomainReply,
EvResponseTabletDistribution,
EvResponseScaleRecommendation,
EvConfigureScaleRecommenderReply,

EvEnd
};
Expand Down Expand Up @@ -876,6 +880,25 @@ namespace NKikimr {

struct TEvResponseTabletDistribution : TEventPB<TEvResponseTabletDistribution,
NKikimrHive::TEvResponseTabletDistribution, EvResponseTabletDistribution> {};

struct TEvRequestScaleRecommendation : TEventPB<TEvRequestScaleRecommendation,
NKikimrHive::TEvRequestScaleRecommendation, EvRequestScaleRecommendation>
{
TEvRequestScaleRecommendation() = default;

TEvRequestScaleRecommendation(TSubDomainKey domainKey) {
Record.MutableDomainKey()->CopyFrom(domainKey);
}
};

struct TEvResponseScaleRecommendation : TEventPB<TEvResponseScaleRecommendation,
NKikimrHive::TEvResponseScaleRecommendation, EvResponseScaleRecommendation> {};

struct TEvConfigureScaleRecommender : TEventPB<TEvConfigureScaleRecommender,
NKikimrHive::TEvConfigureScaleRecommender, EvConfigureScaleRecommender> {};

struct TEvConfigureScaleRecommenderReply : TEventPB<TEvConfigureScaleRecommenderReply,
NKikimrHive::TEvConfigureScaleRecommenderReply, EvConfigureScaleRecommenderReply> {};
};

IActor* CreateDefaultHive(const TActorId &tablet, TTabletStorageInfo *info);
Expand Down
52 changes: 52 additions & 0 deletions ydb/core/cms/console/console__alter_tenant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,48 @@ class TTenantsManager::TTxAlterTenant : public TTransactionBase<TTenantsManager>
return Error(Ydb::StatusIds::BAD_REQUEST, "Data size soft quota cannot be larger than hard quota", ctx);
}
}

// Check scale recommender policies.
if (rec.has_scale_recommender_policies()) {
if (!Self->FeatureFlags.GetEnableScaleRecommender()) {
return Error(Ydb::StatusIds::UNSUPPORTED, "Feature flag EnableScaleRecommender is off", ctx);
}

const auto& policies = rec.scale_recommender_policies();
if (policies.policies().size() > 1) {
return Error(Ydb::StatusIds::BAD_REQUEST, "Currently, no more than one policy is supported at a time", ctx);
}

if (!policies.policies().empty()) {
using enum Ydb::Cms::ScaleRecommenderPolicies_ScaleRecommenderPolicy_TargetTrackingPolicy::TargetCase;
using enum Ydb::Cms::ScaleRecommenderPolicies_ScaleRecommenderPolicy::PolicyCase;

const auto& policy = policies.policies()[0];
switch (policy.GetPolicyCase()) {
case kTargetTrackingPolicy: {
const auto& targetTracking = policy.target_tracking_policy();
switch (targetTracking.GetTargetCase()) {
case kAverageCpuUtilizationPercent: {
auto cpuUtilization = targetTracking.average_cpu_utilization_percent();
if (cpuUtilization < 10 || cpuUtilization > 90) {
return Error(Ydb::StatusIds::BAD_REQUEST, "Average CPU utilization target must be from 10% to 90%", ctx);
}
break;
}
case TARGET_NOT_SET:
return Error(Ydb::StatusIds::BAD_REQUEST, "Target type for target tracking policy is not set", ctx);
default:
return Error(Ydb::StatusIds::BAD_REQUEST, "Unsupported target type for target tracking policy", ctx);
}
break;
}
case POLICY_NOT_SET:
return Error(Ydb::StatusIds::BAD_REQUEST, "Policy type is not set", ctx);
default:
return Error(Ydb::StatusIds::BAD_REQUEST, "Unsupported policy type", ctx);
}
}
}

// Check attributes.
THashSet<TString> attrNames;
Expand Down Expand Up @@ -274,6 +316,11 @@ class TTenantsManager::TTxAlterTenant : public TTransactionBase<TTenantsManager>
updateSubdomainVersion = true;
}

if (rec.has_scale_recommender_policies()) {
ScaleRecommenderPolicies.ConstructInPlace(rec.scale_recommender_policies());
Self->DbUpdateScaleRecommenderPolicies(Tenant, *ScaleRecommenderPolicies, txc, ctx);
}

if (rec.idempotency_key() || Tenant->AlterIdempotencyKey) {
Tenant->AlterIdempotencyKey = rec.idempotency_key();
Self->DbUpdateTenantAlterIdempotencyKey(Tenant, Tenant->AlterIdempotencyKey, txc, ctx);
Expand Down Expand Up @@ -367,6 +414,10 @@ class TTenantsManager::TTxAlterTenant : public TTransactionBase<TTenantsManager>
if (DatabaseQuotas) {
Tenant->DatabaseQuotas.ConstructInPlace(*DatabaseQuotas);
}
if (ScaleRecommenderPolicies) {
Tenant->ScaleRecommenderPolicies.ConstructInPlace(*ScaleRecommenderPolicies);
Tenant->ScaleRecommenderPoliciesConfirmed = false;
}
if (SubdomainVersion) {
Tenant->SubdomainVersion = *SubdomainVersion;
}
Expand All @@ -389,6 +440,7 @@ class TTenantsManager::TTxAlterTenant : public TTransactionBase<TTenantsManager>
THashMap<TString, ui64> PoolsToAdd;
TMaybe<Ydb::Cms::SchemaOperationQuotas> SchemaOperationQuotas;
TMaybe<Ydb::Cms::DatabaseQuotas> DatabaseQuotas;
TMaybe<Ydb::Cms::ScaleRecommenderPolicies> ScaleRecommenderPolicies;
TMaybe<ui64> SubdomainVersion;
bool ComputationalUnitsModified;
TTenant::TPtr Tenant;
Expand Down
43 changes: 43 additions & 0 deletions ydb/core/cms/console/console__create_tenant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,49 @@ class TTenantsManager::TTxCreateTenant : public TTransactionBase<TTenantsManager
Tenant->DatabaseQuotas.ConstructInPlace(quotas);
}

if (rec.has_scale_recommender_policies()) {
if (!Self->FeatureFlags.GetEnableScaleRecommender()) {
return Error(Ydb::StatusIds::UNSUPPORTED, "Feature flag EnableScaleRecommender is off", ctx);
}

const auto& policies = rec.scale_recommender_policies();
if (policies.policies().size() > 1) {
return Error(Ydb::StatusIds::BAD_REQUEST, "Currently, no more than one policy is supported at a time", ctx);
}

if (!policies.policies().empty()) {
using enum Ydb::Cms::ScaleRecommenderPolicies_ScaleRecommenderPolicy_TargetTrackingPolicy::TargetCase;
using enum Ydb::Cms::ScaleRecommenderPolicies_ScaleRecommenderPolicy::PolicyCase;

const auto& policy = policies.policies()[0];
switch (policy.GetPolicyCase()) {
case kTargetTrackingPolicy: {
const auto& targetTracking = policy.target_tracking_policy();
switch (targetTracking.GetTargetCase()) {
case kAverageCpuUtilizationPercent: {
auto cpuUtilization = targetTracking.average_cpu_utilization_percent();
if (cpuUtilization < 10 || cpuUtilization > 90) {
return Error(Ydb::StatusIds::BAD_REQUEST, "Average CPU utilization target must be from 10% to 90%", ctx);
}
break;
}
case TARGET_NOT_SET:
return Error(Ydb::StatusIds::BAD_REQUEST, "Target type for target tracking policy is not set", ctx);
default:
return Error(Ydb::StatusIds::BAD_REQUEST, "Unsupported target type for target tracking policy", ctx);
}
break;
}
case POLICY_NOT_SET:
return Error(Ydb::StatusIds::BAD_REQUEST, "Policy type is not set", ctx);
default:
return Error(Ydb::StatusIds::BAD_REQUEST, "Unsupported policy type", ctx);
}
}
Tenant->ScaleRecommenderPolicies.ConstructInPlace(policies);
Tenant->ScaleRecommenderPoliciesConfirmed = false;
}

if (rec.idempotency_key()) {
Tenant->CreateIdempotencyKey = rec.idempotency_key();
}
Expand Down
3 changes: 2 additions & 1 deletion ydb/core/cms/console/console__scheme.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ struct Schema : NIceDb::Schema {
struct DatabaseQuotas : Column<27, NScheme::NTypeIds::String> {};
struct IsExternalStatisticsAggregator : Column<28, NScheme::NTypeIds::Bool> {};
struct IsExternalBackupController : Column<29, NScheme::NTypeIds::Bool> {};
struct ScaleRecommenderPolicies : Column<30, NScheme::NTypeIds::String> {};

using TKey = TableKey<Path>;
using TColumns = TableColumns<Path, State, Coordinators, Mediators, PlanResolution,
Issue, TxId, UserToken, SubdomainVersion, ConfirmedSubdomain, TimeCastBucketsPerMediator,
Attributes, Generation, SchemeShardId, PathId, ErrorCode, IsExternalSubDomain, IsExternalHive,
AreResourcesShared, SharedDomainSchemeShardId, SharedDomainPathId, IsExternalSysViewProcessor,
SchemaOperationQuotas, CreateIdempotencyKey, AlterIdempotencyKey, DatabaseQuotas, IsExternalStatisticsAggregator,
IsExternalBackupController>;
IsExternalBackupController, ScaleRecommenderPolicies>;
};

struct TenantPools : Table<3> {
Expand Down
Loading

0 comments on commit ad9481c

Please sign in to comment.