浅尝辄止Redis

五个基本数据类型

String(字符串)
  • 使用最广最频繁
  • 常用存储以下数据
    • 常规数据
    • 计数(用户单位时间请求数-简单限流、页面单位时间访问数)
    • 分布式锁(一般是用Lua脚本)
Hash(散列)
  • 存储一个对象,可以直接操作字段,但是一般被String存储对象Json所代替
List(列表)
  • 类比于Java,可以看作是一个可以头操作,尾操作的List<String>
Set(集合)
  • 存放不重复数据
  • 获取多个数据集的交集、并集、差集(共同好友、好友推荐...)
  • 随机获取数据源中的一个数据(抽奖系统、随机点名)
Z-Set(有序集合)
  • 排行榜
  • 滑动窗口限流

三个特殊数据类型

HyperLogLog(基数统计)
  • 统计页面UV
Bitmap(位图)
  • Bitmap 存储的是连续的二进制数字(0 和 1)
  • 统计活跃用户数(key做日期,用户ID作为offset)
Geospatial(地理位置)
  • 不知道
...(布隆过滤器、位域等)

持久化

AOF
  • 记录操作
RDB
  • 默认支持
  • 记录数据

如何判断数据是否过期?

  1. 通过过期字典(类似于Hash结构)保存了数据过期的时间。
  2. 过期字典中的键指向数据库中的Key
  3. 值是一个longlong类型整数,记录的是键的过期时间(毫秒精度)

过期数据的删除策略

  1. 惰性删除:取key的时候判断是否过期
  2. 定期删除:每隔一段时间抽取一批Key执行删除过期Key的操作。底层会该操作的执行时长和频率来减少对CPU的影响

Redis采用的是定期删除+惰性删除的组合方式

Redis内存淘汰机制
  1. volatile-lru:从已设置的过期时间的数据集中挑选最近最少使用的数据淘汰。
  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。
  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。
  4. allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。
  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。
  6. no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!

布隆过滤器

当Key不存在于布隆过滤器中时,在缓存中一定不存在

当Key存在于布隆过滤器中时,在缓存中不一定存在

击穿、穿透、雪崩

缓存穿透
  • 大量请求的Key不合理
  • 根本不存在于缓存中,也不存在于数据库中

解决方案:

  1. 缓存无效的Key
  2. 布隆过滤器
  3. 接口限流
缓存击穿
  • 热点Key过期,导致大量请求直接打到了数据库

解决方案:

  1. 热Key不过期或长过期时间
  2. 预热,在热门活动场景内设置不过期
  3. 请求数据库写入缓存前,获取互斥锁,保证只有一个请求落到数据库
缓存雪崩
  • 缓存在同一时间大面积失效,导致大量请求打到数据库

解决方案:

  1. Redis集群
  2. 缓存预热
  3. 固定过期时间+随机值

如何保证缓存和数据库数据一致性?

  1. 更新数据库+更新缓存(淘汰)
  2. 更新数据库+删除缓存
  3. 在方案2中,并发状态下依然有数据不一致的可能性,解决方案是【延迟双删】,通过重试或者消息队列来实现
  • 41
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值