redis如何实现分布式锁


本文摘自PHP中文网,作者(*-*)浩,侵删。

分布式锁需要解决的问题

互斥性:任意时刻只能有一个客户端拥有锁,不能同时多个客户端获取

安全性:锁只能被持有该锁的用户删除,而不能被其他用户删除 (推荐学习:Redis视频教程)

死锁:获取锁的客户端因为某些原因而宕机,而未能释放锁,其他客户端无法获取此锁,需要有机制来避免该类问题的发生

容错:当部分节点宕机,客户端仍能获取锁或者释放锁

如何通过Redis实现分布式锁:(非完善方法)

SETNX key value :如果key不存在,则创建并赋值

时间复杂度: 0(1)

返回值:设置成功,返回1;设置失败,返回0。

但是此时我们获取的key是长期有效的,所以我们应该如何解决长期有效的问题呢?

EXPIRE key seconds

设置key的生存时间,当key过期时(生存时间为0) ,会被自动删除

缺点:原子性得不到满足

下面是伪代码

1

2

3

4

5

6

7

8

//该程序存在危险,如果执行到第二行就崩溃了,则此时key会被一直占用而无法被释放

RedisService redisService = SpringUtils.getBean(Redi sService.class);

long status = redisService.setnx(key, "1");

if(status == 1) {

    redisService.expire(key, expire);

    //执行独占资源逻辑

    doOcuppiedWork();

}

如何通过Redis实现分布式锁:(正确方式)

1

SET key value [EX seconds] [PX milliseconds] [NX|XX]

EX second :设置键的过期时间为second秒

PX millisecond :设置键的过期时间为millisecond毫秒

NX :只在键不存在时,才对键进行设置操作

XX:只在键已经存在时,才对键进行设置操作

SET操作成功完成时,返回OK ,否则返回nil

下面是伪代码

1

2

3

4

5

6

RedisService redisService = SpringUtils.getBean(RedisService.class); .

String result = redisService.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);

if ("OK".equals(result)) {

    //执行独占资源逻辑

    doOcuppiedWork();

}

大量的key同时过期的注意事项

集中过期,由于清除大量的key很耗时,会出现短暂的卡顿现象

解放方案:在设置key的过期时间的时候,给每个key加上随机值

更多Redis相关技术文章,请访问Redis入门教程栏目进行学习!

以上就是redis如何实现分布式锁的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

Redis字符串类型的几种应用

Redis讲解主从复制和哨兵模式

Redis是线程安全的吗

Redis注册成window服务的方法介绍

Redis info命令介绍

Redis集群中的节点分为哪两个

为什么用Redis缓存

如何实时监控Redis性能

Redis是内存数据库吗

php为什么使用Redis

更多相关阅读请进入《Redis》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...