# raft **Repository Path**: liteJava/raft ## Basic Information - **Project Name**: raft - **Description**: C implementation of the Raft consensus protocol - **Primary Language**: C - **License**: LGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2020-10-29 - **Last Updated**: 2024-06-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [![Build Status](https://travis-ci.org/canonical/raft.png)](https://travis-ci.org/canonical/raft) [![codecov](https://codecov.io/gh/canonical/raft/branch/master/graph/badge.svg)](https://codecov.io/gh/canonical/raft) [![Documentation Status](https://readthedocs.org/projects/raft/badge/?version=latest)](https://raft.readthedocs.io/en/latest/?badge=latest) Fully asynchronous C implementation of the Raft consensus protocol. The library has modular design: its core part implements only the core Raft algorithm logic, in a fully platform independent way. On top of that, a pluggable interface defines the I/O implementation for networking (send/receive RPC messages) and disk persistence (store log entries and snapshots). A stock implementation of the I/O interface is provided when building the library with default options. It is based on [libuv](http://libuv.org) and should fit the vast majority of use cases. The only catch is that it currently requires Linux, since it uses the Linux [AIO](http://man7.org/linux/man-pages/man2/io_submit.2.html) API for disk I/O. Patches are welcome to add support for more platforms. See [raft.h](https://github.com/canonical/raft/blob/master/include/raft.h) for full documentation. Licence ------- This raft C library is released under a slightly modified version of LGPLv3, that includes a copiright exception letting users to statically link the library code in their project and release the final work under their own terms. See the full [license](https://github.com/canonical/raft/blob/LICENSE) text. Features -------- This implementation includes all the basic features described in the Raft dissertation: - Leader election - Log replication - Log compaction - Membership changes It also includes a few optional enhancements: - Optimistic pipelining to reduce log replication latency - Writing to leader's disk in parallel - Automatic stepping down when the leader loses quorum - Leadership transfer extension - Pre-vote protocol Building -------- ```bash autoreconf -i ./configure --enable-example make ``` Example ------- The best way to understand how to use the library is probably reading the code of the [example server](https://github.com/canonical/raft/blob/master/example/server.c) included in the source code. You can also see the example server in action by running: ```bash ./example/cluster ``` which spawns a little cluster of 3 servers, runs a sample workload, and randomly stops and restarts a server from time to time. Quick guide ----------- It is recommended that you read [raft.h](https://github.com/canonical/raft/blob/master/include/raft.h) for documentation details, but here's a quick high-level guide of what you'll need to do (error handling is omitted for brevity). Create an instance of the stock ```raft_io``` interface implementation (or implement your own one if the one that comes with the library really does not fit): ```C const char *dir = "/your/raft/data"; struct uv_loop_s loop; struct raft_uv_transport transport; struct raft_io io; uv_loop_init(&loop); raft_uv_tcp_init(&transport, &loop); raft_uv_init(&io, &loop, dir, &transport); ``` Define your application Raft FSM, implementing the ```raft_fsm``` interface: ```C struct raft_fsm { void *data; int (*apply)(struct raft_fsm *fsm, const struct raft_buffer *buf, void **result); int (*snapshot)(struct raft_fsm *fsm, struct raft_buffer *bufs[], unsigned *n_bufs); int (*restore)(struct raft_fsm *fsm, struct raft_buffer *buf); } ``` Pick a unique ID and address for each server and initialize the raft object: ```C unsigned id = 1; const char *address = "192.168.1.1:9999"; struct raft raft; raft_init(&raft, &io, &fsm, id, address); ``` If it's the first time you start the cluster, create a configuration object containing each server that should be present in the cluster (typically just one, since you can grow your cluster at a later point using ```raft_add``` and ```raft_promote```) and bootstrap: ```C struct raft_configuration configuration; raft_configuration_init(&configuration); raft_configuration_add(&configuration, 1, "192.168.1.1:9999", true); raft_bootstrap(&raft, &configuration); ``` Start the raft server: ```C raft_start(&raft); uv_run(&loop, UV_RUN_DEFAULT); ``` Asynchronously submit requests to apply new commands to your application FSM: ```C static void applyCb(struct raft_apply *req, int status, void *result) { /* ... */ } struct raft_apply req; struct raft_buffer buf; buf.len = ...; /* The length of your FSM entry data */ buf.base = ...; /* Your FSM entry data */ raft_apply(&raft, &req, &buf, 1, apply_callback); ``` To add more servers to the cluster use the ```raft_add()``` and ```raft_promote``` APIs. Notable users ------------- - [dqlite](https://github.com/canonical/dqlite) Credits ------- Of course the biggest thanks goes to Diego Ongaro :) (the original author of the Raft dissertation) A lot of ideas and inspiration was taken from other Raft implementations such as: - CoreOS' Go implementation for [etcd](https://github.com/etcd-io/etcd/tree/master/raft) - Hashicorp's Go [raft](https://github.com/hashicorp/raft) - Willem's [C implementation](https://github.com/willemt/raft) - LogCabin's [C++ implementation](https://github.com/logcabin/logcabin)