1
0
Fork 0

raft testing revealed performance optimisation in receiver and of appendentries

This commit is contained in:
Kaveh Vahedipour 2016-08-04 15:46:23 +02:00
parent c9bd40f50a
commit 307332e817
5 changed files with 104 additions and 63 deletions

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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:

View File

@ -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

View File

@ -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