Код IT
← Каталог

Надежность и доступность — Стратегии равномерного шардирования

Фрагмент из «Надежность и доступность»: Стратегии равномерного шардирования.

go projectencyclopedia7-06-proektirovanie-i-arhitektura-design-2134 embed URL статья в энциклопедии
Go main.go
package consistenthash

import (

    "hash/crc32"
    "sort"
    "strconv"
)

type ConsistentHash struct {
    replicas int
    ring     []uint32
    nodeMap  map[uint32]string
}

func NewConsistentHash(replicas int) *ConsistentHash {
    return &ConsistentHash{
        replicas: replicas,
        ring:     make([]uint32, 0),
        nodeMap:  make(map[uint32]string),
    }
}

func (c *ConsistentHash) AddNode(node string) {
    for i := 0; i < c.replicas; i++ {
        hash := crc32.ChecksumIEEE([]byte(strconv.Itoa(i) + node))
        c.ring = append(c.ring, hash)
        c.nodeMap[hash] = node
    }
    sort.Slice(c.ring, func(i, j int) bool {
        return c.ring[i] < c.ring[j]
    })
}

func (c *ConsistentHash) GetNode(key string) string {
    if len(c.ring) == 0 {
        return ""
    }
    
    hash := crc32.ChecksumIEEE([]byte(key))
    idx := sort.Search(len(c.ring), func(i int) bool {
        return c.ring[i] >= hash
    })
    
    if idx == len(c.ring) {
        idx = 0
    }
    
    return c.nodeMap[c.ring[idx]]
}
package consistenthash

import (

    "hash/crc32"
    "sort"
    "strconv"
)

type ConsistentHash struct {
    replicas int
    ring     []uint32
    nodeMap  map[uint32]string
}

func NewConsistentHash(replicas int) *ConsistentHash {
    return &ConsistentHash{
        replicas: replicas,
        ring:     make([]uint32, 0),
        nodeMap:  make(map[uint32]string),
    }
}

func (c *ConsistentHash) AddNode(node string) {
    for i := 0; i < c.replicas; i++ {
        hash := crc32.ChecksumIEEE([]byte(strconv.Itoa(i) + node))
        c.ring = append(c.ring, hash)
        c.nodeMap[hash] = node
    }
    sort.Slice(c.ring, func(i, j int) bool {
        return c.ring[i] < c.ring[j]
    })
}

func (c *ConsistentHash) GetNode(key string) string {
    if len(c.ring) == 0 {
        return ""
    }
    
    hash := crc32.ChecksumIEEE([]byte(key))
    idx := sort.Search(len(c.ring), func(i int) bool {
        return c.ring[i] >= hash
    })
    
    if idx == len(c.ring) {
        idx = 0
    }
    
    return c.nodeMap[c.ring[idx]]
}