[Election] support set inner priority

This commit is contained in:
obdev
2023-02-06 19:52:39 +08:00
committed by ob-robot
parent 0d77772dac
commit e02b126ceb
7 changed files with 110 additions and 13 deletions

View File

@ -10,6 +10,7 @@
* See the Mulan PubL v2 for more details. * See the Mulan PubL v2 for more details.
*/ */
#include "share/ob_errno.h"
#include "share/ob_occam_time_guard.h" #include "share/ob_occam_time_guard.h"
#include "election_impl.h" #include "election_impl.h"
#include "lib/ob_errno.h" #include "lib/ob_errno.h"
@ -415,6 +416,52 @@ int ElectionImpl::revoke(const RoleChangeReason &reason)
return ret; return ret;
} }
int ElectionImpl::add_inner_priority_seed_bit(const PRIORITY_SEED_BIT new_bit)
{
#define PRINT_WRAPPER KR(ret), K(*this), K(new_bit)
int ret = OB_SUCCESS;
ELECT_TIME_GUARD(500_ms);
LockGuard lock_guard(lock_);
CLICK();
CHECK_ELECTION_INIT();
if (inner_priority_seed_ & static_cast<uint64_t>(new_bit)) {
ret = OB_ENTRY_EXIST;
LOG_NONE(WARN, "set inner priority seed with new bit failed, caus it already exist");
} else {
inner_priority_seed_ |= static_cast<uint64_t>(new_bit);
}
return ret;
#undef PRINT_WRAPPER
}
int ElectionImpl::clear_inner_priority_seed_bit(const PRIORITY_SEED_BIT old_bit)
{
#define PRINT_WRAPPER KR(ret), K(*this), K(old_bit)
int ret = OB_SUCCESS;
ELECT_TIME_GUARD(500_ms);
LockGuard lock_guard(lock_);
CLICK();
CHECK_ELECTION_INIT();
if (!(inner_priority_seed_ | static_cast<uint64_t>(old_bit))) {
ret = OB_ENTRY_NOT_EXIST;
LOG_NONE(WARN, "clear inner priority seed with old bit failed, caus it not exist");
} else {
inner_priority_seed_ &= (~static_cast<uint64_t>(old_bit));
}
return ret;
#undef PRINT_WRAPPER
}
int ElectionImpl::set_inner_priority_seed(const uint64_t seed)
{
int ret = OB_SUCCESS;
ELECT_TIME_GUARD(500_ms);
LockGuard lock_guard(lock_);
CLICK();
inner_priority_seed_ = seed;
return ret;
}
} }
} }
} }

View File

@ -126,6 +126,9 @@ public:
virtual int handle_message(const ElectionAcceptResponseMsg &msg) override final; virtual int handle_message(const ElectionAcceptResponseMsg &msg) override final;
virtual int handle_message(const ElectionChangeLeaderMsg &msg) override final; virtual int handle_message(const ElectionChangeLeaderMsg &msg) override final;
virtual const common::ObAddr &get_self_addr() const override; virtual const common::ObAddr &get_self_addr() const override;
int add_inner_priority_seed_bit(const PRIORITY_SEED_BIT new_bit);
int clear_inner_priority_seed_bit(const PRIORITY_SEED_BIT old_bit);
int set_inner_priority_seed(const uint64_t seed);
TO_STRING_KV(K_(is_inited), K_(is_running), K_(proposer), K_(acceptor), KPC_(priority)); TO_STRING_KV(K_(is_inited), K_(is_running), K_(proposer), K_(acceptor), KPC_(priority));
private:// 定向暴露给友元类 private:// 定向暴露给友元类
void refresh_priority_(); void refresh_priority_();

View File

@ -159,7 +159,10 @@ ElectionPrepareRequestMsgMiddle::ElectionPrepareRequestMsgMiddle() :
ElectionMsgBase(), ElectionMsgBase(),
role_(ObRole::INVALID_ROLE), role_(ObRole::INVALID_ROLE),
is_buffer_valid_(false), is_buffer_valid_(false),
inner_priority_seed_(DEFAULT_SEED) { memset(priority_buffer_, 0, PRIORITY_BUFFER_SIZE); } inner_priority_seed_(static_cast<uint64_t>(PRIORITY_SEED_BIT::DEFAULT_SEED))
{
memset(priority_buffer_, 0, PRIORITY_BUFFER_SIZE);
}
int ElectionPrepareRequestMsgMiddle::set(const ElectionPriority *priority, int ElectionPrepareRequestMsgMiddle::set(const ElectionPriority *priority,
const common::ObRole role) { const common::ObRole role) {
@ -257,7 +260,7 @@ lease_started_ts_on_proposer_(0),
lease_interval_(0), lease_interval_(0),
accepted_(false), accepted_(false),
is_buffer_valid_(false), is_buffer_valid_(false),
inner_priority_seed_(DEFAULT_SEED) inner_priority_seed_(static_cast<uint64_t>(PRIORITY_SEED_BIT::DEFAULT_SEED))
{ {
memset(priority_buffer_, 0, PRIORITY_BUFFER_SIZE); memset(priority_buffer_, 0, PRIORITY_BUFFER_SIZE);
} }

View File

@ -99,9 +99,13 @@ enum class LogPhase
SET_MEMBER = 7, SET_MEMBER = 7,
}; };
// inner priority seed define // inner priority seed define, bigger means lower priority
constexpr int64_t DEFAULT_SEED = (1ULL << 12); enum class PRIORITY_SEED_BIT : uint64_t
constexpr int64_t SEED_NOT_NORMOL_REPLICA_BIT = (1ULL << 48); {
DEFAULT_SEED = (1ULL << 12),
SEED_IN_REBUILD_PHASE_BIT = (1ULL << 32),
SEED_NOT_NORMOL_REPLICA_BIT = (1ULL << 48),
};
constexpr int64_t MSG_DELAY_WARN_THRESHOLD = 200_ms; constexpr int64_t MSG_DELAY_WARN_THRESHOLD = 200_ms;
constexpr int64_t MAX_LEASE_TIME = 10_s; constexpr int64_t MAX_LEASE_TIME = 10_s;

View File

@ -2238,6 +2238,11 @@ int PalfHandleImpl::do_init_mem_(
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
int pret = -1; int pret = -1;
const bool is_normal_replica = (log_meta.get_log_replica_property_meta().replica_type_ == NORMAL_REPLICA); const bool is_normal_replica = (log_meta.get_log_replica_property_meta().replica_type_ == NORMAL_REPLICA);
// inner priority seed: smaller means higher priority
// reserve some bits for future requirements
const uint64_t election_inner_priority_seed = is_normal_replica ?
static_cast<uint64_t>(PRIORITY_SEED_BIT::DEFAULT_SEED) :
0ULL | static_cast<uint64_t>(PRIORITY_SEED_BIT::SEED_NOT_NORMOL_REPLICA_BIT);
palf::PalfRoleChangeCbWrapper &role_change_cb_wrpper = role_change_cb_wrpper_; palf::PalfRoleChangeCbWrapper &role_change_cb_wrpper = role_change_cb_wrpper_;
if ((pret = snprintf(log_dir_, MAX_PATH_SIZE, "%s", log_dir)) && false) { if ((pret = snprintf(log_dir_, MAX_PATH_SIZE, "%s", log_dir)) && false) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
@ -2249,9 +2254,7 @@ int PalfHandleImpl::do_init_mem_(
election_timer, election_timer,
&election_msg_sender_, &election_msg_sender_,
self, self,
/*inner priority seed: smaller means higher priority*/ election_inner_priority_seed,
/*reserve some bits for future requirements*/
is_normal_replica ? DEFAULT_SEED : (0ULL | SEED_NOT_NORMOL_REPLICA_BIT),
1, 1,
[&role_change_cb_wrpper](int64_t id, [&role_change_cb_wrpper](int64_t id,
const ObAddr &dest_addr){ const ObAddr &dest_addr){

View File

@ -99,9 +99,9 @@ public:
}; };
template <typename TAKEOVER_OP> template <typename TAKEOVER_OP>
vector<ElectionImpl *> create_election_group(const int election_num, const vector<uint64_t> &allowed_be_leader, TAKEOVER_OP &&op) vector<ElectionImpl *> create_election_group(const int election_num, const vector<uint64_t> &priority_seed, TAKEOVER_OP &&op)
{ {
if (allowed_be_leader.size() != election_num) { if (priority_seed.size() != election_num) {
abort(); abort();
} }
vector<ElectionImpl *> v; vector<ElectionImpl *> v;
@ -134,9 +134,13 @@ vector<ElectionImpl *> create_election_group(const int election_num, const vecto
&timer, &timer,
&GlobalNetService, &GlobalNetService,
ObAddr(ObAddr::VER::IPV4, "127.0.0.1", port + index), ObAddr(ObAddr::VER::IPV4, "127.0.0.1", port + index),
allowed_be_leader[index], priority_seed[index],
1, 1,
[](const int64_t, const ObAddr &){ return OB_SUCCESS; }, [&election](const int64_t, const ObAddr &dest_addr) {
return THREAD_POOL.commit_task_ignore_ret([&election, dest_addr]() {
election->change_leader_to(dest_addr);
});
},
[op, ret](Election *election, ObRole before, ObRole after, RoleChangeReason reason) { [op, ret](Election *election, ObRole before, ObRole after, RoleChangeReason reason) {
if (before == ObRole::FOLLOWER && after == ObRole::LEADER) { if (before == ObRole::FOLLOWER && after == ObRole::LEADER) {
ELECT_LOG(INFO, "i become LEADER", K(obj_to_string(reason)), KPC(election)); ELECT_LOG(INFO, "i become LEADER", K(obj_to_string(reason)), KPC(election));
@ -559,6 +563,39 @@ TEST_F(TestElection, inner_priority_seed_valid_when_membership_version_equal) {
ASSERT_EQ(stop_to_be_follower_count, 1); ASSERT_EQ(stop_to_be_follower_count, 1);
} }
TEST_F(TestElection, set_inner_priority_seed) {
auto election_list = create_election_group(3, {(uint64_t)PRIORITY_SEED_BIT::DEFAULT_SEED, (uint64_t)PRIORITY_SEED_BIT::DEFAULT_SEED, (uint64_t)PRIORITY_SEED_BIT::DEFAULT_SEED}, [](){});
for (auto &election_1 : election_list) {
for (auto &election_2 : election_list) {
GlobalNetService.connect(election_1, election_2);
}
}
this_thread::sleep_for(chrono::seconds(7));
ObRole role;
int64_t _;
election_list[0]->get_role(role, _);
ASSERT_EQ(role, ObRole::LEADER);
ASSERT_EQ(OB_SUCCESS, election_list[0]->add_inner_priority_seed_bit(PRIORITY_SEED_BIT::SEED_IN_REBUILD_PHASE_BIT));
this_thread::sleep_for(chrono::seconds(3));
election_list[1]->get_role(role, _);
ASSERT_EQ(role, ObRole::LEADER);
for (auto iter = election_list.rbegin(); iter != election_list.rend(); ++iter)
(*iter)->stop();
this_thread::sleep_for(chrono::seconds(2));
for (auto &election_ : election_list)
delete election_;
ASSERT_EQ(leader_takeover_times, 2);
ASSERT_EQ(leader_revoke_times, 2);
ASSERT_EQ(devote_to_be_leader_count, 1);
ASSERT_EQ(lease_expired_to_be_follower_count, 0);
ASSERT_EQ(change_leader_to_be_leader_count, 1);
ASSERT_EQ(change_leader_to_be_follower_count, 1);
ASSERT_EQ(stop_to_be_follower_count, 1);
}
} }
} }

View File

@ -215,7 +215,7 @@ TEST_F(TestElectionMsgCompat, old_new_msg_serialize) {
pos = 0; pos = 0;
ASSERT_EQ(OB_SUCCESS, prepare_msg_new1.deserialize(buffer, buffer_size, pos)); ASSERT_EQ(OB_SUCCESS, prepare_msg_new1.deserialize(buffer, buffer_size, pos));
ELECT_LOG(INFO, "test msg from old to new", K(prepare_msg_old1), K(prepare_msg_new1)); ELECT_LOG(INFO, "test msg from old to new", K(prepare_msg_old1), K(prepare_msg_new1));
ASSERT_EQ(DEFAULT_SEED, prepare_msg_new1.get_inner_priority_seed()); ASSERT_EQ((uint64_t)PRIORITY_SEED_BIT::DEFAULT_SEED, prepare_msg_new1.get_inner_priority_seed());
pos = 0; pos = 0;
ASSERT_EQ(OB_SUCCESS, prepare_msg_new2.serialize(buffer, buffer_size, pos)); ASSERT_EQ(OB_SUCCESS, prepare_msg_new2.serialize(buffer, buffer_size, pos));
pos = 0; pos = 0;