A raft framework, for regular people

Overview

RmqttRaft - A raft framework, for regular people

This is an attempt to create a layer on top of tikv/raft-rs, that is easier to use and implement. This is not supposed to be the most featureful raft, but instead a convenient interface to get started quickly, and have a working raft in no time.

The interface is strongly inspired by the one used by canonical/raft.

Getting started

In order to "raft" storage, we need to implement the Storage trait for it. Bellow is an example with HashStore, which is a thread-safe wrapper around an HashMap:

/// convienient data structure to pass Message in the raft
#[derive(Serialize, Deserialize)]
pub enum Message {
    Insert { key: String, value: String },
    Get { key: String },
}

#[derive(Clone)]
struct HashStore(Arc<RwLock<HashMap<String, String>>>);

impl HashStore {
    fn new() -> Self {
        Self(Arc::new(RwLock::new(HashMap::new())))
    }
    fn get(&self, key: &str) -> Option<String> {
        self.0.read().unwrap().get(key).cloned()
    }
}

#[async_trait]
impl Store for HashStore {
    async fn apply(&mut self, message: &[u8]) -> RaftResult<Vec<u8>> {
        let message: Message = deserialize(message).unwrap();
        let message: Vec<u8> = match message {
            Message::Insert { key, value } => {
                let mut db = self.0.write().unwrap();
                let v = serialize(&value).unwrap();
                db.insert(key, value);
                v
            }
            _ => Vec::new(),
        };
        Ok(message)
    }

    async fn query(&self, query: &[u8]) -> RaftResult<Vec<u8>> {
        let query: Message = deserialize(query).unwrap();
        let data: Vec<u8> = match query {
            Message::Get { key } => {
                if let Some(val) = self.get(&key) {
                    serialize(&val).unwrap()
                } else {
                    Vec::new()
                }
            }
            _ => Vec::new(),
        };
        Ok(data)
    }

    async fn snapshot(&self) -> RaftResult<Vec<u8>> {
        Ok(serialize(&self.0.read().unwrap().clone())?)
    }

    async fn restore(&mut self, snapshot: &[u8]) -> RaftResult<()> {
        let new: HashMap<String, String> = deserialize(snapshot).unwrap();
        let mut db = self.0.write().unwrap();
        let _ = std::mem::replace(&mut *db, new);
        Ok(())
    }
}

Only 4 methods need to be implemented for the Store:

  • Store::apply: applies a commited entry to the store.
  • Store::query query a entry from the store;
  • Store::snapshot: returns snapshot data for the store.
  • Store::restore: applies the snapshot passed as argument.

running the raft

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    
    let store = HashStore::new();

    let raft = Raft::new(options.raft_addr, store.clone(), logger.clone());
    let leader_info = raft.find_leader_info(options.peer_addrs).await?;

    let mailbox = Arc::new(raft.mailbox());
    let (raft_handle, mailbox) = match leader_info {
        Some((leader_id, leader_addr)) => {
            info!(logger, "running in follower mode");
            let handle = tokio::spawn(raft.join(options.id, Some(leader_id), leader_addr));
            (handle, mailbox)
        }
        None => {
            info!(logger, "running in leader mode");
            let handle = tokio::spawn(raft.lead(options.id));
            (handle, mailbox)
        }
    };

    tokio::try_join!(raft_handle)?;
    Ok(())
}

The mailbox gives you a way to interact with the raft, for sending a message, or leaving the cluster for example.

Credit

This work is based on riteraft, but more adjustments and improvements have been made to the code .

License

This library is licensed under either of:

at your option.

You might also like...
The labs of Raft consensus algorithm based on MadSim.

MadRaft The labs of Raft consensus algorithm based on MadSim. Some codes are derived from MIT 6.824 and PingCAP Talent Plan: Raft Lab. Thanks for thei

The Raft algorithm implement by Rust.

Raft The Raft algorithm implement by Rust. This project refers to Eli Bendersky's website, the link as follows: https://eli.thegreenplace.net/2020/imp

Raft distributed consensus for WebAssembly in Rust

WRaft: Raft in WebAssembly What is this? A toy implementation of the Raft Consensus Algorithm for WebAssembly, written in Rust. Basically, it synchron

ChiselStore is an embeddable, distributed SQLite for Rust, powered by Little Raft.

ChiselStore ChiselStore is an embeddable, distributed SQLite for Rust, powered by Little Raft. SQLite is a fast and compact relational database manage

Raft distributed consensus algorithm implemented in Rust.
Raft distributed consensus algorithm implemented in Rust.

Raft Problem and Importance When building a distributed system one principal goal is often to build in fault-tolerance. That is, if one particular nod

🚣‍♀️ 1kloc, well-documented Raft consensus algorithm implementation

miniraft A 1kloc, well-documented Raft consensus algorithm implementation This crate is a minimal implementation of the Raft consensus protocol with

Another minimal Raft implementation in Rust.

raft-rs Not my first time implementing Raft. I wrote about another implementation in Go I did. But you don't learn a concept well until you've impleme

A command-line tool and library for generating regular expressions from user-provided test cases
A command-line tool and library for generating regular expressions from user-provided test cases

Table of Contents What does this tool do? Do I still need to learn to write regexes then? Current features How to install? 4.1 The command-line tool 4

An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs.

regex A Rust library for parsing, compiling, and executing regular expressions. Its syntax is similar to Perl-style regular expressions, but lacks a f

A Rust library for constructing tilings of regular polygons
A Rust library for constructing tilings of regular polygons

tiling tiling is a library for constructing tilings of regular polygons and their dual tilings. Resources Documentation Tilings by regular polygons Li

An interactive scripting language where you can read and modify code comments as if they were regular strings
An interactive scripting language where you can read and modify code comments as if they were regular strings

An interactive scripting language where you can read and modify code comments as if they were regular strings. Add and view text-based visualizations and debugging information inside your source code file.

A fusion of OTP lib/dialyzer + lib/compiler for regular Erlang with type inference

Typed ERLC The Problem I have a dream, that one day there will be an Erlang compiler, which will generate high quality type-correct code from deduced

Prints the absolute path of all regular files in an unmounted btrfs filesystem image.

btrfs-walk-tut Prints the absolute path of all regular files in an unmounted btrfs filesystem image. Learning about btrfs: Btrfs Basics Series This re

RnR is a command-line tool to securely rename multiple files and directories that supports regular expressions
RnR is a command-line tool to securely rename multiple files and directories that supports regular expressions

RnR is a command-line tool to securely rename multiple files and directories that supports regular expressions. Features Batch rename files and direct

The Ergex Regular Expression Library

The Ergex Regular Expression Library Introduction Ergex is a regular expression library that does a few things rather differently from many other libr

A new, portable, regular expression language

rulex A new, portable, regular expression language Read the book to get started! Examples On the left are rulex expressions (rulexes for short), on th

Rust library for regular expressions using "fancy" features like look-around and backreferences

fancy-regex A Rust library for compiling and matching regular expressions. It uses a hybrid regex implementation designed to support a relatively rich

A new, portable, regular expression language

rulex A new, portable, regular expression language Read the book to get started! Examples On the left are rulex expressions (rulexes for short), on th

Rust regex in ECMAScript regular expression syntax!

ecma_regex The goal of ecma_regex is to provide the same functionality as the regex crate in ECMAScript regular expression syntax. Reliable regex engi

Comments
  • How to config checkQuorum to false for raft-rs?

    How to config checkQuorum to false for raft-rs?

    Problem: the leader node will be stuck and constantly compete to become to the leader when it can not receive the Quorum from followers in time.(my follower nodes face a high requests rate from clients). Logs: Sep 06 10:51:16.588 WARN stepped down to follower since quorum is not active, raft_id: 1, version: 1.0.0 Sep 06 10:51:16.588 INFO became follower at term 2, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:18.407 INFO starting a new election, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:18.407 INFO became pre-candidate at term 2, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:18.407 INFO broadcasting vote request, to: [2, 3], log_index: 6, log_term: 2, term: 2, type: MsgRequestPreVote, raft_id: 1, version: 1.0.0 Sep 06 10:51:20.227 INFO starting a new election, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:20.227 INFO became pre-candidate at term 2, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:20.227 INFO broadcasting vote request, to: [2, 3], log_index: 6, log_term: 2, term: 2, type: MsgRequestPreVote, raft_id: 1, version: 1.0.0 Sep 06 10:51:22.047 INFO starting a new election, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:22.047 INFO became pre-candidate at term 2, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:22.047 INFO broadcasting vote request, to: [2, 3], log_index: 6, log_term: 2, term: 2, type: MsgRequestPreVote, raft_id: 1, version: 1.0.0 Sep 06 10:51:23.865 INFO starting a new election, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:23.865 INFO became pre-candidate at term 2, term: 2, raft_id: 1, version: 1.0.0 Sep 06 10:51:23.865 INFO broadcasting vote request, to: [2, 3], log_index: 6, log_term: 2, term: 2, type: MsgRequestPreVote, raft_id: 1, version: 1.0.0

    Reason: I check the reason is checkQuorum is set as true. So do the maintainer know how to set checkQuorum to false when starting the RAFT nodes?

    opened by KunPengRen 1
Releases(0.2.3)
Owner
null
Raft distributed consensus algorithm implemented in Rust.

Raft Problem and Importance When building a distributed system one principal goal is often to build in fault-tolerance. That is, if one particular nod

TiKV Project 2.3k Dec 28, 2022
Another minimal Raft implementation in Rust.

raft-rs Not my first time implementing Raft. I wrote about another implementation in Go I did. But you don't learn a concept well until you've impleme

Phil Eaton 43 Dec 15, 2023
A highly scalable MySQL Proxy framework written in Rust

mysql-proxy-rs An implementation of a MySQL proxy server built on top of tokio-core. Overview This crate provides a MySQL proxy server that you can ex

AgilData 175 Dec 19, 2022
Redis compatible server framework for Rust

Redis compatible server framework for Rust Features Create a fast custom Redis compatible server in Rust Simple API. Support for pipelining and telnet

Josh Baker 61 Nov 12, 2022
A yaml-based SQL planner test framework

SQLPlannerTest A yaml-based SQL planner test framework. SQLPlannerTest is a regression test framework. It will read a special yaml file for describing

The RisingLight Project 23 Sep 21, 2022
A raft framework, for regular people

RmqttRaft - A raft framework, for regular people This is an attempt to create a layer on top of tikv/raft-rs, that is easier to use and implement. Thi

null 16 Dec 21, 2022
Fork of async-raft, the Tokio-based Rust implementation of the Raft protocol.

Agreed Fork of async-raft, the Tokio-based Rust implementation of the Raft distributed consensus protocol. Agreed is an implementation of the Raft con

NLV8 Technologies 8 Jul 5, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
cashio is a decentralized stablecoin made for the people, by the people.

cashio is a decentralized stablecoin made for the people, by the people. We're in active development. For the latest updates, please join our c

Cashio App 42 Sep 29, 2022
Raft implementation in Rust

rsraft Raft implementation in Rust. The aim of this project is implementing the Raft Consensus Algorithm as described in the paper, with the goal of f

Lauro Caetano 42 Dec 24, 2022