2.随机返回池
3.布隆过滤器
4.一致性哈希原理
1.40亿个数出现次数最多的数
思路:
只允许1GB内存
1.遍历数组,利用哈希函数计算哈希值,再取模100
2.先把取模为0的数放到0号文件的哈希表(记录次数)中
3.循环遍历数组,依次处理1~99号文件
4.平均每次只需要用到[(2^35)/100]GB
5.使用哈希函数的目的:让值平均分布
2.随机返回池
template<typename K>
class RandomPool{
private:
map<K, int>keyIndexMap;
map<int, K>indexKeyMap;
int size;
public:
RandomPool() {
size = 0;
}
void insert(K key) {
if (keyIndexMap.find(key) == keyIndexMap.end()) {
keyIndexMap[key] = size;
indexKeyMap[size++] = key;
}
}
void deleteKey(K key) {
if (keyIndexMap.find(key) != keyIndexMap.end()) {
int deleteIndex = keyIndexMap[key];
int lastIndex = --size;
K lastKey = indexKeyMap[lastIndex];
keyIndexMap[lastKey] = deleteIndex;
indexKeyMap[deleteIndex] = lastKey;
keyIndexMap.erase(key);
indexKeyMap.erase(lastIndex);
}
}
//等概率随机返回
K getRandom() {
if (size == 0)_Throw_range_error("容器为空!");
srand((unsigned)time(NULL));
int randomIndex = rand() % size;
return indexKeyMap[randomIndex];
}
};
3.布隆过滤器
作用:通过查询黑名单,判断是否在黑名单里。还有爬虫驱虫
只需要实现加入和查询功能,空间占用少且允许一定失误率
思路:
1.创建位图:bit map。即一个位图的格子占用一个bit位
2.用基础类型实现:int[10]可储存320位信息
int arr[10];
int i=178;
//1.取第178位信息
int numIndex=178/32;//计算在哪个格子的数
int bitIndex=178%32;//计算在该数的第几位
int s=((arr[numIndex]>>(bitIndex))&1);//第178位的信息
//2.把第i位的状态改成1
arr[numIndex]=arr[numIndex]|(1<<(bitIndex));
//3.把第i位的状态改成0
arr[numIndex]=arr[numIndex]&(~(1<<bitIndex));
流程:每个URL通过k个哈希函数,对相应的位描黑,因此可能会把白判成黑,但黑一定是黑。
问题:什么时候可以用布隆过滤器
已有条件:n=样本量,p=失误率
1.看需不需要有删除行为, 2.看允不允许有失误率
样本大小无关紧要
m=-(n*lnp)/((ln2)^2)(bit)
k=ln2*(m/n)=0.7*(m/n)(个),向上取整
p真=(1-e^(-(n*k真)/m真))^k真
4.一致性哈希原理
1.解决数据服务器怎么组织的问题
2.让高频中频低频都能作数据的划分,所以要选择合适的key使其能够达到均分
3.把存储的机器连接起来形成一个哈希环,经过哈希函数后,数据按顺时针的方式选择最近的机器
4.因为机器均分环,所以数据刚好均分
5.增加机器和迁出机器的迁移量低,因为只需向顺时针的第一个机器要数据即可
6.问题:
6.1机器很少时,难把环均分
6.2增加机器后,负载不均衡
7.用虚拟节点技术解决问题:
3台机器去抢环上的点,即圈环上任一处,各机器的点各占 1/3;机器4加入时,去夺环上的点,这样夺的点中,另三台
机器的点等分,就能做到环上的点被4台机器均分;机器4下机后,也是等比例的把点归还给其他3台数据。
8.管理负载:负载能力强的机器负责更多的点