布隆过滤器
-
使用场景:
-
可以应用来推荐系统中,过滤掉用户已经看到的内容。
-
用户请求数据库数据时,可以先通过布隆过滤器,过滤掉对不存在数据的请求,减轻数据库的压力。
-
在项目的多级缓存之上,可以添加一个布隆过滤器,防止用户对不存在的数据的请求直接打到数据库上。
-
爬虫系统中,对URL去重。
-
-
布隆过滤器的原理:
-
是使用了一个大型的位数组和几个不同的的hash函数。
-
向布隆过滤器添加key时,会使用多个hash函数对key进行hash算得一个整数再对数组长度进行取模运算得到一个位置,每个hash函数都会算得一个位置,再把位数组的这几个位置都置为1就完成了添加key操作。
-
向布隆过滤器中查找key是否存在时,也要使用多个hash函数和取模运算得出在数组中的位置,看数组中这几个位置是否都是1,只要有1个位置为0,那么这个key一定不存在。如果都是1,这个key极有可能存在,因为这些位置为1也可能是因为其他key导致的。布隆过滤器判断某个值存在,这个值可能存在可能不存在,布隆过滤器判断某个值不存在,这个值一定不存在。
Scan
- scan 的遍历顺序非常特别。它不是从第一维数组的第 0 位一直遍历到末尾,而是采用 了高位进位加法来遍历。之所以使用这样特殊的方式进行遍历,是考虑到字典的扩容和缩容 时避免槽位的遍历重复和遗漏。
- 假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 以某个固定的已知的前缀开头,可以使用 scan 指令无阻塞的提取出指定模式的 key 列表,但是会有一定的重复率,需要在客户端去重。
- 如果观察到 Redis 的内存大起大落,这有可能是大 key 导致的,因为 key 太大的话会导致数据迁移时出现卡顿,而且扩容时,会一次性申请更大的内存,导致卡顿。删除这个大 key 时,内存会一次性回收,卡顿现象会再次发生。解决方法是需要定位出具体哪个是大 key,进一步定位出具体的业务来源,然后修改相关业务代码的设计。可以采用 scan 指令进行扫描,type 指令获取 key 的类型,然后使用类型对应的 size 方法得到 key 的大小,将前几名作为扫描结果展现出来,这样就查到最大的几个 key 了。
- 原理: Scan 采用的是高位进位加法来做的遍历,高位进位加法指的是从左边加,进位时往右边移动,比如 0110,通过高位进位加法加 1 后变成 1110 。而普通进位加法是 0110 变成 0111。这样做是为了防止重复遍历,比如数组长度由 16 位扩容到 32 位,那么 6 号槽位,也就是 0110 会被 rehash 到新数组的 0110 和 1110 位置,也就是 6 号和 14 号槽位,然后就从 0110 这个槽位还是往后遍历,下一个就是高位加 1 的 1110。
GeoHash
- GeoHash 算法将二维的经纬度数据映射到一维的整数,这样所有的元素都将在挂载到一 条线上,距离靠近的二维坐标映射到一维后的点之间距离也会很接近。当我们想要计算「附 近的人时」,首先将目标位置映射到这条线上,然后在这个一维的线上获取附近的点就行 了。
- 大致的映射方法是将二维平面划分成一系列正方形的方格,所有地图坐标放置在唯一的一个方格中,每个正方形方格可以标记为 00,01,10,11 四个二进制整数,通过这种方式编码后每个地图元素就会变成一个整数了。它内部存储采用的是 zset 结构,通过 zset 的 score 排序就可以得到坐标附近的其他元素了。