Redis除了做缓存,还能做什么

缓存Redis是什么大家都知道 , 一个非关系型数据库 。 大部分情况下我们使用Redis做缓存 。 使用缓存的情况一般是这样的:
Redis除了做缓存,还能做什么文章插图
Redis缓存

(1)从Redis缓存中获取数据 , 如果存在数据 , 直接返回值 。
(2)如果不存在 , 执行数据库的查询方法
(3)将数据库中的值放入缓存 , 并返回值

代码如下:
Redis除了做缓存,还能做什么文章插图
【Redis除了做缓存,还能做什么】当然我们也可以使用Spring的缓存注解@Cacheble 。 我们要在配置类上面开启缓存注解@EnableCaching , 使用如下:
Redis除了做缓存,还能做什么文章插图
有兴趣的童鞋可以看看我写的这篇文章:

利用AOP自定义Redis缓存注解

这篇文章里我重新开发了缓存注解 , 增加了两个功能:设置超时时间和设置并发请求数 。 可以实现不同场景设置不同参数 。
队列上面其实就是我们常用的场景 , 那么Redis除了做缓存 , 还可以做什么呢?
我们还可以使用Redis做队列 。
Redis除了做缓存,还能做什么文章插图
Redis队列
那么我们什么时候可以使用Redis的队列功能呢?
Redis除了做缓存,还能做什么文章插图
示例代码如上 。
关于具体使用情形 , 可以看看我写的这篇文章:

我的多线程爬虫项目实战

这篇文章的爬虫项目中 , 爬取的时候可能因为网络等原因 , 爬取的那一条数据会失败 。 这时我会记录失败的url或code , 并将爬取异常的url或code存入Redis队列 。
我在后台重新启动一个线程 , 自旋的形式将Redis的队列中的数据阻塞式取出 。 然后再一次爬取 。
Redis除了做缓存,还能做什么文章插图
Redis爬虫
签到统计我们可以使用Redis的Bitmap存储签到数据 。
Bitmap是一个二进制的数组 , 长度不限(当长度为20亿时 , 占用内存200多MB) 。 数组内的值为0或1 。
使用Redis的Bitmap , 速度很快 , 在高并发情况下有更优良的性能 。 而且占用空间很小 , Bitmap大约可以存储个bit位(bit数组大约五六亿的长度) 。
例如:sign:1:202009 表示id为1的用户2020年9月的签到记录 。
Redis除了做缓存,还能做什么文章插图
Java示例代码如下:
jedis.bitfield(buildSignKey(userId, date), "GET", type, "0");具体使用情况可以看看我写的这篇文章:

我做了个签到功能 , 架构师用Bitmap优化了

原子扣减库存在秒杀系统中 , 使用Redis来存储库存数量 , 当用户发起抢购请求时 , 先判断Redis中的库存是否可用 。 如果可用 , 将抢购请求放入分布式队列中 , 采用异步方式处理后续操作 , 并完成下单 。 同时在Redis中作库存扣减 。
Redis除了做缓存,还能做什么文章插图
Redis库存扣减
示例代码如下:
Redis除了做缓存,还能做什么文章插图
有兴趣的童鞋可以看看我写的这篇文章:

一次阿里面试 , 我被问到了如何设计秒杀系统

Redis分布式锁现在的系统都是集群部署 , 每个服务都不是单节点的了 。 比如库存服务 , 可能部署到3台机器上分别命名为节点1 , 节点2 , 节点3 。 库存服务(使用数据库如MySQL)需要扣减库存 , 扣减库存肯定需要锁吧 , 如果使用Lock或者synchronized , 只能锁住自己的节点 。 而从前台访问是随机路由到这3台节点的 。 如果线程一进来使节点1上了锁 , 当线程二进来可能访问到的是节点2 , 这时节点2还没有上锁 , 那么库存就会扣减错误 。 而库存扣减还是一个核心操作 , 现在居然有Bug , 想想就可怕 。
Redis分布式锁实现思路如下:
“setnx + 过期时间 用lua脚本保证原子性锁持有心跳检测(防止未解锁 , 锁失效问题)线程自选获取锁”
我们也可以使用已有的轮子Redisson框架 。
Redis除了做缓存,还能做什么文章插图
Redis延迟队列Redis的zset可以用于作延迟队列 , score为延迟的时间点 , 获取时顺序获取端口的值 , 如果当前时间戳等于score则可取出 。