方案一:SETNX加EXPIRE
这是最简单的方法,先设置一个键值对,再设置过期时间,但两个命令可能失败,导致锁无法释放。
方案二:SET NX EX
Redis 2.8后支持SET命令带NX和EX选项,一步完成设置键和过期时间,减少了风险。
方案三:Redlock算法
Redlock算法涉及多个Redis实例,大多数实例获取成功才算获得锁,提高了可靠性,但实现复杂。
方案四:Lua脚本
使用Lua脚本可以原子性地执行SETNX和EXPIRE,避免竞争条件,是单节点下的好选择。
方案五:Redisson框架
Redisson提供了现成的分布式锁实现,支持多种模式,包括可重入锁、公平锁,适合Java项目。
方案六:基于数据库的锁
基于数据库的分布式锁,性能较差,不推荐使用。
方案七:ZooKeeper等外部系统
使用ZooKeeper或etcd等系统实现分布式锁,适合高一致性场景,但引入额外依赖。
立即了解选择指南
如果只是单Redis节点,推荐SET NX EX或Lua脚本;如果需要高可靠性,选择Redlock;如果项目用Java,用Redisson最省事;不建议用数据库,复杂性项目可考虑ZooKeeper。
FAQ
问题1:为什么分布式锁需要设置过期时间?
避免死锁,如果持有锁的客户端崩溃,过期后锁自动释放,其他客户端可以获取。
问题2:Redlock算法真的安全吗?
有争议,在极端情况下可能出现问题,但大多数场景下足够可靠,可根据需求选择。
问题3:如何选择合适的方案?
根据项目复杂度、性能要求和团队经验决定,简单场景用SET NX EX,复杂高可用用Redlock或Redisson。
引用来源
本文基于Redis官方文档、Martin Kleppmann的分布式锁分析以及实践经验总结。具体可参考Redis官网和Redisson文档。