哈希环

作者: 垃圾桶边的狗 | 来源:发表于2023-04-03 14:06 被阅读0次

哈希环(Hash Ring)是一种常见的数据分片方案,用于将数据均匀地分布在多个节点上。哈希环通常用于实现分布式缓存、负载均衡、分布式数据库等系统中。

哈希环的基本原理是将所有节点和数据都映射到一个环上,每个节点和数据在环上都有一个对应的哈希值。当需要访问某个数据时,将该数据的哈希值映射到环上,然后沿着环顺时针方向找到第一个比该哈希值大的节点,该节点即为该数据所在的节点。如果需要增加或删除节点,只需要重新计算节点和数据的哈希值,并在环上重新分配。

算法哈希环的实现通常包括以下步骤:

  • 定义哈希函数,将节点和数据映射到一个哈希值。
def hash_fnv1(key):
    """
    FNV1 hash function
    """
    FNV_OFFSET = 2166136261
    FNV_PRIME = 16777619
    hash_value = FNV_OFFSET
    for byte in key.encode('utf-8'):
        hash_value = (hash_value * FNV_PRIME) % (2 ** 32)
        hash_value = hash_value ^ byte
    return hash_value
  • 将所有节点和数据的哈希值映射到一个环上,按照哈希值从小到大排列。
  • 当需要访问某个数据时,将该数据的哈希值映射到环上,并沿着环顺时针方向查找第一个比该哈希值大的节点,该节点即为该数据所在的节点。
  • 如果需要增加或删除节点,只需要重新计算节点和数据的哈希值,并在环上重新分配。

常见的哈希函数包括MD5、SHA-1、SHA-256等,具体选择哪种哈希函数取决于应用的需求和性能要求。哈希环的优点是可以很好地实现数据均衡和容错,但缺点是当节点数量较少时可能会出现数据倾斜的情况。

import bisect

class HashRing:
    """
    哈希环类
    """
    def __init__(self, nodes, replicas=3, hash_func=hash):
        """
        初始化哈希环
        :param nodes: 节点列表
        :param replicas: 每个节点的虚拟节点数量
        :param hash_func: 哈希函数,默认使用内置的哈希函数
        """
        self.nodes = nodes
        self.replicas = replicas
        self.hash_func = hash_func
        self.ring = dict()
        for node in self.nodes:
            for i in range(self.replicas):
                # 使用节点名和虚拟节点编号生成哈希值
                key = '{}:{}'.format(node, i)
                # 计算哈希值,并将哈希值和节点映射关系加入哈希环中
                self.ring[self.hash_func(key)] = node
        # 将哈希环上的哈希值排序
        self.keys = sorted(self.ring.keys())

    def get_node(self, key):
        """
        获取存储 key 的节点
        :param key: 要存储的键值
        :return: 存储 key 的节点
        """
        if not self.nodes:
            return None
        # 计算 key 的哈希值
        key_hash = self.hash_func(key)
        # 在哈希环上查找距离 key_hash 最近的节点
        pos = bisect.bisect(self.keys, key_hash)
        if pos == len(self.keys):
            # 如果 key_hash 大于哈希环上所有的哈希值,那么返回第一个节点
            return self.ring[self.keys[0]]
        else:
            # 否则返回距离 key_hash 最近的节点
            return self.ring[self.keys[pos]]
        

# 测试代码
nodes = ['node1', 'node2', 'node3']
ring = HashRing(nodes)

ip = '192.23.3.1'
node = ring.get_node(ip)
print('IP {} 存储在节点 {}'.format(ip, node))

相关文章

  • 有环链表

    判断一个单链表是否有环 方法一:哈希表辅助遍历单链表每个节点,并存储在哈希表中,如果下次遍历的节点在哈希表出现,则...

  • 142. 环形链表II

    题目:给定一个链表,如果有环,返回链表开始入环的第一个节点;如果无环,返回null。思路1:哈希表遍历链表中的每个...

  • 哈希 IN 哈希

    具体实例: 把下面的哈希值进行转换成哈希in哈希 转换后: 打印hash,哈希不能直接打印,必须在foreach循...

  • Java数据结构_哈希表_基本概念

    本文目标 哈希表的基本概念,哈希冲突,哈希函数 什么是哈希表 哈希表也叫做散列表(hash有剁碎的意思)哈希表是空...

  • 【perl】perl哈希(一)——哈希简介

    本课包含:哈希简介、哈希的操作、哈希函数、哈希的使用、综合实例 哈希简介 概念 hash,也被称作散列 很散,很多...

  • 「Redis源码解读」—数据结构(二)哈希表

    Redis的字典使用哈希表作为底层实现 知识点 1.数据结构 哈希节点 哈希表 类型处理函数 2.哈希 哈希算法 ...

  • 计算文件哈希值

    什么是哈希值? 哈希值(hash values)是使用哈希函数(hash function)计算得到的值。哈希函数...

  • 《恋上数据结构与算法一》笔记(十五)哈希表

    目录 哈希表 哈希冲突(Hash Collision) JDK1.8的哈希冲突解决方案 哈希函数 如何生成key的...

  • 《数据结构与算法》总结(六)哈希表

    目录 哈希表 哈希冲突(Hash Collision) JDK1.8的哈希冲突解决方案 哈希函数 如何生成key的...

  • 分布式相关

    一致性哈希 对节点和key进行hash计算,分布在2^32槽的环上。对于节点比较少的,虚拟节点防止数据倾斜。 性能...

网友评论

      本文标题:哈希环

      本文链接:https://www.haomeiwen.com/subject/mvndddtx.html