This is a fork from https://github.com/serialx/hashring for a toy project I'm experimenting with.
Changes:
- Removed weight feature for the sake of simplicity of the experiment
- Used
hashring.Node
interface instead ofstring
endpoints so that custom node types can be used - Used stable sorting now to avoid a potential bug (see serialx#24)
- Used RWMutex to make Adding/Removing/Getting nodes concurrency safe (see serialx#20)
- It has a
go.mod
file now
The original readme (with updated examples for custom Node type) goes below:
Implements consistent hashing that can be used when the number of server nodes can increase or decrease (like in memcached). The hashing ring is built using the same algorithm as libketama.
This is a port of Python hash_ring library https://pypi.python.org/pypi/hash_ring/ in Go with the extra methods to add and remove nodes.
Importing ::
import "github.com/mugli/hashring"
Basic example usage ::
// In your code, you probably have a custom data type
// for your cluster nodes. Just add a String function to implement
// hashring.Node interface.
type myNode string
func (m myNode) String() string {
return string(m)
}
memcacheServers := []Node{
myNode("192.168.0.246:11212"),
myNode("192.168.0.247:11212"),
myNode("192.168.0.249:11212")
}
ring := hashring.New(memcacheServers)
server, _ := ring.GetNode("my_key")
To fulfill replication requirements, you can also get a list of servers that should store your key.
serversInRing := []Node{
myNode("192.168.0.246:11212"),
myNode("192.168.0.247:11212"),
myNode("192.168.0.249:11212")
}
replicaCount := 3
ring := hashring.New(serversInRing)
server, _ := ring.GetNodesForReplicas("my_key", replicaCount)
Adding and removing nodes example ::
memcacheServers := []Node{
myNode("192.168.0.246:11212"),
myNode("192.168.0.247:11212"),
myNode("192.168.0.249:11212")
}
ring := hashring.New(memcacheServers)
ring = ring.RemoveNode(myNode("192.168.0.246:11212"))
ring = ring.AddNode(myNode("192.168.0.250:11212"))
server, _ := ring.GetNode("my_key")