mirror of
https://github.com/scylladb/scylladb.git
synced 2026-06-01 12:36:56 +00:00
raft: rename storage to persistence
The new naming scheme more clearly communicates to the client of the raft library that the `persistence` interface implements persistency layer of the fsm that is powering the raft protocol itself rather than the client-side workflow and user-provided `state_machine`. Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com> Message-Id: <20201126135114.7933-1-pa.solodovnikov@scylladb.com>
This commit is contained in:
committed by
Avi Kivity
parent
248449816b
commit
041072b59f
@@ -17,7 +17,7 @@ For more details about Raft see https://raft.github.io/
|
||||
-----
|
||||
|
||||
In order to use the library the application has to provide implementations
|
||||
for RPC, storage and state machine APIs, defined in raft/raft.hh. The
|
||||
for RPC, persistence and state machine APIs, defined in raft/raft.hh. The
|
||||
purpose of these interfaces is:
|
||||
- provide a way to communicate between Raft protocol instances
|
||||
- persist the required protocol state on disk,
|
||||
@@ -32,7 +32,7 @@ of the Raft consistency protocol on its environment:
|
||||
in which messages can be lost, reordered, retransmitted more than
|
||||
once, but not corrupted. Specifically, it's an error to
|
||||
deliver a message to a Raft server which was not sent to it.
|
||||
- storage should provide a durable persistent storage, which
|
||||
- persistence should provide a durable persistent storage, which
|
||||
survives between state machine restarts and does not corrupt
|
||||
its state.
|
||||
- Raft library calls `state_machine::apply_entry()` for entries
|
||||
@@ -54,7 +54,7 @@ is not supported.
|
||||
For an example of first usage see `replication_test.cc` in test/raft/.
|
||||
|
||||
In a nutshell:
|
||||
- create instances of RPC, storage, and state machine
|
||||
- create instances of RPC, persistence, and state machine
|
||||
- pass them to an instance of Raft server - the facade to the Raft cluster
|
||||
on this node
|
||||
- repeat the above for every node in the cluster
|
||||
@@ -64,8 +64,8 @@ In a nutshell:
|
||||
|
||||
### Subsequent usages
|
||||
|
||||
Similar to the first usage, but `storage::load_term_and_vote()`
|
||||
`storage::load_log()`, `storage::load_snapshot()` are expected to
|
||||
Similar to the first usage, but `persistence::load_term_and_vote()`
|
||||
`persistence::load_log()`, `persistence::load_snapshot()` are expected to
|
||||
return valid protocol state as persisted by the previous incarnation
|
||||
of an instance of class server.
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ class fsm {
|
||||
server_id _current_leader;
|
||||
// What state the server is in. The default is follower.
|
||||
std::variant<follower, candidate, leader> _state;
|
||||
// _current_term, _voted_for && _log are persisted in storage
|
||||
// _current_term, _voted_for && _log are persisted in persistence
|
||||
// The latest term the server has seen.
|
||||
term_t _current_term;
|
||||
// Candidate id that received a vote in the current term (or
|
||||
|
||||
16
raft/raft.hh
16
raft/raft.hh
@@ -212,11 +212,11 @@ using rpc_message = std::variant<append_request_send, append_reply, vote_request
|
||||
// std::deque move constructor is not nothrow hence cannot be used
|
||||
using log_entries = boost::container::deque<log_entry_ptr>;
|
||||
|
||||
// rpc, storage and satte_machine classes will have to be implemented by the
|
||||
// rpc, persistence and state_machine classes will have to be implemented by the
|
||||
// raft user to provide network, persistency and busyness logic support
|
||||
// repectively.
|
||||
class rpc;
|
||||
class storage;
|
||||
class persistence;
|
||||
|
||||
// Any of the functions may return an error, but it will kill the
|
||||
// raft instance that uses it. Depending on what state the failure
|
||||
@@ -341,15 +341,15 @@ public:
|
||||
void set_rpc_server(class rpc *rpc) { rpc->_client = this; }
|
||||
};
|
||||
|
||||
// This class represents persistent storage state. If any of the
|
||||
// This class represents persistent storage state for the internal fsm. If any of the
|
||||
// function returns an error the Raft instance will be aborted.
|
||||
class storage {
|
||||
class persistence {
|
||||
public:
|
||||
virtual ~storage() {}
|
||||
virtual ~persistence() {}
|
||||
|
||||
// Persist given term and vote.
|
||||
// Can be called concurrently with other save-* functions in
|
||||
// the storage and with itself but an implementation has to
|
||||
// the persistence and with itself but an implementation has to
|
||||
// make sure that the result is returned back in the calling order.
|
||||
virtual future<> store_term_and_vote(term_t term, server_id vote) = 0;
|
||||
|
||||
@@ -395,8 +395,8 @@ public:
|
||||
// entries.
|
||||
virtual future<> truncate_log(index_t idx) = 0;
|
||||
|
||||
// Stop the storage instance by aborting the work that can be
|
||||
// aborted and waiting for all the rest to complete any
|
||||
// Stop the persistence instance by aborting the work that can be
|
||||
// aborted and waiting for all the rest to complete. Any
|
||||
// unfinished store/load operation may return an error after
|
||||
// this function is called.
|
||||
virtual future<> abort() = 0;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace raft {
|
||||
class server_impl : public rpc_server, public server {
|
||||
public:
|
||||
explicit server_impl(server_id uuid, std::unique_ptr<rpc> rpc,
|
||||
std::unique_ptr<state_machine> state_machine, std::unique_ptr<storage> storage,
|
||||
std::unique_ptr<state_machine> state_machine, std::unique_ptr<persistence> persistence,
|
||||
seastar::shared_ptr<failure_detector> failure_detector, server::configuration config);
|
||||
|
||||
server_impl(server_impl&&) = delete;
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
private:
|
||||
std::unique_ptr<rpc> _rpc;
|
||||
std::unique_ptr<state_machine> _state_machine;
|
||||
std::unique_ptr<storage> _storage;
|
||||
std::unique_ptr<persistence> _persistence;
|
||||
seastar::shared_ptr<failure_detector> _failure_detector;
|
||||
// Protocol deterministic finite-state machine
|
||||
std::unique_ptr<fsm> _fsm;
|
||||
@@ -141,10 +141,10 @@ private:
|
||||
};
|
||||
|
||||
server_impl::server_impl(server_id uuid, std::unique_ptr<rpc> rpc,
|
||||
std::unique_ptr<state_machine> state_machine, std::unique_ptr<storage> storage,
|
||||
std::unique_ptr<state_machine> state_machine, std::unique_ptr<persistence> persistence,
|
||||
seastar::shared_ptr<failure_detector> failure_detector, server::configuration config) :
|
||||
_rpc(std::move(rpc)), _state_machine(std::move(state_machine)),
|
||||
_storage(std::move(storage)), _failure_detector(failure_detector),
|
||||
_persistence(std::move(persistence)), _failure_detector(failure_detector),
|
||||
_id(uuid), _config(config) {
|
||||
set_rpc_server(_rpc.get());
|
||||
if (_config.snapshot_threshold > _config.max_log_length) {
|
||||
@@ -153,10 +153,10 @@ server_impl::server_impl(server_id uuid, std::unique_ptr<rpc> rpc,
|
||||
}
|
||||
|
||||
future<> server_impl::start() {
|
||||
auto [term, vote] = co_await _storage->load_term_and_vote();
|
||||
auto snapshot = co_await _storage->load_snapshot();
|
||||
auto [term, vote] = co_await _persistence->load_term_and_vote();
|
||||
auto snapshot = co_await _persistence->load_snapshot();
|
||||
auto snp_id = snapshot.id;
|
||||
auto log_entries = co_await _storage->load_log();
|
||||
auto log_entries = co_await _persistence->load_log();
|
||||
auto log = raft::log(std::move(snapshot), std::move(log_entries));
|
||||
index_t stable_idx = log.stable_idx();
|
||||
_fsm = std::make_unique<fsm>(_id, term, vote, std::move(log), *_failure_detector,
|
||||
@@ -305,13 +305,13 @@ future<> server_impl::io_fiber(index_t last_stable) {
|
||||
// together. A vote may change independently of
|
||||
// term, but it's safe to update both in this
|
||||
// case.
|
||||
co_await _storage->store_term_and_vote(batch.term, batch.vote);
|
||||
co_await _persistence->store_term_and_vote(batch.term, batch.vote);
|
||||
}
|
||||
|
||||
if (batch.snp) {
|
||||
logger.trace("[{}] io_fiber storing snapshot {}", _id, batch.snp->id);
|
||||
// Persist the snapshot
|
||||
co_await _storage->store_snapshot(*batch.snp, _config.snapshot_trailing);
|
||||
co_await _persistence->store_snapshot(*batch.snp, _config.snapshot_trailing);
|
||||
// If this is locally generated snapshot there is no need to
|
||||
// load it.
|
||||
if (_last_loaded_snapshot_id != batch.snp->id) {
|
||||
@@ -328,12 +328,12 @@ future<> server_impl::io_fiber(index_t last_stable) {
|
||||
auto& entries = batch.log_entries;
|
||||
|
||||
if (last_stable >= entries[0]->idx) {
|
||||
co_await _storage->truncate_log(entries[0]->idx);
|
||||
co_await _persistence->truncate_log(entries[0]->idx);
|
||||
}
|
||||
|
||||
// Combine saving and truncating into one call?
|
||||
// will require storage to keep track of last idx
|
||||
co_await _storage->store_log_entries(entries);
|
||||
// will require persistence to keep track of last idx
|
||||
co_await _persistence->store_log_entries(entries);
|
||||
|
||||
last_stable = (*entries.crbegin())->idx;
|
||||
}
|
||||
@@ -471,7 +471,7 @@ future<> server_impl::abort() {
|
||||
auto snapshots = seastar::when_all_succeed(snp_futures.begin(), snp_futures.end());
|
||||
|
||||
return seastar::when_all_succeed(std::move(_io_status), std::move(_applier_status),
|
||||
_rpc->abort(), _state_machine->abort(), _storage->abort(), std::move(snapshots)).discard_result();
|
||||
_rpc->abort(), _state_machine->abort(), _persistence->abort(), std::move(snapshots)).discard_result();
|
||||
}
|
||||
|
||||
future<> server_impl::add_server(server_id id, bytes node_info, clock_type::duration timeout) {
|
||||
@@ -511,11 +511,11 @@ void server_impl::tick() {
|
||||
}
|
||||
|
||||
std::unique_ptr<server> create_server(server_id uuid, std::unique_ptr<rpc> rpc,
|
||||
std::unique_ptr<state_machine> state_machine, std::unique_ptr<storage> storage,
|
||||
std::unique_ptr<state_machine> state_machine, std::unique_ptr<persistence> persistence,
|
||||
seastar::shared_ptr<failure_detector> failure_detector, server::configuration config) {
|
||||
assert(uuid != raft::server_id{utils::UUID(0, 0)});
|
||||
return std::make_unique<raft::server_impl>(uuid, std::move(rpc), std::move(state_machine),
|
||||
std::move(storage), failure_detector, config);
|
||||
std::move(persistence), failure_detector, config);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const server_impl& s) {
|
||||
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
};
|
||||
|
||||
std::unique_ptr<server> create_server(server_id uuid, std::unique_ptr<rpc> rpc,
|
||||
std::unique_ptr<state_machine> state_machine, std::unique_ptr<storage> storage,
|
||||
std::unique_ptr<state_machine> state_machine, std::unique_ptr<persistence> persistence,
|
||||
seastar::shared_ptr<failure_detector> failure_detector, server::configuration config);
|
||||
|
||||
} // namespace raft
|
||||
|
||||
@@ -202,12 +202,12 @@ struct initial_state {
|
||||
raft::server::configuration server_config = raft::server::configuration{.append_request_threshold = 200};
|
||||
};
|
||||
|
||||
class storage : public raft::storage {
|
||||
class persistence : public raft::persistence {
|
||||
raft::server_id _id;
|
||||
initial_state _conf;
|
||||
public:
|
||||
storage(raft::server_id id, initial_state conf) : _id(id), _conf(std::move(conf)) {}
|
||||
storage() {}
|
||||
persistence(raft::server_id id, initial_state conf) : _id(id), _conf(std::move(conf)) {}
|
||||
persistence() {}
|
||||
virtual future<> store_term_and_vote(raft::term_t term, raft::server_id vote) { return seastar::sleep(1us); }
|
||||
virtual future<std::pair<raft::term_t, raft::server_id>> load_term_and_vote() {
|
||||
auto term_and_vote = std::make_pair(_conf.term, _conf.vote);
|
||||
@@ -319,10 +319,10 @@ create_raft_server(raft::server_id uuid, state_machine::apply_fn apply, initial_
|
||||
auto sm = std::make_unique<state_machine>(uuid, std::move(apply), std::move(val), apply_entries);
|
||||
auto& rsm = *sm;
|
||||
auto mrpc = std::make_unique<rpc>(uuid);
|
||||
auto mstorage = std::make_unique<storage>(uuid, state);
|
||||
auto mpersistence = std::make_unique<persistence>(uuid, state);
|
||||
auto fd = seastar::make_shared<failure_detector>(uuid);
|
||||
|
||||
auto raft = raft::create_server(uuid, std::move(mrpc), std::move(sm), std::move(mstorage),
|
||||
auto raft = raft::create_server(uuid, std::move(mrpc), std::move(sm), std::move(mpersistence),
|
||||
std::move(fd), state.server_config);
|
||||
|
||||
return std::make_pair(std::move(raft), &rsm);
|
||||
|
||||
Reference in New Issue
Block a user