diff --git a/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy.cpp b/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy.cpp index 91af911ecfe..d7ea1b7fdac 100644 --- a/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy.cpp +++ b/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy.cpp @@ -80,8 +80,8 @@ struct TVolumeThrottlingPolicy::TImpl double WriteCostMultiplier = 1; ui32 PostponedWeight = 0; - mutable double UsedIoOperationsBudget = 0; - mutable double UsedBandwidthBudget = 0; + double UsedIoOperationsBudget = 0; + double UsedBandwidthBudget = 0; TImpl( const NProto::TVolumePerformanceProfile& config, @@ -248,23 +248,25 @@ struct TVolumeThrottlingPolicy::TImpl MaxBandwidth(static_cast(requestInfo.OpType)); const auto maxIops = MaxIops(static_cast(requestInfo.OpType)); + const auto recalculatedMaxIops = + CalculateThrottlerC1(maxIops, maxBandwidth); + const auto recalculatedMaxBandwidth = + CalculateThrottlerC2(maxIops, maxBandwidth); auto d = Bucket.Register( ts, m * CostPerIO( - CalculateThrottlerC1(maxIops, maxBandwidth), - CalculateThrottlerC2(maxIops, maxBandwidth), - bandwidthUpdate - ) - ); + recalculatedMaxIops, + recalculatedMaxBandwidth, + bandwidthUpdate)); if (!d.GetValue()) { // 0 is special value which disables throttling by byteCount if (maxBandwidth) { - UsedBandwidthBudget += static_cast(bandwidthUpdate) / - static_cast(maxBandwidth); + UsedBandwidthBudget += + m * (static_cast(bandwidthUpdate) / + static_cast(recalculatedMaxBandwidth)); } - UsedIoOperationsBudget += - static_cast(1) / static_cast(maxIops); + UsedIoOperationsBudget += m * (1.0 / recalculatedMaxIops); return TDuration::Zero(); } @@ -294,24 +296,18 @@ struct TVolumeThrottlingPolicy::TImpl return Bucket.CalculateCurrentSpentBudgetShare(ts); } - double GetUsedIoBudget() const - { - return UsedIoOperationsBudget; - } - - double GetUsedBandwidthBudget() const - { - return UsedBandwidthBudget; - } - - void FlushSpentIopsBudget() const + double TakeUsedIoBudget() { + auto res = UsedIoOperationsBudget; UsedIoOperationsBudget = 0; + return res; } - void FlushSpentBandwidthBudget() const + double TakeUsedBandwidthBudget() { + auto res = UsedBandwidthBudget; UsedBandwidthBudget = 0; + return res; } }; @@ -420,24 +416,14 @@ double TVolumeThrottlingPolicy::CalculateCurrentSpentBudgetShare(TInstant ts) co return Impl->CalculateCurrentSpentBudgetShare(ts); } -double TVolumeThrottlingPolicy::GetUsedIoBudget() const -{ - return Impl->GetUsedIoBudget(); -} - -double TVolumeThrottlingPolicy::GetUsedBandwidthBudget() const -{ - return Impl->GetUsedBandwidthBudget(); -} - -void TVolumeThrottlingPolicy::FlushSpentIoBudget() const +double TVolumeThrottlingPolicy::TakeUsedIoBudget() { - Impl->FlushSpentIopsBudget(); + return Impl->TakeUsedIoBudget(); } -void TVolumeThrottlingPolicy::FlushSpentBandwidthBudget() const +double TVolumeThrottlingPolicy::TakeUsedBandwidthBudget() { - Impl->FlushSpentBandwidthBudget(); + return Impl->TakeUsedBandwidthBudget(); } const TBackpressureReport& TVolumeThrottlingPolicy::GetCurrentBackpressure() const diff --git a/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy.h b/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy.h index 9f9edf1adec..7959768ef97 100644 --- a/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy.h +++ b/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy.h @@ -99,10 +99,8 @@ class TVolumeThrottlingPolicy final TDuration GetCurrentBoostBudget() const; ui32 CalculatePostponedWeight() const; double CalculateCurrentSpentBudgetShare(TInstant ts) const; - [[nodiscard]] double GetUsedIoBudget() const; - [[nodiscard]] double GetUsedBandwidthBudget() const; - void FlushSpentIoBudget() const; - void FlushSpentBandwidthBudget() const; + [[nodiscard]] double TakeUsedIoBudget(); + [[nodiscard]] double TakeUsedBandwidthBudget(); const TBackpressureReport& GetCurrentBackpressure() const; const NProto::TVolumePerformanceProfile& GetConfig() const; diff --git a/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy_ut.cpp b/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy_ut.cpp index e418bd425c8..beb61dff01a 100644 --- a/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy_ut.cpp +++ b/cloud/blockstore/libs/storage/volume/model/volume_throttling_policy_ut.cpp @@ -1,4 +1,5 @@ #include "volume_throttling_policy.h" +#include "cloud/storage/core/libs/throttling/helpers.h" #include @@ -674,24 +675,25 @@ Y_UNIT_TEST_SUITE(TVolumeThrottlingPolicyTest) DO_TEST(tp, 0, 0, byteCount, static_cast(EOpType::Read)); } + auto recalculatedMaxIops = CalculateThrottlerC1(maxIops, maxBandwidth); + auto recalculatedMaxBandwidth = + CalculateThrottlerC2(maxIops, maxBandwidth); + UNIT_ASSERT_DOUBLES_EQUAL( - tp.GetUsedBandwidthBudget(), + tp.TakeUsedBandwidthBudget(), static_cast(ioOperation * byteCount) / - static_cast(maxBandwidth), + static_cast(recalculatedMaxBandwidth), 1e-6); + UNIT_ASSERT_DOUBLES_EQUAL(tp.TakeUsedBandwidthBudget(), 0, 1e-6); + UNIT_ASSERT_DOUBLES_EQUAL( - tp.GetUsedIoBudget(), - static_cast(ioOperation) / static_cast(maxIops), + tp.TakeUsedIoBudget(), + static_cast(ioOperation) / + static_cast(recalculatedMaxIops), 1e-6); - tp.FlushSpentBandwidthBudget(); - - UNIT_ASSERT_DOUBLES_EQUAL(tp.GetUsedBandwidthBudget(), 0, 1e-6); - - tp.FlushSpentIoBudget(); - - UNIT_ASSERT_DOUBLES_EQUAL(tp.GetUsedIoBudget(), 0, 1e-6); + UNIT_ASSERT_DOUBLES_EQUAL(tp.TakeUsedIoBudget(), 0, 1e-6); } Y_UNIT_TEST(UsedBandwidthBudgetZeroWithoutBytesThrotling) @@ -725,12 +727,12 @@ Y_UNIT_TEST_SUITE(TVolumeThrottlingPolicyTest) } UNIT_ASSERT_DOUBLES_EQUAL( - tp.GetUsedBandwidthBudget(), + tp.TakeUsedBandwidthBudget(), 0, 1e-6); UNIT_ASSERT_DOUBLES_EQUAL( - tp.GetUsedIoBudget(), + tp.TakeUsedIoBudget(), static_cast(ioOperation) / static_cast(maxIops), 1e-6); } diff --git a/cloud/blockstore/libs/storage/volume/volume_actor.cpp b/cloud/blockstore/libs/storage/volume/volume_actor.cpp index 019ac7d0882..f30b4635b89 100644 --- a/cloud/blockstore/libs/storage/volume/volume_actor.cpp +++ b/cloud/blockstore/libs/storage/volume/volume_actor.cpp @@ -215,15 +215,13 @@ void TVolumeActor::UpdateLeakyBucketCounters(const TActorContext& ctx) auto& simple = VolumeSelfCounters->Simple; auto& cumulative = VolumeSelfCounters->Cumulative; - const auto& tp = State->GetThrottlingPolicy(); + auto& tp = State->AccessThrottlingPolicy(); cumulative.UsedIoBudget.Increment( - static_cast(tp.GetUsedIoBudget() * 100.0)); - tp.FlushSpentIoBudget(); + static_cast(tp.TakeUsedIoBudget() * 100.0)); cumulative.UsedBandwidthBudget.Increment( - static_cast(tp.GetUsedBandwidthBudget() * 100.0)); - tp.FlushSpentBandwidthBudget(); + static_cast(tp.TakeUsedBandwidthBudget() * 100.0)); ui64 currentRate = tp.CalculateCurrentSpentBudgetShare(ctx.Now()) * 100; simple.MaxUsedQuota.Set(Max(simple.MaxUsedQuota.Value, currentRate)); diff --git a/cloud/blockstore/libs/throttling/throttler.cpp b/cloud/blockstore/libs/throttling/throttler.cpp index 75ee8630363..806313115eb 100644 --- a/cloud/blockstore/libs/throttling/throttler.cpp +++ b/cloud/blockstore/libs/throttling/throttler.cpp @@ -530,8 +530,10 @@ class TThrottler final { ui64 quota = 0; with_lock (ThrottlerLock) { - quota = static_cast(ceil(ThrottlerPolicy - ->CalculateCurrentSpentBudgetShare(Timer->Now()) * 100.0)); + quota = static_cast( + ThrottlerPolicy->CalculateCurrentSpentBudgetShare( + Timer->Now()) * + 100.0); } ThrottlerMetrics->UpdateUsedQuota(quota); ThrottlerMetrics->UpdateMaxUsedQuota();