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

缓存

Redis是什么你们都知道,一个非关系型数据库。大部分状况下咱们使用Redis作缓存。使用缓存的状况通常是这样的:面试

图片Redis缓存数据库

(1)从Redis缓存中获取数据,若是存在数据,直接返回值。数组

(2)若是不存在,执行数据库的查询方法缓存

(3)将数据库中的值放入缓存,并返回值网络

代码以下:多线程

固然咱们也可使用Spring的缓存注解@Cacheble。咱们要在配置类上面开启缓存注解@EnableCaching,使用以下:架构

有兴趣的童鞋能够看看我写的这篇文章:并发

利用AOP自定义Redis缓存注解框架

这篇文章里我从新开发了缓存注解,增长了两个功能:设置超时时间设置并发请求数。能够实现不一样场景设置不一样参数。异步

队列

上面其实就是咱们经常使用的场景,那么Redis除了作缓存,还能够作什么呢?

咱们还可使用Redis作队列。

图片Redis队列

那么咱们何时可使用Redis的队列功能呢?

图片

示例代码如上。

关于具体使用情形,能够看看我写的这篇文章:

个人多线程爬虫项目实战

这篇文章的爬虫项目中,爬取的时候可能由于网络等缘由,爬取的那一条数据会失败。这时我会记录失败的urlcode,并将爬取异常的urlcode存入Redis队列。

我在后台从新启动一个线程,自旋的形式将Redis的队列中的数据阻塞式取出。而后再一次爬取。

Redis爬虫

签到统计

咱们可使用Redis的Bitmap存储签到数据。

Bitmap是一个二进制的数组,长度不限(当长度为20亿时,占用内存200多MB)。数组内的值为0或1。

使用Redis的Bitmap,速度很快,在高并发状况下有更优良的性能。并且占用空间很小,Bitmap大约能够存储个bit位(bit数组大约五六亿的长度)。

例如:sign:1:202009 表示id为1的用户2020年9月的签到记录。

图片

Java示例代码以下:

jedis.bitfield(buildSignKey(userId, date), "GET", type, "0");

具体使用状况能够看看我写的这篇文章:

我作了个签到功能,架构师看了后以为能够优化下

原子扣减库存

在秒杀系统中,使用Redis来存储库存数量,当用户发起抢购请求时,先判断Redis中的库存是否可用。若是可用,将抢购请求放入分布式队列中,采用异步方式处理后续操做,并完成下单。同时在Redis中做库存扣减。

图片Redis库存扣减

示例代码以下:

有兴趣的童鞋能够看看我写的这篇文章:

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

Redis分布式锁

如今的系统都是集群部署,每一个服务都不是单节点的了。好比库存服务,可能部署到3台机器上分别命名为节点1,节点2,节点3。库存服务(使用数据库如MySQL)须要扣减库存,扣减库存确定须要锁吧,若是使用Lock或者synchronized,只能锁住本身的节点。而从前台访问是随机路由到这3台节点的。若是线程一进来使节点1上了锁,当线程二进来可能访问到的是节点2,这时节点2尚未上锁,那么库存就会扣减错误。而库存扣减仍是一个核心操做,如今竟然有Bug,想一想就可怕。

Redis分布式锁实现思路以下:

  • setnx + 过时时间 用lua脚本保证原子性
  • 锁持有心跳检测(防止未解锁,锁失效问题)
  • 线程自选获取锁

咱们也可使用已有的轮子Redisson框架。

Redis延迟队列

Redis的zset能够用于做延迟队列,score为延迟的时间点,获取时顺序获取端口的值,若是当前时间戳等于score则可取出。

示例代码见上图。

其余

Redis还有不少更丰富的功能。好比生成全局的id号(原子自增)、微博点赞次数统计(原子自增)、布隆过滤器(Bitmap)、排行榜实现(zset)、地理位置查询(GEO)、生产者消费者(Stream)、发布订阅。

有兴趣的能够看看个人这篇文章:

Redis进阶

这篇文章就写到这里啦,欢迎你们留言本身在项目中如何使用Redis的。

相关文章
相关标签/搜索