Go語言實現一致性雜湊(Consistent Hashing)演算法

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

         一致性雜湊可用於解決伺服器均衡問題。 用Golang簡單實現了下,並加入了權重。可採用合適的權重配合演算法使用。       

package main//一致性雜湊(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 HashRing) 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 Consistent struct {Nodes     map[uint32]NodenumReps   intResources map[int]boolring      HashRingsync.RWMutex}func NewConsistent() *Consistent {return &Consistent{Nodes:     make(map[uint32]Node),numReps:   DEFAULT_REPLICAS,Resources: make(map[int]bool),ring:      HashRing{},}}func (c *Consistent) Add(node *Node) bool {c.Lock()defer c.Unlock()if _, ok := c.Resources[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.ring = 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演算法 :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)}}/*分布: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*/
  上面是簡單測試後的結果。


MAIL:  xcl_168@aliyun.com

BLOG: http://blog.csdn.net/xcl168





 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.