U8国际 U8国际官方网站 体育APP下载分布式哈希表DHT
栏目:U8哈希 发布时间:2026-02-20
  u8,u8国际,u8国际官方网站,u8国际网站,u8国际网址,u8国际链接,u8体育,u8体育官网,u8体育网址,u8注册,u8体育网址,u8官方网站,u8体育APP,u8体育登录,u8体育入口   (distributed hash table,缩写DHT)是分布式计算系统中的一类,用来将一个键(key)的集合分散到所有在分布式系

  u8,u8国际,u8国际官方网站,u8国际网站,u8国际网址,u8国际链接,u8体育,u8体育官网,u8体育网址,u8注册,u8体育网址,u8官方网站,u8体育APP,u8体育登录,u8体育入口

U8国际 U8国际官方网站 U8体育APP下载分布式哈希表DHT

  (distributed hash table,缩写DHT)是分布式计算系统中的一类,用来将一个键(key)的集合分散到所有在分布式系统中的节点。这里的节点类似哈希表中的存储位置。分布式哈希表通常是为了拥有大量节点的系统,而且系统的节点常常会加入或离开。

  研究分布式哈希表的主要动机是为了开发点对点系统,像是Napster、Gnutella、BitTorrent及Freenet。这些系统使用分散在互联网上的各项资源以提供文件分享服务,特别在带宽及硬盘存储空间上受益良多。

  这些系统使用不同的方法来解决如何找到拥有某数据的节点的问题。Napster使用中央的索引服务器:每个节点加入网络的同时,会将他们所拥有的文件列表发送给服务器,这使得服务器可以进行搜索并将结果回传给进行查询的节点。但中央索引服务器让整个系统易受攻击,且可能造成法律问题。于是,Gnutella和相似的网络改用大量查询模式(flooding query model):每次搜索都会把查询消息广播给网络上的所有节点。虽然这个方式能够防止单点故障(single point of failure),但比起Napster来说却极没效率。

  最后,Freenet使用了完全分布式的系统,但它建置了一套使用经验法则的基于键的路由方法(key based routing)。在这个方法中,每个文件与一个键相结合,而拥有相似键的文件会倾向被相似的节点构成的集合所保管。于是查询消息就可以根据它所提供的键被路由到该集合,而不需要经过所有的节点。然而,Freenet并不保证存在网络上的数据在查询时一定会被找到。

  分布式哈希表为了达到Gnutella与Freenet的分散性(decentralization)以及Napster的效率与正确结果,使用了较为结构化的基于键的路由方法。不过分布式哈希表也有个Freenet有的缺点,就是只能作精确搜索,而不能只提供部分的关键字;但这个功能可以在分布式哈希表的上层实现。

  要达到以上的目标,有一个关键的技术:任一个节点只需要与系统中的部分节点沟通,当成员改变的时候,只有一部分的工作(例如数据或键的发送,哈希表的改变等)必须要完成。

  分布式散列表的结构可以分成几个主要的组件。其基础是一个抽象的键空间(keyspace),例如说所有160位长的字符串集合。键空间分区(keyspace partitioning)将键空间分区成数个,并指定到在此系统的节点中。而延展网络则连接这些节点,并让他们能够借由在键空间内的任一值找到拥有该值的节点。

  假设键空间是一个160位长的字符串集合。为了在分布式散列表中存储一个文件,名称为filename且内容为data,我们计算出filename的SHA1散列值——一个160位的键k——并将消息put(k,data)送给分布式散列表中的任意参与节点。此消息在延展网络中被路由,直到抵达在键空间分区中被指定负责存储关键值k的节点。而(k,data)即存储在该节点。其他的节点只需要重新计算filename的散列值k,然后提交消息get(k)给分布式哈希表中的任意参与节点,以此来找与k相关的数据。此消息也会在延展网络中被路由到负责存储k的节点。而此节点则会负责传回存储的数据data。

  我们将散列表放在一个机器的内存里,当散列表比较小时候,没有问题,但如果这张散列表超过了一台机器的内存时候,或者当存储在一台机器上时候,这台机器挂掉了,那所有的数据都会消失……那现在我们又该怎么做呢?这便需要引入DHT来处理这种情况了,说白了就是将一张哈希表分割在不同的机器上。首先,将上面所说的散列空间0,1...9想像成一个首尾相衔的环,9之后又重新回到零,假设,这就是十台机器。这样我们根据散列算法就可以将不同的学生映射到不同的机器上,实现了数据的分布。

  上面我们使用DHT实现了数据的分布式存储,但再考虑深一层,分布式架构中,节点的故障是不可避免的,当添加和删除某一节点了,会导致大量散列数据失效,需要重新散列。影响非常大,那我们用什么哈希算法来实现DHT才能尽量的避免这种情况呢,这便说到了一致性哈希。consistent hashing 是一种 hash 算法,简单的说,在移除 / 添加一个 cache 时,它能够尽可能小的改变已存在 key 映射关系。刚刚我们把学生散列到了hash数值空间里,现在我们需要的是,同时将机器也散列在这个hash空间,让学生和机器的散列值同处在一个数值空间。

  如上图所示,如果我们将学生和机器同时散列在一个环中,那么假设小张散列后的值为6,我们顺时针寻找,寻找到的第一台机器,则将小张放入其中。依次类推,则得到:小王——机器一小明——机器二小红——机器三小张——机器四假设我们机器三失效了,那这时候影响到的仅仅是小红,重新散列到机器四中。而如果重新加入一台新的机器,影响到的也仅仅是旁边的一台机器,这样便解决了添加删除机器时候的震荡问题,这便是一致性hash的大致思想。

  : 将哈希表分散在不同的节点上,并且能提供相应的方法来查找, 比如DHT算法

  : 当节点宕机或者扩容的时候,需要重新哈希,一致性哈希实现的 DHT 避免对大量的数据重新哈希, 比如Chord DHT). 所以一致性哈希是 DHT 的一种实现,避免在节点变化的时候出现的全部重新哈希的现象. 我不知道为什么wikipedia没有列出memcached client中常用的libketama,在我看来它也是一个易于理解的一致性哈希的实现。

  Kademlia是一种通过 DHT 的协议算法,它是由Petar和David在2002年为P2P网络而设计的。Kademlia规定了网络的结构,也规定了通过节点查询进行信息交换的方式。Kademlia网络节点之间使用UDP进行通讯。参与通讯的所有节点形成一张虚拟网(或者叫做覆盖网)。这些节点通过一组数字(或称为节点ID)来进行身份标识。节点ID不仅可以用来做身份标识,还可以用来进行值定位(值通常是文件的散列或者关键词)。

  当我们在网络中搜索某些值(即通常搜索存储文件散列或关键词的节点)的时候,Kademlia算法需要知道与这些值相关的键,然后逐步在网络中开始搜索。每一步都会找到一些节点,这些节点的ID与键更为接近,如果有节点直接返回搜索的值或者再也无法找到与键更为接近的节点ID的时候搜索便会停止。

  这种搜索值的方法是非常高效的:与其他的分布式哈希表的实现类似,在一个包含n个节点的系统的值的搜索中,Kademlia仅访问O(log(n))个节点。

  Kademlia简称为Kad,它使用了一个精妙的算法,来计算节点之间的距离 (这里的距离不是地理空间的距离,而是路由的跳数),这个算法就是XOR操作(异或),因为这个操作和距离的计算类似。

  Kad使用160位的哈希算法(比如 SHA1),完整的 key 用二进制表示有160位,可以说是不计其数了。Kad把 key 映射到一个二叉树,每一个 key 都是这个二叉树的叶子。