背景
一直都是在有道上用markdown记笔记,前段时间突发奇想为什么不做一个公众号。
一来是记一些随笔,二来也是督促自己学习的一个方式。
本文有关于redis缓存、布隆过滤器和数据库模型方面的知识。
缓存雪崩、缓存穿透、缓存击穿的问题
缓存雪崩
例:假如某东618做活动,00:00某个商铺有场秒杀活动,用户量大概在6 000左右,缓存每秒可以顶住5 000个请求。但是呢,在零点的时候也,缓存过期了,当时key全部失效,一下子6 000多个请求全部绕开缓存,直接打在数据库上(直接请求数据库了),这样用户体验就很差。原本从缓存中取数据,假设时间复杂度为O(1)。这样一来,用户就口吐芬芳,什么破系统,老娘不买了。
如图
处理缓存雪崩
我们可以在redis上设置key值随机过期,这样保证了同一时间,不会有大量的数据直接绕开缓存,访问数据库。
setRedis(key, value, exprTime + Math.random * num);
当然如果redis部署在集群上(redis cluster),热点数据分布在不同主机,同样可以避免同一时间key值失效。
缓存穿透、缓存击穿
缓存穿透
指的是原本数据库中没有数据,而用户不断访问,而缓存中无法读到对应的数据,直接访问数据库。这点,好比黑客攻击,假设我们Key值设定的是自增类型的int,从0到5 000,但是黑客一直拿着-1或者5 000+去访问,那肯定获取不到数据。不断的攻击导致服务器压力过大。
解决一:
我们在提供接口时,要有种“不信任的新”,要做鉴权校验,不符合的直接return。
还有一个是,当一个黑客每秒访问量超过预设的阈值,比如说某IP我设定它每秒钟访问10次,那么超过这个次数,我们就拉黑。
解决二:
布隆过滤器
简而言之,我们通过这种数据结构,去判断,当不存在的时候我们直接return,存在才去取数据。
在了解布隆过滤器之前,首先要知道HashMap,简单的来说,对于一个key:value,他们是怎样存储的呢?首先要准备一个哈希函数H()和一个散列表ht(数组),值是怎样存储的呢?
ht[H(key)] =value
当然,会出现一些哈希冲突的问题,这里就不深入了。
布隆过滤器的结构
布隆过滤器是一个bit向量或者说是bit数组,长成这样:
对于一个值,比如说0到 5 000要映射到布隆过滤器,我们需要使用多个Hash函数,生成hashCode,然后将值打在布隆过滤器上,存在的话,就将对应的bit设置成1,不存在设置成0。手写一个简单的布隆过滤器:
private BloomFilter( int initSize) { bitSet = new BitSet( initSize); } private static BitSet bitSet; public static void Instance( int initSize = MAX_LEN) { if( 0 == bitSet.size() ) { BloomFilter(initSize); } } public void add( int key) { int location1 = Math.abs(hash1(key)); int location2 =Math.abs(hash2(key)); int location3 = Math.abs(hash3(key)); bitSet.set( location1); bitSet.set( location2); bitSet.set( location3); } public bool contains(int key) { int location1 = Math.abs(hash1(key)); int location2 = Math.abs(hash2(key)); int location3 = Math.abs(hash3(key)); return bitSet.get(location1) && bitSet.get(location2) && bitSet.get(location3) ; } private: int hash1(Integer key) { return key.hashCode(); } int hash2(Integer key) { return key.hashCode()^(key.hashCode()>>3); } int hash3(Integer key) { return key.hashCode()^(key.hashCode()>>16); } }public class BloomFilter{
缓存击穿
就是对于某个热点数据,它的单个的并发量很大,突然间,他失效了,导致,很多数据一下子全部访问了数据库。
我们可以设置热点数据永不过期或者是加锁。
如果觉得《缓存击穿 穿透 雪崩_缓存雪崩 缓存穿透 缓存击穿的问题》对你有帮助,请点赞、收藏,并留下你的观点哦!