InfinityStore is a distributed key-value store built using the Raft Consensus algorithm for high availability and consistency. This documentation provides an overview of how to run the application and interact with its API.
- Running the Application 🚀
- HTTP API 📡
2.1. Set
2.2. Get
2.3. Join - Dependencies 📦
- Configuration ⚙️
- Example
To run InfinityStore, follow these steps:
git clone https://github.com/heyyakash/infinitystore.git
cd infinitystore
go build -o store
./infinitystore --node-id=node1 --raft-addr=localhost:8000 --http-addr=:8001
InfinityStore exposes several HTTP endpoints to interact with the distributed key-value store.
Endpoint: /set
Method: POST
Description: Sets a key-value pair in the store.
Request Body:
{
"action" :"set"
"key": "your_key",
"value": "your_value"
}
Example:
curl -X POST http://localhost:8001/set -d '{"key":"foo", "value":"bar","action":"set"}'
curl -X POST http://localhost:8001/set -d '{"key":"foo", "value":"bar","action":"delete"}'
Response:
200 OK: Set successful
400 Bad Request: Invalid body
500 Internal Server Error: Couldn't add to store
Endpoint: /get
Method: GET
Description: Retrieves the value for a given key.
Query Parameters:
- key: The key to retrieve the value for. Example:
curl -X GET "http://localhost:8001/get?key=foo"
Response:
200 OK: Key and value
400 Bad Request: Missing key
404 Not Found: Key does not exist
Endpoint: /join
Method: POST
Description: Joins a new node to the cluster.
Query Parameters:
- nodeid: The ID of the node to join.
- nodeaddr: The address of the node to join.
Example:
curl -X POST "http://localhost:8001/join?nodeid=node2&nodeaddr=localhost:8002"
Response:
200 OK: Voter added
400 Bad Request: Not a leader
500 Internal Server Error: Failed to add voter
InfinityStore relies on several external packages:
- github.com/gorilla/mux: Router for handling HTTP requests.
- github.com/hashicorp/raft: Implementation of the Raft consensus protocol.
- github.com/heyyakash/infinitystore/datastore: Custom data store implementation.
- github.com/heyyakash/infinitystore/fsmachine: Finite state machine for Raft.
- github.com/heyyakash/infinitystore/helper: Helper functions for response generation.
- github.com/heyyakash/infinitystore/models: Data models used in the application.
- github.com/heyyakash/infinitystore/raft: Raft consensus setup and management.
The application configuration is managed via command-line flags:
node-id: Unique identifier for the node (default: "node1").
raft-addr: Address for the Raft server (default: "localhost:8000").
http-addr: Address for the HTTP server (default: ":8001").
These flags are parsed during the initialization phase:
func Init() {
nodeID = flag.String("node-id", "node1", "Node ID")
raftAddr = flag.String("raft-addr", "localhost:8000", "Raft Server Address")
httpAddr = flag.String("http-addr", ":8001", "Http server Address")
flag.Parse()
}
For simplicity we'll create 3 instances to imitate 3 nodes on same node.
- Create a Leader Node
./store --http-addr=:8001 --raft-addr=localhost:8000 --node-id=node-1
- Create a follower node
./store --http-addr=:8011 --raft-addr=localhost:8001 --node-id=node-2
- Create another follower node
./store --http-addr=:8021 --raft-addr=localhost:8020 --node-id=node-3
Note
:To gain majority minimum no. of available nodes should be cieling of (N+1)/2. So for a basic cluster we are going to have 3 nodes.
- Join the Follower nodes to the Leader node.
curl -X POST "http://localhost:8001/join?nodeid=node-2&nodeaddr=localhost:8010" curl -X POST "http://localhost:8001/join?nodeid=node-3&nodeaddr=localhost:8020"
- Now send a set request to Leader Node
curl -X POST http://localhost:8001/set -d '{"key":"foo", "value":"bar","action":"set"}'
- Now send a get request to one of the follower
curl -X GET "http://localhost:8011/get?key=foo"