离散哈希表
网上存储系统
有时候上传一个大文件到网盘会很快,这是怎样实现的?
新文件上传
需要确定网盘上是否已经存在相同的文件
方法
1.一般比较方法
上传新文件
遍历所有已经存储的文件
一个字节接一个字节的和每一个已存在的文件比较
如果存在和新文件相同的文件,存储该文件的链接,而不存储新文件
缺点
一定要先上传新文件
时间复杂度为O(NS),其中S为比较文件的大小,N为要比较文件的数目
2.比较哈希值
利用Rabin Karp算法先计算文件的哈希值
如果哈希值不同,对应的文件也不相同
如果已存在文件的哈希值和要上传文件的哈希值相等,上传新文件,然后直接比较
缺点
存在冲突
仍一定要需要上传新文件,并比较
仍需要和所有存在的N个文件比较
3.多个哈希值比较
选择不同的哈希函数,也就是使用不同的p或x对应的哈希函数
如果以存在的一个文件和新文件的所有哈希值都相同,那么他们是相同文件的几率非常大
这时,不再上传新文件,直接保存已存在文件的链接即可
新文件的哈希值在上传之前,在本地计算
分析
即使同时使用多个哈希值,仍可能存在冲突
存在某种算法可以找出已知函数间存在的冲突
但是发生冲突的概率会非常小,例如,使用3-5个哈希值对应一个文件时,可能某人在一生的时间里都不可能碰冲突
问题
仍需要比较已存在文件数目N次
4.预计算哈希值
在确定上传文件之前计算好哈希值
在一个哈希表里存储文件的地址和对应的哈希值
只需要在哈希表里寻找需要的哈希值,即可判断文件是否存在
5.最终方案
选择3-5个哈希函数
在一个哈希表里存储文件的地址和对应的哈希值
在上传新文件之前,在本地计算新文件的哈希值
在哈希表里寻找新文件
如果新文件对应的所有哈希值均能找到,说明网盘上已经存在该文件
那么不在上传新文件,只要保存已存在的相同文件的链接即可
问题
每天都会有上千万的文件上传
已存在文件的个数有亿万个
对于一个简单的哈希表来说,太过巨大
而且可能会有上百万的用户同时上传文件
对于一个哈希表来说,访问量会非常巨大,不能实现快速搜索和访问
解决方案——离散哈希表
使用1000台计算机
创建一个哈希表对应上述计算机
确定资源对象O属于那台计算机:h(O) mod 1000
在需要上传文件时,访问资源对应的计算机
问题
有的计算机会当机,例如,每两年计算机会损坏一次,那么1000台计算机平均每天会有一台损坏
需要存储备份信息
某些计算机脱机后,上面的资源需要重新被定位
服务增加后,可能会添加新的计算机
h(o) mod 1000 将不能在被使用
解决方案——一致性哈希
选择基数为m的哈希函数h,然后把数字从0—m-1按顺时针圆圈排放
每个对象O根据h(O)映射到圆上的一点
计算机对应的ID也根据h(comID)映射到圆上额点
每个对象资源存储在距离它最近的点对应的计算机上
减少计算机和添加计算机
当有计算机脱机,旁边的计算机获得他的数据
当有一个计算机加入,它也从旁边的计算机取得数据