http://zhangtielei.com/posts/blog-redlock-reasoning.html

链接里这篇 blog 讨论了 redis 分布式锁的实现以及安全性

我要参考 基于单Redis节点的分布式锁,实现一个 基于单Redis节点的分布式读写锁

先是想到一个不是很好的方案

read lock

eval "if not redis.call('GET', KEYS[1]) then return redis.call('SET', KEYS[2] .. '.' .. ARGV[1], ARGV[1], 'NX', 'PX', ARGV[2]) end" 2 rwlock.write rwlock.read unique_value 300000

write lock 分两步,第一步 SET 成功且第二步返回空,则写锁成功。第二步等待所有的读都解锁,只是这个 KEYS 命令效率太低,所以说这不是一个好方案

SET rwlock.write unique_value NX PX 300000
KEYS rwlock.read.*

read unlock

DEL rwlock.read.unique_value

write unlock

eval "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end" 1 rwlock.write unique_value

这个读写锁有个好处,当有人等待可写状态时,不会再有新的人增加读状态的人数,所以不会有等到死也等不来可写状态的事情发生

好一点的读写锁

参考 https://github.com/redisson/redisson/blob/master/redisson/src/main/java/org/redisson/RedissonReadLock.java

额外弄一个 hash table 存取读的信息,避免用 KEYS 命令。大致步骤如下

read lock

eval
"if not redis.call('GET', KEYS[1]) then
redis.call('HSET', KEYS[2], ARGV[1], ARGV[2])
redis.call('SET', ARGV[1], ARGV[2], 'PX', ARGV[2])
local t = redis.call('PTTL', KEYS[2])
redis.call('PEXPIRE', KEYS[2], math.max(t, ARGV[2]))
end" 2 rwlock.write rwlock.read unique_value 300000

write lock

SET rwlock.write unique_value NX PX 300000
EXISTS rwlock.read  // 这里等待的时候应该不断地更新 rwlock.write 的过期时间

read unlock

"if redis.call('HEXISTS', KEYS[1], KEYS[2]) == 0 then return end
redis.call('HDEL', KEYS[1], KEYS[2]);
local t1 = redis.call('PTTL', KEYS[1]);
local t2 = redis.call('PTTL', KEYS[2]);
redis.call('DEL', KEYS[2])
if t1 > t2 then return end
local maxRemainTime = -2
local keys = redis.call('HKEYS', KEYS[1]);
for k,v in pairs(keys) do
local remainTime = redis.call('PTTL', v)
maxRemainTime = math.max(maxRemainTime, remainTime)
end
if maxRemainTime > 0 then
redis.call('PEXPIRE', KEYS[1], maxRemainTime)
end" 2 rwlock.read unique_value

write unlock

eval "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end" 1 rwlock.write unique_value

第二种如果要支持重复加锁,只需稍微再改改

redis 分布式读写锁的更多相关文章

  1. Java之——redis并发读写锁,使用Redisson实现分布式锁

    原文:http://blog.csdn.net/l1028386804/article/details/73523810 1. 可重入锁(Reentrant Lock) Redisson的分布式可重入 ...

  2. Redis实现分布式读写锁(Java基于Lua实现)

    https://blog.csdn.net/grandachn/article/details/89032815 https://blog.csdn.net/xingsilong/article/de ...

  3. 使用ZooKeeper实现Java跨JVM的分布式锁(读写锁)

    一.使用ZooKeeper实现Java跨JVM的分布式锁 二.使用ZooKeeper实现Java跨JVM的分布式锁(优化构思) 三.使用ZooKeeper实现Java跨JVM的分布式锁(读写锁) 读写 ...

  4. 【分布式锁】07-Zookeeper实现分布式锁:Semaphore、读写锁实现原理

    前言 前面已经讲解了Zookeeper可重入锁的实现原理,自己对分布式锁也有了更深的认知. 我在公众号中发了一个疑问,相比于Redis来说,Zookeeper的实现方式要更好一些,即便Redis作者实 ...

  5. redis 读写锁实现

    一 先搞清楚读写锁要做什么. 基本就是 读读不互斥,读写互斥,写写互斥.可重入. 关于redis读写锁,我写了一次之后,总觉得很怪,然后就上网看到大神的redisson了,果断借鉴一番. 二 读行为 ...

  6. 一文读懂 Redis 分布式部署方案

    为什么要分布式 Redis是一款开源的基于内存的K-V型数据库,因为内存访问速度快,一般被用来做系统的缓存. Redis作为单机部署能够支持业务简单,数据量不大的系统需求,但在实际应用中,一旦系统规模 ...

  7. Redis专题(3):锁的基本概念到Redis分布式锁实现

    拓展阅读:Redis闲谈(1):构建知识图谱 Redis专题(2):Redis数据结构底层探秘 近来,分布式的问题被广泛提及,比如分布式事务.分布式框架.ZooKeeper.SpringCloud等等 ...

  8. 死磕 java同步系列之redis分布式锁进化史

    问题 (1)redis如何实现分布式锁? (2)redis分布式锁有哪些优点? (3)redis分布式锁有哪些缺点? (4)redis实现分布式锁有没有现成的轮子可以使用? 简介 Redis(全称:R ...

  9. 乐观、悲观锁、redis分布式锁

    悲观锁总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给 ...

随机推荐

  1. .net core 微服务之日志落盘设计

    原文:.net core 微服务之日志落盘设计 目录 1.设计目标 2.日志流程 3.串联请求事务 3.1 请求ID 3.2 处理服务器.服务 3.3 处理接口名 3.4 日志的发生时间 3.5 接口 ...

  2. 29 _react-router说明

    一.SPA的理解 1.单页面web应用(single page web application ,SPA) 2.整个应用只有一个完整的页面 3.点击页面中的链接不会刷新页面,本身也不会向服务器发请求 ...

  3. 用js控制 给一个input赋值之后,change事件不能捕获到,解决办法

    你用js给input赋值后要调用change方法 下面是jquery的写法 $('input#3').val("50"); $('input#3').change(); 自己试试吧

  4. sentinel 控制台接入

    SpringBoot  Web应用== 1. 引入sentinel依赖(你可以在maven仓库查找最新版,点击直接查看) sentinel别的依赖不用引入了,这个依赖基本全部引入了. <!--接 ...

  5. Jekins在Tomcat上的安装和配置

    首先,apache.org的官网下载Apache Tomcat. 第二:点击/一步一步的安装tomcat,没有任何需要说明的难点. 我偏好选择安装tomcat可执行文件,这样可以在安装时就自动吧tom ...

  6. java引用

    java1.2之后将引用分为强引用(Strong Reference).软引用(Soft Reference).弱引用(Weak Reference).虚引用(Phantom Reference)4种 ...

  7. [Solution] 973. K Closest Points to Origin

    Difficulty: Easy Problem We have a list of points on the plane. Find the K closest points to the ori ...

  8. 信号基础知识----线性调频信号LFM //matlab命令:chirp

    %关于线性调频信号(LFM) %参考书目:声呐技术,第二章P33 clc;close all;clear all;%参数----------------------------------f0=100 ...

  9. canvas(二) lineCap demo

    var dom = document.getElementById('clock'), ctx = dom.getContext('2d'); ctx.beginPath(); ctx.moveTo( ...

  10. 微信小程序之----制作视频弹幕

    1. 文件目录     使用微信, 长度单位使用 rpx 可以避免不同设备的样式调试问题     经验总结,之前一直使用px ,发现换了测试机就崩了        2. index.wxml页面设置v ...