This is a creation in Article, where the information may have evolved or changed.
The consistency hash can be is used to solve the server balancing problem. With Golang simple implementation of the next, and added the weight. Suitable weights can be used with the algorithm.
Package main//Consistency Hash (consistent Hashing)//author:xiong Chuan liang//date:2015-2-20import ("FMT" "Hash/crc32" "Sort" " StrConv "" Sync ") const DEFAULT_REPLICAS = 160type hashring []uint32func (c hashring) len () int {return Len (c)}func (c Hashri NG) Less (i, J int) bool {return c[i] < C[j]}func (c hashring) Swap (i, J int) {C[i], c[j] = c[j], c[i]}type Node struct {ID intip stringport inthostname stringweight int}func NewNode (id int, IP string, port int, name string, Weight int) *node {return &node{id:id,ip:ip,port:port,hostname:name,weight:weight,}}type Consi Stent struct {Nodes map[uint32]nodenumreps intresources map[int]boolring hashringsync.rwmutex}func NewConsisten T () *consistent {return &consistent{nodes:make (Map[uint32]node), Numreps:default_replicas,resources:make (map[i Nt]bool), Ring:hashring{},}}func (c *consistent) Add (node *node) bool {c.lock () defer c.unlock () If _, OK: = C.resource S[node. ID]; OK {return False}coUNT: = c.numreps * node. Weightfor I: = 0; I < count; i++ {str: = C.JOINSTR (i, node) c.nodes[c.hashstr (str)] = * (node)}c.resources[node. Id] = truec.sorthashring () return True}func (c *consistent) sorthashring () {c.ring = hashring{}for k: = Range C.nodes {C.ri ng = Append (c.ring, k)}sort. Sort (c.ring)}func (c *consistent) joinstr (i int, node *node) string {return node. Ip + "*" + StrConv. Itoa (node. Weight) + "-" + StrConv. Itoa (i) + "-" + StrConv. Itoa (node. ID)}//MurmurHash algorithm: Https://github.com/spaolacci/murmur3func (c *consistent) hashstr (key string) UInt32 {return CRC32. Checksumieee ([]byte (Key))}func (c *consistent) Get (key string) Node {C.rlock () defer c.runlock () Hash: = C.HASHSTR (key) I: = C.search (hash) return C.nodes[c.ring[i]]}func (c *consistent) search (hash uint32) int {i: = sort. Search (Len (c.ring), func (i int) bool {return c.ring[i] >= hash}) If I < Len (c.ring) {if i = = Len (c.ring)-1 {return 0} else {return i}} else {return Len (c.ring)-1}}func (c *consistent) Remove (node *node{C.lock () defer c.unlock () If _, OK: = C.resources[node. ID];!ok {return}delete (c.resources, node. ID) Count: = c.numreps * node. Weightfor I: = 0; I < count; i++ {str: = C.JOINSTR (i, node) Delete (C.nodes, c.hashstr (str))}c.sorthashring ()}func main () {chashring: = Newconsistent ( ) for I: = 0; I < 10; i++ {si: = fmt. Sprintf ("%d", i) Chashring.add (NewNode (i, "172.18.1.") +si, 8080, "Host_" +si, 1))}for K, V: = Range Chashring.nodes {fmt. Println ("Hash:", K, "IP:", V.ip)}ipmap: = Make (Map[string]int, 0) for I: = 0; i < 1000; i++ {si: = fmt. Sprintf ("key%d", i) K: = Chashring.get (SI) If _, OK: = Ipmap[k.ip]; OK {Ipmap[k.ip] + = 1} else {Ipmap[k.ip] = 1}}for k, V: = Range IpMap {fmt. Println ("Node IP:", K, "Count:", v)}}/* distribution: Node ip:172.18.1.2 count:115node ip:172.18.1.8 count:111node ip:172.18.1 .3 Count:94node ip:172.18.1.1 count:84node ip:172.18.1.7 count:107node ip:172.18.1.6 count:117node ip:172.18.1 .4 Count:92node ip:172.18.1.5 Count:112node ip:172.18.1.0 count:63nOde ip:172.18.1.9 count:105*/
Above is the result of a simple test.
Mail:xcl_168@aliyun.com
blog:http://blog.csdn.net/xcl168