有勇气的牛排博客

Redis常见问题/应用场景/面试题总结(含答案)

有勇气的牛排 552 数据库 2023-05-01 19:06:58

1、什么redis

开源:Redis是完全免费开源的,遵守BSD协议,是一个高性能的Key-Value数据库,并且为多种语言提供API。

对比传统数据库:与传统数据库不同的是,redis将数据存储在内存中,所以读写速度非常快,因此redis被广泛应用于缓存方向。

**其他:**除此之外,redis还支持多种数据类型、持久化、LUA脚本、多种集群方案等。

哈喽,大家好,我是[有勇气的牛排](全网同名)🐮🐮🐮

有问题的小伙伴欢迎在文末[评论,点赞、收藏]是对我最大的支持!!!。

2、redis有什么特点

(2)支持多种数据类型:Redis不仅仅支持简单的Key-Value,同时还提供list、set、zset、hash等数据结构的存储。

(3)可备份(持久化):Redis支持数据的备份,方式有RDB与AOF两种。

3、redis与memcache的区别

(1)持久化:memcache将数据全部存储在内存之中,断电后会丢失,并且数据不能超过内存大小,即不支持持久化;redis则支持持久化。

(2)数据类型:相比memcache,redis拥有更丰富的数据类型。

(3)集群:redis支撑分布式集群,memcache不支持。

(4)内存使用率:redis采用hash结构来做key-value存储,其利用率高于memcache。

(5)性能对比:redis使用单核,memcache使用多核。

4、按照数据类型,说下redis有哪些应用场景

4.1 String setnx分布式锁

setnx:当key不存在时才能成功设置值

在加分布式锁的时候,记得加上锁过期时间,避免因为各种原因导致锁无法得到释放。

4.2 hash 结构化数据

其存放的数据为结构化对象

# 场景:购物车 --- 一个用户,加购多个商品 bigkey smallkey value 用户id 商品id 商品属性 # 用户charles,加购2号商品5个 hset charles 2 5 # 用户charles,加购3号商品1个 hset charles 3 1 # 2号商品数量又+2 hset charles 2 2 # 2号合计7个 # 获取用户charles购物车所有商品 hget charles

4.3 list 队列、订阅

使用此数据结构,可以实现简单的队列功能,其中lrange命令,可以做分页功能。

# 场景:生产者、消费者
# 场景:公众号订阅 --- 创作者发布文章后,将文章写入订阅者的List中。

4.4 set 点赞、共同好友

set集合是放一堆不重复值的集合,自带去重功能(有交并补差功能)。

场景:抽奖

# 场景:抽奖 # (1) 001、002号用户参与抽奖 sadd user:lottery 001 sadd user:lottery 002 # (2) 查看参与人数 scard user:lottery # (3) 随机选中2个中奖人 srandmember user:lottery 2 # 元素不删除 spop user:lottery 2 # 元素会删除(即不允许重复抽奖)

场景: 朋友圈点赞

# 场景: 朋友圈点赞 # 消息ID: 101 # 点赞用户: 001、002 # (1) 新增点赞 sadd pub:101 001 002 # (2) 001用户取消点赞 srem pub:001 # (3) 查看所有点赞用户 smembers pub:101 # (4) 点赞数量统计 scard pub:101

场景:可能喜欢的人

# 场景:可能喜欢的人 # 原理:取差集 sdiff user1 user2

4.5 zset 排行榜、TopN

场景:销售排行榜

# 场景:销售排行榜 商品 销售数量 101 10 102 15 # 添加商品到排行榜 zadd goods:sellsort 10 101 15 102 # 101又被卖出2个 zincrby goods:sellsort 2 101 # 查询销量前10名(定时刷新获取) zrange goods:sellsort 0 9 withscores

4.6 bitmap 位图、打卡、签到、是否登录、广告点击

bitmap是由二进制位组成的bit数组

场景:统计用户登录次数

# 场景:按日期统计用户登录次数 # 创建用户映射 mysql数据id --- redis序号(序号指定唯一,不变,看需求,这步骤非必须) hset uid:map 0 uid_0 hset uid:map 1 uid_1 hset uid:map 2 uid_2 hset uid:map 3 uid_3 # 查看所有用户 hgetall uid:map # 记录登录过得用户 # 10号登录用户 setbit 20230310 0 1 setbit 20230310 1 1 setbit 20230310 2 1 # 11号登录用户 setbit 20230311 0 1 setbit 20230311 3 1 # 查看11号、0号用户是否登录 getbit 20230311 0 # 统计10、11号都登录过得用户 bitop and haslogin 20230310 20230311 bitcount haslogin

5、单线程的redis为什么这么快

(1)纯内存操作

(2)单线程操作,避免了频繁的上下文

(3)采用了非租塞I/0多路复用机制

6、缓存穿透、缓存雪崩、缓存预热

6.1 缓存穿透

一、定义

一般指缓存系统通过key到缓存中查找value,如果缓存中不存在,则会到对应的后端查找;如果用户恶意发起大量不存在的key,就会导致后端压力非常大,这就叫做缓存穿透。

二、解决方法

(1)采用布隆过滤器(Bloom Filter)

  • 将所有可能存在的数据key映射到布隆过滤器中,查询时,先判断key是否存在,如果不存在,则直接返回。

  • 缺点是存在一定的误判,因此需要业务有一定的容错性。

  • 使用bitmap数据结构,可以将高效利用空间。

(2)缓存空对象

将空值也缓存起来,缺点是会造成占用大量空间、特别浪费。

6.2 缓存雪崩

一、定义

缓存雪崩通常指缓存服务器重启、**大量缓存同一时间失效(失效时间不合理)**的情况下,大量本该访问缓存的请求,直接去访问了数据库,导致系统宕机或服务器瘫痪。

二、解决方法
(1)使用Redis集群,高可用架构,来保证redis不会挂。

(2)给缓存时间加随机值,避免集体失效。

(3)预热缓存:利用定时任务预热缓存,避免缓存失效后请求第一时间到达数据库

(4)多级缓存:在多级缓存中,可以设置不同缓存有效期,并将不同级别的数据合理分布在不同服务器上,从而空值缓存雪崩。

6.3 缓存预热

一、定义

缓存预热指当用户在访问网站时,预先将网站数据存入缓存中,以便用户访问时,直接从缓存中拿取。

二、实现方法

(1)定时任务:利用定时任务,实现定时刷新缓存。

(2)在项目上线时,如果数据量不大,自动加载。

6.4 缓存降级

一、定义

缓存降级指当访问量过大时,可能会导致缓存失效或服务器挂掉得情况,调整缓存策略,以减小缓存服务器压力,以保证服务的正常,比如某些服务暂停提供等。

二、举例说明

(1)热榜topN等服务暂停,只保证核心业务正常。


留言

专栏
文章
加入群聊