一致性哈希算法优势在哪?如何实现?

这篇具有很好参考价值的文章主要介绍了一致性哈希算法优势在哪?如何实现?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 普通哈希算法

1.1 简介Hash

哈希算法即散列算法,是一种从任意文件中创造小的数字「指纹」的方法。与指纹一样,散列算法就是一种以较短的信息来保证文件唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。因此,当原有文件发生改变时,其标志值也会发生改变,从而告诉文件使用者当前的文件已经不是你所需求的文件。
简单hash算法在实现上为:目标 target = hash(key)% 质数

1.2 普通Hash算法缺陷

举个例子:现在有一个数据库m1,要对一个user表进行水平拆分为user_0,user_1,user_2 三张表,如何进行合理的数据映射?

使用普通的hash算法的策略:
根据user的id进行hash运算,从而映射到对应的表,这时候 target = hash(key) % 3,即user_0 放的user的id都是 3的整数,同理user_1,user_2存放的user的id分别为 3余1,3余2…

如果随着业务的增加,user表要从原来的三个增为五个user表,上述表达式变为 target = hash(key) % 5, 这时所有记录的映射关系都会发生改变,导致我们需要对所有数据重新规整,放到对应的表中,这个任务量显然是巨大的…

2. 一致性哈希算法

一致性hash算法就是为了解决普通hash算法带来的痛点。

2.1 一致性hash算法原理

  1. 一致性Hash算法也是使用取模的方法,只是,刚才描述的取模法是对服务器的数量进行取模,而一致性Hash算法是对2^32取模,一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环,将各个服务器使用Hash进行计算,具体可以根据关键字进行哈希,这样每个记录就能确定其在哈希环上的位置。

可参考 https://blog.csdn.net/a745233700/article/details/120814088

2.2 一致性hash算法的代码实现

具体的项目实践,可参考这篇博客 : Sharding-JDBC 一致性hash算法数据库分片实践文章来源地址https://www.toymoban.com/news/detail-436911.html


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.SortedMap;
import java.util.TreeMap;
 public class ConsistentHashing {
     // 一致性哈希算法中使用的哈希函数,默认使用FNV1_32_HASH
    private HashFunction hashFunction;
    // 虚拟节点个数
    private int numberOfReplicas;
    // 使用TreeMap来存储虚拟节点的哈希值和物理节点的映射关系
    private SortedMap<Integer, String> circle = new TreeMap<>();
     /**
     * 构造函数,初始化哈希函数和虚拟节点个数
     * @param hashFunction 哈希函数
     * @param numberOfReplicas 虚拟节点个数
     */
    public ConsistentHashing(HashFunction hashFunction, int numberOfReplicas) {
        this.hashFunction = hashFunction;
        this.numberOfReplicas = numberOfReplicas;
    }
     /**
     * 添加物理节点
     * @param node 物理节点名称
     */
    public void addNode(String node) {
        for (int i = 0; i < numberOfReplicas; i++) {
            // 对于每个物理节点,根据其名称和编号生成一个虚拟节点,并将其添加到虚拟节点环中
            int hashValue = hashFunction.getHash(node + i);
            circle.put(hashValue, node);
        }
    }
     /**
     * 删除物理节点
     * @param node 物理节点名称
     */
    public void removeNode(String node) {
        for (int i = 0; i < numberOfReplicas; i++) {
            // 对于每个物理节点,根据其名称和编号生成一个虚拟节点,并将其从虚拟节点环中删除
            int hashValue = hashFunction.getHash(node + i);
            circle.remove(hashValue);
        }
    }
     /**
     * 根据给定的key选择一个物理节点
     * @param key key
     * @return 物理节点名称
     */
    public String getNode(String key) {
        if (circle.isEmpty()) {
            return null;
        }
        int hashValue = hashFunction.getHash(key);
        // 如果环中不存在大于该hash值的节点,则直接返回环中最小的节点
        if (!circle.containsKey(hashValue)) {
            SortedMap<Integer, String> tailMap = circle.tailMap(hashValue);
            hashValue = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
        }
        return circle.get(hashValue);
    }
     /**
     * 返回所有的物理节点
     * @return
     */
    public Collection<String> getAllNodes() {
        return new ArrayList<>(circle.values());
    }
     /**
     * 哈希函数接口
     */
    public interface HashFunction {
        int getHash(String key);
    }
     /**
     * FNV1_32_HASH算法,使用32位的FNV做hash,对于相同的字符串,不同的种子会产生不同的hash值
     */
    public static class FNV1_32_HASH implements HashFunction {
         public int getHash(String key) {
            final int p = 16777619;
            int hash = (int) 2166136261L;
            for (int i = 0; i < key.length(); i++) {
                hash = (hash ^ key.charAt(i)) * p;
            }
            hash += hash << 13;
            hash ^= hash >> 7;
            hash += hash << 3;
            hash ^= hash >> 17;
            return hash;
        }
    }
 }

到了这里,关于一致性哈希算法优势在哪?如何实现?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【负载均衡——一致性哈希算法】

    一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题。 一致哈希算法也用了取模运算,但与哈希算法不同的是,哈希算法是对节点的数量进行取模运算,而一致 哈希算法 是对 2^32 进行取模运算,是一个固定的值。 一致性哈希要进行两步

    2024年04月10日
    浏览(54)
  • 07. 算法之一致性哈希算法介绍

    哈希算法在程序开发中的很多地方都能看到他的身影,但是哈希有他的局限性,比如如果两个key哈希到同一个位置的时候,此时就不好处理。本节我们介绍一下常规处理方式。 哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。

    2024年02月06日
    浏览(53)
  • Python小知识 - 一致性哈希算法

    一致性哈希算法 一致性哈希算法(Consistent Hashing Algorithm)是用于解决分布式系统中节点增减比较频繁的问题。它的思想是,将数据映射到0~2^64-1的哈希空间中,并通过哈希函数对数据进行映射,计算出数据所在的节点。当节点增加或减少时,只需要重新计算数据所在的节点即

    2024年02月09日
    浏览(50)
  • Redis扩容机制与一致性哈希算法解析

    在分布式系统设计中,Redis是一个备受欢迎的内存数据库,而一致性哈希算法则是分布式系统中常用的数据分片和负载均衡技术。本文将深入探讨Redis的扩容机制以及一致性哈希算法的原理,同时提供示例代码以帮助读者更好地理解这两个重要概念。 Redis是一种高性能的内存数

    2024年02月11日
    浏览(47)
  • 【分布式】一致性哈希和哈希槽

    当我们拥有了多台存储服务器之后,现在有多个key,希望可以将这些个key均匀的缓存到这些服务器上,可以使用哪些方案呢? 1.1 直接哈希取模 这是一种最容易想到的方法,使用取模算法hash(key)% N,对key进行hash运算后取模,N是机器的数量。key进行hash后的结果对3取模,得

    2024年02月03日
    浏览(49)
  • 一致性哈希(哈希环)解决数据分布问题

    哈希算法是程序开发过程中最广泛接触到的的算法之一,典型的应用有安全加密、数据校验、唯一标识、散列函数、负载均衡、数据分片、分布式存储。前些天遇到用一致性哈希(哈希环)的场景,不过我细想一下,对这个知识点好像了解过,但是又没太深印象,说不出具体

    2024年02月04日
    浏览(54)
  • Dubbo负载均衡策略之 一致性哈希

    本文主要讲解了一致性哈希算法的原理以及其存在的数据倾斜的问题,然后引出解决数据倾斜问题的方法,最后分析一致性哈希算法在Dubbo中的使用。通过这篇文章,可以了解到一致性哈希算法的原理以及这种算法存在的问题和解决方案。 在这里引用dubbo官网的一段话——

    2024年02月08日
    浏览(66)
  • 得物面试:Redis用哈希槽,而不是一致性哈希,为什么?

    在40岁老架构师 尼恩的 读者交流群 (50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: Redis为何用哈希槽而不用一致性哈希? 最近有小伙伴在面试网易,又遇到了相关的面试题。

    2024年02月21日
    浏览(58)
  • Dubbo负载均衡策略之 一致性哈希 | 京东云技术团队

    本文主要讲解了一致性哈希算法的原理以及其存在的数据倾斜的问题,然后引出解决数据倾斜问题的方法,最后分析一致性哈希算法在Dubbo中的使用。通过这篇文章,可以了解到一致性哈希算法的原理以及这种算法存在的问题和解决方案。 在这里引用dubbo官网的一段话——

    2024年02月08日
    浏览(49)
  • JAVA面试题分享五百六十五:为啥Redis用哈希槽,不用一致性哈希?

    无论是哈希槽,还是一致性hash,都属于hash取模数据分片。 先从经典的hash取模数据分片说起 假如 Redis集群的节点数为3个,使用经典的hash取模算法进行数据分片,实际上就是一个节点一个数据分片,分为3片而已。 每次请求使用 hash(key) % 3 的方式计算对应的节点,或者进行

    2024年04月16日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包