mirror of https://gitee.com/bigwinds/arangodb
AddFollower to handle multiple followers at the same time
This commit is contained in:
parent
9245a09808
commit
c6ef45b64d
|
@ -32,7 +32,34 @@ AddFollower::AddFollower(Node const& snapshot, Agent* agent,
|
||||||
std::string const& prefix, std::string const& database,
|
std::string const& prefix, std::string const& database,
|
||||||
std::string const& collection,
|
std::string const& collection,
|
||||||
std::string const& shard,
|
std::string const& shard,
|
||||||
std::string const& newFollower)
|
std::initializer_list<std::string> const& newFollower)
|
||||||
|
: Job(snapshot, agent, jobId, creator, prefix),
|
||||||
|
_database(database),
|
||||||
|
_collection(collection),
|
||||||
|
_shard(shard),
|
||||||
|
_newFollower(newFollower) {
|
||||||
|
try {
|
||||||
|
JOB_STATUS js = status();
|
||||||
|
|
||||||
|
if (js == TODO) {
|
||||||
|
start();
|
||||||
|
} else if (js == NOTFOUND) {
|
||||||
|
if (create()) {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (std::exception const& e) {
|
||||||
|
LOG_TOPIC(WARN, Logger::AGENCY) << e.what() << __FILE__ << __LINE__;
|
||||||
|
finish("Shards/" + _shard, false, e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AddFollower::AddFollower(Node const& snapshot, Agent* agent,
|
||||||
|
std::string const& jobId, std::string const& creator,
|
||||||
|
std::string const& prefix, std::string const& database,
|
||||||
|
std::string const& collection,
|
||||||
|
std::string const& shard,
|
||||||
|
std::vector<std::string> const& newFollower)
|
||||||
: Job(snapshot, agent, jobId, creator, prefix),
|
: Job(snapshot, agent, jobId, creator, prefix),
|
||||||
_database(database),
|
_database(database),
|
||||||
_collection(collection),
|
_collection(collection),
|
||||||
|
@ -109,7 +136,13 @@ bool AddFollower::create() {
|
||||||
_jb->add("database", VPackValue(_database));
|
_jb->add("database", VPackValue(_database));
|
||||||
_jb->add("collection", VPackValue(_collection));
|
_jb->add("collection", VPackValue(_collection));
|
||||||
_jb->add("shard", VPackValue(_shard));
|
_jb->add("shard", VPackValue(_shard));
|
||||||
_jb->add("newFollower", VPackValue(_newFollower));
|
_jb->add(VPackValue("newFollower"));
|
||||||
|
{
|
||||||
|
VPackArrayBuilder b(_jb.get());
|
||||||
|
for (auto const& i : _newFollower) {
|
||||||
|
_jb->add(VPackValue(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
_jb->add("jobId", VPackValue(_jobId));
|
_jb->add("jobId", VPackValue(_jobId));
|
||||||
_jb->add("timeCreated", VPackValue(now));
|
_jb->add("timeCreated", VPackValue(now));
|
||||||
|
|
||||||
|
@ -142,7 +175,7 @@ bool AddFollower::start() {
|
||||||
|
|
||||||
for (auto const& srv : VPackArrayIterator(current)) {
|
for (auto const& srv : VPackArrayIterator(current)) {
|
||||||
TRI_ASSERT(srv.isString());
|
TRI_ASSERT(srv.isString());
|
||||||
if (srv.copyString() == _newFollower) {
|
if (srv.copyString() == _newFollower.front()) {
|
||||||
finish("Shards/" + _shard, false,
|
finish("Shards/" + _shard, false,
|
||||||
"newFollower must not be already holding the shard.");
|
"newFollower must not be already holding the shard.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -150,7 +183,7 @@ bool AddFollower::start() {
|
||||||
}
|
}
|
||||||
for (auto const& srv : VPackArrayIterator(planned)) {
|
for (auto const& srv : VPackArrayIterator(planned)) {
|
||||||
TRI_ASSERT(srv.isString());
|
TRI_ASSERT(srv.isString());
|
||||||
if (srv.copyString() == _newFollower) {
|
if (srv.copyString() == _newFollower.front()) {
|
||||||
finish("Shards/" + _shard, false,
|
finish("Shards/" + _shard, false,
|
||||||
"newFollower must not be planned for shard already.");
|
"newFollower must not be planned for shard already.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -206,7 +239,9 @@ bool AddFollower::start() {
|
||||||
for (auto const& srv : VPackArrayIterator(planned)) {
|
for (auto const& srv : VPackArrayIterator(planned)) {
|
||||||
pending.add(srv);
|
pending.add(srv);
|
||||||
}
|
}
|
||||||
pending.add(VPackValue(_newFollower));
|
for (auto const& i : _newFollower) {
|
||||||
|
pending.add(VPackValue(i));
|
||||||
|
}
|
||||||
pending.close();
|
pending.close();
|
||||||
|
|
||||||
// --- Increment Plan/Version
|
// --- Increment Plan/Version
|
||||||
|
@ -237,7 +272,7 @@ bool AddFollower::start() {
|
||||||
|
|
||||||
if (res.accepted && res.indices.size() == 1 && res.indices[0]) {
|
if (res.accepted && res.indices.size() == 1 && res.indices[0]) {
|
||||||
LOG_TOPIC(INFO, Logger::AGENCY)
|
LOG_TOPIC(INFO, Logger::AGENCY)
|
||||||
<< "Pending: Addfollower " + _newFollower + " to shard " + _shard;
|
<< "Pending: Addfollower " << _newFollower << " to shard " << _shard;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,8 +288,12 @@ JOB_STATUS AddFollower::status() {
|
||||||
try {
|
try {
|
||||||
_database = _snapshot(pos[status] + _jobId + "/database").getString();
|
_database = _snapshot(pos[status] + _jobId + "/database").getString();
|
||||||
_collection = _snapshot(pos[status] + _jobId + "/collection").getString();
|
_collection = _snapshot(pos[status] + _jobId + "/collection").getString();
|
||||||
_newFollower =
|
for (auto const& i :
|
||||||
_snapshot(pos[status] + _jobId + "/newFollower").getString();
|
VPackArrayIterator(
|
||||||
|
_snapshot(pos[status] + _jobId + "/newFollower").getArray())) {
|
||||||
|
_newFollower.push_back(i.copyString());
|
||||||
|
}
|
||||||
|
_snapshot(pos[status] + _jobId + "/newFollower").getArray();
|
||||||
_shard = _snapshot(pos[status] + _jobId + "/shard").getString();
|
_shard = _snapshot(pos[status] + _jobId + "/shard").getString();
|
||||||
} catch (std::exception const& e) {
|
} catch (std::exception const& e) {
|
||||||
std::stringstream err;
|
std::stringstream err;
|
||||||
|
@ -271,7 +310,7 @@ JOB_STATUS AddFollower::status() {
|
||||||
|
|
||||||
Slice current = _snapshot(curPath).slice();
|
Slice current = _snapshot(curPath).slice();
|
||||||
for (auto const& srv : VPackArrayIterator(current)) {
|
for (auto const& srv : VPackArrayIterator(current)) {
|
||||||
if (srv.copyString() == _newFollower) {
|
if (srv.copyString() == _newFollower.front()) {
|
||||||
if (finish("Shards/" + _shard)) {
|
if (finish("Shards/" + _shard)) {
|
||||||
return FINISHED;
|
return FINISHED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,17 @@ namespace consensus {
|
||||||
|
|
||||||
struct AddFollower : public Job {
|
struct AddFollower : public Job {
|
||||||
|
|
||||||
|
AddFollower (Node const& snapshot,
|
||||||
|
Agent* agent,
|
||||||
|
std::string const& jobId,
|
||||||
|
std::string const& creator,
|
||||||
|
std::string const& prefix,
|
||||||
|
std::string const& database,
|
||||||
|
std::string const& collection,
|
||||||
|
std::string const& shard,
|
||||||
|
std::initializer_list<std::string> const&);
|
||||||
|
|
||||||
|
|
||||||
AddFollower (Node const& snapshot,
|
AddFollower (Node const& snapshot,
|
||||||
Agent* agent,
|
Agent* agent,
|
||||||
std::string const& jobId,
|
std::string const& jobId,
|
||||||
|
@ -40,7 +51,8 @@ struct AddFollower : public Job {
|
||||||
std::string const& database = std::string(),
|
std::string const& database = std::string(),
|
||||||
std::string const& collection = std::string(),
|
std::string const& collection = std::string(),
|
||||||
std::string const& shard = std::string(),
|
std::string const& shard = std::string(),
|
||||||
std::string const& newFollower = std::string());
|
std::vector<std::string> const& newFollowers = {});
|
||||||
|
|
||||||
|
|
||||||
virtual ~AddFollower ();
|
virtual ~AddFollower ();
|
||||||
|
|
||||||
|
@ -51,7 +63,7 @@ struct AddFollower : public Job {
|
||||||
std::string _database;
|
std::string _database;
|
||||||
std::string _collection;
|
std::string _collection;
|
||||||
std::string _shard;
|
std::string _shard;
|
||||||
std::string _newFollower;
|
std::vector<std::string> _newFollower;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -69,15 +69,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// @brief Find active agency from persisted
|
|
||||||
bool activeAgencyFromPersistence();
|
|
||||||
|
|
||||||
/// @brief We are a restarting active RAFT agent
|
/// @brief We are a restarting active RAFT agent
|
||||||
bool restartingActiveAgent();
|
bool restartingActiveAgent();
|
||||||
|
|
||||||
/// @brief Find active agency from command line
|
|
||||||
bool activeAgencyFromCommandLine();
|
|
||||||
|
|
||||||
/// @brief Try to estimate good RAFT min/max timeouts
|
/// @brief Try to estimate good RAFT min/max timeouts
|
||||||
bool estimateRAFTInterval();
|
bool estimateRAFTInterval();
|
||||||
|
|
||||||
|
|
|
@ -355,7 +355,7 @@ bool RemoveServer::scheduleAddFollowers() {
|
||||||
|
|
||||||
AddFollower(_snapshot, _agent, _jobId + "-" + std::to_string(sub++),
|
AddFollower(_snapshot, _agent, _jobId + "-" + std::to_string(sub++),
|
||||||
_jobId, _agencyPrefix, database.first, collptr.first,
|
_jobId, _agencyPrefix, database.first, collptr.first,
|
||||||
shard.first, newServer);
|
shard.first, {newServer});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -634,18 +634,29 @@ void Supervision::enforceReplication() {
|
||||||
|
|
||||||
// Enough DBServer to
|
// Enough DBServer to
|
||||||
if (replicationFactor > shard.slice().length() &&
|
if (replicationFactor > shard.slice().length() &&
|
||||||
available.size() >= replicationFactor) {
|
available.size() > shard.slice().length()) {
|
||||||
for (auto const& i : VPackArrayIterator(shard.slice())) {
|
for (auto const& i : VPackArrayIterator(shard.slice())) {
|
||||||
available.erase(
|
available.erase(
|
||||||
std::remove(
|
std::remove(
|
||||||
available.begin(), available.end(), i.copyString()),
|
available.begin(), available.end(), i.copyString()),
|
||||||
available.end());
|
available.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t optimal = replicationFactor - shard.slice().length();
|
||||||
|
std::vector<std::string> newFollowers;
|
||||||
|
for (size_t i = 0; i < optimal; ++i) {
|
||||||
auto randIt = available.begin();
|
auto randIt = available.begin();
|
||||||
std::advance(randIt, std::rand() % available.size());
|
std::advance(randIt, std::rand() % available.size());
|
||||||
|
newFollowers.push_back(*randIt);
|
||||||
|
available.erase(randIt);
|
||||||
|
if (available.empty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AddFollower(
|
AddFollower(
|
||||||
_snapshot, _agent, std::to_string(_jobId++), "supervision",
|
_snapshot, _agent, std::to_string(_jobId++), "supervision",
|
||||||
_agencyPrefix, db_.first, col_.first, shard_.first, *randIt);
|
_agencyPrefix, db_.first, col_.first, shard_.first, newFollowers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue