哈希算法地原理就是将任意长度地二进制值串映射为固定长度地二进制值串,映射规则就是哈希算法;
哈希算法需要满足地要求:
常用于加密的哈希算法是MD5(MD5:Message-Digest Algorithm,消息摘要算法)和SHA(Secure Hash Algorithm,安全散列算法),除此之外还有很多其它加密算法,比如DES(Data Encryption Standard,数据加密标准)、AES(Advanced Encryption Standard,高级加密标准;
对于安全加密来说,很难根据哈希值反向推导出原始数据和散列冲突的概率要很小,这两点特性很重要;
像MD5,有2^128个不同的哈希值,所以散列冲突的概率是很小的;
在海量的图片中,搜索一张图片是否存在,不可能仅仅只靠图片的名称等信息来比对;那就可以通过哈希算法给每张图片
取一个唯一标识,例如:对于一张图片,可以从图片的二进制码串分别在开头 中间 结尾各取100个字节,将300个字节放在一起,采用哈希算法生成一个哈希字符串,用来作为图片的唯一标识;
可以把图片的唯一标识和相应的图像文件在图库中的路径信息,都存储在散列表中,极大的提高了查找的效率。
BT下载的原理是基于P2P的,从很多机器上并行下载一个几个G的大文件,这个文件会被划分为许多文件块,下载完之后在组成一个完整的文件即可。
但是网络传输不安全也不稳定,如何确定自己下载的文件块是否经过恶意修改的呢?
可以采用哈希算法进行数据校验,对划分为许多块的文件分别取哈希值,哈希值对数据很敏感,只要文件块的内容篡改一点,得到的哈希值就会完全不同;在对于下载好的文件计算哈希值,在与种子文件中保存的哈希值进行比对,如果不同则说明数据已被篡改,需要重新下载。
散列函数是设计一个散列表的关键,直接决定了散列冲突的概率和散列表的性能
,散列函数的设计追求简单高效;
我们如何在对于同一个客户端,在一次会话中的所有请求都路由到同一个服务器中;
最简单的方法就是维护一张映射表,保存客户端IP地址与服务器编号之间的映射关系;
弊端:
借助哈希算法,对于客户端IP地址或者会话ID计算哈希值,将取出的哈希值与服务器列表大小进行取模运算,最终得到的值就是被路由到的服务器编号;这样就可以把同一个IP过来的所有请求,都路由到同一个后端服务器上;
日志文件中包含许多搜索关键词,没法放到一台机器的内存中。同时,一台计算机处理时间会很长;
为此可以先进行数据分片,然后采用多台机器处理,提高处理速度;思路:
采用n台机器并行处理,从搜索记录的日志文件中,依次读出每个搜索关键词,并且通过哈希函数来计算哈希值,然后再跟n取模,得到的值就是应该被分配到的机器编号;
那么哈希值相同的搜索关键词就会被分配到同一台机器上,每个机器会分别计算出关键词出现的次数,然后合并起来就是最终得到的结果。
对于海量的图库,同样可以先对数据进行分片,采用多机处理。准备n台机器,让每台机器只维护某一部分图片对应的散列表。我们从图库中读取一个图片,计算出唯一标识,然后与机器个数n求余取模,得到的值就是机器编号,将这个图片的唯一标识和图片路径发往对应的机器构建散列表;
当判断一张图片是否再图库中时,采用同样的哈希算法,计算出唯一标识,在与机器个数n取模,假设得到的值为k,那就去编号为k的机器构建的散列表中查找;
面对海量的数据,为了提升对于数据的读写能力,一般都采用分布式的方式来存储数据,分布式缓存;
那么如何决定将哪个数据放到哪台机器上?
我们可以借助前面数据分片的方式,通过哈希算法对数据取哈希值,然后在对机器个数取模,最终得到应该缓存的机器编号;
随着数据量的增大,原来的10台机器已经无法承受了,就需要进行扩容,但不仅仅是简单增加机器就可以的,原先是与10取模计算编号,现在是与11取模进行编号计算;
如果所有的数据都要重新计算哈希值,然后再重新将数据搬移到正确的机器中;这个时候数据库中的所有数据一下子都失效了,就会穿透缓存,直接去请求数据库,就会发生雪崩效应,压垮数据库;
可以采用一致性哈希算法:
假设我们有k个机器,数据哈希值的范围是[0,MAX],我们将整个范围划分成m个小区间,每个机器负责m/k个小区间,当有新的机器加入的时候,我们就将某几个小区间的数据,从原来的数据中搬移到新的机器中,这样既不用全部重新哈希、搬移数据,也保持了各个机器数据数量的均衡;
三言两语说不完,回头我在补充!