分布式锁----Redis实现

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 分布式锁----Redis实现分布式锁  为什么需要有分布式锁呢,在单点的时候synchronized 就能解决,但是服务拆分之后,每个服务都是单独的机器,无法解决,所以出现了分布式锁,其实也就是用各种手段,实现获取唯一锁,别人无法得到。

分布式锁----Redis实现
分布式锁
  为什么需要有分布式锁呢,在单点的时候synchronized 就能解决,但是服务拆分之后,每个服务都是单独的机器,无法解决,所以出现了分布式锁,其实也就是用各种手段,实现获取唯一锁,别人无法得到。

  其实在做分布式锁的前提,需要先明白,synchronized 为啥不能使用了,啥原理让他在一个机器上可以使用。

  

  synchronized 的原理   
  众所周知 Synchronize 关键字是解决并发问题常用解决方案,有以下三种使用方式:

同步静态方法,锁的是当前 Class 对象。
同步块,锁的是 {} 中的对象。
同步普通方法,锁的是当前对象。
  实现原理:
  JVM 是通过进入、退出对象监视器( Monitor )来实现对方法、同步块的同步的。

  具体实现是在编译之后在同步方法调用前加入一个 monitor.enter 指令,在退出方法和异常处插入 monitor.exit 的指令。

  其本质就是对一个对象监视器( Monitor )进行获取,而这个获取过程具有排他性从而达到了同一时刻只能一个线程访问的目的。

  而对于没有获取到锁的线程将会阻塞到方法入口处,直到获取锁的线程 monitor.exit 之后才能尝试继续获取锁。

可以通过使用 javap -c Synchronize 可以查看编译之后的具体信息 ,这里我就不再粘贴了。

所以可以知道,单独的Java虚拟机是可实现锁的,但是多台手就伸不到了,只能在依赖外部的形式去产生一个唯一锁。

以上是参考别人的博客拿到的信息,亲自试用得到,准确 :链接:https://www.jianshu.com/p/2ba154f275ea

  Redis实现的分布式锁
  主要是利用了redis的set NX的原理,以及对redis的script脚本原子性利用。(个人看法,其实后面一步就看各自的程序逻辑如何去判定到底要不要这一步了)

  简单的说一下主要流程:

首先设置一个全局唯一的key和一个唯一性的value(value是一个解锁的保障,删除之前判断一下值是否一致)
使用Redis的set 方法 以多参数形式配置key,value,nx,px,过期时间 (参数 NX:只有键不存在时,才能对其进行设置操作)
利用Redis的script脚本来对key的删除操作,只能自己删除自己的value(删除之前先判断一下value是否是我之前的value,是否被改过,没有就删了)
   这是脚本的主要 内容 if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end
   对其解释: 根据 get 获取到 key 的值 ,判断key的值是否跟你传的值相等,相等则 执行del key 否则返回0 结束
   对此推荐去看一下redis的Lua脚本,给个简单的:http://redisdoc.com/script/eval.html
  
  在实际场景中可以利用AOP的切点切面形式,实现具体是什么地方需要分布式锁,搭配分布式锁,再搭配注解方式,来实现想要的自定义设置那里需要就点哪里
  AOP的主要实现是
@pointcut 切注解类
在使用@around环绕对前后做处理
前面加锁
后面解锁del 使用script脚本
  
  代码主要实现
  注解类 DistributedLock
  

复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface DistributedLock {

/**
 * 自定义形式添加你对分布式锁的对外配置属性  
 * 例如:key的规则,锁的超时时间,获取锁的等待时间,等一系列的属性配置
 * 
 */

}
复制代码
  切面类 DistributedLockAspect
复制代码
@Aspect
@Component
public class DistributedLockAspect {


 /**
 * 层切点
 */
@Pointcut("@annotation(com.creditease.hardess.common.annotation.DistributedLock)")
public void distributedLockAspect() {}

/**

 * @param joinPoint 切点
 * @return Object 添加分布式锁后,实际调用业务逻辑部分代码的返回值
 * @throws Throwable 产生的所有异常,为了避免对异常处理流程产生干扰,所有异常都应该继续抛出
 */
@Around("distributedLockAspect()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
 /**
  *主要写一些锁的获取,和业务逻辑执行,锁的删除等
  *
 */
 return returnObject;
}

/**

 * 获取 DistributedLock 注解
 * 
 * @param joinPoint
 * @return 代码中定义的注解
 * @throws NoSuchMethodException
 */
private static DistributedLock getDistributedLock(ProceedingJoinPoint joinPoint)
        throws NoSuchMethodException {
    String methodName = joinPoint.getSignature().getName();

    Class<?> classTarget = joinPoint.getTarget().getClass();
    Class<?>[] par = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
    Method objMethod = classTarget.getMethod(methodName, par);

    return objMethod.getAnnotation(DistributedLock.class);
}

}

}
复制代码
原文地址https://www.cnblogs.com/zhouguanglin/p/11246239.html

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
NoSQL 算法 安全
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
153 0
|
1月前
|
NoSQL 关系型数据库 MySQL
分布式锁(redis/mysql)
分布式锁(redis/mysql)
58 1
|
28天前
|
NoSQL Java Redis
如何通俗易懂的理解Redis分布式锁
在多线程并发的情况下,我们如何保证一个代码块在同一时间只能由一个线程访问呢?
37 2
|
1月前
|
人工智能 监控 NoSQL
【万字长文 一文搞定】Redis:从新手村到大师殿堂的奥德赛之旅 9种实现分布式锁的全技术指南
【万字长文 一文搞定】Redis:从新手村到大师殿堂的奥德赛之旅 9种实现分布式锁的全技术指南
81 4
|
13天前
|
NoSQL Linux Redis
06- 你们使用Redis是单点还是集群 ? 哪种集群 ?
**Redis配置:** 使用哨兵集群,结构为1主2从,加上3个哨兵节点,总计分布在3台Linux服务器上,提供高可用性。
40 0
|
22天前
|
负载均衡 监控 NoSQL
Redis的集群方案有哪些?
Redis集群包括主从复制(基础,手动故障恢复)、哨兵模式(自动高可用)和Redis Cluster(官方分布式解决方案,自动分片和容错)。此外,还有如Codis、Redisson和Twemproxy等第三方工具用于代理和负载均衡。选择方案需考虑应用场景、数据规模和并发需求。
34 2
|
27天前
|
NoSQL Redis
Redis集群(六):集群常用命令及说明
Redis集群(六):集群常用命令及说明
29 0
|
2月前
|
运维 NoSQL 算法
Redis-Cluster 与 Redis 集群的技术大比拼
Redis-Cluster 与 Redis 集群的技术大比拼
46 0
|
21天前
|
NoSQL Java 测试技术
面试官:如何搭建Redis集群?
**Redis Cluster** 是从 Redis 3.0 开始引入的集群解决方案,它分散数据以减少对单个主节点的依赖,提升读写性能。16384 个槽位分配给节点,客户端通过槽位信息直接路由请求。集群是无代理、去中心化的,多数命令直接由节点处理,保持高性能。通过 `create-cluster` 工具快速搭建集群,但适用于测试环境。在生产环境,需手动配置文件,启动节点,然后使用 `redis-cli --cluster create` 分配槽位和从节点。集群动态添加删除节点、数据重新分片及故障转移涉及复杂操作,包括主从切换和槽位迁移。
31 0
面试官:如何搭建Redis集群?