图片来自宝兔网本文将介绍Bloomfilter,以空间换时间,以更低的内存空间高效解决这个问题。性能不够,用缓存来弥补。现在,年轻人喜欢在网上购物。没事的时候可以去淘宝逛一逛,买点自己喜欢的,释放一下工作压力。地址:https://detail.tmall.com/item.htm?id=628993216729上图为天猫iPhone12商品详情页,id为商品序列号。我们都知道淘宝的访问量是非常高的。为了提高系统的吞吐量,做了很多性能优化。其中最重要的一点是将信息异构存储到缓存中。有句话说得好:性能不够,缓存可以弥补。但是,在使用缓存的时候,我们要注意一个重要的问题。如果缓存没有命中怎么办?缓存不命中怎么办?如上图所示:我们首先查询缓存,判断缓存中是否有数据。如果有数据,直接返回。如果cache为Empty,则需要再次查询数据库,将数据格式异构化,然后预热到buffer中,然后返回结果。注:步骤③存在风险漏洞。如果缓存中的数据不存在,压力就会转移到数据库中。如果被竞争对手利用进行无效请求流量攻击,瞬间向数据库发送大量请求,对系统性能影响很大,很容易挂掉数据库。这种现象称为缓存穿透。那么如何应对缓存穿透呢?我们的思路是在缓存中判断这个数据库值是否存在。如果真的不存在,直接返回,避免数据库查询。由于不存在是无限边界,我们采用反向策略来建立对现有值的有效检索。每次缓存一个值时,首先执行一次空搜索。简单总结一下,这个框架的要求是:检索速度快,内存空间非常小经过研究,我们发现Bloomfilters满足了以上两个条件。什么是布隆过滤器?BloomFilter是Bloom在1970年提出的,它实际上是一个长二值向量和一系列随机映射函数。布隆过滤器可用于检索元素是否在集合中:优点:空间效率和查询时间远超一般算法。缺点:有一定的误识别率,删除难度大。布隆过滤器是如何构造的?布隆过滤器本质上是一个n位的二进制数组,由0和1表示。以商品为例,共有三种商品,商品编码分别为id1、id2、id3。①首先对id1进行3次哈希,确定其在二进制数组中的位置。三个哈希,对应的二进制数组下标分别为2、5、8,将原始数据从0变为1。②对id2进行3次哈希,确定其在二进制数组中的位置。三个哈希,对应的二进制数组下标分别为2、7、98,将原来的数据从0变为1。下标2已经被之前的操作设置为1,所以这次认为是哈希碰撞,并没有需要改变。哈希规则:如果哈希后原位为0,则由0变为1;如果该位本身为1,则保持不变。如何使用布隆过滤器?如下图所示:与初始化过程类似。在查询商品的缓存信息时,首先要判断商品是否存在:通过三个哈希函数计算商品id的哈希值,然后在Bloom数组中查找并访问对应的位值,判断是否为0或者1,只要这三个值有一个不为1,那么我们就认为数据不存在。注意:布隆过滤器只能准确判断数据是否缺失。只能说是数据存在的可能,因为存在Hash冲突。当然,这个概率很低。如何减少布隆过滤器的误判?①增加二进制位数组的长度。这样数据经过散列后会更加离散,发生冲突的概率会大大降低。②变相增加哈希数,增加数据特征。特征越多,冲突的概率越低。布隆过滤器会不会消耗大量内存?带着疑惑,我们来做个实验:假设有1000万条数据,我们需要记录是否存在。如果存在则标记为1,如果不存在则标记为0。在技术选型上,框架使用了Redis的BitMap存储。数据初始化预热代码:redisTemplate.executePipelined(newRedisCallback
