当前位置:   article > 正文

初识Redis分布式锁:_redis锁查看

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的操作,并且这种操作是原子操作。

  1. set key value [EX seconds] [PX milliseconds] [NX|XX]
  2. EX seconds:设置失效时长,单位秒
  3. PX milliseconds:设置失效时长,单位毫秒
  4. NX:key不存在时设置value,成功返回OK,失败返回(nil)
  5. XX:key存在时设置value,成功返回OK,失败返回(nil)
  6. 案例:设置name=p7+,失效时长100s,不存在时设置
  7. 1.1.1.1:6379> set name p7+ ex 100 nx
  8. OK
  9. 1.1.1.1:6379> get name
  10. "p7+"
  11. 1.1.1.1:6379> ttl name
  12. (integer) 94

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/561506
推荐阅读
相关标签
  

闽ICP备14008679号