哈希函数的应用场景(散列表、布隆过滤器、分布式一致性哈希)

哈希函数的应用场景

本文主要介绍哈希函数的常见应用场景,包括散列表、布隆过滤器以及分布式一致性哈希。

散列表(哈希表)

哈希函数的性质

哈希函数是一种映射函数Hash(key)=addr
通过对哈希地址进一步映射(通常是取余),得到相对应的索引
思考:通过对哈希地址进一步映射可以看作是进一步的哈希函数,例如(hash2(key)=hash1(key)%size)
哈希函数可能使不同的key映射到同一个地址(索引),这种情况称为哈希冲突
哈希函数可能使不同的key得到相同的索引(可能是相同或不同的哈希地址),这种情况成为哈希冲突
注明:哈希函数的定义有点混乱,有人说得到哈希码是哈希函数,有人说得到索引值是哈希函数,这边采用第一种定义了

选择哈希函数

  1. 计算速度快
  2. 强随机分布性
  3. 通常选择murmurhash2、siphash、cityhash

负载因子

用于形容散列表的存储密度,计算方式为数据存储元素的个数/数据长度;负载因子越小,冲突越小。负载因子越大,冲突越大。

散列表数据存储

散列表通常使用一个数组来存储元素,在没有哈希冲突的情况下,便将数据存放在数组索引为hash(key)%size的地方

解决散列表中的哈希冲突

负载因子在合理范围内(0.1size<used<size):

  1. 链表法
  2. 开放寻址法

负载因子不在合理范围内(used<0.1size)或(used>size):

  1. 缩容或者扩容,然后进行再哈希

散列表的应用

STL容器中:

  1. unordered_set
  2. unordered_map
  3. unordered_multiset
  4. unordered_multimap

与此同时,为了实现迭代器,同时将结点串成一个单链表

散列表与平衡二叉树对比:

平衡二叉树通过对key值比较,结构有序来提升搜索效率
散列表得到key与存储结点位置的映射关系

布隆过滤器

背景

内存有限,只需要确定某个key存不存在,而不需要具体的数据。

布隆过滤器与散列表对比

散列表通常使用数组存储元素,并只有一个哈希函数

布隆过滤器通常使用位图存储元素,并有多个哈希函数

布隆过滤器数据存储

位图

在这里插入图片描述

多个哈希函数

在这里插入图片描述
由上图可得布隆过滤器不支持删除操作

判断数据(key)存在

当通过哈希函数找到索引位置时

  1. 只要有一个为0,就一定不存在
  2. 如果都为1,不一定存在,但可以对概率(假阳率)进行控制

布隆过滤器参数配置

在这里插入图片描述
使用布隆过滤器时,往往先确定n和p,进而得到m和k

分布式一致性哈希

用途

解决分布式缓存扩容的问题(缓存失效)
在这里插入图片描述

改进

改进1

如下图所示,对结点和键值都使用哈希函数,并且取相同的模,称为固定算法。采用顺时针查找(例如k1放到192.168.1.101)。当这时添加一个新的结点时(192.168.1.103),只有在192.168.1.102与192.168.1.103映射的索引这段范围的键值会发生缓存失效,只是局部的缓存失效。这时,要将这段范围存储的键值与数据从192.168.1.100迁移到192.168.1.103,称为哈希迁移。这样便可以避免缓存失效了。
在这里插入图片描述

改进2

上述方法有个问题,当结点数较少时,可能有点结点会存储大量数据而有的结点存储少量的数据,相对应的哈希迁移数据量也差异较大,称为哈希偏移

通过增加虚拟结点,可以解决哈希偏移问题,如下图所示
在这里插入图片描述

总结

分布式一致性哈希通过固定算法数据迁移避免了缓存失效
分布式一致性哈希通过虚拟结点保证数据均衡

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值