Skip to content

Redis入门_Redis实战篇

参考: https://cyborg2077.github.io/2022/10/22/RedisPractice/

视频内容: https://www.bilibili.com/video/BV1cr4y1671t/

结合文章一起看一下

后续再跟进一下,这里记录的其实还挺好的,需要花费一段时间看一下

短信登录

Session 方案

  • 1、单体的话进行登录校验的话,一般会使用 session 会话的方式,

大体的流程

这里使用了 用户信息存放到 ThreadLocal 的操作,

image.png

用户信息返回的时候一般会使用 vo 对象,将 User 和 UserVo 对象做一个转换,避免将敏感信息泄漏

使用 共享 session 会存在的问题

image.png

Redis 方案

Redis 替代 session 的业务流程

  • 这里存入登录用户信息,一般会使用 String 或者 Hash 的结构(存放 session 信息或者 jwt 信息)
  • 这里采用的是 hash 结构
    • 考虑一下 key 的组成
      • 1、不建议使用 Phone 等敏感信息
      • 2、保证 key 是唯一性
      • 3、key 方便携带

访问流程

image.png

代码内容

  • 1、生成唯一 token,前缀 + token 作为 key
  • 2、用户信息作为 hash 的 value
  • 3、存放 用户信息 到 redis 中
  • 4、删除验证码信息

image.png

登录刷新问题

  • 问题
    • 如果用户没有任何操作30分钟,则token会消失,用户需要重新登录
  • 解决
    • 用户每次请求都进行一次拦截,进行刷新令牌的操作

image.png

查询缓存

缓存方式

//本地用高并发
Static final ConcurrentHashMap<K,V> map = new ConcurrentHashMap<>();
//Redis 缓存
static final Cache<K,V> USER_CACHE = CacheBuilder.newBuilder().build();
//本地缓存
Static final Map<K,V> map =  new HashMap();
  • 由于其被static修饰,所以随着类的加载而加载到内存之中,作为本地缓存,由于其又被final修饰,所以其引用之间的关系是固定的,不能改变,因此不用担心复制导致缓存失败

常用缓存

  • 浏览器缓存
  • 应用层缓存
  • 数据库缓存
  • CPU 缓存

缓存常见问题

  • 缓存穿透
    • ⽤户频繁使⽤缓存和数据库中不存在的数据进⾏访 问,导致流量直接打到数据库,导致数据库挂了
    • 解决方式
      • 接⼝层增加校验
      • 如果缓存中不存在该值,就缓存空值到缓存中(空对象缓存)
      • 使⽤布隆过滤器,布隆过滤器是⼀个位图,如果它说不存在就 ⼀定不存在,如果说存在只能是可能存在,可以将可能存在的 key放⼊bitmap进⾏过滤
      • 热点数据限流
  • 缓存击穿
    • ⼤量⽤户访问某个key时,这个key刚好失效,导致流 量直接打到数据库,导致数据库挂了
    • 解决方式
      • 设置热点数据永不过期
      • 加互斥锁
      • 逻辑过期
  • 缓存雪崩
    • 由于⼤量的key在同⼀时间失效,导致流量直接打到数 据库,导致数据库挂了
    • 解决方式
      • 可以将key的过期时间设置随机值,避免同⼀时间过期
      • 给每⼀个缓存数据加⼀个缓存标记来记录缓存是否失效,如果 失效就更新
      • 并发量不多的时候可以采⽤加锁排队
      • 限流
      • 多级缓存(浏览器缓存 → Nginx 缓存 → Redis 缓存 → JVM 进程缓存 → 数据库)

逻辑过期方案

  • 线程读取过程中不需要等待,性能好,有一个额外的线程持有锁去进行重构缓存数据,但是在重构数据完成之前,其他线程只能返回脏数据,且实现起来比较麻烦

image.png

封装 Redis 工具类

大概知道一下工具类常见方法有哪些

to be contined....

优惠券秒杀

分布式锁

分布式锁

分布式锁

  • 满足分布式系统或集群模式下多线程课件并且可以互斥的锁
  • 分布式锁的核心思想就是让大家共用同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路

常见的分布式锁有三种

  • MySQL:MySQL本身就带有锁机制,但是由于MySQL的性能一般,所以采用分布式锁的情况下,使用MySQL作为分布式锁比较少见
    • (例如基于 CAS 的乐观锁)
  • Redis:Redis作为分布式锁是非常常见的一种使用方式,现在企业级开发中基本都是用Redis或者Zookeeper作为分布式锁,利用SETNX这个方法,如果插入Key成功,则表示获得到了锁,如果有人插入成功,那么其他人就回插入失败,无法获取到锁,利用这套逻辑完成互斥,从而实现分布式锁
  • Zookeeper:Zookeeper也是企业级开发中较好的一种实现分布式锁的方案(利用节点的唯一性和有序性实现互斥)

其他方案后面看

Redis 方案

  • 加锁 setnx
  • 释放锁 del

image.png

分布式锁-Redisson

秒杀优化

Redis 消息队列

达人探店

好友关注

附近商户

用户签到

UV 统计