-
Notifications
You must be signed in to change notification settings - Fork 702
Add stats for grouped limiter and caches #20738
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
Changes from 5 commits
1957ac0
320a636
30facd3
f989e0a
94162e1
d8fbd40
91f1db7
9f51600
3e2ba33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,10 @@ namespace NKikimr::NMemory { | |
enum class EMemoryConsumerKind { | ||
SharedCache, | ||
MemTable, | ||
ScanMemoryLimiter, | ||
CompMemoryLimiter, | ||
BlobCache, | ||
DataAccessorCache | ||
}; | ||
|
||
struct IMemoryConsumer : public TThrRefBase { | ||
|
@@ -17,7 +21,7 @@ enum EEvMemory { | |
EvConsumerRegister = EventSpaceBegin(TKikimrEvents::ES_MEMORY), | ||
EvConsumerRegistered, | ||
EvConsumerLimit, | ||
|
||
EvMemTableRegister, | ||
EvMemTableRegistered, | ||
EvMemTableCompact, | ||
|
@@ -47,10 +51,12 @@ struct TEvConsumerRegistered : public TEventLocal<TEvConsumerRegistered, EvConsu | |
|
||
struct TEvConsumerLimit : public TEventLocal<TEvConsumerLimit, EvConsumerLimit> { | ||
ui64 LimitBytes; | ||
std::optional<ui64> HardLimitBytes; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LimitBytes и так работает как hard limit не надо сюда ничего такого было добавлять, к тому же по использованию вижу что вы просто домнажаете hard limit на коэффицент чтобы получить soft просто делайте это внутри вашего memory consumer'а |
||
|
||
TEvConsumerLimit(ui64 limitBytes) | ||
TEvConsumerLimit(ui64 limitBytes, std::optional<ui64> hardLimitBytes = std::nullopt) | ||
: LimitBytes(limitBytes) | ||
{} | ||
, HardLimitBytes(std::move(hardLimitBytes)) { | ||
} | ||
}; | ||
|
||
struct TEvMemTableRegister : public TEventLocal<TEvMemTableRegister, EvMemTableRegister> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,8 +16,6 @@ | |
#include <ydb/core/tx/columnshard/blob_cache.h> | ||
#include <ydb/core/tx/columnshard/common/limits.h> | ||
#include <ydb/core/tx/columnshard/data_accessor/cache_policy/policy.h> | ||
#include <ydb/core/tx/limiter/grouped_memory/usage/events.h> | ||
#include <ydb/core/tx/limiter/grouped_memory/usage/service.h> | ||
#include <ydb/library/actors/core/actor_bootstrapped.h> | ||
#include <ydb/library/actors/core/log.h> | ||
#include <ydb/library/actors/core/process_stats.h> | ||
|
@@ -86,6 +84,7 @@ struct TConsumerState { | |
ui64 MinBytes = 0; | ||
ui64 MaxBytes = 0; | ||
bool CanZeroLimit = false; | ||
std::optional<ui64> ExactLimit; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. если нужен был точный лимит, то можно просто MinBytes=MaxBytes выставить и не усложнять весь пересчёт ещё одним полем сбоку а для того чтобы метрика была одна (без Min/Max) добавить флаг аналогично CanZeroLimit |
||
|
||
TConsumerState(const TMemoryConsumer& consumer) | ||
: Kind(consumer.Kind) | ||
|
@@ -266,21 +265,31 @@ class TMemoryController : public TActorBootstrapped<TMemoryController> { | |
|
||
ui64 consumersLimitBytes = 0; | ||
for (const auto& consumer : consumers) { | ||
ui64 limitBytes = consumer.GetLimit(coefficient); | ||
if (resultingConsumersConsumption + otherConsumption + externalConsumption > softLimitBytes && consumer.CanZeroLimit) { | ||
limitBytes = SafeDiff(limitBytes, resultingConsumersConsumption + otherConsumption + externalConsumption - softLimitBytes); | ||
const bool isExactLimitConsumer = consumer.ExactLimit.has_value(); | ||
ui64 limitBytes; | ||
if (isExactLimitConsumer) { | ||
limitBytes = consumer.ExactLimit.value(); | ||
} else { | ||
limitBytes = consumer.GetLimit(coefficient); | ||
if (resultingConsumersConsumption + otherConsumption + externalConsumption > softLimitBytes && consumer.CanZeroLimit) { | ||
limitBytes = SafeDiff(limitBytes, resultingConsumersConsumption + otherConsumption + externalConsumption - softLimitBytes); | ||
} | ||
} | ||
consumersLimitBytes += limitBytes; | ||
|
||
LOG_INFO_S(ctx, NKikimrServices::MEMORY_CONTROLLER, "Consumer " << consumer.Kind << " state:" | ||
<< " Consumption: " << HumanReadableBytes(consumer.Consumption) << " Limit: " << HumanReadableBytes(limitBytes) | ||
<< " Min: " << HumanReadableBytes(consumer.MinBytes) << " Max: " << HumanReadableBytes(consumer.MaxBytes)); | ||
auto& counters = GetConsumerCounters(consumer.Kind); | ||
auto& counters = GetConsumerCounters(consumer.Kind, !isExactLimitConsumer); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. я бы ожидал что аргумент будет просто называться так же как флаг, без лишней инверсии |
||
counters.Consumption->Set(consumer.Consumption); | ||
counters.Reservation->Set(SafeDiff(limitBytes, consumer.Consumption)); | ||
counters.LimitBytes->Set(limitBytes); | ||
counters.LimitMinBytes->Set(consumer.MinBytes); | ||
counters.LimitMaxBytes->Set(consumer.MaxBytes); | ||
if (counters.LimitMinBytes) { | ||
counters.LimitMinBytes->Set(consumer.MinBytes); | ||
} | ||
if (counters.LimitMaxBytes) { | ||
counters.LimitMaxBytes->Set(consumer.MaxBytes); | ||
} | ||
SetMemoryStats(consumer, memoryStats, limitBytes); | ||
|
||
ApplyLimit(consumer, limitBytes); | ||
|
@@ -289,8 +298,6 @@ class TMemoryController : public TActorBootstrapped<TMemoryController> { | |
Counters->GetCounter("Stats/ConsumersLimit")->Set(consumersLimitBytes); | ||
|
||
ProcessResourceBrokerConfig(ctx, memoryStats, hardLimitBytes, activitiesLimitBytes); | ||
ProcessGroupedMemoryLimiterConfig(ctx, memoryStats, hardLimitBytes); | ||
ProcessCacheConfig(ctx, memoryStats, hardLimitBytes); | ||
|
||
Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId()), memoryStatsUpdate); | ||
|
||
|
@@ -361,10 +368,15 @@ class TMemoryController : public TActorBootstrapped<TMemoryController> { | |
case EMemoryConsumerKind::MemTable: | ||
ApplyMemTableLimit(limitBytes); | ||
break; | ||
default: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. вернуть как было с default соответственно |
||
case EMemoryConsumerKind::SharedCache: | ||
case EMemoryConsumerKind::BlobCache: | ||
case EMemoryConsumerKind::DataAccessorCache: | ||
Send(consumer.ActorId, new TEvConsumerLimit(limitBytes)); | ||
break; | ||
|
||
case EMemoryConsumerKind::ScanMemoryLimiter: | ||
case EMemoryConsumerKind::CompMemoryLimiter: | ||
Send(consumer.ActorId, new TEvConsumerLimit(limitBytes * NKikimr::NOlap::TGlobalLimits::GroupedMemoryLimiterSoftLimitCoefficient, limitBytes)); | ||
break; | ||
} | ||
} | ||
|
||
|
@@ -377,43 +389,6 @@ class TMemoryController : public TActorBootstrapped<TMemoryController> { | |
} | ||
} | ||
|
||
void ProcessGroupedMemoryLimiterConfig(const TActorContext& /*ctx*/, NKikimrMemory::TMemoryStats& /*memoryStats*/, ui64 hardLimitBytes) { | ||
ui64 columnTablesScanLimitBytes = GetColumnTablesReadExecutionLimitBytes(Config, hardLimitBytes); | ||
ui64 columnTablesCompactionLimitBytes = GetColumnTablesCompactionLimitBytes(Config, hardLimitBytes) * | ||
NKikimr::NOlap::TGlobalLimits::GroupedMemoryLimiterCompactionLimitCoefficient; | ||
|
||
ApplyGroupedMemoryLimiterConfig(columnTablesScanLimitBytes, columnTablesCompactionLimitBytes); | ||
} | ||
|
||
void ApplyGroupedMemoryLimiterConfig(const ui64 scanHardLimitBytes, const ui64 compactionHardLimitBytes) { | ||
namespace NGroupedMemoryManager = ::NKikimr::NOlap::NGroupedMemoryManager; | ||
using UpdateMemoryLimitsEv = NGroupedMemoryManager::NEvents::TEvExternal::TEvUpdateMemoryLimits; | ||
|
||
Send(NGroupedMemoryManager::TScanMemoryLimiterOperator::MakeServiceId(SelfId().NodeId()), | ||
new UpdateMemoryLimitsEv(scanHardLimitBytes * NKikimr::NOlap::TGlobalLimits::GroupedMemoryLimiterSoftLimitCoefficient, | ||
scanHardLimitBytes)); | ||
|
||
Send(NGroupedMemoryManager::TCompMemoryLimiterOperator::MakeServiceId(SelfId().NodeId()), | ||
new UpdateMemoryLimitsEv(compactionHardLimitBytes * NKikimr::NOlap::TGlobalLimits::GroupedMemoryLimiterSoftLimitCoefficient, | ||
compactionHardLimitBytes)); | ||
} | ||
|
||
void ProcessCacheConfig(const TActorContext& /*ctx*/, NKikimrMemory::TMemoryStats& /*memoryStats*/, ui64 hardLimitBytes) { | ||
ui64 columnTablesBlobCacheLimitBytes = GetColumnTablesCacheLimitBytes(Config, hardLimitBytes); | ||
|
||
ApplyCacheConfig(columnTablesBlobCacheLimitBytes); | ||
} | ||
|
||
void ApplyCacheConfig(const ui64 cacheLimitBytes) { | ||
using TUpdateMaxBlobCacheDataSizeEv = NBlobCache::TEvBlobCache::TEvUpdateMaxCacheDataSize; | ||
using TGeneralCache = NKikimr::NOlap::NDataAccessorControl::TGeneralCache; | ||
using TGlobalLimits = NKikimr::NOlap::TGlobalLimits; | ||
|
||
Send(NKikimr::NBlobCache::MakeBlobCacheServiceId(), new TUpdateMaxBlobCacheDataSizeEv(cacheLimitBytes * TGlobalLimits::BlobCacheCoefficient)); | ||
|
||
TGeneralCache::UpdateMaxCacheSize(cacheLimitBytes * TGlobalLimits::DataAccessorCoefficient); | ||
} | ||
|
||
void ProcessResourceBrokerConfig(const TActorContext& ctx, NKikimrMemory::TMemoryStats& memoryStats, ui64 hardLimitBytes, | ||
ui64 activitiesLimitBytes) { | ||
ui64 queryExecutionConsumption = TAlignedPagePool::GetGlobalPagePoolSize(); | ||
|
@@ -470,18 +445,21 @@ class TMemoryController : public TActorBootstrapped<TMemoryController> { | |
queue->MutableLimit()->SetMemory(limitBytes); | ||
} | ||
|
||
TConsumerCounters& GetConsumerCounters(EMemoryConsumerKind consumer) { | ||
TConsumerCounters& GetConsumerCounters(EMemoryConsumerKind consumer, const bool minMaxRequired) { | ||
auto it = ConsumerCounters.FindPtr(consumer); | ||
if (it) { | ||
return *it; | ||
} | ||
|
||
TCounterPtr limitMinBytes = minMaxRequired ? Counters->GetCounter(TStringBuilder() << "Consumer/" << consumer << "/LimitMin") : nullptr; | ||
TCounterPtr limitMaxBytes = minMaxRequired ? Counters->GetCounter(TStringBuilder() << "Consumer/" << consumer << "/LimitMax") : nullptr; | ||
|
||
return ConsumerCounters.emplace(consumer, TConsumerCounters{ | ||
Counters->GetCounter(TStringBuilder() << "Consumer/" << consumer << "/Consumption"), | ||
Counters->GetCounter(TStringBuilder() << "Consumer/" << consumer << "/Reservation"), | ||
Counters->GetCounter(TStringBuilder() << "Consumer/" << consumer << "/Limit"), | ||
Counters->GetCounter(TStringBuilder() << "Consumer/" << consumer << "/LimitMin"), | ||
Counters->GetCounter(TStringBuilder() << "Consumer/" << consumer << "/LimitMax"), | ||
limitMinBytes, | ||
limitMaxBytes, | ||
}).first->second; | ||
} | ||
|
||
|
@@ -497,6 +475,26 @@ class TMemoryController : public TActorBootstrapped<TMemoryController> { | |
stats.SetSharedCacheLimit(limitBytes); | ||
break; | ||
} | ||
case EMemoryConsumerKind::ScanMemoryLimiter: { | ||
stats.SetScanMemoryLimiterConsumption(consumer.Consumption); | ||
stats.SetScanMemoryLimiterLimit(limitBytes); | ||
break; | ||
} | ||
case EMemoryConsumerKind::CompMemoryLimiter: { | ||
stats.SetCompMemoryLimiterConsumption(consumer.Consumption); | ||
stats.SetCompMemoryLimiterLimit(limitBytes); | ||
break; | ||
} | ||
case EMemoryConsumerKind::BlobCache: { | ||
stats.SetBlobCacheConsumption(consumer.Consumption); | ||
stats.SetBlobCacheLimit(limitBytes); | ||
break; | ||
} | ||
case EMemoryConsumerKind::DataAccessorCache: { | ||
stats.SetDataAccessorCacheConsumption(consumer.Consumption); | ||
stats.SetDataAccessorCacheLimit(limitBytes); | ||
break; | ||
} | ||
default: | ||
Y_ABORT("Unhandled consumer"); | ||
} | ||
|
@@ -517,6 +515,23 @@ class TMemoryController : public TActorBootstrapped<TMemoryController> { | |
result.CanZeroLimit = true; | ||
break; | ||
} | ||
case EMemoryConsumerKind::ScanMemoryLimiter: { | ||
result.ExactLimit = GetColumnTablesReadExecutionLimitBytes(Config, hardLimitBytes); | ||
break; | ||
} | ||
case EMemoryConsumerKind::CompMemoryLimiter: { | ||
result.ExactLimit = GetColumnTablesCompactionLimitBytes(Config, hardLimitBytes) * | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. я бы ожидал что коэфицент думаю это можно легко сделать реализовав метод GetColumnTablesCompactionLimitBytes в memory_controller/memory_controller_config.h, внутри перевызвав GetColumnTablesCompactionLimitBytes который будет например в internal namespace и домножит его результат There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а ух, у нас вышло что часть лимитов названа так же как настройки, а часть нет, сложно( тогда лучше сделать рядом с друг дружкой методы в memory_controller_config.h типа GetColumnTablesCompaction???LimitBytes, GetColumnTablesCompactionGeneralQueueLimitBytes и т.д и коэфиценты перенести к ним же так как по сути коэфиценты это то как конфиг преобразовывается в наши консьюмеры |
||
NKikimr::NOlap::TGlobalLimits::GroupedMemoryLimiterCompactionLimitCoefficient; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using NKikimr::NOlap::TGlobalLimits в файле можно сделать |
||
break; | ||
} | ||
case EMemoryConsumerKind::BlobCache: { | ||
result.ExactLimit = GetColumnTablesCacheLimitBytes(Config, hardLimitBytes) * NKikimr::NOlap::TGlobalLimits::BlobCacheCoefficient; | ||
break; | ||
} | ||
case EMemoryConsumerKind::DataAccessorCache: { | ||
result.ExactLimit = GetColumnTablesCacheLimitBytes(Config, hardLimitBytes) * NKikimr::NOlap::TGlobalLimits::DataAccessorCoefficient; | ||
break; | ||
} | ||
default: | ||
Y_ABORT("Unhandled consumer"); | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.