Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NBS] make new volume counters to fix UsedQuota strange values #2704

Merged
merged 17 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cloud/blockstore/config/storage.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1074,4 +1074,7 @@ message TStorageServiceConfig

// Enabling direct copying of data between disk agents.
optional bool UseDirectCopyRange = 394;

// Enabling UsedQuota calculation as UsedIoQuota + UsedBandwidthQuota
optional bool CalculateUsedQuotaFromOtherMetrics = 395;
}
1 change: 1 addition & 0 deletions cloud/blockstore/libs/storage/core/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ TDuration MSeconds(ui32 value)
xxx(VolumeProxyCacheRetryDuration, TDuration, Seconds(15) )\
\
xxx(UseDirectCopyRange, bool, false )\
xxx(CalculateUsedQuotaFromOtherMetrics, bool, false )\
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved
xxx(MaxShadowDiskFillBandwidth, ui32, 512 )\
xxx(MaxShadowDiskFillIoDepth, ui32, 1 )\
xxx(BackgroundOperationsTotalBandwidth, ui32, 1024 )\
Expand Down
1 change: 1 addition & 0 deletions cloud/blockstore/libs/storage/core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ class TStorageConfig
TString GetCachedDiskAgentSessionsPath() const;

bool GetUseDirectCopyRange() const;
bool GetCalculateUsedQuotaFromOtherMetrics() const;
ui32 GetMaxShadowDiskFillBandwidth() const;
ui32 GetMaxShadowDiskFillIoDepth() const;
ui32 GetBackgroundOperationsTotalBandwidth() const;
Expand Down
10 changes: 10 additions & 0 deletions cloud/blockstore/libs/storage/core/disk_counters.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,12 +623,22 @@ struct TVolumeSelfCumulativeCounters
EPublishingPolicy::All,
TCumulativeCounter::ECounterType::Generic,
ECounterExpirationPolicy::Permanent};
TCounter UsedIoQuota{
EPublishingPolicy::All,
TCumulativeCounter::ECounterType::Generic,
ECounterExpirationPolicy::Permanent};
TCounter UsedBandwidthQuota{
EPublishingPolicy::All,
TCumulativeCounter::ECounterType::Generic,
ECounterExpirationPolicy::Permanent};

static constexpr TMeta AllCounters[] = {
MakeMeta<&TVolumeSelfCumulativeCounters::ThrottlerRejectedRequests>(),
MakeMeta<&TVolumeSelfCumulativeCounters::ThrottlerPostponedRequests>(),
MakeMeta<&TVolumeSelfCumulativeCounters::ThrottlerSkippedRequests>(),
MakeMeta<&TVolumeSelfCumulativeCounters::UsedQuota>(),
MakeMeta<&TVolumeSelfCumulativeCounters::UsedIoQuota>(),
MakeMeta<&TVolumeSelfCumulativeCounters::UsedBandwidthQuota>(),
};
};
static_assert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ struct TVolumeThrottlingPolicy::TImpl
double WriteCostMultiplier = 1;
ui32 PostponedWeight = 0;

double UsedIoOperationsBudget = 0;
double UsedBandwidthQuota = 0;
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved

TImpl(
const NProto::TVolumePerformanceProfile& config,
const ui32 policyVersion,
Expand Down Expand Up @@ -236,7 +239,7 @@ struct TVolumeThrottlingPolicy::TImpl
return TDuration::Zero();
}

ui32 bandwidthUpdate = requestInfo.ByteCount;
const ui32 bandwidthUpdate = requestInfo.ByteCount;
double m = static_cast<EOpType>(requestInfo.OpType) == EOpType::Read
? 1.0
: WriteCostMultiplier;
Expand All @@ -245,16 +248,25 @@ struct TVolumeThrottlingPolicy::TImpl
MaxBandwidth(static_cast<EOpType>(requestInfo.OpType));
const auto maxIops = MaxIops(static_cast<EOpType>(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) {
UsedBandwidthQuota +=
m * (static_cast<double>(bandwidthUpdate) /
static_cast<double>(recalculatedMaxBandwidth));
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved
}
UsedIoOperationsBudget += m * (1.0 / recalculatedMaxIops);
return TDuration::Zero();
}

Expand Down Expand Up @@ -283,6 +295,20 @@ struct TVolumeThrottlingPolicy::TImpl
{
return Bucket.CalculateCurrentSpentBudgetShare(ts);
}

double TakeUsedIoQuota()
{
auto res = UsedIoOperationsBudget;
UsedIoOperationsBudget = 0;
return res;
}

double TakeUsedBandwidthQuota()
{
auto res = UsedBandwidthQuota;
UsedBandwidthQuota = 0;
return res;
}
};

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -390,6 +416,16 @@ double TVolumeThrottlingPolicy::CalculateCurrentSpentBudgetShare(TInstant ts) co
return Impl->CalculateCurrentSpentBudgetShare(ts);
}

double TVolumeThrottlingPolicy::TakeUsedIoQuota()
{
return Impl->TakeUsedIoQuota();
}

double TVolumeThrottlingPolicy::TakeUsedBandwidthQuota()
{
return Impl->TakeUsedBandwidthQuota();
}
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved

const TBackpressureReport& TVolumeThrottlingPolicy::GetCurrentBackpressure() const
{
return Impl->CurrentBackpressure;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ class TVolumeThrottlingPolicy final
TDuration GetCurrentBoostBudget() const;
ui32 CalculatePostponedWeight() const;
double CalculateCurrentSpentBudgetShare(TInstant ts) const;
[[nodiscard]] double TakeUsedIoQuota();
[[nodiscard]] double TakeUsedBandwidthQuota();
const TBackpressureReport& GetCurrentBackpressure() const;
const NProto::TVolumePerformanceProfile& GetConfig() const;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "volume_throttling_policy.h"
#include "cloud/storage/core/libs/throttling/helpers.h"

#include <cloud/blockstore/libs/storage/protos/part.pb.h>

Expand Down Expand Up @@ -643,6 +644,99 @@ Y_UNIT_TEST_SUITE(TVolumeThrottlingPolicyTest)
DO_TEST(tp, 4'379'770, 10'000, 1_MB, static_cast<ui32>(EOpType::Write));
}

Y_UNIT_TEST(CollectThrotlingDiagnostics)
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved
{
const ui64 maxBandwidth = 2_MB;
const ui64 maxIops = 4;

const auto config = MakeSimpleConfig(
maxBandwidth,
maxIops,
100, // burstPercentage
0, // boostTime
0, // boostRefillTime
0, // boostPercentage
1_GB // maxPostponedWeight
);
TVolumeThrottlingPolicy tp(
config,
TThrottlerConfig(
TDuration::Seconds(1), // maxDelay
Max<ui32>(), // maxWriteCostMultiplier
1, // defaultPostponedRequestWeight
CalculateBoostTime(config), // initialBoostBudget
false // useDiskSpaceScore
));

const auto byteCount = 256_KB;
const auto ioOperation = 2;
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved

for (auto i = 0; i < ioOperation; ++i) {
DO_TEST(tp, 0, 0, byteCount, static_cast<ui32>(EOpType::Read));
}

auto recalculatedMaxIops = CalculateThrottlerC1(maxIops, maxBandwidth);
auto recalculatedMaxBandwidth =
CalculateThrottlerC2(maxIops, maxBandwidth);

UNIT_ASSERT_DOUBLES_EQUAL(
tp.TakeUsedBandwidthQuota(),
static_cast<double>(ioOperation * byteCount) /
static_cast<double>(recalculatedMaxBandwidth),
1e-6);

UNIT_ASSERT_DOUBLES_EQUAL(tp.TakeUsedBandwidthQuota(), 0, 1e-6);

UNIT_ASSERT_DOUBLES_EQUAL(
tp.TakeUsedIoQuota(),
static_cast<double>(ioOperation) /
static_cast<double>(recalculatedMaxIops),
1e-6);

UNIT_ASSERT_DOUBLES_EQUAL(tp.TakeUsedIoQuota(), 0, 1e-6);
}

Y_UNIT_TEST(UsedBandwidthQuotaZeroWithoutBytesThrotling)
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved
komarevtsev-d marked this conversation as resolved.
Show resolved Hide resolved
{
const ui64 maxIops = 4;

const auto config = MakeSimpleConfig(
0,
maxIops,
100, // burstPercentage
0, // boostTime
0, // boostRefillTime
0, // boostPercentage
1_GB // maxPostponedWeight
);
TVolumeThrottlingPolicy tp(
config,
TThrottlerConfig(
TDuration::Seconds(1), // maxDelay
Max<ui32>(), // maxWriteCostMultiplier
1, // defaultPostponedRequestWeight
CalculateBoostTime(config), // initialBoostBudget
false // useDiskSpaceScore
));

const auto byteCount = 256_KB;
const auto ioOperation = 2;
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved

for (auto i = 0; i < ioOperation; ++i) {
DO_TEST(tp, 0, 0, byteCount, static_cast<ui32>(EOpType::Read));
}

UNIT_ASSERT_DOUBLES_EQUAL(
tp.TakeUsedBandwidthQuota(),
0,
1e-6);

vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved
UNIT_ASSERT_DOUBLES_EQUAL(
tp.TakeUsedIoQuota(),
static_cast<double>(ioOperation) / static_cast<double>(maxIops),
1e-6);
}

#undef DO_TEST

Y_UNIT_TEST(MergeBackpressureReports)
Expand Down
22 changes: 20 additions & 2 deletions cloud/blockstore/libs/storage/volume/volume_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,26 @@ void TVolumeActor::UpdateLeakyBucketCounters(const TActorContext& ctx)

auto& simple = VolumeSelfCounters->Simple;
auto& cumulative = VolumeSelfCounters->Cumulative;
const auto& tp = State->GetThrottlingPolicy();
ui64 currentRate = tp.CalculateCurrentSpentBudgetShare(ctx.Now()) * 100;
auto& tp = State->AccessThrottlingPolicy();

auto usedIoQuota = tp.TakeUsedIoQuota();
auto usedBandwidthQuota = tp.TakeUsedBandwidthQuota();

cumulative.UsedIoQuota.Increment(static_cast<ui64>(usedIoQuota * 100.0));
cumulative.UsedBandwidthQuota.Increment(
static_cast<ui64>(usedBandwidthQuota * 100.0));

Config->GetCalculateUsedQuotaFromOtherMetrics();
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved

auto currentRate = static_cast<ui64>(Min(
[&]()
vladstepanyuk marked this conversation as resolved.
Show resolved Hide resolved
{
if (Config->GetCalculateUsedQuotaFromOtherMetrics()) {
return (usedIoQuota + usedBandwidthQuota) * 100.0;
komarevtsev-d marked this conversation as resolved.
Show resolved Hide resolved
}
return tp.CalculateCurrentSpentBudgetShare(ctx.Now()) * 100.0;
}(),
100.0));
simple.MaxUsedQuota.Set(Max(simple.MaxUsedQuota.Value, currentRate));
cumulative.UsedQuota.Increment(currentRate);
}
Expand Down
6 changes: 4 additions & 2 deletions cloud/blockstore/libs/throttling/throttler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,8 +530,10 @@ class TThrottler final
{
ui64 quota = 0;
with_lock (ThrottlerLock) {
quota = static_cast<ui64>(ceil(ThrottlerPolicy
->CalculateCurrentSpentBudgetShare(Timer->Now()) * 100.0));
quota = static_cast<ui64>(
ThrottlerPolicy->CalculateCurrentSpentBudgetShare(
Timer->Now()) *
100.0);
}
ThrottlerMetrics->UpdateUsedQuota(quota);
ThrottlerMetrics->UpdateMaxUsedQuota();
Expand Down
Loading