Skip to content

Commit 8ef86ab

Browse files
vporyadkemarsaly79
authored andcommitted
do not trigger emergency balancer when all nodes have high usage (ydb-platform#6532)
1 parent 10f92a1 commit 8ef86ab

File tree

5 files changed

+79
-1
lines changed

5 files changed

+79
-1
lines changed

ydb/core/mind/hive/hive_impl.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -2329,7 +2329,8 @@ void THive::Handle(TEvPrivate::TEvProcessTabletBalancer::TPtr&) {
23292329
nodeUsageHistogram.IncrementFor(record.Usage * 100);
23302330
}
23312331

2332-
if (stats.MaxUsage >= GetMaxNodeUsageToKick()) {
2332+
double minUsageToKick = GetMaxNodeUsageToKick() - GetNodeUsageRangeToKick();
2333+
if (stats.MaxUsage >= GetMaxNodeUsageToKick() && stats.MinUsage < minUsageToKick) {
23332334
std::vector<TNodeId> overloadedNodes;
23342335
for (const auto& [nodeId, nodeInfo] : Nodes) {
23352336
if (nodeInfo.IsAlive() && !nodeInfo.Down && nodeInfo.IsOverloaded()) {

ydb/core/mind/hive/hive_impl.h

+4
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,10 @@ TTabletInfo* FindTabletEvenInDeleting(TTabletId tabletId, TFollowerId followerId
934934
return CurrentConfig.GetStorageBalancerInflight();
935935
}
936936

937+
double GetNodeUsageRangeToKick() const {
938+
return CurrentConfig.GetNodeUsageRangeToKick();
939+
}
940+
937941
static void ActualizeRestartStatistics(google::protobuf::RepeatedField<google::protobuf::uint64>& restartTimestamps, ui64 barrier);
938942
static ui64 GetRestartsPerPeriod(const google::protobuf::RepeatedField<google::protobuf::uint64>& restartTimestamps, ui64 barrier);
939943
static bool IsSystemTablet(TTabletTypes::EType type);

ydb/core/mind/hive/hive_ut.cpp

+70
Original file line numberDiff line numberDiff line change
@@ -3996,6 +3996,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
39963996
// this value of MaxNodeUsageToKick is selected specifically to make test scenario work
39973997
// in link with number of tablets and values of network usage metrics used below
39983998
app.HiveConfig.SetMaxNodeUsageToKick(0.01);
3999+
app.HiveConfig.SetNodeUsageRangeToKick(0);
39994000
app.HiveConfig.SetEmergencyBalancerInflight(1); // to ensure fair distribution
40004001
});
40014002

@@ -4968,6 +4969,75 @@ Y_UNIT_TEST_SUITE(THiveTest) {
49684969
UNIT_ASSERT_VALUES_EQUAL(newDistribution[1].size(), TABLETS_PER_NODE - 1);
49694970
}
49704971

4972+
Y_UNIT_TEST(TestHiveBalancerHighUsage) {
4973+
static constexpr ui64 NUM_NODES = 2;
4974+
TTestBasicRuntime runtime(2, false);
4975+
Setup(runtime, true, 1, [](TAppPrepare& app) {
4976+
app.HiveConfig.SetTabletKickCooldownPeriod(0);
4977+
app.HiveConfig.SetResourceChangeReactionPeriod(0);
4978+
});
4979+
const int nodeBase = runtime.GetNodeId(0);
4980+
TActorId senderA = runtime.AllocateEdgeActor();
4981+
const ui64 hiveTablet = MakeDefaultHiveID();
4982+
const ui64 testerTablet = MakeTabletID(false, 1);
4983+
4984+
auto getDistribution = [hiveTablet, nodeBase, senderA, &runtime]() -> std::array<std::vector<ui64>, NUM_NODES> {
4985+
std::array<std::vector<ui64>, NUM_NODES> nodeTablets = {};
4986+
{
4987+
runtime.SendToPipe(hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo());
4988+
TAutoPtr<IEventHandle> handle;
4989+
TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
4990+
for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
4991+
UNIT_ASSERT_C(((int)tablet.GetNodeID() - nodeBase >= 0) && (tablet.GetNodeID() - nodeBase < NUM_NODES),
4992+
"nodeId# " << tablet.GetNodeID() << " nodeBase# " << nodeBase);
4993+
nodeTablets[tablet.GetNodeID() - nodeBase].push_back(tablet.GetTabletID());
4994+
}
4995+
}
4996+
return nodeTablets;
4997+
};
4998+
4999+
CreateTestBootstrapper(runtime, CreateTestTabletInfo(hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
5000+
5001+
// wait for creation of nodes
5002+
{
5003+
TDispatchOptions options;
5004+
options.FinalEvents.emplace_back(TEvLocal::EvStatus, NUM_NODES);
5005+
runtime.DispatchEvents(options);
5006+
}
5007+
5008+
TTabletTypes::EType tabletType = TTabletTypes::Dummy;
5009+
for (size_t i = 0; i < 2; ++i) {
5010+
THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
5011+
ev->Record.SetObjectId(i);
5012+
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
5013+
MakeSureTabletIsUp(runtime, tabletId, 0);
5014+
}
5015+
5016+
auto initialDistribution = getDistribution();
5017+
5018+
std::array<double, NUM_NODES> usages = {.89, .91};
5019+
for (ui32 i = 0; i < 2; ++i) {
5020+
for (ui32 node = 0; node < NUM_NODES; ++node) {
5021+
TActorId sender = runtime.AllocateEdgeActor(node);
5022+
THolder<TEvHive::TEvTabletMetrics> metrics = MakeHolder<TEvHive::TEvTabletMetrics>();
5023+
metrics->Record.SetTotalNodeUsage(usages[node]);
5024+
5025+
runtime.SendToPipe(hiveTablet, sender, metrics.Release(), node);
5026+
}
5027+
}
5028+
5029+
{
5030+
TDispatchOptions options;
5031+
options.FinalEvents.emplace_back(NHive::TEvPrivate::EvBalancerOut);
5032+
runtime.DispatchEvents(options, TDuration::Seconds(10));
5033+
}
5034+
5035+
// Check that balancer moved no tablets
5036+
auto newDistribution = getDistribution();
5037+
5038+
UNIT_ASSERT_EQUAL(initialDistribution, newDistribution);
5039+
}
5040+
49715041
Y_UNIT_TEST(TestUpdateTabletsObjectUpdatesMetrics) {
49725042
TTestBasicRuntime runtime(1, false);
49735043
Setup(runtime, true);

ydb/core/mind/hive/monitoring.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ class TTxMonEvent_Settings : public TTransactionBase<THive>, public TLoggedMonTr
794794
UpdateConfig(db, "MinNetworkScatterToBalance", configUpdates);
795795
UpdateConfig(db, "MinCounterScatterToBalance", configUpdates);
796796
UpdateConfig(db, "MaxNodeUsageToKick", configUpdates, TSchemeIds::State::MaxNodeUsageToKick);
797+
UpdateConfig(db, "NodeUsageRangeToKick", configUpdates);
797798
UpdateConfig(db, "ResourceChangeReactionPeriod", configUpdates, TSchemeIds::State::ResourceChangeReactionPeriod);
798799
UpdateConfig(db, "TabletKickCooldownPeriod", configUpdates, TSchemeIds::State::TabletKickCooldownPeriod);
799800
UpdateConfig(db, "SpreadNeighbours", configUpdates, TSchemeIds::State::SpreadNeighbours);
@@ -1140,6 +1141,7 @@ class TTxMonEvent_Settings : public TTransactionBase<THive>, public TLoggedMonTr
11401141
ShowConfig(out, "MinCounterScatterToBalance");
11411142
ShowConfig(out, "MinNodeUsageToBalance");
11421143
ShowConfig(out, "MaxNodeUsageToKick");
1144+
ShowConfig(out, "NodeUsageRangeToKick");
11431145
ShowConfig(out, "ResourceChangeReactionPeriod");
11441146
ShowConfig(out, "TabletKickCooldownPeriod");
11451147
ShowConfig(out, "NodeSelectStrategy");

ydb/core/protos/config.proto

+1
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,7 @@ message THiveConfig {
14701470
optional double MinGroupUsageToBalance = 72 [default = 0.1];
14711471
optional uint64 StorageBalancerInflight = 73 [default = 1];
14721472
optional bool EnableDestroyOperations = 74 [default = false];
1473+
optional double NodeUsageRangeToKick = 75 [default = 0.2];
14731474
}
14741475

14751476
message TBlobCacheConfig {

0 commit comments

Comments
 (0)