[[八股-Redis]]/✅RDB和AOF的写回策略分别是什么?.md
Redis/✅Redis 5.0中的 Stream是什么?.md
Redis/✅Redis Cluster 中使用事务和 lua 有什么限制?.md
Redis/✅Redis 与 Memcached 有什么区别?.md
Redis/✅Redis 使用什么协议进行通信?.md
Redis/✅Redis 支持哪几种数据类型?.md
Redis/✅Redis 的事务机制是怎样的?.md
Redis/✅Redis 的过期策略是怎么样的?.md
Redis/✅Redisson 中为什么要废弃 RedLock,该用啥?.md
Redis/✅Redisson 的 watchdog 什么情况下可能会失效?.md
Redis/✅Redisson和Jedis有啥区别?如何选择?.md
Redis/✅Redisson如何保证解锁的线程一定是加锁的线程?.md
Redis/✅Redisson的lock和tryLock有什么区别?.md
Redis/✅Redisson的watchdog机制是怎么样的?.md
Redis/✅Redisson解锁失败,watchdog会不会一直续期下去?.md
Redis/✅Redis中key过期了一定会立即删除吗.md
Redis/✅Redis中有一批key瞬间过期,为什么其它key的读写效率会降低?.md
Redis/✅Redis中的Zset是怎么实现的?.md
Redis/✅Redis中的setnx命令为什么是原子性的.md
Redis/✅Redis为什么被设计成是单线程的?.md
Redis/✅Redis为什么要自己定义SDS?.md
Redis/✅Redis为什么这么快?.md
Redis/✅Redis如何实现发布_订阅?.md
Redis/✅Redis如何实现延迟消息?.md
Redis/✅Redis如何高效安全的遍历所有key.md
Redis/✅Redis实现分布锁的时候,哪些问题需要考虑?.md
Redis/✅Redis是AP的还是CP的?.md
Redis/✅Redis的Key和Value的设计原则有哪些?.md
Redis/✅Redis的事务和Lua之间有哪些区别?.md
Redis/✅Redis的内存淘汰策略是怎么样的?.md
Redis/✅Redis的持久化机制是怎样的?.md
Redis/✅Redis的虚拟内存机制是什么?.md
Redis/✅Redis能完全保证数据不丢失吗?.md
Redis/✅watchdog一直续期,那客户端挂了怎么办?.md
Redis/✅为什么Lua脚本可以保证原子性?.md
Redis/✅为什么Redis 6.0引入了多线程?.md
Redis/✅为什么Redis不支持回滚?.md
Redis/✅为什么Redis设计成单线程也能这么快?.md
Redis/✅为什么ZSet 既能支持高效的范围查询,还能以 O(1) 复杂度获取元素权重值?.md
Redis/✅为什么需要延迟双删,两次删除的原因是什么?.md
Redis/✅什么情况下会出现数据库和缓存不一致的问题?.md
Redis/✅什么是GEO,有什么用?.md
Redis/✅什么是RedLock,他解决了什么问题?.md
Redis/✅什么是Redis的Pipeline,和事务有什么区别?.md
Redis/✅什么是Redis的数据分片?.md
Redis/✅什么是Redis的渐进式rehash.md
Redis/✅什么是大Key问题,如何解决?.md
Redis/✅什么是热Key问题,如何解决热key问题.md
Redis/✅什么是缓存击穿、缓存穿透、缓存雪崩?.md
Redis/✅介绍一下Redis的集群模式?.md
Redis/✅介绍下Redis集群的脑裂问题?.md
Redis/✅如何在 Redis Cluster 中执行 lua 脚本?.md
Redis/✅如何基于Redisson实现一个延迟队列.md
Redis/✅如何基于Redis实现滑动窗口限流?.md
Redis/✅如何用Redisson实现分布式锁?.md
Redis/✅如何用Redis实现乐观锁?.md
Redis/✅如何用SETNX实现分布式锁?.md
Redis/✅如何用setnx实现一个可重入锁?.md
Redis/✅如何解决Redis和数据库的一致性问题?.md
Redis/✅对于 Redis 的操作,有哪些推荐的 Best Practices?.md
Redis/✅除了做缓存,Redis还能用来干什么?.md
| | | | |
| ---------------------------------------- | ------------------------------------------------------------------------------ | ----------------------------------- | --------------------------------------------------------------------------------- |
| **初步问题** | **一句话回答** | **追问** | **追问回答** |
| Redis 使用什么协议进行通信?| Redis使用RESP(Redis Serialization Protocol)协议进行通信。| RESP协议相比其他文本协议有什么特点?| RESP协议简单、快速、易于解析,并支持二进制安全。|
| RDB和AOF的写回策略分别是什么?| RDB是周期性快照,AOF有always、everysec、no三种写回策略。| `everysec`策略下,如果Redis突然宕机,会丢失多少数据?| 最多丢失1秒的数据,因为数据每秒同步一次到磁盘。|
| Redis 的过期策略是怎么样的?| Redis的过期策略主要有定时删除、惰性删除和定期删除三种。| 这三种策略是如何协同工作的?| 定时删除用于精确删除,惰性删除在访问时检查,定期删除则周期性随机抽样删除。|
| Redis 5.0中的 Stream是什么?| Stream是Redis 5.0引入的一种新的数据类型,主要用于实现消息队列和事件日志。| Stream相比List在消息队列场景下有什么优势?| Stream支持多消费者组、消息持久化和更细粒度的消费进度控制。|
| Redis Cluster 中使用事务和 lua 有什么限制?| 事务和Lua脚本都不能跨Redis Cluster节点执行,只能在一个节点上操作。| 如果需要跨节点执行原子性操作,有什么替代方案?| 可以考虑使用Redisson等客户端提供的分布式锁,或者应用层协调多个单节点操作。|
| Redis 与 Memcached 有什么区别?| Redis支持更多数据类型、持久化、复制、集群,Memcached则更简单、纯内存、并发性能更高。| 在什么场景下你会优先选择Memcached而不是Redis?| 当仅需要简单的KV缓存,对持久化、数据类型和高级功能无需求,且追求极致的并发吞吐时。|
| Redis 支持哪几种数据类型?| Redis支持String、Hash、List、Set、ZSet、Stream、GEO和Bitmap等。| 你最常用哪种数据类型?在什么场景下使用?| 我最常用String和Hash,String用于缓存简单数据,Hash用于存储对象结构。|
| Redis 的事务机制是怎样的?| Redis事务通过MULTI、EXEC、DISCARD、WATCH命令实现,保证一组命令的原子性。| Redis事务与传统数据库事务有什么区别?| Redis事务不具备回滚能力(除了语法错误),且仅保证命令的串行执行,不保证隔离性。|
| Redisson 中为什么要废弃 RedLock,该用啥?| Redisson废弃RedLock是因为其在分布式场景下存在可用性和正确性问题,推荐使用Redisson自带的分布式锁。| Redisson自带的分布式锁解决了RedLock的哪些问题?| Redisson的分布式锁通过Watchdog机制自动续期,并在大部分节点宕机时仍能保证锁的可用性。|
| Redisson 的 watchdog 什么情况下可能会失效?| Watchdog可能因网络延迟过大、Redis节点长时间阻塞或客户端GC等原因导致失效。| Watchdog失效后,分布式锁会发生什么情况?| 如果watchdog失效,锁可能在任务完成前自动释放,导致其他线程获取到锁,破坏锁的排他性。|
| Redisson和Jedis有啥区别?如何选择?| Jedis是低层级的Redis Java客户端,Redisson是基于Jedis的高级客户端,提供了更多分布式特性。| 在选择Redisson和Jedis时,你会考虑哪些因素?| 如果需要分布式锁、分布式对象等高级功能,选择Redisson;如果仅需基本Redis操作且追求性能极致,选择Jedis。|
| Redisson如何保证解锁的线程一定是加锁的线程?| Redisson通过在加锁时存储线程ID和客户端ID,解锁时进行比对来保证。| 如果获取锁的客户端崩溃,锁没有被正确释放怎么办?| Redisson的Watchdog机制会根据锁的有效期自动释放锁,避免死锁。|
| Redisson的lock和tryLock有什么区别?| `lock()`是阻塞的,直到获取到锁;`tryLock()`是非阻塞的,尝试获取锁,如果失败立即返回。| 在什么场景下你会优先使用`tryLock()`而不是`lock()`?| 在需要避免线程长时间阻塞,或者需要快速失败并进行其他操作的场景下。|
| Redisson的watchdog机制是怎么样的?| Watchdog会为获取到锁的线程自动续期,避免因业务执行时间过长导致锁自动释放。| Watchdog的续期周期是多久?可以配置吗?| 默认续期周期是10秒,可以通过Redisson配置进行调整。|
| Redisson解锁失败,watchdog会不会一直续期下去?| 不会。如果解锁失败,watchdog会在下一次续期检查时发现锁已过期或不存在,便停止续期。| 在Redisson解锁失败时,如何确保锁最终被释放?| Watchdog机制会根据锁的超时时间自动释放,或者通过人工干预强制释放。|
| Redis中key过期了一定会立即删除吗?| 不一定。Redis通过惰性删除和定期删除策略来处理过期key,不保证立即删除。| 惰性删除有什么优点和缺点?| 优点是减少CPU开销,缺点是可能导致内存中存在大量过期但未删除的key。|
| Redis中有一批key瞬间过期,为什么其它key的读写效率会降低?| 大量key同时过期会导致定期删除策略的CPU开销增加,影响其他操作的响应时间。| 如何避免大量key瞬间过期导致的问题?| 可以将key的过期时间分散开,或者使用Redis 4.0+的过期事件通知来异步处理。|
| Redis中的Zset是怎么实现的?| Zset底层使用跳跃表(skiplist)和哈希表(hashtable)实现。| 跳跃表相比平衡树,在Zset的实现中有哪些优势?| 跳跃表实现更简单,内存占用更小,且在大部分操作上性能与平衡树相近。|
| Redis中的setnx命令为什么是原子性的?| `setnx`命令是原子性的,因为Redis是单线程处理命令的,避免了并发冲突。| `setnx`在实现分布式锁时有什么局限性?| `setnx`需要手动设置过期时间,且不具备可重入性和自动续期功能。|
| Redis为什么被设计成是单线程的?| Redis是单线程的,可以避免线程切换和锁的开销,从而提高执行效率。| 单线程模型如何处理网络IO?| Redis使用I/O多路复用技术(如Epoll/Kqueue)来处理并发连接。|
| Redis为什么要自己定义SDS?| Redis定义了简单动态字符串(SDS)来存储字符串,解决了C语言字符串的缓冲区溢出和获取长度效率低的问题。| SDS相比C字符串有什么优点?| SDS支持二进制安全,能高效获取长度,并具有空间预分配和惰性空间释放特性。|
| Redis为什么这么快?| Redis快是因为其基于内存操作、单线程模型、I/O多路复用、高效的数据结构以及C语言实现。| 这些因素中,你认为哪个对Redis的性能影响最大?| 我认为是内存操作和单线程模型,它们显著减少了I/O等待和并发竞争的开销。|
| Redis如何实现发布/订阅?| Redis通过PUB/SUB命令实现发布/订阅模式,发布者将消息发送到频道,订阅者接收频道消息。| 发布/订阅模式在Redis中有什么缺点?| 消息不持久化,如果订阅者离线则会丢失消息;不保证消息的可靠性。|
| Redis如何实现延迟消息?| 延迟消息可以通过ZSet(利用score存储时间戳)或Redis Stream结合Consumer Group实现。| ZSet实现延迟消息的优缺点是什么?| 优点是实现简单,缺点是需要客户端定时轮询,可能导致大量无效操作。|
| Redis如何高效安全的遍历所有key?| Redis通过`SCAN`命令进行渐进式迭代,避免阻塞Redis服务器。| 为什么不推荐使用`KEYS`命令遍历所有key?| `KEYS`命令会阻塞Redis服务器,在生产环境中可能导致性能问题甚至服务不可用。|
| Redis实现分布锁的时候,哪些问题需要考虑?| 需要考虑锁的互斥性、死锁、可重入性、公平性、高可用性和性能。| 在你的经验中,哪个问题最难解决?| 死锁问题通常是最难解决的,需要复杂的机制如看门狗或超时释放来保证。|
| Redis是AP的还是CP的?| Redis在单机模式下是AP,集群模式下更倾向于CP但不是严格的CP,是最终一致性。| 解释一下Redis Cluster在网络分区下的行为。| 在网络分区时,Redis Cluster的从节点可能会晋升为主节点,导致旧的主节点数据可能丢失,但集群仍能对外提供服务。|
| Redis的Key和Value的设计原则有哪些?| Key要短小精悍、有意义、避免大Key;Value根据业务选择合适的数据结构,避免大Value。| 大Key问题会带来什么影响?| 大Key会导致网络传输慢、内存碎片、删除时阻塞等问题,影响Redis性能。|
| Redis的事务和Lua之间有哪些区别?| 事务保证命令原子性但不回滚,Lua脚本保证原子性且可在脚本内执行复杂逻辑。| 在什么场景下你会优先选择Lua脚本而不是Redis事务?| 当需要执行复杂的多步操作,且这些操作需要强原子性并可能涉及分支判断时。|
| Redis的内存淘汰策略是怎么样的?| Redis的内存淘汰策略包括noeviction、allkeys-lru、volatile-lru、allkeys-random等。| LRU和LFU策略有什么区别?| LRU(Least Recently Used)淘汰最近最少使用的key,LFU(Least Frequently Used)淘汰最不经常使用的key。|
| Redis的持久化机制是怎样的?| Redis提供RDB(快照)和AOF(只追加文件)两种持久化机制。| RDB和AOF各自的优缺点是什么?| RDB恢复快但可能丢失数据,AOF数据完整性高但文件大恢复慢。|
| Redis的虚拟内存机制是什么?| Redis 2.4版本之前曾有虚拟内存机制,可以将冷数据交换到磁盘,但后来被废弃。| 为什么Redis废弃了虚拟内存机制?| 虚拟内存会增加复杂性,引入额外的I/O开销,且与操作系统的虚拟内存机制冲突。|
| Redis能完全保证数据不丢失吗?| 不能完全保证。在RDB和AOF的everysec策略下,仍可能丢失少量数据。| 如何最大限度地保证Redis数据不丢失?| 结合AOF的always策略和RDB,同时配置主从复制,并开启AOF fsync always。|
| watchdog一直续期,那客户端挂了怎么办?| Redisson的watchdog依赖客户端线程存活,若客户端挂掉,watchdog无法续期,锁会根据超时时间自动释放。| 在生产环境中,客户端挂了导致锁未释放的情况,有什么措施可以减轻影响?| 可以在应用层面实现锁的监控和告警,并设置合理的锁超时时间,结合看门狗机制。|
| 为什么Lua脚本可以保证原子性?| Redis是单线程执行命令的,Lua脚本在执行过程中不会被其他命令打断。| Lua脚本的原子性对开发有什么帮助?| 可以确保一组复杂操作的原子性,避免并发问题和数据不一致。|
| 为什么Redis 6.0引入了多线程?| Redis 6.0引入多线程主要是为了处理网络I/O,提升大带宽场景下的性能,并非多线程处理命令。| Redis 6.0的多线程是否会引入锁竞争问题?| 不会。多线程只用于处理网络I/O和数据解析,核心命令执行仍是单线程。|
| 为什么Redis不支持回滚?| Redis事务的命令是按顺序添加到队列中,执行时不会检查语义错误,仅在语法错误时才会失败。| Redis不支持回滚对实际开发有什么影响?| 开发者需要确保事务内的逻辑正确性,避免因业务逻辑错误导致数据不一致。|
| 为什么Redis设计成单线程也能这么快?| Redis快得益于纯内存操作、高效I/O多路复用、精心优化的数据结构和C语言实现。| 这些因素中,哪些是Redis速度的关键?| 内存访问速度、非阻塞I/O以及避免了多线程上下文切换和锁竞争的开销。|
| 为什么ZSet 既能支持高效的范围查询,还能以 O(1) 复杂度获取元素权重值?| ZSet结合了跳跃表(范围查询)和哈希表(O(1)获取权重值)的优势。| 跳跃表在范围查询中的具体优势体现在哪里?| 跳跃表通过多层索引,使得跳跃查找成为可能,从而实现对数级的查询复杂度。|
| 为什么需要延迟双删,两次删除的原因是什么?| 延迟双删是为了解决缓存和数据库数据不一致的问题,两次删除是为了确保删除操作最终成功。| 延迟双删的具体流程是怎样的?| 先删除缓存,再更新数据库,然后延迟一段时间后再次删除缓存。|
| 什么情况下会出现数据库和缓存不一致的问题?| 在高并发场景下,先删除缓存再更新数据库,或先更新数据库再删除缓存,都可能导致不一致。| 如何解决数据库和缓存不一致的问题?| 可以采用延迟双删、消息队列、或者读写分离等方案。|
| 什么是GEO,有什么用?| GEO是Redis 3.2引入的地理空间数据类型,用于存储地理位置信息并进行地理位置计算。| GEO的底层数据结构是什么?| GEO底层基于ZSet实现,利用Geohash算法将经纬度编码为一维的整数值。|
| 什么是RedLock,他解决了什么问题?| RedLock是分布式锁的一种算法,旨在解决单机Redis锁的单点故障问题。| RedLock的缺点和争议在哪里?| RedLock在实际分布式环境下的可靠性受到质疑,因为它对时间同步和故障情况的假设过于理想。|
| 什么是Redis的Pipeline,和事务有什么区别?| Pipeline是将多个命令打包一次发送,减少网络开销;事务是保证命令的原子性执行。| Pipeline和事务可以同时使用吗?| 可以。事务内的命令可以打包到Pipeline中,提高原子性操作的效率。|
| 什么是Redis的数据分片?| 数据分片是将Redis的数据分散存储到多个Redis实例中,以扩展存储容量和吞吐量。| Redis Cluster是如何实现数据分片的?| Redis Cluster通过哈希槽(hash slot)机制将数据自动分配到集群中的各个节点。|
| 什么是Redis的渐进式rehash?| 渐进式rehash是Redis在进行哈希表扩容或收缩时,分批次将数据从旧哈希表迁移到新哈希表,避免阻塞。| 渐进式rehash在什么情况下会被触发?| 当哈希表的使用率达到一定阈值或执行`BGSAVE`等操作时,可能会触发渐进式rehash。|
| 什么是大Key问题,如何解决?| 大Key是指存储的数据量过大的Key,会影响Redis性能;可以通过拆分、压缩或更换数据结构解决。| 你在实际项目中如何发现大Key问题?| 可以通过`redis-cli --bigkeys`命令或Redis监控工具来发现大Key。|
| 什么是热Key问题,如何解决热key问题?| 热Key是指被高频访问的Key,会导致单个Redis节点压力过大;可以通过多级缓存、Key分散或只读副本解决。| 解决热Key问题的常见方法有哪些?| 可以通过引入本地缓存、将热Key分散到多个Redis实例或使用读写分离和只读副本。|
| 什么是缓存击穿、缓存穿透、缓存雪崩?| 缓存击穿是单个热Key过期瞬间大量请求穿透到DB;缓存穿透是查询不存在的Key穿透到DB;缓存雪崩是大量Key同时过期导致DB压力骤增。| 如何有效地解决缓存穿透问题?| 可以通过布隆过滤器、缓存空值或API限流来解决缓存穿透问题。|
| 介绍一下Redis的集群模式?| Redis集群是一种分布式解决方案,通过分片和主从复制实现高可用和可伸缩性。| Redis集群的故障转移是如何工作的?| 当主节点故障时,集群中的从节点会自动晋升为新的主节点,保证服务的可用性。|
| 介绍下Redis集群的脑裂问题?| 脑裂是指Redis集群在网络分区时,多个节点都认为自己是主节点,导致数据不一致。| 如何避免Redis集群的脑裂问题?| 可以通过配置最小主节点数(`cluster-node-timeout`、`cluster-require-full-coverage`)或Quorum机制来避免。|
| 如何在 Redis Cluster 中执行 lua 脚本?| 在Redis Cluster中执行Lua脚本需要确保脚本操作的所有Key都在同一个哈希槽上。| 如果Lua脚本需要操作不同哈希槽的Key怎么办?| 无法在同一个Lua脚本中原子性操作不同哈希槽的Key,需要拆分为多个脚本或在客户端进行协调。|
| 如何基于Redisson实现一个延迟队列?| 可以利用Redisson的RBlockingDeque或RDelayedQueue结合`RBatch`和`RExecutorService`来实现延迟队列。| Redisson实现延迟队列相比ZSet有哪些优势?| Redisson的延迟队列封装了更多分布式特性,如自动续期、分布式执行等,简化了开发。|
| 如何基于Redis实现滑动窗口限流?| 可以利用Redis的ZSet数据结构,将请求时间戳作为score,用range命令统计窗口内的请求数。| 滑动窗口限流相比计数器限流有什么优势?| 滑动窗口限流更平滑,能够防止短时间内的突发流量,提供更精确的控制。|
| 如何用Redisson实现分布式锁?| 通过`RedissonClient.getLock("myLock").lock()`方法即可实现分布式锁。| Redisson分布式锁的可重入性是如何实现的?| Redisson在加锁时会记录当前线程的持有次数,同一线程可以多次获取同一个锁。|
| 如何用Redis实现乐观锁?| Redis通过`WATCH`命令监视Key,在事务执行前检查Key是否被修改,实现乐观锁。| 乐观锁在什么场景下比较适用?| 适用于读多写少,并发冲突概率较低的场景,避免了悲观锁的性能开销。|
| 如何用SETNX实现分布式锁?| 通过`SETNX key value`命令尝试获取锁,如果设置成功则表示获取到锁,并通过`EXPIRE`设置过期时间。| `SETNX`实现分布式锁的缺点有哪些?| 不具备可重入性、无法自动续期、容易产生死锁(如果忘记设置过期时间)。|
| 如何用setnx实现一个可重入锁?| 在`SETNX`的基础上,需要额外存储当前线程的持有次数,并在重入时增加计数。| 这种手动实现可重入锁的复杂性在哪里?| 需要维护额外的数据结构来记录线程和计数,且在高并发下容易出错。|
| 如何解决Redis和数据库的一致性问题?| 可以采用延迟双删、消息队列、事务补偿、读写分离等方案来保证一致性。| 在你接触过的项目中,哪种方案最常用?| 延迟双删和结合消息队列的方案在实际项目中比较常用。|
| 对于 Redis 的操作,有哪些推荐的 Best Practices?| 合理设计Key和Value、避免大Key和热Key、利用Pipeline、选择合适的持久化和淘汰策略、注意Redis Cluster的限制等。| 你认为在实际开发中,最容易被忽视的Best Practice是什么?| 我觉得是Key和Value的合理设计,尤其是在数据量大或高并发的场景下,不合理的设计会带来很多隐患。|
| 除了做缓存,Redis还能用来干什么?| Redis可以用于分布式锁、计数器、排行榜、消息队列、实时统计、Session存储、地理位置服务等。| 在这些非缓存应用中,你认为哪个最具代表性?| 分布式锁,因为它充分利用了Redis的原子性和高性能特点,解决了分布式系统中的并发问题。|