Skip to content
/ raft Public

Package raft implements the Raft distributed consensus protocol based on hslam/rpc.

License

Notifications You must be signed in to change notification settings

hslam/raft

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

raft

Package raft implements the Raft distributed consensus protocol.

Features

  • Leader Election
  • Log Replication
  • Membership Changes
  • Log Compaction (Snapshotting)
  • RPC transport
  • WAL
  • ReadIndex/Lease Read
  • Non-Voting Members (The leader only replicates log entries to them)
  • Snapshot Policies (Never/EverySecond/CustomSync/Always)

Get started

Install

go get github.com/hslam/raft

Import

import "github.com/hslam/raft"
  • Leader Election
  • Non-Voting Members
  • Membership Changes

helloworld.go

package main

import (
	"flag"
	"fmt"
	"github.com/hslam/raft"
	"strings"
	"time"
)

var (
	host  string
	port  int
	path  string
	join  bool
	peers string
)

func init() {
	flag.StringVar(&host, "h", "localhost", "hostname")
	flag.IntVar(&port, "p", 9001, "port")
	flag.StringVar(&path, "path", "raft.helloworld/node.1", "data dir")
	flag.BoolVar(&join, "join", false, "")
	flag.StringVar(&peers, "peers", "localhost:9001,false;", "host:port,nonVoting;host:port,nonVoting;")
}
func main() {
	flag.Parse()
	raft.SetLogLevel(raft.DebugLevel)
	var nodes []string
	var infos []*raft.NodeInfo
	if peers != "" {
		nodes = strings.Split(peers, ";")
		for _, v := range nodes {
			if v == "" {
				continue
			}
			info := strings.Split(v, ",")
			var NonVoting bool
			if len(info) > 1 {
				if info[1] == "true" {
					NonVoting = true
				}
			}
			infos = append(infos, &raft.NodeInfo{Address: info[0], NonVoting: NonVoting, Data: nil})
		}
	}
	node, err := raft.NewNode(host, port, path, nil, join, infos)
	if err != nil {
		panic(err)
	}
	node.Start()
	for {
		fmt.Printf("%d State:%s - Leader:%s\n", time.Now().Unix(), node.State(), node.Leader())
		time.Sleep(time.Second * 3)
	}
}

one node

./node -h=localhost -p=9001 -path="raft.helloworld/node.1" -join=false -peers="localhost:9001"

three nodes

./node -h=localhost -p=9001 -path="raft.helloworld/node.hw.1" -join=false -peers="localhost:9001;localhost:9002;localhost:9003"
./node -h=localhost -p=9002 -path="raft.helloworld/node.hw.2" -join=false -peers="localhost:9001;localhost:9002;localhost:9003"
./node -h=localhost -p=9003 -path="raft.helloworld/node.hw.3" -join=false -peers="localhost:9001;localhost:9002;localhost:9003"

non-voting

./node -h=localhost -p=9001 -path="raft.helloworld/node.nv.1" -join=false -peers="localhost:9001;localhost:9002;localhost:9003;localhost:9004,true"
./node -h=localhost -p=9002 -path="raft.helloworld/node.nv.2" -join=false -peers="localhost:9001;localhost:9002;localhost:9003;localhost:9004,true"
./node -h=localhost -p=9003 -path="raft.helloworld/node.nv.3" -join=false -peers="localhost:9001;localhost:9002;localhost:9003;localhost:9004,true"
./node -h=localhost -p=9004 -path="raft.helloworld/node.nv.4" -join=false -peers="localhost:9001;localhost:9002;localhost:9003;localhost:9004,true"

membership changes

./node -h=localhost -p=9001 -path="raft.helloworld/node.mc.1" -join=false
./node -h=localhost -p=9002 -path="raft.helloworld/node.mc.2" -join=true -peers="localhost:9001;localhost:9002"
./node -h=localhost -p=9003 -path="raft.helloworld/node.mc.3" -join=true -peers="localhost:9001;localhost:9002;localhost:9003"
  • Leader Election
  • Non-Voting Members
  • Membership Changes
  • Log Replication
  • Log Compaction (Snapshotting)
  • ReadIndex/Lease Read
  • Snapshot Policies
  • Benchmark

one node set

./example -h=localhost -p=9001 -path="raft.example/node.1" -join=false -peers="localhost:9001" -log=true -b=true  -o=set -parallel=4096 -total=100000

one node readindex

./example -h=localhost -p=9001 -path="raft.example/node.1" -join=false -peers="localhost:9001" -log=true -b=true  -o=readindex -parallel=4096 -total=100000

one node lease

./example -h=localhost -p=9001 -path="raft.example/node.1" -join=false -peers="localhost:9001" -log=true -b=true  -o=lease -parallel=4096 -total=100000

three nodes set

./example -h=localhost -p=9001 -path="raft.example/node.tn.1" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=set -parallel=4096 -total=100000
./example -h=localhost -p=9002 -path="raft.example/node.tn.2" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=set -parallel=4096 -total=100000
./example -h=localhost -p=9003 -path="raft.example/node.tn.3" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=set -parallel=4096 -total=100000

three nodes readindex

./example -h=localhost -p=9001 -path="raft.example/node.tn.1" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=readindex -parallel=4096 -total=100000
./example -h=localhost -p=9002 -path="raft.example/node.tn.2" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=readindex -parallel=4096 -total=100000
./example -h=localhost -p=9003 -path="raft.example/node.tn.3" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=readindex -parallel=4096 -total=100000

three nodes lease

./example -h=localhost -p=9001 -path="raft.example/node.tn.1" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=lease -parallel=4096 -total=100000
./example -h=localhost -p=9002 -path="raft.example/node.tn.2" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=lease -parallel=4096 -total=100000
./example -h=localhost -p=9003 -path="raft.example/node.tn.3" -join=false -peers="localhost:9001;localhost:9002;localhost:9003" -log=true -b=true    -o=lease -parallel=4096 -total=100000

The raftdb implements a simple distributed key-value datastore, using the raft distributed consensus protocol.

Benchmark

Running on three nodes cluster.

Write

write-qpswrite-p99

Read Index

read-qpsread-p99

License

This package is licensed under a MIT license (Copyright (c) 2019 Meng Huang)

Author

raft was written by Meng Huang.

About

Package raft implements the Raft distributed consensus protocol based on hslam/rpc.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages