2024年Redis面试题之一
Redis  /  管理员 发布于 10个月前   246
Redis 如何实现延时队列
使用 sortedset,使用时间戳做 score, 消息内容作为 key, 调用 zadd 来生产消息,
消费者使用 zrangbyscore 获取 n 秒之前的数据做轮询处理。
redis 缓存击穿是什么?如何解决?
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,
同时读缓存没读 到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
和缓存雪崩不同的是,缓存击穿指并 发查同一条数据,缓存雪崩是不同数据都过期了,
很多数据都查不到从而查数据库。
解决方案
设置热点数据永远不过期。
redis 缓存穿透是什么?如何解决?
缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,
造成数据库短时间内承受大量请求而 崩掉。
解决方案
接口层增加校验,如用户鉴权校验,id 做基础校验,id<=0 的直接拦截;
从缓存取不到的数据,在数据库中也没有取到,这时也可以将 key-value 对写为 key-null,
缓存有效时间可以设 置短点,如 30 秒(设置太长会导致正常情况也没法使用)。
这样可以防止攻击用户反复用同一个 id 暴力攻击
【推荐】采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,
一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。
redis 缓存雪崩是什么?如何解决?
缓存雪崩指的是在某个时间点,缓存中的大量数据同时失效,导致大量请求直接落到数据库上,
造成数据库压力过大,甚至引发系统崩溃。
/** 缓存雪崩通常是由以下原因引起的:
缓存过期时间设置不合理:如果缓存中的数据在同一时间点过期,那么大量请求就会直接访问数据库。
缓存服务器宕机:当缓存服务器宕机时,无法提供缓存服务,请求会直接落到数据库上。
/** 解决方案
设置合理的缓存过期时间:合理设置缓存的过期时间,避免大量缓存在同一时间点失效。
使用多级缓存:引入多级缓存架构,将请求分散到不同的缓存层,减轻单一缓存层的压力。
实时监控缓存状态:通过监控工具实时监测缓存的状态,及时发现问题并进行处理。
增加服务端熔断或者限流。
Redis 事务保证原子性吗,支持回滚吗
Redis 中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。
事务中任意命令执行失败,其余的命令可 以仍会被执行。
Redis 事务支持隔离性吗
Redis 是单进程程序,并且它保证在执行事务时,不会对事务进行中断,
事务可以运行直到执行完所有事务队列中的命令为止。因此,Redis 的事务是总是带有隔离性的。
Redis 的线程模型是咋样的?
Redis 基于 Reactor 模式开发了网络事件处理器,
这个处理器被称为文件事件处理器(file event handler)。
它的组成结构为 4 部分:多个套接字、IO 多路复用程序、文件事件分派器、事件处理器。
因为文件事件分派器队列的消费是 单线程的,所以 Redis 才叫单线程模型。
文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字,
并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作
时, 与操作相对应的文件事件就会产生,
这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
虽然文件事件处理器以单线程方式运行, 但通过使用 I/O 多路复用程序来监听多个套接字,
文件事件处理器既实现了高性能的网络通信模型, 又可以很好地与 redis 服务器中其他同样以单线程方式运行的模块进行对接, 这保持了
Redis 内部单线程设计的简单性。
Redis 的内存淘汰策略有哪些
Redis 的内存淘汰策略是指在 Redis 的用于缓存的内存不足时,
怎么处理需要新写入且需要申请额外空间的数据。 全局的键空间选择性移除
noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key。
(这个是最常用的) allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key。
设置过期时间的键空间选择性移除
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,
移除最近最少使用的 key。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移 除。
9、Redis 的内存用完了会发生什么?
如果达到设置的上限,Redis 的写命令会返回错误信息(但是读命令还可以正常返回。)
或者你可以配置内存淘汰机 制,当 Redis 达到内存上限时会冲刷掉旧的内容。
请对比下 redis 持久化之 RDB 和 AOF?
1 Redis 默认开启 RDB 持久化方式,在指定的时间间隔内,执行指定次数的写操作,
则将内存中的数据写入到磁盘中。
2 RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
3 Redis 需要手动开启 AOF 持久化方式,默认是每秒将写操作日志追加到 AOF 文件中。
4 AOF 的数据完整性比 RDB 高,但记录内容多了,会影响数据恢复的效率。
5 Redis 针对 AOF 文件大的问题,提供重写的瘦身机制。
6 若只打算用 Redis 做缓存,可以关闭持久化。
7 若打算使用 Redis 的持久化。建议 RDB 和 AOF 都开启。其实 RDB 更适合做数据的备份,留一后手。AOF 出问题了, 还有 RDB。
请说说对 redis 事务的理解?
Redis 事务的概念:
Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,
一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,
其他客户端提交的命令请求不会插入到事务执行命令序列中。
总结说:redis 事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。
Redis 事务没有隔离级别的概念:
redis 没有事务隔离界别
Redis 不保证原子性:
Redis 中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。
事务中任意命令执行失败,其余的命 令仍会被执行。
Redis 事务的三个阶段: 开始事务
命令入队
执行事务
Redis 事务相关命令:
watch key1 key2 … :
监视一或多个 key, 如果在事务执行之前,被监视的 key 被其他命令改动,
则事务被打断 ( 类似乐观锁 )
multi : 标记一个事务块的开始( queued )
exec : 执行所有事务块的命令 ( 一旦执行 exec 后,之前加的监控锁都会被取消掉 )
discard : 取消事务,放弃事务块中的所有命令
unwatch : 取消 watch 对所有 key 的监控
Redis 事务使用案例:
(1) 正常执行
(2) 放弃事务
(3) 若在事务队列中存在命令性错误,则执行 EXEC 命令时,所有命令都不会执行
(4) 若在事务队列中存在语法性错误,则执行 EXEC 命令时,其他正确命令会被执行,错误命令抛出异常。
(5) 使用 watch
案例一:
使用 watch 检测 balance,事务期间 balance 数据未变动,事务执行成功
案例二:
使用 watch 检测 balance,在开启事务后(标注 1 处),在新窗口执行标注 2 中的操作,
更改 balance 的值, 模拟其他客户端在事务执行期间更改 watch 监控的数据,
然后再执行标注 1 后命令,执行 EXEC 后,事务未成功执行。
一但执行 EXEC 开启事务的执行后,无论事务使用执行成功, WARCH 对变量的监控都将被取消。
故当事务执行失败后,需重新执行 WATCH 命令对变量进行监控,并开启新的事务进行操作。
总结:
watch 指令类似于乐观锁,在事务提交时,如果 watch 监控的多个 KEY 中任何 KEY 的值
已经被其他客户端更改,则 使用 EXEC 执行事务时,事务队列将不会被执行,
同时返回 Nullmulti-bulk 应答以通知调用者事务执行失败。
Redis 有哪些优缺点
优点
读写性能优异。
支持数据持久化,支持 AOF 和 RDB 两种持久化方式。
支持事务,Redis 的所有操作都是原子性的,同时 Redis 还支持对几个操作合并后的原子性执行。
数据结构丰富,除了支持 string 类型的 value 外还支持 hash、set、zset、list 等数据结构。
支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。
缺点
数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,
因此 Redis 适合的场景主要局限在较小数据 量的高性能操作和运算上。
Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,
需要等待机器重启或者手动切换前端的 IP 才能恢复。
主机宕机,宕机前有部分数据未能及时同步到从机,切换 IP 后还会引入数据不一致的问题,
降低了系统的可用 性。
Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。
为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。
redis 的 list 队列先进先出如何解决插队问题?
参考答案:
通常使用一个 list 来实现队列操作,这样有一个小限制,所以的任务统一都是先进先出,
如果想优先处理某个任务就 不太好处理了,这就需要让队列有优先级的概念,
我们就可以优先处理高级别的任务,实现方式有以下几种方式:
1) 单一列表实现:队列正常的操作是 左进右出(lpush,rpop)为了先处理高优先级任务,
在遇到高级别任务时,可以直接插队,直接放入队列头部(rpush),
这样,从队列头部(右侧)获取任务时,取到的就是高优先级的任务(rpop)
2) 使用两个队列,一个普通队列,一个高级队列,针对任务的级别放入不同的队列,
获取任务时也很简单,redis 的
BRPOP 命令可以按顺序从多个队列中取值,BRPOP 会按照给出的 key 顺序查看,
并在找到的第一个非空 list 的尾部弹出一个元素,redis> BRPOP list1 list2 0
list1 做为高优先级任务队列 list2 做为普通任务队列
这样就实现了先处理高优先级任务,当没有高优先级任务时,就去获取普通任务
方式 1 最简单,但实际应用比较局限,
方式 3 可以实现复杂优先级,但实现比较复杂,不利于维护
方式 2 是推荐用法,实际应用最为合适
redis 如何优化
参考答案:
1、建立 redis 连接池
2、建立 redis 集群和一主多从
3、设置 key 有效期
4、设置 bit 级别的存储,如 GETBIT 和 SETBIT 等
5、想要一次添加多条数据的时候可以使用管道
6、根据业务需要选择合适的数据类型,并为不同的应用场景设置相应的紧凑存储参数。
7、当业务场景不需要数据持久化时,关闭所有的持久化方式可以获得最佳的性能以及最大的内存使用量。
8、如果需要使用持久化,根据是否可以容忍重启丢失部分数据在快照方式与语句追加方式之间选择其一,不要使用 虚拟内存以及 diskstore 方式。
9、不要让你的 Redis 所在机器物理内存使用超过实际内存总量的 3/5。
使用 redis 你 lpop 一条数据后, 插入数据库失败怎么办?
一般使用 list 结构作为队列,rpush 生产消息,lpop 消费消息。
当 lpop 没有消息的时候,要适当 sleep 一会再重试。
缺点:
在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如 rabbitmq 等。
redis 支持哪几种常见数据类型?
String 字符串: Hash(哈希)
List(列表) Set(集合)
zset (sorted set:有序集合)
使用过 Redis 分布式锁么,它是怎么实现的?
先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。
Redis 为单进程单线程模式,采用队列模式将并发访问变成串行访问,
且多客户端对 Redis 的连接并不存在竞争关系
Redis 中可以使用 SETNX 命令实现分布式锁。
当且仅当 key 不存在,将 key 的值设为 value。
若给定的 key 已经存在,则 SETNX 不做任何动作
SETNX 是『SET if Not eXists』(如果不存在,则 SET) 的简写。返回值:设置成功,返回 1 。
设置失败,返回 0 。
使用 SETNX 完成同步锁的流程及事项如下:
使用 SETNX 命令获取锁,若返回 0(key 已存在,锁已存在)则获取失败,反之获取成功
为了防止获取锁后程序出现异常,导致其他线程 / 进程调用 SETNX 命令总是返回 0 而进入死锁状态,
需要为该 key 设置 一个 “合理” 的过期时间
释放锁,使用 DEL 命令将锁数据删除
Redis 与 Memcached 的 2 个主要区别
1. Redis不仅支持简单的k/v类型的数据,同时还支持list、set、zset(sorted set)、
hash等数据结构的存储,使得它拥有更广阔的应用场景。
2. Redis最大的亮点是支持数据持久化,它在运行的时候可以将数据备份在磁盘中,
断电或重启后,缓存数据可以 再次加载到内存中,只要Redis配置的合理,基本上不会丢失数据。
说说你对 redis 哨兵的理解
Redis 服务器毫无征兆的罢工是个麻烦事,如何保证备份的机器是原始服务器的完整备份呢?
这时候就需要哨兵和复 制。
Sentinel 可以管理多个 Redis 服务器,它提供了监控,提醒以及自动的故障转移的功能,
Replication 则是负责让一个
Redis 服务器可以配备多个备份的服务器。
123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号