`
gaojingsong
  • 浏览: 1211273 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

【分布式的存储系统之一致性哈希算法】

阅读更多
算法有点难以理解,看不懂的可以放弃,毕竟是分布式算法,主要解决怎么把一个值缓存映射到服务器上面,下次查找可以直接从缓存中找回来,而不用再去查找数据库。应用程序首先去缓存取得数据,如果取不到,再去数据库查找,把查找到得数据库缓存到缓存服务器上面,下次就可以从缓存服务器查找相同数据了,从而减轻对数据库的压力,提高网页访问速率。
例如手机朋友网有n个服务器,为了方便用户的访问会在服务器上缓存数据,因此用户每次访问的时候最好能保持同一台服务器。已有的做法是根据ServerIPIndex[QQNUM%n]得到请求的服务器,这种方法很方便将用户分到不同的服务器上去。但是如果一台服务器死掉了,那么n就变为了n-1,那么ServerIPIndex[QQNUM%n]与ServerIPIndex[QQNUM%(n-1)]基本上都不一样了,所以大多数用户的请求都会转到其他服务器,这样会发生大量访问错误。
 问:  如何改进或者换一种方法,使得:
(1)一台服务器死掉后,不会造成大面积的访问错误,
(2)原有的访问基本还是停留在同一台服务器上;
(3)尽量考虑负载均衡。
比如你有 N 个 cache 服务器(后面简称 cache ),那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache ;
hash(object)%N
一切都运行正常,再考虑如下的两种情况;
1 一个 cache 服务器 m down 掉了(在实际应用中必须要考虑这种情况),这样所有映射到 cache m 的对象都会失效,怎么办,需要把 cache m 从 cache 中移除,这时候 cache 是 N-1 台,映射公式变成了 hash(object)%(N-1) ;
2 由于访问加重,需要添加 cache ,这时候 cache 是 N+1 台,映射公式变成了 hash(object)%(N+1) ;
1 和 2 意味着什么?这意味着突然之间几乎所有的 cache 都失效了。对于服务器而言,这是一场灾难,洪水般的访问都会直接冲向后台服务器;
再来考虑第三个问题,由于硬件能力越来越强,你可能想让后面添加的节点多做点活,显然上面的 hash 算法也做不到。
 
 
一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的hash方法,将数据映射到具体的节点上,如key%N,key是数据的key,N是机器节点数,如果有一个机器加入或退出这个集群,则所有的数据映射都无效了,如果是持久化存储则要做数据迁移,如果是分布式缓存,则其他缓存就失效了。这就是取模算法的局限性,因此,引入了一致性哈希算法:
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。 
 
 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义:
 
1、平衡性(Balance):平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
 
2、单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。 
 
3、分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。 
 
4、负载(Load):负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同 的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。
代码如下:
/** 把一个字符串映射为一个hash之后的数字
*  MurMurHash算法,是非加密HASH算法,性能很高, 
*  比传统的CRC32,MD5,SHA-1(这两个算法都是加密HASH算法,复杂度本身就很高,带来的性能上的损害也不可避免) 
 *  等HASH算法要快很多,而且据说这个算法的碰撞率很低. 
 *  http://murmurhash.googlepages.com/ 
 */  
 private static Long hash(String key) {  
     ByteBuffer buf = ByteBuffer.wrap(key.getBytes());  
        int seed = 0x1234ABCD;  
        ByteOrder byteOrder = buf.order();
        buf.order(ByteOrder.LITTLE_ENDIAN);
        long m = 0xc6a4a7935bd1e995L;  
        int r = 47;  
        long h = seed ^ (buf.remaining() * m);
        long k;
        while (buf.remaining() >= 8) {
            k = buf.getLong();
            k *= m;
                     k ^= k >>> r; 
            k *= m;
 
            h ^= k;  
            h *= m;  
        }  
        if (buf.remaining() > 0) {
            ByteBuffer finish = ByteBuffer.allocate(8).order(
                    ByteOrder.LITTLE_ENDIAN); 
            // for big-endian version, do this first: 
            // finish.position(8-buf.remaining()); 
            finish.put(buf).rewind(); 
            h ^= finish.getLong(); 
            h *= m; 
        }  
        h ^= h >>> r; 
        h *= m;  
        h ^= h >>> r; 
        buf.order(byteOrder);
        return h; 
    }
 
 
//映射key到真实节点  
public void keyToNode(String key){  
        // 沿环的顺时针找到一个虚拟节点  
        SortedMap<Long, Node> tail = nodes.tailMap(this.hash(key)); 
        if (tail.size() == 0) {  
            return;  
        }  
  treeKey.put(hash(key), tail.get(tail.firstKey()));  
System.out.println(key+"(hash:"+hash(key)+")连接到主机->"+tail.get(tail.firstKey()));  
    }  
 
// 初始化一致性hash环  
 private void init() { 
        nodes = new TreeMap<Long, Node>();  
        treeKey = new TreeMap<Long, Node>();  
        for (int i = 0; i != shards.size(); ++i) { // 每个真实机器节点都需要关联虚拟节点  
            final Node shardInfo = shards.get(i);  
  
            for (int n = 0; n < NODE_NUM; n++)  
                // 一个真实机器节点关联NODE_NUM个虚拟节点  
                nodes.put(hash("SHARD-" + shardInfo.name + "-NODE-" + n), shardInfo);  
        }  
    }  
 
 
 
public class Shard<Node> { // S类封装了机器节点的信息 ,如name、password、ip、port等  
  
    static private TreeMap<Long, Node> nodes; // 虚拟节点到真实节点的映射  
    static private TreeMap<Long,Node> treeKey; //key到真实节点的映射  
    static private List<Node> shards = new ArrayList<Node>(); // 真实机器节点  
    private final int NODE_NUM = 100; // 每个机器节点关联的虚拟节点个数  
    boolean flag = false;  
      
    public Shard(List<Node> shards) {  
        super();  
        this.shards = shards;  
        init();  
    }  
}
  • 大小: 43 KB
  • 大小: 24.8 KB
0
1
分享到:
评论

相关推荐

    分布式存储系统中一致性哈希算法的研究.pdf

    综上所述,一致性哈希算法在分布式存储系统中的应用具有深远的意义。通过优化数据分布,算法不仅提高了系统的扩展性,还保证了在节点变化情况下的高效运行。尽管存在一些需要改进的地方,但一致性哈希算法已经成为...

    分布式存储系统中改进的一致性哈希算法.pdf

    整体来看,文章介绍的改进一致性哈希算法,通过在分布式存储系统中对节点进行逻辑划分、引入主从模式以及分析不同读写策略的数据一致性,旨在提升系统的性能和可靠性。这对于推动分布式存储系统的进一步发展具有重要...

    基于一致性哈希算法的分布式数据库高效扩展方法.pdf

    一致性哈希算法最初由麻省理工学院的K等人提出,并被广泛应用于分布式系统中,以解决节点动态变化时数据一致性问题。其核心思想是通过引入哈希环,将数据对象均匀分布在哈希环上的不同节点中,以此降低节点变更对...

    一致性哈希算法在分布式系统中的应用.pdf

    总之,一致性哈希算法是分布式系统中不可或缺的一部分,它通过创新的哈希映射策略,解决了数据分布的难题,提升了系统的性能和稳定性,是构建大规模分布式服务的核心技术之一。在设计和实现分布式系统时,理解并有效...

    一致性哈希算法及其在分布式系统中的应用

    ### 一致性哈希算法及其在分布式系统中的应用 #### 摘要 一致性哈希算法是一种用于解决分布式系统中节点动态变化导致的数据重新分布...在现代分布式系统的设计和实践中,一致性哈希算法已成为不可或缺的核心技术之一。

    基于一致性哈希算法的分布式数据库高效扩展方法研究.pdf

    本文针对这一问题,深入研究了一致性哈希算法在分布式数据库扩展中的应用,并提出了一种创新的扩展方法,旨在提高扩展效率,降低扩展成本,为大数据环境下的数据库管理带来新的优化方案。 一致性哈希算法最初由...

    一致性哈希算法C版实现

    一致性哈希算法是一种在分布式系统中解决数据分片和负载均衡问题的算法,它主要解决了在动态添加或移除节点时,尽可能少地改变已经存在的数据分布。在云计算和大数据处理领域,一致性哈希被广泛应用,例如在分布式...

    基于C# 实现的一致性哈希算法

    一致性哈希算法是一种分布式哈希(Distributed Hash Table, DHT)技术,它解决了在分布式环境中数据分片和负载均衡的问题。在传统的哈希算法中,如果增加或减少服务器节点,会导致大量数据重新分配,而一致性哈希...

    一致性哈希算法演示.rar

    一致性哈希算法是一种分布式哈希表(DHT)中用于解决数据分片和负载均衡问题的算法。在大型分布式系统中,例如缓存系统、分布式数据库等,一致性哈希能够确保当节点加入或离开时,尽可能少的数据需要迁移,从而保持...

    一致性哈希算法源码 Ketama一致性hash算法源码

    总的来说,Ketama一致性哈希算法是分布式系统中解决数据分布问题的重要工具,通过巧妙的设计实现了在节点变化时尽可能少的数据迁移,提高了系统的稳定性和扩展性。通过深入理解并运用这种算法,我们可以构建更加健壮...

    分布式radius系统高可用负载均衡算法的设计与实现.pdf

    综上所述,分布式RADIUS系统采用一致性哈希算法进行高可用负载均衡的设计与实现,是应对网络服务多元化、用户需求增长的必要举措。这种方法在实际部署中表现出良好的效果,满足了高性能、扁平化和精细化网络的需求,...

    一致性哈希算法应用及优化(最简洁明了的教程)

    一致性哈希算法应用及优化是IT领域中分布式系统设计的核心技术之一,特别是在处理大规模数据分布与缓存系统中,其重要性不言而喻。本文将深入探讨一致性哈希算法的基本概念、工作原理以及在实际场景中的应用和优化...

    解决分布式数据插入数据库~一致性hash算法

    一致性哈希算法(Consistent Hashing)是一种常用于分布式系统中的数据分片策略,它有效地解决了数据在多台服务器间均匀分布的问题,同时减少了因节点加入或离开时的数据迁移成本。 首先,一致性哈希的基本原理是将...

    分布式哈希表和一致性哈希

    分布式哈希表(Distributed Hash Table,简称DHT)是一种在分布式系统中用以实现大规模数据存储和快速定位的算法。DHT通过分布式的方式将数据以键值对的形式存储在各个节点上,从而实现无需中心服务器的高效数据管理...

    深入探讨一致性哈希:分布式系统中的应用与优势

    一致性哈希(Consistent Hashing)是一种特殊的哈希算法,它在分布式缓存和负载均衡等场景中被广泛应用。它通过将数据和服务器节点映射到一个哈希环上,提供了一种在节点增减时能够最小化数据重新分配的机制。本文将...

    一致性哈希算法(ketama hashing)

    一致性哈希算法(Consistent Hashing)是一种在分布式系统中实现负载均衡的算法,尤其在分布式缓存如Memcached和Redis等场景下广泛使用。它解决了传统哈希算法在节点增减时导致的大量数据迁移问题,提高了系统的可用...

    白话解析:一致性哈希算法1

    一致性哈希算法是解决分布式缓存问题的解决方案。缓存服务器数量的变化会引起缓存的雪崩,导致整体系统压力过大而崩溃。为了解决这个问题,一致性哈希算法诞生了。 在了解一致性哈希算法之前,需要了解一个经典的...

    基于Spring Boot框架的分布式缓存系统.zip

    本项目是一个基于Spring Boot框架的分布式缓存系统,采用一致性哈希算法实现数据的分布式存储和管理。系统通过虚拟节点和多种哈希算法(如CRC32、Guava的Murmur332、MD5、SHA256等)来确保数据在多个缓存节点上的...

Global site tag (gtag.js) - Google Analytics