# 内存溢出

内存溢出(out of memory): 是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出

内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

# 内存泄露

内存泄露(memory leak): 是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但是内存泄露堆积后果很严重,无论多少内存,迟早会被占光

# 缓存穿透

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会被打到数据库上。即这个数据根本不存在,如果黑客攻击时,启用很多个线程,一直对这个不存在的数据发送请求,那么请求就会一直打到数据库上,很容易将数据库打崩

# 解决方案

  1. 缓存空对象

    优点:实现简单,维护方便
    缺点: 额外的内存消耗,因为缓存了一些瞎编的id对应的空对象,但是可以通过给对象设置TTL解决,但是会造成短期的数据不一致

  2. 布隆过滤器

    优点:内存占用少
    缺点: 实现复杂,存在捂盘

  3. 其他

    使用bitmaps类型定义访问白名单,或进行实时监控和运维人员配合排查访问对象和访问数据设置黑名单限制服务

# 缓存击穿

缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个key有大量的并发请求过来,从而大量的请求打到db,属于常见的热点问题

# 解决方案

  1. 预先设置热门数据,提前存入缓存
  2. 实时监控热门数据,调整key过期时长
  3. 二级缓存:对于热点数据进行二级缓存,并对于不同级别的缓存设置不同的失效时间
  4. 设置分布式锁

# 缓存雪崩

大量的应用请求无法在Redis缓存中进行处理,紧接着应用将大量请求发送到数据库层,导致数据库层的压力激增,击穿与雪崩的区别在于击穿是对于特定的热点数据来说,而雪崩是全部数据

# 原因一:缓存中有大量key同时过期,导致大量请求无法得到处理,大量数据需要回源数据库

# Redis实例发生故障宕机,无法处理请求,就会导致大量请求挤压到数据库底层

# 资料

什么是内存泄漏?内存溢出? (opens new window)

缓存穿透,缓存击穿,缓存雪崩详解 (opens new window)