komuw / kshaka

Kshaka is a Go implementation of the CASPaxos consensus protocol.
MIT License
23 stars 2 forks source link
caspaxos paxos raft

Kshaka

CircleCI codecov GoDoc Go Report Card

Kshaka is a Go implementation of the CASPaxos consensus protocol.
It's name is derived from the Kenyan hip hop group, Kalamashaka.

CASPaxos is a replicated state machine (RSM) kshaka. Unlike Raft and Multi-Paxos, it doesn’t use leader election and log replication, thus avoiding associated complexity.
Its symmetric peer-to-peer approach achieves optimal commit latency in wide-area networks and doesn’t cause transient unavailability when any [N−1] of N nodes crash." - The CASPaxos whitepaper

This is work in progress, do not use it anywhere you would regret. API will change over time.

Installation

Usage

package main

import (
    "fmt"

    "github.com/hashicorp/raft-boltdb"
    "github.com/komuw/kshaka"
)

func main() {
    // The store should, ideally be disk persisted.
    // Any that implements hashicorp/raft StableStore interface will suffice
    boltStore, err := raftboltdb.NewBoltStore("/tmp/bolt.db")
    if err != nil {
        panic(err)
    }

    // The function that will be applied by CASPaxos.
    // This will be applied to the current value stored
    // under the key passed into the Propose method of the proposer.
    var setFunc = func(val []byte) kshaka.ChangeFunction {
        return func(current []byte) ([]byte, error) {
            return val, nil
        }
    }

    // Note that, in practice, nodes ideally should be
    // in different machines each with its own store.
    node1 := kshaka.NewNode(1, boltStore)
    node2 := kshaka.NewNode(2, boltStore)
    node3 := kshaka.NewNode(3, boltStore)

    transport1 := &kshaka.InmemTransport{Node: node1}
    transport2 := &kshaka.InmemTransport{Node: node2}
    transport3 := &kshaka.InmemTransport{Node: node3}
    node1.AddTransport(transport1)
    node2.AddTransport(transport2)
    node3.AddTransport(transport3)

    kshaka.MingleNodes(node1, node2, node3)

    key := []byte("name")
    val := []byte("Masta-Ace")

    // make a proposition; consensus via CASPaxos will happen
    newstate, err := node2.Propose(key, setFunc(val))
    if err != nil {
        fmt.Printf("err: %v", err)
    }
    fmt.Printf("\n newstate: %v \n", newstate)
}

System design

1. Intro:

2. Algo:

A. Prepare phase

B. Accept phase

C. End

3. Cluster membership change

4. Deleting record/s

5. Optimizations

dev

debug one test;

dlv test -- -test.v -test.run ^Test_proposer_Propose