几率大的Redis面试题(含答案) https://blog.csdn.net/Butterfly_resting/article/details/89668661
一、String应用场景
- 单值缓存
SET key value
GET key
- 对象缓存
1)SET user value(json格式数据)
2)MSET user:name lcq user:age 26
MSET user:name user:age
- 分布式锁
SETNX apply:20200321000001 true
//执行业务逻辑操作
DEL apply:20200321000001
SET apply:20200321000001 true ex 10 nx --设置锁超时时间,防止程序意外退出
- 计数器
INCR article:readcount:{文章ID}
GET article:readcount:{文章ID}
- Web集群session共享
spring session + redis实现session共享
- 分布式系统全局序列号
INCRBY orderId 1000
- 统计功能
1、统计 某用户 任意时间窗口内 登录的天数
SETBIT lcq 7 1;//用户lcq第8天登录
SETBIT lcq 364 1;//用户lcq第365天登录
BITCOUNT lcq 0 -1;//统计用户lcq一年内登录次数
2、统计 任意时间窗口内 活跃用户 的数量
SETBIT 20200101 7 1;//用户id为7的在20200101登录过,20200101= 10000000
SETBIT 20200102 7 1;//用户id为7的在20200102登录过,20200102= 10000000
SETBIT 20200102 19 1;//用户id为19的在20200102登录过,20200102=10000000000010000000
BITOP OR activeUser 20200101 20200102;//对两天的数据做逻辑或,activeUser=10000000000010000000
BITCOUNT activeUser 0 -1;//统计两天内活跃用户数
二、Hash应用场景
hash类型是一个string类型的field和value的映射表,每个 hash 可以存储 232 - 1 键值对(40多亿),hash类型主要有以下应用场景。
- Hash常用操作
HSET key field value
HSETNX key field value
HMSET key field value [field value...]
HGET key field
HMGET key field [field...]
HDEL key field [field...]
HLEN key
HGETALL key
HINCRBY key field increment
- 电商购物车
- Hash结构优缺点
- 存储对象
hash类型的(key, field, value)的结构与对象的(对象id, 属性, 值)的结构相似,也可以用来存储对象。
在介绍string类型的应用场景时有所介绍,string + json也是存储对象的一种方式,那么存储对象时,到底用string + json还是用hash呢?
两种存储方式的对比如下表所示。
string + json | hash | |
效率 | 很高 | 高 |
容量 | 低 | 低 |
灵活性 | 低 | 高 |
序列化 | 简单 | 复杂 |
当对象的某个属性需要频繁修改时,不适合用string+json,因为它不够灵活,每次修改都需要重新将整个对象序列化并赋值,如果使用hash类型,则可以针对某个属性单独修改,没有序列化,也不需要修改整个对象。比如,商品的价格、销量、关注数、评价数等可能经常发生变化的属性,就适合存储在hash类型里。
当然,不常变化的属性存储在hash类型里也没有问题,比如商品名称、商品描述、上市日期等。但是,当对象的某个属性不是基本类型或字符串时,使用hash类型就必须手动进行复杂序列化,比如,商品的标签是一个标签对象的列表,商品可领取的优惠券是一个优惠券对象的列表(如下图所示)等,即使以coupons(优惠券)作为field,value想存储优惠券对象列表也还是要使用json来序列化,这样的话序列化工作就太繁琐了,不如直接用string + json的方式存储商品信息来的简单。
综上,一般对象用string + json存储,对象中某些频繁变化的属性抽出来用hash存储。
三、List应用场景
- List常用操作
- List常用数据结构
- 微博消息和微信公众号消息
- 排行榜
list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如京东每日的手机销量排行、学校每次月考学生的成绩排名、斗鱼年终盛典主播排名等,下图是酷狗音乐“K歌擂台赛”的昨日打擂金曲排行榜,每日计算一次,存储在list类型中,接口访问时,通过page和size分页获取打擂金曲。(打个小广告,酷狗音乐“K歌擂台赛”每天都能产生一批优质翻唱作品,对普通人优质歌声有兴趣的朋友不妨来听听)。
但是,并不是所有的排行榜都能用list类型实现,只有定时计算的排行榜才适合使用list类型存储,与定时计算的排行榜相对应的是实时计算的排行榜,list类型不能支持实时计算的排行榜,之后在介绍有序集合sorted set的应用场景时会详细介绍实时计算的排行榜的实现。
那么问题来了,对于排行榜和最新列表两种应用场景,list类型能做到的sorted set类型都能做到,list类型做不到的sorted set类型也能做到,那为什么还要使用list类型去实现排行榜或最新列表呢,直接用sorted set类型不是更好吗?原因是sorted set类型占用的内存容量是list类型的数倍之多(之后会在容量章节详细介绍),对于列表数量不多的情况,可以用sorted set类型来实现,比如上文中举例的打擂金曲排行榜,每天全国只有一份,两种数据类型的内存容量差距可以忽略不计,但是如果要实现某首歌曲的翻唱作品地区排行榜,数百万的歌曲,300多个地区,会产生数量庞大的榜单,或者数量更加庞大的朋友圈点赞列表,就需要慎重地考虑容量的问题了。
四、Set应用场景
- Set常用操作
- 微信抽奖小程序
- 随机展示
通常,app首页的展示区域有限,但是又不能总是展示固定的内容,一种做法是先确定一批需要展示的内容,再从中随机获取。如下图所示,酷狗音乐K歌擂台赛当日的打擂歌曲共29首,首页随机展示5首;昨日打擂金曲共200首,首页随机展示30首。
set类型适合存放所有需要展示的内容,而srandmember命令则可以从中随机获取几个。
- 黑名单/白名单
经常有业务出于安全性方面的考虑,需要设置用户黑名单、ip黑名单、设备黑名单等,set类型适合存储这些黑名单数据,sismember命令可用于判断用户、ip、设备是否处于黑名单之中。
- 微信微博点赞,收藏,标签
- Set集合操作
- 集合操作实现微信微博关注模型
- 集合操作实现电商商品筛选
五、ZSet应用场景
- ZSet常用操作
- ZSet集合操作
- ZSet集合操作实现排行榜