一致性哈希(consistent hashing)
来源:互联网 发布:淘宝网健身手球 编辑:程序博客网 时间:2024/05/17 20:33
啥是consistent hashing?
不管是一致性哈希还是二致性哈希还是什么阿猫阿狗哈希,都是哈希。只不过它有些特殊,特殊性就体现在名字上一致性
。
为了表明它的与众不同,先看看啥是哈希(hashing)。在英文中,字面上hash
大致是切分的意思。hashing通常是将一个数据通过哈希函数映射成另一种数据的过成。例如将字符串hello
映射成57,Hasta la vista, baby
映射成33。具体映射逻辑就是哈希函数的逻辑,这个由自己来定。
哈希表
当用一个数据存储一群人的名字时候,为了增加事后查找效率,通常使用名字的hash值作为数组索引,即名字作为key,用某种hash function算出hash值。比如名字为David的名字经过hash后的值为4,那么存放在数组的索引为4的位置。
当人名多了,hash值并不能保证唯一,如果David和Andson的hash值都是4,那么就造成了hash碰撞。通常的解决方案是数组索引为4的位置不再存放一个元素了,取而代之的是一个链表,链表存储David和Andson,如果再有其它名字也hash到了4这个位置,那么将他存在该链表的末尾。
这样的数据结构就是hash table
在分布式环境中应用hash
想想一下,有几台分布式的Memcached服务器,一些数据对象通过hash 映射,均匀分布在这几台服务器上存储。如果一台服务器挂了,或者添加服务器,那么hash function里的映射逻辑就要跟着变,读取数据的时候,被分配到其他服务器上去读取,自然读取不到,然后Memcached去原始服务器上读取数据。这样的情况在数据量非常大的情况下,会造成原始服务器压力陡增,进而崩掉。
怎样保证在缓存服务器减少或者增加的情况下,尽量少地影响原数据的读取位置呢?
一个解决方法就是 一致性哈希。
一致性哈希
一致性哈希的整体思想就是将数据和服务器通过相同的hash function映射到一个单元环上(unit circle)。每个数据存放在逆时针方向上最近的那个服务器上。
图中,A B C 是三台服务器,其他圆圈是数据。按逆时针方向查找,每个数据都有自已的“归属”。
如果此时,服务器B挂了,B存储的数据“bill”被rehashing道服务器C上,而其他数据几乎不受影响。
下面几十行golang代码模拟了模拟了一致性hash的unit circle。
package mainimport "fmt"import "sync"import "hash/crc32"import "sort"import "errors"// unit circletype Ring struct { Nodes Nodes // 环上部署的服务器节点 sync.Mutex}// 用数组表示一个循环链表,表达unit circletype Nodes []*Nodefunc (n Nodes) Len() int {return len(n)}func (n Nodes) Swap(i, j int) {n[i], n[j] = n[j], n[i]}func (n Nodes) Less(i, j int) bool {return n[i].HashId < n[j].HashId}type Node struct { Id string HashId int }func NewNode(id string) *Node { return &Node{ Id: id, HashId: hashId(id), }}// 这里使用crc32.ChecksumIEEE方法取得节点的hash值,可以使用其他自定义func hashId(key string) int { return int(crc32.ChecksumIEEE([]byte(key)))}func NewRing() *Ring { return &Ring{ Nodes: Nodes{}, }}func (r *Ring) AddNode(id string) { r.Lock() defer r.Unlock() node := NewNode(id) r.Nodes = append(r.Nodes, node) sort.Sort(r.Nodes)}func (r *Ring) RemoveNode(id string) error { r.Lock() defer r.Unlock() i := r.Search(id) if i >= len(r.Nodes) || id != r.Nodes[i].Id { return NotFountError } r.Nodes = append(r.Nodes[:i], r.Nodes[i+1:]...) return nil}func (r *Ring) Search(id string) int { searchfn := func (i int) bool { return r.Nodes[i].HashId >= hashId(id) } return sort.Search(len(r.Nodes), searchfn)}func (r *Ring) Get(id string) string { i := r.Search(id) if i >= len(r.Nodes) { i = 0 } return r.Nodes[i].Id}var NotFountError = errors.New("node not found")func main() { r := NewRing() r.AddNode("jian") r.AddNode("yong") r.AddNode("li") fmt.Println(r.Get("sf")) r.RemoveNode("li") fmt.Println(r.Get("sf")) fmt.Println(r.RemoveNode("yon"))}
- 一致性哈希(Consistent Hashing)
- 一致性哈希(Consistent Hashing)
- 一致性哈希(Consistent Hashing)
- 一致性哈希(Consistent Hashing)
- 一致性哈希(Consistent Hashing)
- 一致性哈希(consistent hashing)
- 总结一致性哈希(Consistent Hashing)
- 一致性哈希算法(Consistent Hashing)
- Consistent Hashing 一致性哈希算法
- 总结一致性哈希(Consistent Hashing)
- 一致性哈希算法(consistent hashing)
- 转-- 一致性哈希(Consistent Hashing)
- 一致性哈希算法(Consistent Hashing)
- 一致性哈希算法 consistent hashing
- 一致性哈希算法(Consistent Hashing)
- 一致性哈希算法(Consistent Hashing)
- 一致性哈希算法(Consistent Hashing)
- 一致性哈希算法 - Consistent Hashing
- 机器学习正则化与过拟合
- Find a way HDU
- Error compiling OpenCV, fatal error: stdlib.h: No such file or directory
- 关于学习新框架
- 浅谈SVD分解和CUR分解
- 一致性哈希(consistent hashing)
- mysql忘记密码解决办法
- 秒杀系统 是 如何设计
- Lua知识点六 数据结构
- 输入输出流章节的重点总结
- K-mean(多维度)聚类算法(matlab代码)
- 500. Keyboard Row
- tomcat+nginx+redis实现均衡负载、session共享(一)
- 深入理解PHP内核[读书笔记]--第四章:函数的实现 --匿名函数及闭包