分布式锁

jedis实现分布式锁(悲观锁)

陌路散爱 提交于 2021-02-16 13:06:41
redis需单点部署(非集群) redis分布式锁解决多个应用进程间同步操作 整理了很多网上文档 发现都没有解决如下问题。。。 参考 http://www.cnblogs.com/it-cen/p/4984272.html ... 1.时间同步问题 2.在一个进程cash后失效时间后自动释放锁 3.有些多线程race condition没有考虑到 以下java版本实现彻底解决 充分测试 ** 方案一(推荐)** import java.util.List; import java.util.UUID; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.Transaction; import redis.clients.jedis.exceptions.JedisException; /** * Jedis实现分布式锁 * * @author 三文鱼 * */ public class DistributionLock { private final JedisPool jedisPool; public DistributionLock(JedisPool jedisPool) { this.jedisPool = jedisPool;

【Redis】1. redission分布式锁

ε祈祈猫儿з 提交于 2020-04-07 21:48:18
模拟扣库存服务,不加任何锁: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> package com.hknetty.redis; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexContrpller { @Autowired private StringRedisTemplate stringRedisTemplate; @GetMapping("/deduct_stock") public String deductStock() { //商品ID String

Redis 系列 -- SpringBoot中 基于 Redis 实现分布式锁

非 Y 不嫁゛ 提交于 2020-04-06 19:01:11
分布式锁应用场景 锁的应用常出现在一些多线程、高并发的场景中,如秒杀、抢购、12306抢票,还有一些商品库存管理等。在一般的单体应用中,我们通常使用 synchronized、ReentrantLock 等来进行共享变量的管理,从而实现线程锁功能。但随着互联网发展、用户的剧增,单体应用已无法满足需求,多服务器部署、分布式应用越来越被广泛使用。但问题也出现了,对于之前的基于本地变量锁的形式,在不同服务器间无法共享。所以分布式锁应运而生,如基于中间件 redis 、zookeeper等实现的分布式锁。 为什么使用redis 分布式锁 1、redis 读写快 与mysql等传统数据库进行内存、磁盘I\O 流操作过程相比,redis 基于内存操作和I\O多路复用具有更快的读写效率。 2、redis 单线程 操作简单 基于单线程设计,所以redis在处理一些并发问题上具有天生的优势。 使用命令 SETNX命令 SETNX key value 当且仅当 key 不存在,将 key 的值设为 value ,并返回1;若给定的 key 已经存在,则 SETNX 不做任何动作,并返回0。 GETSET命令 GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值 (old value),当 key 存在但不是字符串类型时,返回一个错误,当key不存在时

关于Redis RedLock算法的争论

我怕爱的太早我们不能终老 提交于 2020-04-06 11:44:38
内容简介:Martin上来就问,我们要锁来干啥呢?2个原因:对于第1种原因,我们对锁是有一定宽容度的,就算发生了两个节点同时工作,对系统的影响也仅仅是多付出了一些计算的成本,没什么额外的影响。这个时候 使用对于第2种原因,对正确性严格要求的场景(比如订单,或者消费),就算使用了 RedLock 算法仍然 Martin上来就问,我们要锁来干啥呢?2个原因: 提升效率,用锁来保证一个任务没有必要被执行两次。比如(很昂贵的计算) 保证正确,使用锁来保证任务按照正常的步骤执行,防止两个节点同时操作一份数据,造成文件冲突,数据丢失。 对于第1种原因,我们对锁是有一定宽容度的,就算发生了两个节点同时工作,对系统的影响也仅仅是多付出了一些计算的成本,没什么额外的影响。这个时候 使用 单点的 Redis 就能很好的解决问题,没有必要使用RedLock,维护那么多的 Redis 实例,提升系统的维护成本。 对于第2种原因,对正确性严格要求的场景(比如订单,或者消费),就算使用了 RedLock 算法仍然 不能保证锁的正确性 。 我们分析一下 RedLock 的有啥缺陷吧: 作者 Martin 给出这张图,首先我们上一讲说过,RedLock中,为了防止死锁,锁是具有过期时间的。这个过期时间被 Martin 抓住了小辫子。 如果 Client 1 在持有锁的时候,发生了一次很长时间的 FGC

Spring优雅整合Redis缓存

99封情书 提交于 2020-04-06 06:06:00
“小明,多系统的session共享,怎么处理?”“Redis缓存啊!” “小明,我想实现一个简单的消息队列?”“Redis缓存啊!” “小明,分布式锁这玩意有什么方案?”“Redis缓存啊!” “小明,公司系统响应如蜗牛,咋整?”“Redis缓存啊!” 本着研究的精神,我们来分析下小明的第四个问题。 准备: Idea2019.03/Gradle6.0.1/Maven3.6.3/JDK11.0.4/Lombok0.28/SpringBoot2.2.4RELEASE/mybatisPlus3.3.0/Soul2.1.2/ Dubbo2.7.5/Druid1.2.21/Zookeeper3.5.5/Mysql8.0.11/Vue2.5/Redis3.2 难度:新手-- 战士 --老兵--大师 目标: Spring优雅整合Redis做数据库缓存 步骤: 为了遇见各种问题,同时保持时效性,我尽量使用最新的软件版本。源码地址: https://github.com/xiexiaobiao/vehicle-shop-admin 1 先说结论 Redis缓存不是金弹,若系统DB毫无压力,系统性能瓶颈不在DB上,不建议强加缓存层! 增加业务复杂度:同一缓存必须被全部相关方法所覆盖,如订单缓存,只要涉及到订单数据更新的方法都要进行缓存逻辑处理。 同时,KV存储时,因各方法返回的类型不同

【Redis】入门

て烟熏妆下的殇ゞ 提交于 2020-04-05 16:44:14
Redis概述 Redis常用数据结构 Redis删除过期数据策略 Redis内存淘汰机制 Redis持久化机制 缓存问题及解决方案 Redis概述 Redis是一个开源的、基于内存的数据结构存储器,可以用作数据库、缓存和消息中间件 Redis最常用的功能 缓存 分布式锁 本文介绍使用环境 Windows 10 Redis 3.0.504 如何安装Redis就不做介绍,若不想安装Redis环境,可以使用 try redis 尝试Redis功能 CMD 启动 Redis,打开Reids目录,执行下面命令,出现下面图片代表启动成功 redis-server redis.windows.conf Redis常用数据结构 字符串(String) 用途 存放字符串/数字 常规key-value缓存应用 常规计数:订单数,商品数 常用命令 用途 set key value 设置指定 key 的值 get key 获取指定key的值 decr key 将指定的key的值递减1,若设置的值不是数字,报错 incr key 将指定的key的值递增1,若设置的值不是数字,报错 mget key1 [key2] 获取指定的key,返回多个值 哈希(Hash) 用途 hash 特别适合用于存储对象(用户信息,商品信息) 可以修改/读取对象某个值 常用命令 用途 hset key field value

Redis入门及锁和计数的实现

[亡魂溺海] 提交于 2020-04-02 15:59:04
一、Redis简介 Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 Redis支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 二、Redis的命令 命令行进入客户端 $ redis-cli 进入远程客户端 $ redis-cli -h host -p port -a password 查看redis信息 127.0.0.1:6379> info all 1、String 增改 redis 127.0.0.1:6379> SET runoobkey redis OK 查 redis 127.0.0.1:6379> GET runoobkey

分布式系统---幂等性设计

 ̄綄美尐妖づ 提交于 2020-04-02 15:00:38
最近做的项目的性能调优中关于幂等设计的一些总结 场景:假设有这样一个方法,包含了一些DB操作,check if existing then update else save. 如果两个线程同时去执行这个方法,并且他们处理的是同一条数据,期望应该是其中一个线程是save,另外一个是update。但是有可能线程的处理时间相当重合,线程A在check的时候,线程B也在check,这时A和B都认为数据不存在,都去save,在 数据库 有unique 约束的情况下其中一个操作会失败,而我们期望的可能是后面一个操作应该update(取决于具体业务)。 这是很典型的多线程问题,check - then do something,在单系统环境中这很容易用线程同步来处理(syncronised). 但是如果是分布式系统,这两个线程在不同的server上面,syncronised 是不会起效的,而且同步往往降低效率,并不是我们想要的。 拥有相同参数的多次请求对系统造成的副作用应该是相同的,这就是幂等性。在这个例子里面就是说保证相同的ID组合只会插入一条数据到DB里面,如果一个请求是save,后续的都应该update这条。在单系统中也可以用幂等的设计来规避使用syncronized,因为那会降低效率。一般情况下数据库就能保证这种幂等性--用unique关键字,以上面的场景为例

普通锁和分布式锁

谁说我不能喝 提交于 2020-04-02 09:33:57
1、普通锁和分布式锁 为什么有了普通锁还需要分布式锁,当然是因为普通锁和分布式锁各有各的使用场景。普通针对多线程的场景,一般可以synchronized和lock。而分布式针对的是分布式的环境,系统部署在多个机器中,也会出现并发问题,并且场景是多个进程之间的并发问题。使用内存标记无法解决这个问题,因为内存是线程共享的。 2、普通锁 主要有两种synchronized和lock。下面介绍一下两个锁的异同点: 1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;   2)synchronized除了在流程走完释放锁,还在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock 时需要在finally块中释放锁;   3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;当通过lockInterruptibly()方法获取某个锁时,如果不能获取到,只有进行等待的情况下,是可以响应中断的。   4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。   5)Lock可以提高多个线程进行读操作的效率

【分布式锁】06-Zookeeper实现分布式锁:可重入锁源码分析

心已入冬 提交于 2020-03-30 07:41:34
前言 前面已经讲解了Redis的客户端Redission是怎么实现分布式锁的,大多都深入到源码级别。 在分布式系统中,常见的分布式锁实现方案还有Zookeeper,接下来会深入研究Zookeeper是如何来实现分布式锁的。 Zookeeper初识 文件系统 Zookeeper维护一个类似文件系统的数据结构 image.png 每个子目录项如NameService都被称为znoed,和文件系统一样,我们能够自由的增加、删除znode,在znode下增加、删除子znode,唯一不同的在于znode是可以存储数据的。 有4种类型的znode PERSISTENT--持久化目录节点客户端与zookeeper断开连接后,该节点依旧存在 PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 EPHEMERAL-临时目录节点客户端与zookeeper断开连接后,该节点被删除 EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 通知机制 客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)等,zookeeper会通知客户端。 分布式锁