一致性哈希算法

简介: 一致性哈希算法

原理

直接看白话解析:一致性哈希算法 consistent hashing写的非常好

代码

package main
import (
  "fmt"
  "hash/crc32"
  "log"
  "sort"
  "strconv"
  "strings"
)
// HashFunc 定义生成哈希的函数
type HashFunc func(data []byte) uint32
// Map 存储节点,你可以从Map中选择节点
type Map struct {
  hashFunc HashFunc       //哈希算法
  replicas int            //虚拟节点的数量
  keys     []int          //所有虚拟节点的哈希值
  hashMap  map[int]string //key->虚拟节点的哈希值,value->节点,实现虚拟节点映射到真实节点
}
// New 创建Map
func New(replicas int, fn HashFunc) *Map {
  m := &Map{
    replicas: replicas,
    hashFunc: fn,
    hashMap:  make(map[int]string),
  }
  if m.hashFunc == nil {
    m.hashFunc = crc32.ChecksumIEEE
  }
  return m
}
// IsEmpty Map中是否存在节点
func (m *Map) IsEmpty() bool {
  return len(m.keys) == 0
}
// AddNode 将给定的节点添加到一致性哈希中
func (m *Map) AddNode(keys ...string) {
  for _, key := range keys {
    if key == "" {
      continue
    }
    for i := 0; i < m.replicas; i++ {
      //计算虚拟节点哈希值
      hash := int(m.hashFunc([]byte(strconv.Itoa(i) + key)))
      //存储虚拟节点的哈希值
      m.keys = append(m.keys, hash)
      //存入map做映射
      m.hashMap[hash] = key
    }
  }
  //排序哈希值,下面匹配的时候要二分搜索
  sort.Ints(m.keys)
}
// getPartitionKey 支持哈希标记
func getPartitionKey(key string) string {
  beg := strings.Index(key, "{")
  if beg == -1 {
    return key
  }
  end := strings.Index(key, "}")
  if end == -1 || end == beg+1 {
    return key
  }
  return key[beg+1 : end]
}
// PickNode 获取与key最接近的节点。
func (m *Map) PickNode(key string) string {
  if m.IsEmpty() {
    return ""
  }
  partitionKey := getPartitionKey(key)
  //计算传入key的哈希
  hash := int(m.hashFunc([]byte(partitionKey)))
  // sort.Search 使用二分查找满足 m.keys[i] >= hash 的最小哈希值
  idx := sort.Search(len(m.keys), func(i int) bool { return m.keys[i] >= hash })
  // 若 key 的 hash 值大于最后一个虚拟节点的 hash 值,则选择第一个虚拟节点
  if idx == len(m.keys) {
    idx = 0
  }
  return m.hashMap[m.keys[idx]]
}
func TestHash() {
  m := New(3, nil)
  m.AddNode("a", "b", "c", "d")
  if m.PickNode("zxc") != "a" {
    log.Println("wrong answer")
  }
  if m.PickNode("123{abc}") != "b" {
    log.Println("wrong answer")
  }
  if m.PickNode("abc") != "b" {
    log.Println("wrong answer")
  }
  for i := 0; i < 26; i++ {
    fmt.Println(string(97+i)+"wxfQQ68725032", "在[", m.PickNode(string(97+i)), "]节点")
  }
}
func main() {
  TestHash()
}
目录
相关文章
|
4月前
|
缓存 算法 NoSQL
Java中的分布式缓存与一致性哈希算法
Java中的分布式缓存与一致性哈希算法
|
5月前
|
存储 NoSQL 算法
Redis集群,集群的概念 三种主流分片方式1.哈希求余 一致性哈希算法:方案三:哈希槽分区算法问题一Redis集群是最多有16384个分片吗问题二:为什么是16384个,集群扩容:1.新的主节点
Redis集群,集群的概念 三种主流分片方式1.哈希求余 一致性哈希算法:方案三:哈希槽分区算法问题一Redis集群是最多有16384个分片吗问题二:为什么是16384个,集群扩容:1.新的主节点
|
缓存 算法
【分布式系统】一致性哈希算法
一致性哈希算法在1997年由[麻省理工学院](https://baike.baidu.com/item/%E9%BA%BB%E7%9C%81%E7%90%86%E5%B7%A5%E5%AD%A6%E9%99%A2/117999 "麻省理工学院")提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 [1] 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式[哈希表](https://baike.baidu.com/item/%E5%93%88%E5%B8%8C%E8%A1%A8/5981869 "哈希表")(
274 0
|
6月前
|
存储 缓存 算法
【算法理论】一致性哈希
【1月更文挑战第26天】【算法理论】一致性哈希
|
6月前
|
存储 缓存 负载均衡
一文理解一致性哈希算法
一文理解一致性哈希算法
133 0
|
6月前
|
存储 缓存 运维
解密一致性哈希算法:实现高可用和负载均衡的秘诀
解密一致性哈希算法:实现高可用和负载均衡的秘诀
737 0
|
6月前
|
算法 Python
Python小知识 - 一致性哈希算法
Python小知识 - 一致性哈希算法
|
11月前
|
存储 缓存 算法
五分钟看懂一致性哈希算法
五分钟看懂一致性哈希算法
67 0
|
存储 缓存 负载均衡
图解一致性哈希算法,看这一篇就够了!
近段时间一直在总结分布式系统架构常见的算法。前面我们介绍过布隆过滤器算法。接下来介绍一个非常重要、也非常实用的算法:一致性哈希算法。通过介绍一致性哈希算法的原理并给出了一种实现和实际运用的案例,带大家真正理解一致性哈希算法。
11888 4
图解一致性哈希算法,看这一篇就够了!
|
运维 算法 数据库
浅析数据库算法与数据结构(五)一致性哈希
我们在第二期中讲过,HASH算法是一种非常快速的查找算法,可以用于对数据进行分区和分片。但是有一个问题。根据常规哈希算法算出来的哈希值,通常是无法扩展的,也就是说,假如说,我们一开始想将数据分成四个数据片,随着我们数据量的增长,四个数据片都接近了系统的极限,现在我们想加入一个新的数据片。这时使用传统的哈希算法,通常是无法做到的。只能讲数据重新在汇总起来再重新分成五分,这样就导致了巨大的运维成本。
142 0
浅析数据库算法与数据结构(五)一致性哈希