Redis——分布式锁

什么是分布式锁

  1. 分布式锁: 进行逻辑处理时经常会遇到并发问题。可以借助redis来实现分布式锁,简单来说就是限制两个操作不同时进行,每次执行某个操作的时候用setnx()加锁,当没被锁再执行下一个操作.限制程序的并发执行!
  2. 一般步骤: 使用 setnx(set if not exists) 指令,只允许被一个客户端占坑。先来先占,用完了,再调用 del 指令释放茅坑。
  3. setnx lock:XXX true

分布式锁问题

  1. 锁的释放问题: 如果执行到一半出现问题,没有执行del释放锁,那么锁就得不到释放

    可以给锁加个expire过期时间

  2. 锁的超时问题: 当设置过期时间比较短的时候,可能程序还未执行完毕,锁已经超时过期了.第二个线程重新持有了这把锁, 但是紧接着第一个线程执行完了业务逻辑,就把锁给释放了,第三个线程就会在第二个线程逻 辑执行完之间拿到了锁。(超时后使用del 导致误删其他线程的锁)

    • 分布式锁不要用于长时间的任务
    • 给value设置一个随机数,释放的时候匹配随机数是否一致再删除
    • 编写守护进程,当一个锁快要过期的时候,任务还未结束,可以给锁续一波命(过期时间),任务结束关闭该守护进程

lua脚本实现匹配和删除的一个原子操作

	# delifequals
	if redis.call("get",KEYS[1]) == ARGV[1] 
	then
		return redis.call("del",KEYS[1])
	else
		return 0
	end
<?php
// php中使用redis执行lua脚本
$lua = <<<SCRIPT
     lua代码
SCRIPT;
$s = $redis->eval($lua,'参数');
  1. 请求加锁失败的处理:
    • 抛出异常,稍后重试
    • 将请求添加到延时队列
    • sleep几秒钟

分布式锁应用场景

  1. 订单等并发请求
  2. 任务队列
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章