3.3 数据校验
P2P下载,从多个机器并行下载一个2G电影,该电影文件可能被分割成很多文件块。等所有的文件块都下载完成之后,再组装成一个完整的电影文件就行了。
网络传输是不安全的,下载的文件块有可能是被宿主机器恶意修改过的,又或者下载过程中出现了错误,所以下载的文件块可能不是完整的。如果没有能力检测这种恶意修改或者文件下载出错,就会导致最终合并后的电影无法观看,甚至导致电脑中毒。
如何校验文件块的安全、正确、完整?
使用哈希算法对100个文件块分别取哈希值,并保存在种子文件。
只要文件块内容有丁点改变,最后哈希值就完全不同。
所以,当文件块下载完成后:
- 使用相同哈希算法对下载好的文件块逐一求哈希
- 对比种子文件中的哈希值:
- 若不同
说明该文件块不完整或被篡改,重新从其它宿主机器下载该文件块
3.4 Hash函数
该场景:
- 对hash算法冲突的要求较低,偶尔hash冲突问题不大
- 也不关心hash函数对于hash算法计算得到的值,是否能反向解密
hash函数中用到的hash算法,更加关注hash后的值是否能均匀分布。
hash函数执行的快慢,也影响hash表的性能,所以,hash函数用的hash算法一般较简单,追求效率。
哈希算法还能解决很多分布式问题。
3.5 负载均衡
实现一个会话粘滞(session sticky)负载均衡算法,需在同一客户端上,在一次会话中的所有请求都路由同一服务器。
最直接的维护一张映射关系表:
客户端IP地址或会话ID =》服务器编号的映射关系
客户端发出的每次请求,先映射表查找路由的服务器编号,再请求对应服务器。
简单直观,但:
- 客户端很多
映射表可能会很大,比较浪费内存空间 - 客户端下线、上线,服务器扩容、缩容都会导致映射失效
维护映射表的成本很大
借助哈希算法即可解决:对客户端IP地址或会话ID计算哈希值,与服务器列表的大小取模,最终得到的值即被路由到的服务器编号。
这就可以把同一IP过来的所有请求,都路由到同一后端服务器。
3.6 数据分片
统计关键词
假如1T日志文件,这里面记录了用户的搜索关键词,快速统计出每个关键词被搜索的次数。
这个问题有两个难点:
- 搜索日志很大,没法放到一台机器的内存
- 如果只用一台机器来处理这么巨大的数据,处理时间会很长。
可以先对数据进行分片,然后采用多台机器处理提高处理速度:
用n台机器并行处理:
- 从搜索记录的日志文件依次读出每个搜索关键词
- 通过哈希函数计算哈希值
- 再跟n取模
- 得到应该被分配到的机器编号
哈希值相同的搜索关键词就被分配到了同一个机器上。即同一个搜索关键词会被分配到同一个机器上。每个机器会分别计算关键词出现的次数,最后合并起来就是最终的结果。
MapReduce的基本思想。