分布式系统设计理论之一致性哈希

简介: 分布式系统设计理论之一致性哈希

分布式系统设计理论之一致性哈希

主要参考和围绕这篇论文讲解:Consistent Hashing

1 问题引入

什么是一致性哈希?为什么要用一致性哈希?

2 一致性哈希算法出现之前的分布式系统设计

例如系统需要构建分布式缓存,多个节点分别部署而形成的一个分布式集群,当有请求到来时进行负载均衡,具体的负载均衡方式就是将节点的ID(唯一标识)进行哈希值的取余运算,得到结果的机器就是进行请求处理的机器。

上述方式存在的问题

当一个节点进行更换(增加或删除节点)时,原有的节点消失或增加新的节点,会导致多个请求同时指向一个节点进而造成节点的宕机等问题。

总之一句话就是,当服务器个数发生改变时,缓存可能会失效。

图解:

正常情况下:

网络异常,图片无法展示
|


删除一个服务器之后:

网络异常,图片无法展示
|


3 什么是一致性哈希,它是如何解决上述问题的?

3.1 一致性哈希的核心思想

⼀致性哈希算法的基本思想是使⽤相同的哈希函数服务器节点对象和请求的缓存进⾏哈希,即⼀致地将对象映射到相同的缓存机器。

3.2 引入哈希环

整数int在Java中的取值范围是2的-31次方到2的31次方-1之间,那么就可以让请求的缓存和服务器节点同时进行相同的哈希算法后得到一个int值,进而形成一个哈希环,请求和服务器节点保持“顺时针就近”原则进行对应的请求:

网络异常,图片无法展示
|


A,B,C代表三个服务器节点,1,2,3,4代表着不同的缓存请求,按照“顺时针就近”原则,1,4会请求服务器A节点,2请求服务器B节点,3请求服务器C节点。

3.3 存在问题

(1)增删节点带来的问题

网络异常,图片无法展示
|


新增服务器节点D,按照之前的原则4就会向服务器D节点发起请求,在4和D之间的一部分缓存将会失效,这是问题之一。

(2)哈希倾斜

所谓哈希倾斜就是表示如上图,服务器A,B相距较近,假如没有服务器D节点,那么B到A这一段的请求都会落在A节点上,即大部分请求都指向A节点,而极少部分请求放在了B节点,这个问题就是“哈希倾斜”。

3.4 增加虚拟节点解决问题

解决上边两个问题的最佳方案就是增加虚拟节点,就是在哈希环中增加无数个虚拟节点,请求指向虚拟节点,虚拟节点指向真实节点,这样就会增加请求平均的概率,如图:

网络异常,图片无法展示
|


而且论文中还指出,虚拟节点的数量越大,请求产生的偏差越小:

网络异常,图片无法展示
|


4 Java代码实现一致性哈希

/**
 * @desc: Java实现一致性哈希
 * @author: YanMingXin
 * @create: 2021/10/16-16:46
 **/
public class ConsistentHash<T> {
    /**
     * 哈希函数类
     */
    private final HashFunction hashFunction;
    /**
     * 虚拟节点个数(不同节点一共的,会自动平均)
     */
    private final int numberOfReplicas;
    /**
     * 哈希环
     */
    private final SortedMap<Integer, T> circle = new TreeMap<Integer, T>();
    /**
     * 构造方法
     *
     * @param hashFunction     自定义哈希函数类(必须有hash()方法)
     * @param numberOfReplicas 副本个数
     * @param nodes            服务器节点
     */
    public ConsistentHash(HashFunction hashFunction,
                          int numberOfReplicas, Collection<T> nodes) {
        this.hashFunction = hashFunction;
        this.numberOfReplicas = numberOfReplicas;
        for (T node : nodes) {
            add(node);
        }
    }
    public ConsistentHash(int numberOfReplicas, Collection<T> nodes) {
        this.hashFunction = new HashFunction();
        this.numberOfReplicas = numberOfReplicas;
        for (T node : nodes) {
            add(node);
        }
    }
    /**
     * 向哈希环增加节点的副本
     *
     * @param node
     */
    public void add(T node) {
        for (int i = 0; i < numberOfReplicas; i++) {
            circle.put(hashFunction.hash(node.toString() + i), node);
        }
    }
    /**
     * 删除节点
     *
     * @param node
     */
    public void remove(T node) {
        for (int i = 0; i < numberOfReplicas; i++) {
            circle.remove(hashFunction.hash(node.toString() + i));
        }
    }
    /**
     * 根据请求得到他将要访问的节点
     *
     * @param key
     * @return
     */
    public T get(Object key) {
        if (circle.isEmpty()) {
            return null;
        }
        //将请求hash转换
        int hash = hashFunction.hash(key);
        //将请求放入哈希环
        if (!circle.containsKey(hash)) {
            //返回该映射中键值大于或等于hash的部分的视图。 
            SortedMap<Integer, T> tailMap = circle.tailMap(hash);
            //判断tailMap是否为空,是则返回哈希环第一个节点的值,反之则返回最近的节点
            hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
        }
        return circle.get(hash);
    }
    /**
     * 哈希函数类
     */
    class HashFunction {
        /**
         * 具体的哈希函数
         *
         * @param key
         * @return
         */
        public int hash(Object key) {
            return key.hashCode() / Integer.MAX_VALUE;
        }
    }
}
复制代码

部分图片和内容来自:tom-e-white.com/2007/11/con…


相关文章
|
1月前
|
消息中间件 算法 分布式数据库
Raft算法:分布式一致性领域的璀璨明珠
【4月更文挑战第21天】Raft算法是分布式一致性领域的明星,通过领导者选举、日志复制和安全性解决一致性问题。它将复杂问题简化,角色包括领导者、跟随者和候选者。领导者负责日志复制,确保多数节点同步。实现细节涉及超时机制、日志压缩和网络分区处理。广泛应用于分布式数据库、存储系统和消息队列,如Etcd、TiKV。其简洁高效的特点使其在分布式系统中备受青睐。
|
1月前
|
算法 分布式数据库
Paxos算法:分布式一致性的基石
【4月更文挑战第21天】Paxos算法是分布式一致性基础,由Leslie Lamport提出,包含准备和提交阶段,保证安全性和活性。通过提案编号、接受者和学习者实现,广泛应用于分布式数据库、锁和配置管理。其简单、高效、容错性强,影响了后续如Raft等算法,是理解分布式系统一致性关键。
|
1月前
|
存储 缓存 负载均衡
分布式系统Session一致性问题
分布式系统Session一致性问题
41 0
|
1月前
|
消息中间件 Dubbo 应用服务中间件
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
108 0
|
21天前
|
消息中间件 中间件 程序员
分布式事务大揭秘:使用MQ实现最终一致性
本文由小米分享,介绍分布式事务中的MQ最终一致性实现,以RocketMQ为例。RocketMQ的事务消息机制包括准备消息、本地事务执行、确认/回滚消息及事务状态检查四个步骤。这种机制通过消息队列协调多系统操作,确保数据最终一致。MQ最终一致性具有系统解耦、提高可用性和灵活事务管理等优点,广泛应用于分布式系统中。文章还讨论了RocketMQ的事务消息处理流程和失败情况下的处理策略,帮助读者理解如何在实际应用中解决分布式事务问题。
29 6
|
22天前
|
消息中间件 数据库 RocketMQ
可靠消息最终一致性分布式事务
推荐一个零声教育C/C++后台开发的免费公开课程,个人觉得老师讲得不错,分享给大家:C/C++后台开发高级架构师,内容包括Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习
32 2
|
26天前
|
运维 程序员 数据库
如何用TCC方案轻松实现分布式事务一致性
TCC(Try-Confirm-Cancel)是一种分布式事务解决方案,将事务拆分为尝试、确认和取消三步,确保在分布式系统中实现操作的原子性。它旨在处理分布式环境中的数据一致性问题,通过预检查和资源预留来降低失败风险。TCC方案具有高可靠性和灵活性,但也增加了系统复杂性并可能导致性能影响。它需要为每个服务实现Try、Confirm和Cancel接口,并在回滚时确保资源正确释放。虽然有挑战,TCC在复杂的分布式系统中仍被广泛应用。
32 5
|
3天前
|
存储 算法 安全
程序员必知:分布式一致性Raft与JRaft
程序员必知:分布式一致性Raft与JRaft
|
1月前
|
算法 程序员
破解Paxos活性难题:分布式一致性的终极指南
Paxos算法是解决分布式系统一致性问题的关键,由Leslie Lamport提出。它涉及提议者、接受者和学习者三个角色,通过准备和接受两个阶段达成共识。然而,确保算法的活性,即在面对网络分区、竞争冲突和节点故障时仍能及时决策,是一个挑战。解决方法包括领导者选举、优化提案编号管理、使用超时机制和Fast Paxos等。实际案例中,通过领导者选举和超时机制,可以提高Paxos在应对网络延迟和冲突时的活性。
45 1
|
1月前
|
Java 数据库连接 API
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
79 0