Skip to content

Instantly share code, notes, and snippets.

@hawaijar
Last active August 1, 2025 09:30
Show Gist options
  • Save hawaijar/631cfdee8bdc6a8b7778e7f50fde6a8e to your computer and use it in GitHub Desktop.
Save hawaijar/631cfdee8bdc6a8b7778e7f50fde6a8e to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"log"
)
func main() {
// Create a consistent hash ring with 150 virtual nodes per physical node
ring := consistenthash.New(150)
// Add some cache servers
servers := []string{"cache-1", "cache-2", "cache-3"}
for _, server := range servers {
ring.AddNode(server)
log.Printf("Added node: %s", server)
}
// Route some keys
keys := []string{"user:123", "session:456", "product:789", "order:234", "cart:567"}
fmt.Println("\nKey Distribution:")
for _, key := range keys {
node := ring.GetNode(key)
fmt.Printf("%s -> %s\n", key, node)
}
// Get replica nodes for fault tolerance
fmt.Println("\nReplica nodes for 'user:123':")
replicas := ring.GetNodes("user:123", 3)
for i, replica := range replicas {
fmt.Printf(" Replica %d: %s\n", i+1, replica)
}
// Simulate adding a new node
fmt.Println("\nAdding new node 'cache-4'...")
ring.AddNode("cache-4")
fmt.Println("\nNew distribution (notice minimal movement):")
moved := 0
for _, key := range keys {
oldNode := ring.GetNode(key) // This would be from before in real scenario
newNode := ring.GetNode(key)
fmt.Printf("%s -> %s", key, newNode)
if oldNode != newNode {
fmt.Printf(" (moved)")
moved++
}
fmt.Println()
}
fmt.Printf("\nOnly %d/%d keys moved (%.1f%%)\n", moved, len(keys), float64(moved)/float64(len(keys))*100)
// Show statistics
stats := ring.GetStats()
fmt.Printf("\nRing Statistics:\n")
fmt.Printf(" Physical nodes: %d\n", stats.PhysicalNodes)
fmt.Printf(" Virtual nodes: %d\n", stats.VirtualNodes)
fmt.Printf(" Virtual nodes per physical node: %d\n", stats.Replicas)
// Check distribution quality
testKeys := make([]string, 10000)
for i := 0; i < 10000; i++ {
testKeys[i] = fmt.Sprintf("test-key-%d", i)
}
distribution := ring.GetDistribution(testKeys)
fmt.Println("\nLoad distribution (10,000 keys):")
for node, count := range distribution {
percentage := float64(count) / float64(len(testKeys)) * 100
fmt.Printf(" %s: %d keys (%.1f%%)\n", node, count, percentage)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment