面试题答案
一键面试Redis分布式锁常用过期策略
- 定时删除: 在设置键的过期时间的同时,创建一个定时器,当过期时间到达时,由定时器立即执行对键的删除操作。此策略对内存友好,能及时释放过期键的内存空间,但会对CPU不友好,因为需要额外创建定时器,且大量过期键集中过期时,会产生较高的CPU负载。
- 惰性删除: 键过期了也不主动删除,每次从键空间获取键时,都检查一下该键是否过期,如果过期就删除,返回空。此策略对CPU友好,只有在访问到过期键时才进行删除操作,但对内存不友好,若过期键长时间未被访问,会一直占用内存。
- 定期删除: 每隔一段时间,对数据库进行一次检查,随机抽查一部分键并删除其中过期的键。此策略是前两者的折中,通过合理设置抽查频率和每次抽查的键数量,来平衡CPU性能和内存空间的使用。
自动续期基本实现思路
- WatchDog机制:
- 原理:在获取锁的同时,启动一个后台线程(可以是守护线程)作为WatchDog。WatchDog会周期性地检查锁是否快要过期,如果快要过期且当前线程仍然持有锁,就自动延长锁的过期时间。
- 实现步骤:
- 获取锁:客户端尝试获取Redis分布式锁时,设置一个较短的初始过期时间(例如30秒),同时启动WatchDog线程。
- WatchDog检查:WatchDog线程按照一定的时间间隔(如10秒)检查锁的剩余过期时间。如果剩余过期时间小于某个阈值(如5秒),且当前线程仍然持有锁(可通过Lua脚本原子性地判断和续期),则执行续期操作,例如将过期时间延长30秒。
- 停止WatchDog:当客户端释放锁时,要同时停止WatchDog线程,避免其继续运行造成资源浪费。
- 使用Redisson框架: Redisson框架内部实现了自动续期功能。它在获取锁时,会默认开启一个WatchDog,以确保锁在持有期间不会过期。Redisson通过发送Lua脚本到Redis服务器,原子性地完成锁的获取、续期和释放操作,保证了操作的原子性和一致性。具体实现中,Redisson会维护一个时间戳记录锁的获取时间,通过比较当前时间与获取时间来判断锁是否仍然有效,并在需要时进行续期操作。