【Redis】实战详解

Redis

  • 前言
  • redis 简介
  • Redis 应用场景
    • 分布式锁
    • 计数器(string)
    • 分布式全局唯一id(string)
    • 消息队列(list)
    • 点赞,签到,收藏
    • 热点数据
    • 排行榜
  • 内存淘汰策略
    • 默认淘汰策略
    • LRU淘汰策略
    • TTL淘汰策略
    • Random 淘汰策略
  • Redis的持久化策略
  • Redis 缓存问题
    • 缓存雪崩
      • 如何解决缓存雪崩
    • 缓存穿透
      • 如何解决缓存穿透

前言

想必大家在做项目的时候一定接触过或者用过Redis,对于Redis也有了一定的了解,那么这篇文章就介绍一下redis的应用场景及其原理。

redis 简介

redis是一个以高性能、基于内存和单线程实现的数据库系统。 由于其高性能的特性,redis始终被用作缓存。并且它采用的是单线程的KV模型;

Redis 应用场景

分布式锁

计数器(string)

分布式全局唯一id(string)

消息队列(list)

点赞,签到,收藏

热点数据

排行榜

内存淘汰策略

Redis提供的内存淘汰策略有如下几种:

默认淘汰策略

noeviction 不会继续服务写请求 (DEL 请求可以继续服务),读请求可以继续进行。这样可以保证不会丢失数据,但是会让线上的业务不能持续进行。

LRU淘汰策略

volatile-lru 尝试淘汰设置了过期时间的 key,最少使用的 key 优先被淘汰。没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。(这个是使用最多的)

allkeys-lru 区别于 volatile-lru,这个策略要淘汰的 key 对象是全体的 key 集合,而不只是过期的 key 集合。这意味着没有设置过期时间的 key 也会被淘汰。

TTL淘汰策略

volatile-ttl 跟上面一样,除了淘汰的策略不是 LRU,而是 key 的剩余寿命 ttl 的值,ttl 越小越优先被淘汰。

Random 淘汰策略

volatile-random 跟上面一样,不过淘汰的 key 是过期 key 集合中随机的 key。

allkeys-random 跟上面一样,不过淘汰的策略是随机的 key。allkeys-random 跟上面一样,不过淘汰的策略是随机的 key。

Redis的持久化策略

Redis的数据是存在内存中的,如果Redis发生宕机,那么数据会全部丢失,因此必须提供持久化机制。

Redis 的持久化机制有两种,第一种是快照(RDB),第二种是 AOF 日志快照是一次全量备份,AOF 日志是连续的增量备份。 快照是内存数据的二进制序列化形式,在存储上非常紧凑,而 AOF 日志记录的是内存数据修改的指令记录文本。AOF 日志在长期的运行过程中会变的无比庞大,数据库重启时需要加载 AOF 日志进行指令重放,这个时间就会无比漫长。所以需要定期进行 AOF 重写,给 AOF 日志进行瘦身。

RDB是通过Redis主进程fork子进程,让子进程执行磁盘 IO 操作来进行 RDB 持久化,AOF 日志存储的是 Redis 服务器的顺序指令序列,AOF 日志只记录对内存进行修改的指令记录。即RDB记录的是数据,AOF记录的是指令

Redis 缓存问题

缓存雪崩

假设有如下一个系统,高峰期请求为5000次/秒,4000次走了缓存,只有1000次落到了数据库上,数据库每秒1000的并发是一个正常的指标,完全可以正常工作,但如果缓存宕机了,每秒5000次的请求会全部落到数据库上,数据库立马就死掉了,因为数据库一秒最多抗2000个请求,如果DBA重启数据库,立马又会被新的请求打死了,这就是缓存雪崩。

如何解决缓存雪崩

  • 事前:redis高可用,主从+哨兵,redis cluster,避免全盘崩溃
  • 事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL被打死
  • 事后:redis持久化,快速恢复缓存数据

缓存穿透

假如客户端每秒发送5000个请求,其中4000个为黑客的恶意攻击,即在数据库中也查不到。举个例子,用户id为正数,黑客构造的用户id为负数,
如果黑客每秒一直发送这4000个请求,缓存就不起作用,数据库也很快被打死。

如何解决缓存穿透

查询不到的数据也放到缓存,value为空,如set -999 “”

总而言之,缓存雪崩就是缓存失效,请求全部全部打到数据库,数据库瞬间被打死。缓存穿透就是查询了一个一定不存在的数据,并且从存储层查不到的数据没有写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

你可能感兴趣的:(#,redis,redis,缓存,java)