redis 正确实现分布式锁的正确方式
前言
最近在自己所管理的项目中,发现redis加锁的方式不对,在高并发的情况有问题。故在网上找搜索了一把相关资料。发现好多都是互相抄袭的,很多都是有缺陷的。好多还在用redis 的 setnx命令来实现分布式锁。其实redis 中的set命令本身就已经集成了setnx命令的功能了,而且比其还强大。这里,我使用 redis-cli 客户端 结合lua脚本 原生 的实现redis 分布式锁。
准备材料
- redis-server
- redis-cli
LUA 与 REDIS 的关系
从 redis2.6.0 开始, redis 内部就内置了lua解释器。lua也就是成了redis扩展的一种解决方案了。
格式:
eval scripts num [keys ...] [argv ...]
- eval : redis中执行lua脚本的命令
- scripts : lua脚本,不必一定得是lua函数
- num : keys 的个数,用于区分 keys 和 argv ;没有keys,则写0
- keys: 可变数组,一般用于表示redis 的键,下标从1 开始
- argv: 可变数组,一般用于表示redis 的值,下标从1 开始
redis 与 lua 的交互

分两种情况:
- redis 执行 lua 脚本 : 使用 redis中的 eval命令 即可
- lua & redis
- lua 接收 redis 发送过来的数据 , 在 SCRIPTS中使用 KEYS[] 与 ARGV[]
- lua 调用redis 命令, 在SCRIPTS中使用 call() 或者 pcall()
- lua 将结果返回给redis , 使用return
案例解析
1.利用lua 打印参数
127.0.0.1:6379> eval "return {KEYS[1],ARGV[1],ARGV[2]}" 3 key1 key2 first second threed
1) "key1"
2) "second"
3) "threed"

2.通过lua 设置变量
# 设置一个 foo='hello' 键值对
127.0.0.1:6379> eval "return redis.call('set','foo','hello')" 0
OK
127.0.0.1:6379> scan 0
1) "0"
2) 1) "foo"
127.0.0.1:6379> get foo
"hello"
127.0.0.1:6379>
3.通过lua 传参的方式 设置变量
127.0.0.1:6379> eval "return redis.call('set',KEYS[1],ARGV[1])" 1 name Bob
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"Bob"
127.0.0.1:6379>
4. 利用redis-cli 设置分布式锁
# 加锁 , 直接使用 set nx模式 【生产环境中123456 是一个唯一的随机数】
127.0.0.1:6379> set lock 123456 EX 40 NX
OK
# 解锁 , 结合 lua脚本
127.0.0.1:6379> eval "if redis.call('get','lock') == ARGV[1] then return redis.call('del','lock') else return 0 end" 0 123456
(integer) 1
127.0.0.1:6379> get lock
(nil)
上面的lua脚本格式化后的样子如下:
if redis.call('get','lock') == ARGV[1]
then
return redis.call('del','lock')
else
return 0
end
redis 正确实现分布式锁的正确方式的更多相关文章
- Redis系列四 - 分布式锁的实现方式
前言 分布式锁一般有3中实现方式: 数据库乐观锁: 基于Redis的分布式锁: 基于ZooKeeper的分布式锁. 以下将详细介绍如何正确地实现Redis分布式锁. 可靠性 首先,为了确保分布式锁的可 ...
- 一个Redis实现的分布式锁
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.conne ...
- Redis实现分布式锁的正确使用方式(java版本)
Redis实现分布式锁的正确使用方式(java版本) 本文使用第三方开源组件Jedis实现Redis客户端,且只考虑Redis服务端单机部署的场景. 分布式锁一般有三种实现方式: 1. 数据库乐观锁: ...
- 基于Redis分布式锁的正确打开方式
分布式锁是在分布式环境下(多个JVM进程)控制多个客户端对某一资源的同步访问的一种实现,与之相对应的是线程锁,线程锁控制的是同一个JVM进程内多个线程之间的同步.分布式锁的一般实现方法是在应用服务器之 ...
- 【分布式缓存系列】集群环境下Redis分布式锁的正确姿势
一.前言 在上一篇文章中,已经介绍了基于Redis实现分布式锁的正确姿势,但是上篇文章存在一定的缺陷——它加锁只作用在一个Redis节点上,如果通过sentinel保证高可用,如果master节点由于 ...
- 【分布式缓存系列】Redis实现分布式锁的正确姿势
一.前言 在我们日常工作中,除了Spring和Mybatis外,用到最多无外乎分布式缓存框架——Redis.但是很多工作很多年的朋友对Redis还处于一个最基础的使用和认识.所以我就像把自己对分布式缓 ...
- Redis全方位详解--数据类型使用场景和redis分布式锁的正确姿势
一.Redis数据类型 1.string string是Redis的最基本数据类型,一个key对应一个value,每个value最大可存储512M.string一半用来存图片或者序列化的数据. 2.h ...
- 如何用redis正确实现分布式锁?
先把结论抛出来:redis无法正确实现分布式锁!即使是redis单节点也不行!redis的所谓分布式锁无法用在对锁要求严格的场景下,比如:同一个时间点只能有一个客户端获取锁. 首先来看下单节点下一般r ...
- 七种方案!探讨Redis分布式锁的正确使用姿势
前言 日常开发中,秒杀下单.抢红包等等业务场景,都需要用到分布式锁.而Redis非常适合作为分布式锁使用.本文将分七个方案展开,跟大家探讨Redis分布式锁的正确使用方式.如果有不正确的地方,欢迎大家 ...
随机推荐
- Set-Get(?占位符)-Java(新手)
创建实体类: package JdbcDome; public class EmpL { private int uid; private String uNAME; private int age; ...
- SpringMVC框架——数据绑定
Spring MVC 数据绑定 使用POJO绑定参数 entity package com.sunjian.entity; /** * @author sunjian * @date 2020/3/1 ...
- Journal of Proteome Research | iHPDM: In Silico Human Proteome Digestion Map with Proteolytic Peptide Analysis and Graphical Visualizations(iHPDM: 人类蛋白质组理论酶解图谱的水解肽段分析和可视化展示)| (解读人:邓亚美)
文献名:iHPDM: In Silico Human Proteome Digestion Map with Proteolytic Peptide Analysis and Graphical Vi ...
- 条件随机场 CRF
2019-09-29 15:38:26 问题描述:请解释一下NER任务中CRF层的作用. 问题求解: 在做NER任务的时候,神经网络学习到了文本间的信息,而CRF学习到了Tag间的信息. 加入CRF与 ...
- Java 访问修饰符大全详解
鉴于笔试面试总会遇到,决心仔细认真梳理一下: 1:涉及的关键字:public,default(表示缺省),protected,private,static,final,abstract. 2:关键字含 ...
- 插入排序与Shell排序
ElementType ShellSort( ElementType A[], int N ) { ;h>;h/=){ for(int i=h;i<N;i++){ ElementType ...
- Vue2.0 -- 钩子函数/ 过度属性/常用指令/以及Vue-resoure发送请求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- FME中矢量裁剪
- 【LeetCode】141.环形链表
题目描述 141.环形链表 给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中 ...
- Python终端打印彩色文字
终端彩色文字 class Color_f: black = 30 red = 31 green = 32 yellow= 33 blue = 34 fuchsia=35 cyan = 36 white ...