https://zhuanlan.zhihu.com/p/1888284764827522341
http://www.coonote.com/redis-note/redis-interview-questions.html
1 数据类型及底层数据结构
GEO
redis GEO 类型原理及命令详解
Redis系列9:Geo 类型赋能亿级地图位置计算
HyperLogLog
HyperLogLog 使用及其算法原理详细讲解
命令scan
redis系列——scan机制:高位进位加法
redis使用scan count 返回数量不准确
2 Redis的应用场景
Redis–基础知识点–25–redis使用场景
3 穿透、击穿、雪崩
3.1 穿
Redis常见面试题(一)中 二
3.2 击穿
Redis常见面试题(一)中 三
3.3 雪崩
Redis常见面试题(一)中 四
解决方案:
- 给不同的Key的TTL添加随机值,将缓存失效时间分散开
- 永不过期
- 利用Redis集群提高服务的可用性,Redis的哨兵模式和集群模式,为防止Redis集群单节点故障,可以通过这两种模式实现高可用
- 给业务添加多级缓存,比如:使用nginx缓存+redis缓存+其他缓存,不同层使用不同的缓存,可靠性更强
- 缓存预热:不要等到请求到来再去查询数据库存入缓存,可以提前将数据存入缓存。使用缓存预热机制通常有专门的后台程序(例如定时任务)去将数据库的数据同步到缓存。
- 熔断降级:熔断(服务异常后,阻止上游服务调用该服务)和降级(上游服务远程调用发现下游熔断后,执行后备方法)计算机编程杂识–9–限流、熔断、降级
4 过期删除策略
Redis–基础知识点–26–过期删除策略 与 淘汰策略 中1
5 淘汰删除策略
Redis–基础知识点–26–过期删除策略 与 淘汰策略 中2
6.1 淘汰策略其它问题
6.1.1 数据库有1000万数据,Redis只能缓存20w数据,如何保证Redis中的数据都是热点数据 ?
高并发下千万数据量的Mysql中热点数据如何持续保留在Redis中
6.1.2 Redis的内存用完了会发生什么
主要要看淘汰策略配置的什么。对于写操作来说,如果没有配置淘汰策略或 maxmemory=0[无内存限制],导致内存溢出,redis进程会崩掉;如果配置了noeviction,会直接写失败;如果配置了其它策略会根据相应策略淘汰数据,并将新数据写进去。对于读操作的话如果读取的数据在内存中会成功,不在内存中的数据也需要业务程序从mysql中获取相应的数据,并更新到redis内存中,此时的情况就跟写操作情况是一样的。
7 Reids持久化机制
该部分 的 问题目录与Redis–基础知识点–17–rdb_aof 一样
7.1 RDB
7.1.1 RDB 是什么
7.1.2 开启关闭RDB
7.1.3 RDB 触发机制
7.1.4 RDB 执行原理7
7.1.5 RDB记的快照内容
7.2 AOF
7.2.1 AOF 是什么
7.2.2 开启关闭AOF
7.2.3 AOF 触发机制[刷盘机制]
7.2.4 AOF 重写机制
7.3 RDB 与 AOF 对比
7.4 混合模式
7.5 适用场景
7 Redis性能
7.1 Redis 为什么采用单线程不采用多线程
往往采用多线程的原因是性能瓶颈在I/O,导致不能更好的利用cpu,而redis 是基于内存的,不存在I/O瓶颈;
使用了多线程反而存在锁的获取、释放 与 上下文切换 反而会消耗更多的资源影响性能。
7.2 Redis 单线程为什么还这么快
即:Redis为什么能扛住百万QPS?
- 基于内存:Redis是基于内存的,内存的读写速度非常快;
- 上下文切换:单线程避免了不必要的上下文切换和竞争条件;
- IO多路复用:底层采用NIO(非阻塞IO),NIO采用IO多路复用技术,一个线程通过多路复用器处理多个连接。
- 高效数据结构:比如跳表查询复杂度O(logN)
7.3 Redis 的瓶颈
- 内存:因为读写在内存中进行,内存大小会影响Redis性能。可以通过加内存、读写分离优化性能。
- 网络带宽:网络 IO是Redis最大瓶颈,也就是客户端和服务端之间的网络传输延迟。Redis6.0引入了网络IO多线程模型,提高了性能瓶颈。
Redis6.0 引入多线程?
7.4 Redis是单线程的,如何提高多核CPU的利用率?
可以在同一个服务器部署多个 Redis 的实例,并把他们当作不同的服 务器来使用,在某些时候,无论如何一个服务器是不够的, 所以, 如果你想使用多个 CPU,你可以考虑一下分片(shard)。
7.5 如何优化Redis性能和内存使用
https://cloud.tencent.com/developer/techpedia/1572
7.6 Redis为什么性能比Mysql快那么多
- 基于内存的操作:Redis将所有数据存储在内存中,而MySQL主要依赖于磁盘存储。内存的读写速度远高于磁盘。
- 数据结构与访问模式:Redis支持多种简洁的数据结构,对于键值对类型的数据访问来说,时间复杂度通常是O(1)。而MySQL使用B+树作为索引结构,查找操作的时间复杂度通常是O(logn)。
- 单线程模型与多路复用:Redis使用单线程模型处理客户端请求,通过I/O多路复用技术高效地管理多个连接,避免了多线程切换带来的开销。
- 无事务和SQL解析开销:Redis没有复杂的SQL解析、优化及事务处理逻辑,使得数据操作更为直接快速。
8 锁
8.1 分布式锁
8.1 分布式锁原理
Redis–基础知识点–24–分布式锁
8.1.2 看门狗实现原理
自动续期:
- 当一个线程成功获取锁后,会为该锁设置一个初始的有效期(例如 30 秒)。
- 看门狗会启动一个后台线程,定期(通常是锁有效期的一半时间)发送命令给 Redis,以自动延长锁的过期时间。只要持有锁的线程仍在运行且未显式释放锁,锁的有效期将被持续延长。
锁释放:
- 当持有锁的线程完成任务后,显式调用 unlock 方法释放锁。
- 释放锁后,看门狗停止续期操作。
异常处理:
- 如果持有锁的线程因异常终止,看门狗将不再续期锁的有效期,锁会在其原始过期时间后自动释放,避免死锁。
8.1.3 Redis 锁保证原子性为什么用lua脚本,不用事务
原因:lua脚本可以写复杂的逻辑,而事务不行。一个线程在释放锁时需要有判断逻辑[if 语句],判断是不是自己获取到的锁,lua脚本可以,事务就不可以。
8.2 红锁
了解即可,一般不会用
【redis】redis实现红锁
8.3 可重入锁
Redis可重入锁原理
9 双写一致
目的:保证缓存和数据库中数据的最终一致性
9.1 对于缓存应该使用删除还是更新
- 1 更新缓存比删除缓存更耗费性能,尤其对于复杂的结构的数据
- 2 站在懒加载的角度,更新的数据不一定会马上被访问,既然如此,不如不做,等待其它读操作在需要的时候再来进行缓存重建即可,这样既提高性能,还提高了程序的运行效率。
9.2 方案一:延时双删
9.2.1 原理
- 1 先删除缓存
- 2 更新数据库
- 3 等待一段时间删除缓存
9.2.2 步骤1 第一次删除缓存的意义是什么
Redis 延时双删的第一个删除操作是不可省略的,它是为了保证数据一致性,让老数据尽快失效,避免用户拿到过期数据。延时再删是为了进一步确保缓存里没有脏数据。这两个操作相辅相成,缺一不可。
9.2.3 步骤3 为什么需要等待一段时间删除缓存
避免以下场景:线程1删除缓存,接着去请求更新数据库,但该请求发生了网络延迟;此时线程2去从缓存读数据,发现缓存中没有数据,然后去数据库中读数据,读的是旧数据,完了之后请求将读到的数据写到缓存中,但此时又发生了网络延迟;此时线程1 请求更新数据库的请求到达并更新数据库后,并请求拿到更新后的数据,然后不等待
直接删除缓存并将最新数据添加到缓存;此时线程2 请求到达缓存将读到旧数据又写到了缓存。
这种情况导致 缓存与数据库中的数据不一致。所以延时双删第三步需要等待一段时间再去删除缓存并添加到缓存,即线程1等待线程2先将旧数据到更新到缓存后,线程1再去删除缓存并将新数据添加到缓存。这样就能最大程度
保持缓存与数据库最终一致。
为什么说最大程度保持缓存与数据库一致?因为如果缓存和数据库负载很高,主从同步很慢,很有可能不能在延时的时间内实现同步。
9.2.4 步骤3 等待一段时间删除缓存的休眠等待时间应该设置多久
太短了,可能并发写操作还没完,老数据还会被写回缓存;太长了,影响系统性能,用户体验不好。所以,得找个平衡点。
这个休眠时间 = 读业务逻辑数据[从数据库读数据]的耗时 + 回写缓存时间 + 几百毫秒。
9.3 方案二:先更新数据库 再删除缓存
9.3.1 原理
- 1 先更新数据库
- 2 删除缓存并将新的数据添加到缓存中
9.4 两种方案中删除缓存失败时怎么处理
延时双删第一次删除缓存失败:即停止继续执行,可以直接给客户端返回相应的报错
延时双删
第二次删除缓存失败 和 先更新数据库再删除缓存
删除缓存失败 可以采用重试
的方案。
具体删除及重试删除方案缓存:浅谈双写导致的数据一致性问题 中四,这两种方案其实都是异步删除。即 延时双删方案中也就不要考虑延时的问题了。
9.5 两种方案的适用场景
方案 |
优点 |
缺点 |
实现复杂度 |
适用场景 |
先更新数据库后删除缓存 |
减少了一次缓存删除的开销 |
在数据库更新期间,读取请求可能读取到失效的缓存数据 |
简单 |
数据一致性要求较低、对性能要求较高的场景 |
延时双删 |
保证了数据一致性,读取请求不会读取到失效的缓存数据 |
需要进行两次缓存删除操作,增加了一定的资源开销 |
复杂 |
数据一致性要求较高的场景,同时对性能影响有一定容忍度的场景 |
10 Redis 事务
10.1 事务特点
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
10.2 事务相关命令
MULTI: 开始事务,命令入队(批量操作 Redis 的命令,先进先出(FIFO)的顺序执行)
EXEC:执行所有事务块内的命令
WATCH: 监视一个(或多个) key ,如果在事务EXEC执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断,不会执行
UNWATCH: 取消 WATCH 命令对所有 key 的监视。
DISCARD: 取消事务,放弃执行事务块内的所有命令。
10.3 事务是否满足ACID
原子性(Atomicity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
- 不支持,1 事务中的某一条命令执行失败时其它命令仍会继续执行;2 没有回滚机制。也就是说有的命令起作用了有的命令不起作用,所以不支持原子性。
隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
- 支持,事务的操作不被其他用户操作所打断;watch 保证事务命令的隔离性;lua脚本满足隔离性;
持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
- redis只有在 aof 持久化策略的时候,并且需要在 redis.conf 中 appendfsync=always 才具备持久性;实际项目中几乎不会使用 aof 持久化策略;
一致性(Consistency): 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
- 不支持,事务使数据库从一个一致性状态到另外一个一致性状态;这里的一致性是指预期的一致性而不是异常后的一致性;当redis 执行事务时有一条命令执行失败,其它命令仍会执行,因此不能保证一致性
11 慢查询
线上阻塞如何排查 及 慢查询如何排查
Redis–基础知识点–28–慢查询相关中有以下几个问题的详细介绍
11.1 慢查询的原因
11.2 慢查询排查方案
11.3 慢查询解决方案
12 pipline
Redis中Pipline管道命令详解
13 大Key
Redis 大 Key:别让你的 Redis 变成“胖子”! 中以下几个问题都有,目录一致
13.1 什么是大Key
13.2 什么情况下会导致大 Key
13.3 大 Key 问题会带来什么危害
13.4 如何识别大 Key
13.5 解决大 Key 问题的方案
14 Redis是AP还是CP
15 分区
为什么要做Redis分区?
https://www.bjpowernode.com/redismst.html
你知道有哪些Redis分区实现方案?
Redis分区有什么缺点?
16 部署方案
16.1 主从模式
16.1.1 解决了单实例模式中的什么问题
16.1.2 还存在的问题
16.1.3 原理
16.2 哨兵模式
16.2.1 解决了主从模式中的什么问题
16.2.2 还存在的问题
16.2.3 原理
16.2 哨兵模式
16.3 集群模式
16.3.1 解决了哨兵模式中的什么问题
16.3.2 还存在的问题
16.3.3 原理
16.4 哨兵模式脑裂问题如何解决
Redis脑裂问题的解决分析方法
16.5 Redis高可用的机制有哪些
- 持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
- 复制:复制是高可用Redis的基础,哨兵和集群都是在复制基础上实现高可用的。复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
- 哨兵:哨兵实现了主从复制中故障的自动化恢复。缺陷:写操作无法负载均衡;存储能力受到单机的限制。
- 集群:通过集群,解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。
Redis集群是什么工作原理?
Redis的主从同步机制
如何实现Redis高可用(主从哨兵集群)
脑裂问题如何解决
为什么Redis集群中,哈希槽数量是16384?
什么是一致性哈希算法?Redis为什么使用哈希槽而非一致性哈希算法?
Redis为什么使用哈希槽而不用一致性哈希?
Redis主从数据一致性怎么保证
9 Redis有哪些回收策略?
7 Redis内存泄漏的场景?
9 Redis内存溢出的解决策略有哪些?
10 Redis内存满了如何处理