High Availability Raft Framework for Go
High Availabilty Framework for Happy Data
Uhaha is a framework for building highly available Raft-based data applications in Go. This is basically an upgrade to the Finn project, but has an updated API, better security features (TLS and auth passwords), customizable services, deterministic time, recalculable random numbers, simpler snapshots, a smaller network footprint, and more. Under the hood it utilizes hashicorp/raft, tidwall/redcon, and tidwall/wal.
Below a simple example of a service for monotonically increasing tickets.
…Using the source file from the examples directory, we'll build an application named "ticket"
go build -o ticket examples/ticket/main.goIt's ideal to have three, five, or seven nodes in your cluster.
Let's create the first node.
./ticket -n 1 -a :11001This will create a node named 1 and bind the address to :11001
Now let's create two more nodes and add them to the cluster.
./ticket -n 2 -a :11002 -j :11001
./ticket -n 3 -a :11003 -j :11001Now we have a fault-tolerant three node cluster up and running.
You can use any Redis compatible client, such as the redis-cli, telnet, or netcat.
I'll use the redis-cli in the example below.
Connect to the leader. This will probably be the first node you created.
redis-cli -p 11001Send the server a TICKET command and receive the first ticket.
> TICKET
"1"From here on every TICKET command will guarentee to generate a value larger than the previous TICKET command.
> TICKET
"2"
> TICKET
"3"
> TICKET
"4"
> TICKET
"5"There are a number built-in commands for managing and monitor the cluster.
…And also some client commands.
QUIT # close the client connection
PING # ping the server
ECHO [message] # echo a message to the server
AUTH password # authenticate with a passwordBy default a single Uhaha instance is bound to the local 127.0.0.1 IP address. Thus nothing outside that machine, including other servers in the cluster or machines on the same local network will be able communicate with this instance.
To open up the service you will need to provide an IP address that can be reached from the outside.
For example, let's say you want to set up three servers on a local 10.0.0.0 network.
On server 1:
./ticket -n 1 -a 10.0.0.1:11001On server 2:
./ticket -n 2 -a 10.0.0.2:11001 -j 10.0.0.1:11001On server 3:
./ticket -n 3 -a 10.0.0.3:11001 -j 10.0.0.1:11001Now you have a Raft cluster running on three distinct servers in the same local network. This may be enough for applications that only require a network security policy. Basically any server on the local network can access the cluster.
If you want to lock down the cluster further you can provide a secret auth, which is more or less a password that the cluster and client will need to communicate with each other.
./ticket -n 1 -a 10.0.0.1:11001 --auth my-secretAll the servers will need to be started with the same auth.
./ticket -n 2 -a 10.0.0.2:11001 --auth my-secret -j 10.0.0.1:11001./ticket -n 2 -a 10.0.0.3:11001 --auth my-secret -j 10.0.0.1:11001The client will also need the same auth to talk with cluster. All redis clients support an auth password, such as:
redis-cli -h 10.0.0.1 -p 11001 -a my-secretThis may be enough if you keep all your machines on the same private network, but you don't want all machines or applications to have unfettered access to the cluster.
Finally you can use TLS, which I recommend along with an auth password.
In this example a custom cert and key are created using the mkcert tool.
mkcert uhaha-example
# produces uhaha-example.pem, uhaha-example-key.pem, and a rootCA.pemThen create a cluster using the cert & key files. Along with an auth.
./ticket -n 1 -a 10.0.0.1:11001 --tls-cert uhaha-example.pem --tls-key uhaha-example-key.pem --auth my-secret./ticket -n 2 -a 10.0.0.2:11001 --tls-cert uhaha-example.pem --tls-key uhaha-example-key.pem --auth my-secret -j 10.0.0.1:11001./ticket -n 2 -a 10.0.0.3:11001 --tls-cert uhaha-example.pem --tls-key uhaha-example-key.pem --auth my-secret -j 10.0.0.1:11001Now you can connect to the server from a client that has the rootCA.pem.
You can find the location of your rootCA.pem file in the running ls "$(mkcert -CAROOT)/rootCA.pem".
redis-cli -h 10.0.0.1 -p 11001 --tls --cacert rootCA.pem -a my-secretBelow are the primary command line options.
…No open issues yet, or sync has not completed.