Telehash (JSON + UDP + DHT = Freedom )

分布式哈希表(DHT)

普通的Hash方式

普通的Hash的特点:

  • 创建哈希表(HashMap)需要先指定大小,即默认创建一个能够存储多少个元素的哈希表。

  • 当不断地向HashMap中添加元素时,HashMap越来越满,当添加的元素达到了装载因子乘以表长时,就需要扩容了。扩容时,原来已经映射到哈希表中的某个位置(桶)的元素需要重新再哈希,然后再把原来的数据复制到新的哈希表中。

对于普通的哈希表而言,扩容的代价是很大的

例子

普通的Hash计算地址方式如下:Hash(Key)%M,

假设哈希函数为 hash(x)=x ,哈希表的长度为5(有5个桶)。

  1. key=6时,hash(6)%5 = 1,即Key为6的元素存储在第一个桶中
  2. key=7时,hash(7)%5 = 2,即Key为7的元素存储在第二个桶中
  3. Key=13时,hash(13)%5=3,即Key为13的元素存储在第三个桶中

假设现在hash表长度扩容成8,那么Key为6,7,13 的数据全都需要重新哈希。

  1. key=6时,hash(6)%8 = 6,即Key为6的元素存储在第六个桶中
  2. key=7时,hash(2)%8 = 7,即Key为7的元素存储在第七个桶中
  3. Key=13时,hash(13)%8=5,即key为13的元素存储在第五个桶中

从上可以看出:扩容之后,元素的位置全变了。比如:Key为6的元素原来存储在第一个桶中,扩容之后需要存储到第6个桶中。

因此,这是普通哈希的一个不足:扩容可能会影响到所有元素的移动。这也是为什么:为了减少扩容时元素的移动,总是将哈希表扩容成原来大小的两倍的原因。因为,有数学证明,扩容成两倍大小,使得再哈希的元素个数最少。(?)

一致性哈希方式

在分布式系统中,节点的宕机、某个节点加入或者移出集群是常事。对于分布式存储而言,假设存储集群中有10台机子,如果采用Hash方式对数据分片(即将数据根据哈希函数映射到某台机器上存储),哈希函数应该是这样的:hash(file) % 10。

根据上面的介绍,扩容是非常不利的,如果要添加一台机器,很多已经存储到机器上的文件都需要重新分配移动,如果文件很大,这种移动就造成网络的负载

因此,就出现了一种一致性哈希的方式。一致性哈希,其实就是把哈希函数可映射的空间(相当于普通哈希中桶的数目是固定的)固定下来了,比如固定为: 2n1 ,并组织成环的形状。

每个机器对应着一个n位的ID,并且映射到环中。每个查询键,也是一个 n 位的ID,节点的ID和查询键对应着相同的映射空间。

Each node choose a n-bit ID
// ID是随机的,所以所有的node是随机分布在环上
  Intention is that they be random Though probably a hash of some fixed info IDs are arranged in a ring
// key的哈希跟ID属于同一个域内,也是分布在同一个环上
Each lookup key is also a n-bit ID
   I.e., the hash of the real lookup key
   Node IDs and keys occupy the same space!

例子

如下图:有四台机器映射到固定大小为

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值