初识Redis分布式锁:

Redis支持数据的持久化,可以将在内存中的数据保存在磁盘中,而且在重启的时候,是可以再次加载并进行使用的,. redis不仅仅支持简单的key-value类型数据,同时还提供其他众多的数据类型.

Redis是采用单进程的方式,单进程模型来处理客户端请求,对读写等事件的响应式通过epoll函数的包装来做的,Redis的实际处理速度完全依赖主进程的执行效率.

Epoll是linux内核为处理大批量文件描述符而作了改进的epoll,是linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的下同CPU利用率。2、默认16个库,类似数组下标从零开始,初始默认使用零号库。

select命令可以切换数据库

Dbsize查看当前数据库的key的数量

Flushdb:清空当前库

flushall:通杀全部库

统一密码管理,16个库都是同样密码,要么都ok要么一个也连接不上。

Redis索引都是从零开始。

默认端口是6379

redis常见的应用场景:

热点数据的缓存.

限时业务的运用

计数器相关问题

排行榜相关问题

分布式锁: 通过redis来编写分布式的锁.

延时操作:

社交网络:

消息系统:

因为redis支持的应用场景较多,所以在很多情况下都可以使用到Redis的分布式锁机制.

常见的方式:

  1. 基于redis命令行方式: 加锁: 执行setnx,若成功再执行expire添加过期时间, 解锁: 执行delete命令.;

优点: 实现简单,相比数据库和分布式系统的实现,该方案最轻,性能最好

缺点: sentnxexpire2步执行,非原子操作,如果sentnx执行成功,expire执行失败,就有可能造成死锁,(因为expire是给锁加上过期时间,到时间会自动释放锁和资源.)

.delete命令存在误删除非当前线程持有的锁的可能.不支持阻塞等待、不可重入

2,.基于Redis Lua脚本: 加锁: 执行SET lock_name random_value EX seconds NX 命令

解锁: 执行Lua脚本,释放锁时验证random_value

优点: 同上;实现逻辑上也更严谨。

缺点: 不支持锁重入,不支持阻塞等待

线程锁,进程锁,分布式锁:

线程锁:

主要用来给方法,代码块加锁,在同一时刻仅由一个线程在执行该方法或该代码段,线程锁只在同一个jvm(java虚拟机)中有效果.因为线程锁的实现在根本上是依靠线程之间共享内存实现. 比如Synchronized、Lock等。

进程锁:

为了控制同一操作系统中多个进程访问某个共享资源,因为进程具有独立性,各个进程无法访问其他进程的资源,因此无法通过synchronized等线程锁实现进程锁。

分布式锁:

当多个进程不在同一个系统中,用分布式锁控制多个进程对资源的访问,

分布式锁需要满足的四个条件:

  1. 互斥性: 在任意时刻只能有一个客户端持有锁
  2. 不会发生死锁:即是有一个客户端在持有锁期间崩溃,而没有主动解锁后,也要能保证其他客户端能够加锁,
  3. 安全性: 加锁和解锁必须是同一个客户端,客户端不能去修改别人的锁
  4. 容错性: 当部分节点宕机,客户端任然能够获得锁和释放锁.

基于Redis命令实现分布式锁:

setnx命令格式: setnx key value

 将 key 的值设为 value,当且仅当 key 不存在。

若给定的 key 已经存在,则 SETNX 不做任何动作。

SETNX 是SET if Not eXists的简写

返回值:

-1, 当key的值被设置

-0 当key的值没被设置

使用SETNX实现分布式锁

多个进程执行以下Redis命令:

SETNX lock.foo <current Unix time + lock timeout >

如果setnx返回1,说明该进程获得锁,setnx将键lock.foo的值设置为锁的超时时间(当前时间 + 锁的有效时间)。

如果 SETNX 返回0,说明其他进程已经获得了锁,进程不能进入临界区。进程可以在一个循环中不断地尝试 SETNX 操作,以获得锁。

解决死锁:

如果在setnx之后执行expire执行之前进程出现意外crash或者要重启维护,.这样会导致锁不会进行释放,导致死锁发生,. 因为setnx不能保证操作的原子性. 这里可以通过set命令完成对setnx和expire的操作,并且这种操作是原子操作。

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

EX seconds:设置失效时长,单位秒

PX milliseconds:设置失效时长,单位毫秒

NX:key不存在时设置value,成功返回OK,失败返回(nil)

XX:key存在时设置value,成功返回OK,失败返回(nil)



案例:设置name=p7+,失效时长100s,不存在时设置

1.1.1.1:6379> set name p7+ ex 100 nx

OK

1.1.1.1:6379> get name

"p7+"

1.1.1.1:6379> ttl name

(integer) 94

从上面,看到,将多个命令放在Redis链接中,并且Redis是单线程, 因此上面的操作可以看成setnx和expire的结合体,是原子性的。

还可以使用watchDog,使用该机制来为Redis中key值进行锁续命,防止业务处理时间过程,key过期,导致误删key.可以用lua脚本对Redis进行指令的原子性操作, 注意 lua脚本中不能有复杂逻辑,防止阻塞redis

这里补充下: 从2.6.12版本后, 就可以使用set来获取锁, Lua 脚本来释放锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴爃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值