Redis面试题分享七:Redis 的常用应用场景?最适合的场景?

目录

​编辑

01、缓存

02、分布式锁

03、实时排行榜

04、计数器/自增ID

05、消息队列

06、地理位置应用

07、抽奖

08、Set实现点赞/收藏功能

09、PV统计(incr自增计数)

10、UV统计(HeyperLogLog)

11、去重(BloomFiler)

12、用户签到(BitMap)

13、简单限流

14、认识的人/好友推荐

15、发布/订阅

16、数据共享(session共享)

17、商品筛选

18、购物车

19、定时取消订单(key过期监听)

20、物流信息(时间线)


01、缓存

Redis 最常见的应用场景就是作为缓存来提高读写性能。由于 Redis 基于内存读写,响应速度非常快,因此可以用来缓存热点数据,如网站首页、商品信息等。通过使用 TTL(time to live)机制来设置缓存过期时间,可以避免缓存数据过期而导致的问题。

02、分布式锁

Redis 可以用作分布式锁,通过设置一个唯一的键值对来控制访问某个资源的并发数。当一个客户端需要访问该资源时,先去获取分布式锁,执行完后再释放锁,以保证同时只有一个客户端在访问该资源。这种方式可以有效避免因为并发访问而导致的数据冲突和竞争问题。

Redis实现分布式锁的技术方案有很多,其中比较常用的包括:

1)基于SETNX命令+Lua脚本:使用SETNX命令创建一个键值对,如果该键不存在,表示加锁成功;否则表示加锁失败。释放锁时,使用DEL命令删除该键。配合Lua脚本可以让加锁和释放锁过程封装成原子性操作,避免出现误删等问题。

2)Redisson:是一个Java实现的Redis客户端,提供了完整的分布式锁解决方案,支持多种锁模式(例如可重入锁、公平锁等),并提供了超时自动释放锁、异步执行等功能。

3)Spring Boot + LockRegistry(推荐):LockRegistry是Spring Boot提供的接口,可以轻松地将分布式锁嵌入到应用程序中。LockRegistry接口可以与不同的分布式锁提供者(如Redis)集成,并提供了简单易用的API,使开发人员无需关注底层实现细节。

需要注意的是,在选择分布式锁方案时,需要根据实际情况进行考虑。不同的方案具有不同的特点和适用场景,需要根据业务需求和系统负载情况进行选择和优化。同时,分布式锁的实现过程需要特别注意死锁和误删等问题,必要时可以借助第三方库进行实现。

03、实时排行榜

Redis 可以用来实现实时排行榜,通过将用户行为数据记录下来,如点赞数、评论数等,然后通过 ZSET(有序集合)数据类型来实现实时排名和排序。这种方式可以很好地满足诸如游戏排名、电商销量排行等实时统计的需求。

04、计数器/自增ID

Redis 还可以用作计数器,通过使用 INCR 命令来实现。当需要对某个计数器进行增加操作时,只需要执行一次 INCR 命令即可。由于 Redis 的原子性操作,可以保证在高并发场景下的数据一致性。

05、消息队列

Redis 也可以用作消息队列,在分布式系统中起到重要的作用。生产者将消息存入队列中,消费者从队列中取出消息进行处理。通过使用 Redis 的 PUB/SUB(发布/订阅)功能或者 Stream来实现消息的发布和订阅,保证了消息传递的可靠性和高效性。

06、地理位置应用

Redis 还具有地理位置服务的特性,可以记录每个用户的位置信息,并将其保存在 Redis 中。然后通过 GeoHash 和 Geospatial 数据类型来实现位置信息的查找和计算,以实现类似于附近的人、打车等服务。

07、抽奖

曾几何时,抽奖是互联网APP热衷的一种推广、拉新的方式,节假日没有好的策划,那就抽个奖吧!一堆用户参与进来,然后随机抽取几个幸运用户给予实物/虚拟的奖品;此时,开发人员就需要写上一个抽奖的算法,来实现幸运用户的抽取;其实我们完全可以利用Redis的集合(Set),就能轻松实现抽奖的功能;

08、Set实现点赞/收藏功能

有互动属性APP一般都会有点赞/收藏/喜欢等功能,来提升用户之间的互动。

传统的实现:用户点赞之后,在数据库中记录一条数据,同时一般都会在主题库中记录一个点赞/收藏汇总数,来方便显示;

Redis方案:基于Redis的集合(Set),记录每个帖子/文章对应的收藏、点赞的用户数据,同时set还提供了检查集合中是否存在指定用户,用户快速判断用户是否已经点赞过

09、PV统计(incr自增计数)

Page View(PV)指的是页面浏览量,是用来衡量流量的一个重要标准,也是数据分析很重要的一个依据;通常统计规则是页面被展示一次,就加一;

10、UV统计(HeyperLogLog)

前面,介绍了通过(INCR)方式来实现页面的PV;除了PV之外,UV(独立访客)也是一个很重要的统计数据;

但是如果要想通过计数(INCR)的方式来实现UV计数,就非常的麻烦,增加之前,需要判断这个用户是否访问过;那判断依据就需要额外的方式再进行记录。

此时,HeyperLogLog数据结构,就能完美的解决这一问题,它提供了一种不精准的去重计数方案,注意!这里强调一下,是不精准的,会存在误差,不过误差也不会很大,**标准的误差率是0.81%**,这个误差率对于统计UV计数,是能够容忍的;所以,不要将这个数据结构拿去做精准的去重计数。

另外,HeyperLogLog 是会占用12KB的存储空间,虽然说,Redis 对 HeyperLogLog 进行了优化,在存储数据比较少的时候,采用了稀疏矩阵存储,只有在数据量变大,稀疏矩阵空间占用超过阈值时,才会转为空间为12KB的稠密矩阵;相比于成千、上亿的数据量,这小小的12KB,简直是太划算了;但是还是建议,不要将其用于数据量少,且频繁创建 HeyperLogLog 的场景,避免使用不当,造成资源消耗没减反增的不良效果。

11、去重(BloomFiler)

通过上面HeyperLogLog的学习,我们掌握了一种不精准的去重计数方案,但是有没有发现,他没办法获取某个用户是否访问过;理想中,我们是希望有一个PFEXISTS的命令,来判断某个key是否存在,然而HeyperLogLog并没有;要想实现这一需求,就得 BloomFiler 上场了。

  • 什么是Bloom Filter?

    Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法。 通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合。 基于一种概率数据结构来实现,是一个有趣且强大的算法。

  • 同样,BloomFiler 也不那么精准,在默认参数情况下,是存在1%左右的误差;但是 BloomFiler 是允许通过error_rate(误差率)以及initial_size(预计大小)来设置他的误差比例

  • error_rate:误差率,越低,需要的空间就越大;

  • initial_size:预计放入值的数量,当实际放入的数量大于设置的值时,误差率就会逐渐升高;所以为了避免误差率,可以提前做好估值,避免再次大的误差;

12、用户签到(BitMap)

Redis做法:由于签到数据的关注点就2个:是否签到(0/1)、连续性,因此就完全可以利用BitMap(位图)来实现;

一个月的签到情况,4个字节就记录了(图源:网络)

如上图所示,将一个月的31天,用31个位(4个字节)来表示,偏移量(offset)代表当前是第几天,0/1表示当前是否签到,连续签到只需从右往左校验连续为1的位数;

由于String类型的最大上限是512M,转换为bit则是2^32个bit位。

所需命令:

  • SETBIT key offset value:向指定位置offset存入一个0或1

  • GETBIT key offset:获取指定位置offset的bit值

  • BITCOUNT key [start] [end]:统计BitMap中值为1的bit位的数量

  • BITFIELD: 操作(查询,修改,自增)BitMap中bit 数组中的指定位置offset的值

    这里最不容易理解的就是:BITFIELD,详情可参考:https://deepinout.com/redis-cmd/redis-bitmap-cmd/redis-cmd-bitfield.html  而且这部分还必须理解了,否则,该需求的核心部分就没办法理解了;

13、简单限流

为了保证项目的安全稳定运行,防止被恶意的用户或者异常的流量打垮整个系统,一般都会加上限流,比如常见的sentialhystrix,都是实现限流控制;如果项目用到了Redis,也可以利用Redis,来实现一个简单的限流功能;

功能所需命令

  • INCR:将 key 中储存的数字值增一

  • Expire:设置key的有效期

14、认识的人/好友推荐

在支付宝、抖音、QQ等应用中,都会看到好友推荐;

好友推荐往往都是基于你的好友关系网来推荐,将你可能认识的人推荐给你,让你去添加好友,如果随意在系统找个人推荐给你,那你认识的可能性是非常小的,此时就失去了推荐的目的;

比如,A和B是好友,B和C是好友,此时A和C认识的概率是比较大的,就可以在A和C之间的好友推荐;

基于这个逻辑,就可以利用 Redis 的 Set 集合,缓存各个用户的好友列表,然后以差集的方式,来实现好友推荐;

功能所需的命令

  • SADD key member [member …]:集合中添加元素,缓存好友列表

  • SDIFF key [key …]:取两个集合间的差集,找出可以推荐的用户

15、发布/订阅

发布/订阅是比较常用的一种模式;在分布式系统中,如果需要实时感知到一些变化,比如:某些配置发生变化需要实时同步,就可以用到发布,订阅功能

常用API

  • PUBLISH channel message:将消息推送到指定的频道

  • SUBSCRIBE channel [channel …]:订阅给定的一个或多个频道的信息

16、数据共享(session共享)

既然Redis能持久化数据,就可以用它来实现模块间的数据共享;SpringBoot Session 利用的这个机制来实现 Session 共享;

17、商品筛选

商城类的应用,都会有类似于下图的一个商品筛选的功能,来帮用户快速搜索理想的商品;

假如现在iphone 100 、华为mate 5000 已发布,在各大商城上线;下面就通过 Redis 的 set 来实现上述的商品筛选功能;

功能所需命令

  • SADD key member [member …]:添加一个或多个元素

  • SINTER key [key …]:返回给定所有集合的交集

18、购物车

商品缓存

电商项目中,商品消息,都会做缓存处理,特别是热门商品,访问用户比较多,由于商品的结果比较复杂,店铺信息,产品信息,标题、描述、详情图,封面图;为了方便管理和操作,一般都会采用 Hash 的方式来存储(key为商品ID,field用来保存各项参数,value保存对于的值)

购物车

当商品信息做了缓存,购物车需要做的,就是通过Hash记录商品ID,以及需要购买的数量(其中key为用户信息,field为商品ID,value用来记录购买的数量) ;

功能所需命令

  • HSET key field value : 将哈希表 key 中的字段 field 的值设为 value ;

  • HMSET key field1 value1 [field2 value2 ] :同时将多个 field-value (域-值)对设置到哈希表 key 中。

  • HGET key field:获取存储在哈希表中指定字段的值。

  • HGETALL key :获取在哈希表中指定 key 的所有字段和值

  • HINCRBY key field increment :为哈希表 key 中的指定字段的整数值加上增量 increment 。

  • HLEN key:获取哈希表中字段的数量

19、定时取消订单(key过期监听)

电商类的业务,一般都会有订单30分钟不支付,自动取消的功能,此时就需要用到定时任务框架,Quartz、xxl-job、elastic-job 是比较常用的 Java 定时任务;我们也可以通过 Redis 的定时过期、以及过期key的监听,来实现订单的取消功能;

  • Redis key 过期提醒配置

  • 添加RedisKeyExpirationListener的监听

  • 不推荐使用

    基于这一套机制,确实能够实现订单的超时取消,但是还是不太建议使用,这里仅作为一个思路;原因主要有以下几个:

    1. redis 的过期删除策略是采用定时离线扫描,或者访问时懒性检测删除,并没有办法保证时效性,有可能key已经到期了,但Redis并没有扫描到,导致通知的延迟;

    2. 消息发送即忘(fire and forget),并不会保证消息的可达性,如果此时服务不在线或者异常,通知就再也收不到了;

20、物流信息(时间线)

寄快递、网购的时候,查询物流信息,都会给我们展示xxx时候,快递到达什么地方了,这就是一个典型的时间线列表;

数据库的做法,就是每次变更就插入一条带时间的信息记录,然后根据时间和ID(ID是必须的,如果出现两个相同的时间,单纯时间排序,会造成顺序不对),来排序生成时间线;

我们也可以通过 Redis 的 List 来实现时间线功能,由于 List 采用的是双向链表,因此升序,降序的时间线都能正常满足;

  • RPUSH key value1 [value2]:在列表中添加一个或多个值,(升序时间线)

  • LPUSH key value1 [value2]:将一个或多个值插入到列表头部(降序时间线)

  • LRANGE key start stop:获取列表指定范围内的元素

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值