@@ -3996,6 +3996,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
3996
3996
// this value of MaxNodeUsageToKick is selected specifically to make test scenario work
3997
3997
// in link with number of tablets and values of network usage metrics used below
3998
3998
app.HiveConfig.SetMaxNodeUsageToKick(0.01);
3999
+ app.HiveConfig.SetNodeUsageRangeToKick(0);
3999
4000
app.HiveConfig.SetEmergencyBalancerInflight(1); // to ensure fair distribution
4000
4001
});
4001
4002
@@ -4968,6 +4969,75 @@ Y_UNIT_TEST_SUITE(THiveTest) {
4968
4969
UNIT_ASSERT_VALUES_EQUAL(newDistribution[1].size(), TABLETS_PER_NODE - 1);
4969
4970
}
4970
4971
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
+
4971
5041
Y_UNIT_TEST(TestUpdateTabletsObjectUpdatesMetrics) {
4972
5042
TTestBasicRuntime runtime(1, false);
4973
5043
Setup(runtime, true);
0 commit comments