mirror of https://gitee.com/bigwinds/arangodb
raft testing revealed performance optimisation in receiver and of appendentries
This commit is contained in:
parent
c9bd40f50a
commit
307332e817
|
@ -248,14 +248,23 @@ bool Agent::recvAppendEntriesRPC(term_t term,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_state.removeConflicts(queries);
|
size_t nqs = queries->slice().length();
|
||||||
|
|
||||||
|
if (nqs > 0) {
|
||||||
|
|
||||||
|
size_t ndups = _state.removeConflicts(queries);
|
||||||
|
|
||||||
|
if (nqs > ndups) {
|
||||||
|
|
||||||
|
LOG_TOPIC(DEBUG, Logger::AGENCY)
|
||||||
|
<< "Appending " << nqs - ndups << " entries to state machine." <<
|
||||||
|
nqs << " " << ndups;
|
||||||
|
|
||||||
|
size_t highest = _state.log(queries, ndups);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (queries->slice().length()) {
|
|
||||||
LOG_TOPIC(DEBUG, Logger::AGENCY) << "Appending "
|
|
||||||
<< queries->slice().length()
|
|
||||||
<< " entries to state machine.";
|
|
||||||
/* bool success = */
|
|
||||||
_state.log(queries, term, prevIndex, prevTerm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_spearhead.apply(_state.slices(_lastCommitIndex + 1, leaderCommitIndex));
|
_spearhead.apply(_state.slices(_lastCommitIndex + 1, leaderCommitIndex));
|
||||||
|
@ -263,7 +272,6 @@ bool Agent::recvAppendEntriesRPC(term_t term,
|
||||||
_lastCommitIndex = leaderCommitIndex;
|
_lastCommitIndex = leaderCommitIndex;
|
||||||
|
|
||||||
if (_lastCommitIndex >= _nextCompationAfter) {
|
if (_lastCommitIndex >= _nextCompationAfter) {
|
||||||
|
|
||||||
_state.compact(_lastCommitIndex);
|
_state.compact(_lastCommitIndex);
|
||||||
_nextCompationAfter += _config.compactionStepSize;
|
_nextCompationAfter += _config.compactionStepSize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,66 +138,91 @@ std::vector<arangodb::consensus::index_t> State::log(
|
||||||
|
|
||||||
/// Log transactions (follower)
|
/// Log transactions (follower)
|
||||||
arangodb::consensus::index_t State::log(
|
arangodb::consensus::index_t State::log(
|
||||||
query_t const& transactions, term_t term,
|
query_t const& transactions, size_t ndups) {
|
||||||
arangodb::consensus::index_t prevLogIndex, term_t prevLogTerm) {
|
|
||||||
|
|
||||||
if (transactions->slice().type() != VPackValueType::Array) {
|
VPackSlice slices = transactions->slice();
|
||||||
return false;
|
|
||||||
}
|
TRI_ASSERT(slices.isArray());
|
||||||
|
|
||||||
|
size_t nqs = slices.length();
|
||||||
|
|
||||||
|
TRI_ASSERT(nqs > ndups);
|
||||||
|
|
||||||
MUTEX_LOCKER(mutexLocker, _logLock); // log entries must stay in order
|
MUTEX_LOCKER(mutexLocker, _logLock); // log entries must stay in order
|
||||||
|
|
||||||
arangodb::consensus::index_t highest = (_log.empty()) ? 0 : _log.back().index;
|
for (size_t i = ndups; i < nqs; ++i) {
|
||||||
for (auto const& i : VPackArrayIterator(transactions->slice())) {
|
|
||||||
|
VPackSlice slice = slices[i];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto idx = i.get("index").getUInt();
|
auto idx = slice.get("index").getUInt();
|
||||||
auto trm = i.get("term").getUInt();
|
auto trm = slice.get("term").getUInt();
|
||||||
if (highest < idx) {
|
auto buf = std::make_shared<Buffer<uint8_t>>();
|
||||||
highest = idx;
|
|
||||||
}
|
buf->append(
|
||||||
std::shared_ptr<Buffer<uint8_t>> buf = std::make_shared<Buffer<uint8_t>>();
|
(char const*)slice.get("query").begin(), slice.get("query").byteSize());
|
||||||
buf->append((char const*)i.get("query").begin(),i.get("query").byteSize());
|
// to RAM
|
||||||
_log.push_back(log_t(idx, trm, buf));
|
_log.push_back(log_t(idx, trm, buf));
|
||||||
persist(idx, trm, i.get("query")); // to disk
|
// to disk
|
||||||
|
persist(idx, trm, slice.get("query"));
|
||||||
} catch (std::exception const& e) {
|
} catch (std::exception const& e) {
|
||||||
LOG_TOPIC(ERR, Logger::AGENCY) << e.what() << " " << __FILE__ << __LINE__;
|
LOG_TOPIC(ERR, Logger::AGENCY) << e.what() << " " << __FILE__ << __LINE__;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return highest;
|
TRI_ASSERT(!_log.empty());
|
||||||
|
return _log.back().index;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void State::removeConflicts (query_t const& transactions) {
|
size_t State::removeConflicts (query_t const& transactions) {
|
||||||
|
|
||||||
VPackSlice slice = transactions->slice();
|
VPackSlice slices = transactions->slice();
|
||||||
TRI_ASSERT(slice.isArray());
|
TRI_ASSERT(slices.isArray());
|
||||||
|
size_t ndups = 0;
|
||||||
|
|
||||||
if (slice.length() > 0) {
|
if (slices.length() > 0) {
|
||||||
|
|
||||||
auto bindVars = std::make_shared<VPackBuilder>();
|
auto bindVars = std::make_shared<VPackBuilder>();
|
||||||
bindVars->openObject();
|
bindVars->openObject();
|
||||||
bindVars->close();
|
bindVars->close();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto idx = slice[0].get("index").getUInt();
|
|
||||||
|
auto idx = slices[0].get("index").getUInt();
|
||||||
|
|
||||||
if (idx-_cur < _log.size()) {
|
if (idx-_cur < _log.size()) {
|
||||||
|
|
||||||
|
for (auto const& slice : VPackArrayIterator(slices)) {
|
||||||
|
|
||||||
|
auto trm = slice.get("term").getUInt();
|
||||||
|
idx = slice.get("index").getUInt();
|
||||||
|
|
||||||
|
if (trm > VPackSlice(
|
||||||
|
_log.at(idx-_cur).entry->data()).get("term").getUInt()) {
|
||||||
|
|
||||||
LOG_TOPIC(DEBUG, Logger::AGENCY)
|
LOG_TOPIC(DEBUG, Logger::AGENCY)
|
||||||
<< "Removing " << _log.size()-idx+_cur
|
<< "Removing " << _log.size()-idx+_cur
|
||||||
<< " entries from log starting with " << idx << "=" << _log.at(idx-_cur).index;
|
<< " entries from log starting with " << idx << "="
|
||||||
|
<< _log.at(idx-_cur).index;
|
||||||
|
|
||||||
// persisted logs
|
// persisted logs
|
||||||
std::stringstream aql;
|
std::stringstream aql;
|
||||||
aql << "FOR l IN log FILTER l._key >= '" << stringify(idx)
|
aql << "FOR l IN log FILTER l._key >= '" << stringify(idx)
|
||||||
<< "' REMOVE l IN log";
|
<< "' REMOVE l IN log";
|
||||||
|
|
||||||
arangodb::aql::Query
|
arangodb::aql::Query
|
||||||
query(false, _vocbase, aql.str().c_str(), aql.str().size(), bindVars,
|
query(false, _vocbase, aql.str().c_str(), aql.str().size(),
|
||||||
nullptr, arangodb::aql::PART_MAIN);
|
bindVars, nullptr, arangodb::aql::PART_MAIN);
|
||||||
|
|
||||||
auto queryResult = query.execute(_queryRegistry);
|
auto queryResult = query.execute(_queryRegistry);
|
||||||
|
|
||||||
if (queryResult.code != TRI_ERROR_NO_ERROR) {
|
if (queryResult.code != TRI_ERROR_NO_ERROR) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(queryResult.code, queryResult.details);
|
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||||
|
queryResult.code, queryResult.details);
|
||||||
}
|
}
|
||||||
|
|
||||||
queryResult.result->slice();
|
queryResult.result->slice();
|
||||||
|
|
||||||
// volatile logs
|
// volatile logs
|
||||||
|
@ -206,6 +231,13 @@ void State::removeConflicts (query_t const& transactions) {
|
||||||
_log.erase(_log.begin()+idx-_cur-1, _log.end());
|
_log.erase(_log.begin()+idx-_cur-1, _log.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
++ndups;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (std::exception const& e) {
|
} catch (std::exception const& e) {
|
||||||
LOG_TOPIC(ERR, Logger::AGENCY) << e.what() << " " << __FILE__ << __LINE__;
|
LOG_TOPIC(ERR, Logger::AGENCY) << e.what() << " " << __FILE__ << __LINE__;
|
||||||
|
@ -213,6 +245,8 @@ void State::removeConflicts (query_t const& transactions) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ndups;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,7 @@ class State {
|
||||||
std::vector<bool> const& indices, term_t term);
|
std::vector<bool> const& indices, term_t term);
|
||||||
|
|
||||||
/// @brief Log entries (followers)
|
/// @brief Log entries (followers)
|
||||||
index_t log(query_t const& queries, term_t term, index_t prevLogIndex,
|
arangodb::consensus::index_t log(query_t const& queries, size_t ndups = 0);
|
||||||
term_t prevLogTerm);
|
|
||||||
|
|
||||||
/// @brief Find entry at index with term
|
/// @brief Find entry at index with term
|
||||||
bool find(index_t index, term_t term);
|
bool find(index_t index, term_t term);
|
||||||
|
@ -103,7 +102,7 @@ class State {
|
||||||
|
|
||||||
bool compact(arangodb::consensus::index_t cind);
|
bool compact(arangodb::consensus::index_t cind);
|
||||||
|
|
||||||
void removeConflicts(query_t const&);
|
size_t removeConflicts(query_t const&);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -52,7 +52,7 @@ COMP=100
|
||||||
BASE=4001
|
BASE=4001
|
||||||
NATH=$(( $NRDBSERVERS + $NRCOORDINATORS + $NRAGENTS ))
|
NATH=$(( $NRDBSERVERS + $NRCOORDINATORS + $NRAGENTS ))
|
||||||
|
|
||||||
rm -rf cluster
|
#rm -rf cluster
|
||||||
mkdir -p cluster
|
mkdir -p cluster
|
||||||
echo Starting agency ...
|
echo Starting agency ...
|
||||||
if [ $NRAGENTS -gt 1 ]; then
|
if [ $NRAGENTS -gt 1 ]; then
|
||||||
|
|
|
@ -22,8 +22,8 @@ fi
|
||||||
MINP=0.5
|
MINP=0.5
|
||||||
MAXP=2.0
|
MAXP=2.0
|
||||||
SFRE=2.5
|
SFRE=2.5
|
||||||
COMP=10
|
COMP=100
|
||||||
BASE=4001
|
BASE=5001
|
||||||
|
|
||||||
rm -rf agency
|
rm -rf agency
|
||||||
mkdir -p agency
|
mkdir -p agency
|
||||||
|
|
Loading…
Reference in New Issue