Index: src/kudu/master/auto_leader_rebalancer.cc IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/kudu/master/auto_leader_rebalancer.cc b/src/kudu/master/auto_leader_rebalancer.cc --- a/src/kudu/master/auto_leader_rebalancer.cc (revision 909b5676bff20400628a2338f0087940fa3bc524) +++ b/src/kudu/master/auto_leader_rebalancer.cc (revision d2a611fa8102e62d407f7eff3b3a2280e2d3518d) @@ -201,6 +201,16 @@ map> replica_and_leader_count_by_ts_uuid; // uuid->leader should transfer count map leader_transfer_source; + uint32_t remain_tablets_num = tablet_infos.size(); + uint32_t remain_tservers = tserver_uuids.size(); + // Get the exact num of tablet servers who will take a part in the leader rebalance. + for (const auto& uuid : tserver_uuids) { + auto* tablet_ids_ptr = FindOrNull(tablet_ids_by_ts_uuid, uuid); + uint32_t replica_count = tablet_ids_ptr ? tablet_ids_ptr->size() : 0; + if (replica_count == 0) { + remain_tservers --; + } + } for (const auto& uuid : tserver_uuids) { auto* tablet_ids_ptr = FindOrNull(tablet_ids_by_ts_uuid, uuid); uint32_t replica_count = tablet_ids_ptr ? tablet_ids_ptr->size() : 0; @@ -215,15 +225,26 @@ VLOG(1) << Substitute( "uuid: $0, replica_count: $1, leader_count: $2", uuid, replica_count, leader_count); - // Our target is every tserver' replicas, number of leader : number of follower is - // 1 : (replica_refactor -1). The constant 1 is a coarse-grained correction factor to help - // leader rebalancer to converge stable. - int32_t should_transfer_count = static_cast(leader_count) - - (static_cast(replica_count) / replication_factor + 1); + // If the remaining tablets could be divided by the remaining tablet servers, + // the leader num of all the remaining tablet servers should be the division + // result. + // Else, The maximum leader num of a tablet server should be the ceil value + // of average leaders num. Transfer the excess leaders if a tablet server have + // leaders more than that. + int32_t expect_leader_count; + if (remain_tablets_num % remain_tservers == 0) { + expect_leader_count = remain_tablets_num / tserver_uuids.size(); + } else { + expect_leader_count = std::ceil(remain_tablets_num / + static_cast(remain_tservers)); + } + int32_t should_transfer_count = leader_count - expect_leader_count; if (should_transfer_count > 0) { leader_transfer_source.insert({uuid, should_transfer_count}); VLOG(1) << Substitute("$0 should transfer leader count: $1", uuid, should_transfer_count); } + remain_tablets_num -= expect_leader_count; + remain_tservers--; } // Step 3. @@ -383,7 +404,10 @@ // we get all tserver uuids TSDescriptorVector descriptors; ts_manager_->GetAllDescriptors(&descriptors); - + if (PREDICT_FALSE(descriptors.empty())) { + LOG(INFO) << "No tserver registered for now, skipping this loop."; + return Status::OK(); + } vector tserver_uuids; for (const auto& e : descriptors) { if (e->PresumedDead()) {