如何操作Redis和zookeeper实现分布式锁
如何操作Redis和zookeeper实现分布式锁
在分布式场景下,有很多种情况都需要实现最终一致性。在设计远程上下文的领域事件的时候,为了保证最终一致性,在通过领域事件进行通讯的方式中,可以共享存储(领域模型和消息的持久化数据源),或者做全局XA事务(两阶段提交,数据源可分开),也可以借助消息中间件(消费者处理需要能幂等)。通过Observer模式来发布领域事件可以提供很好的高并发性能,并且事件存储也能追溯更小粒度的事件数据,使各个应用系统拥有更好的自治性。
1.分布式锁
分布式锁一般用在分布式系统或者多个应用中,用来控制同一任务是否执行或者任务的执行顺序。在项目中,部署了多个tomcat应用,在执行定时任务时就会遇到同一任务可能执行多次的情况,我们可以借助分布式锁,保证在同一时间只有一个tomcat应用执行了定时任务。
2.分布式锁的实现方式
使用redis的setnx()和expire() 使用redis的getset() 使用zookeeper的创建节点node 使用zookeeper的创建临时序列节点setnx(key,value) 如果key不存在,设置为当前key的值为value;如果key存在,直接返回。
expire()来设置超时时间
定义注解类:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Lockable{
// redis缓存key
String key();
// redis缓存key中的数据
String value() default
// 过期时间(秒),默认为一分钟
long expire() default 60;
定时任务增加注解@Lockable:
@Lockable(key = DistributedLock:dealExpireRecords )
public void dealExpireRecords() {
定义一个aop切面LockAspect,使用@Around处理所有注解为@Lockable的方法,通过连接点确认此注解是用在方法上,通过方法获取注解信息,使用setIfAbsent来判断是否获取分布式锁,如果没有获取分布式锁,直接返回;如果获取到分布式锁,通过expire设置过期时间,并调用指定方法。
@Component
@Slf4j
@Aspect
public class LockAspect {
@Autowired
private RedisTemplate redisTemplate;
@Around( @annotation(com.records.aop.Lockable) )
public Object distributeLock(ProceedingJoinPoint pjp) {
Object resultObject = null;
//确认此注解是用在方法上
Signature signature = pjp.getSignature();
if (!(signature instanceof MethodSignature)) {
log.error( Lockable is method annotation! );
return resultObject;
}
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
//获取注解信息
Lockable lockable = targetMethod.getAnnotation(Lockable.class);
String key = lockable.key();
String value = lockable.value();
long expire = lockable.expire();
// 分布式锁,如果没有此key,设置此值并返回true;如果有此key,则返回false
boolean result = redisTemplate.boundValueOps(key).setIfAbsent(value);
if (!result) {
//其他程序已经获取分布式锁
return resultObject;
}
//设置过期时间,默认一分钟
redisTemplate.boundValueOps(key).expire(expire, TimeUnit.SECONDS);
try {
resultObject = pjp.proceed(); //调用对应方法执行
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return resultObject;
}
}
4.使用redis的getset()来实现分布式锁
此方法使redisTemplate.boundValueOps(key).getAndSet(value)的方法,如果返回空,表示获取了分布式锁;如果返回不为空,表示分布式锁已经被其他程序占用
5.使用zookeeper的创建节点node
使用zookeeper创建节点node,如果创建节点成功,表示获取了此分布式锁;如果创建节点失败,表示此分布式锁已经被其他程序占用(多个程序同时创建一个节点node,只有一个能够创建成功)
6.使用zookeeper的创建临时序列节点
使用zookeeper创建临时序列节点来实现分布式锁,适用于顺序执行的程序,大体思路就是创建临时序列节点,找出最小的序列节点,获取分布式锁,程序执行完成之后此序列节点消失,通过watch来监控节点的变化,从剩下的节点的找到最小的序列节点,获取分布式锁,执行相应处理,依次类推
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
我想要获取技术服务或软件
服务范围:MySQL、ORACLE、SQLSERVER、MongoDB、PostgreSQL 、程序问题
服务方式:远程服务、电话支持、现场服务,沟通指定方式服务
技术标签:数据恢复、安装配置、数据迁移、集群容灾、异常处理、其它问题
本站部分文章参考或来源于网络,如有侵权请联系站长。
数据库远程运维 如何操作Redis和zookeeper实现分布式锁
相关文章
- 浅谈分布式锁的几种使用方式(redis、zookeeper、数据库)
- Redis实现全局分布式锁实现(redis全局锁)
- 哈希槽:Redis实现分布式锁的关键技术(redis的哈希槽)
- 使用Redis实现分布式锁(分布式锁redis)
- 用 Redis 实现高效的分布式锁机制。(redis实现锁)
- 高效抢购,红利加速:Redis分布式锁机制助力秒杀活动(redis分布式锁秒杀)
- 红色起源:以Redis为基础的项目实践(redis项目实例)
- 用Redis实现高性能的并发计数器(并发 redis 计数器)
- 基于Redis的订单管理系统实现(订单redis实现)
- 查看Redis服务状态的命令行分析(查看redis状态命令行)
- 分布式Redis从原理到应用(漫谈分布式redis)
- 深入研究分布式Redis架构(深度分布式redis)
- Redis及其实践精选浅析数据缓存与分布式存储(有关redis书籍推荐)
- 重新设置Redis服务器端口号(改redis服务器端口)
- 深度优化多线程Redis发挥巨大作用(支持多线程redis)
- 为何选择Redis分片(为什么要用redis分片)
- 单台Redis能否实现分布式锁系统(单台redis支持 锁吗)
- 技术分布式部署的Redis缓存提升系统效率(分布式部署redis缓存)
- 以分布式方式使用Redis弹性扩展服务(分布式部署redis)
- 利用Redis实现分布式缓存(分布式缓存-redis)
- 利用Redis实现高效分布式ID Generator(分布式id redis)
- 如何快速配置并连接Redis(安装好redis怎么连接)
- 总结分布式Redis面试总结与展望(分布式redis面试)
- Redis实现高性能分布式客户端(redis 高并发客户端)
- 更换IP地址,重建Redis集群(redis集群 更换ip)
- 据库Redis集群建立高可用安全的分布式数据库(redis集群数)
- Redis实现分布式锁管理(redis集成分布式锁)
- 研究Redis实现的高性能分布式锁方法(redis锁方法)
- 比拼Redis与Tair的高效性(redis跟 tair)
- Redis中的超时机制一个必要的规则(redis超时规则)
- 利用Redis瞬间读取缓存数据(redis 读取缓存数据)
- 调整如何优化Redis连接数配置(redis连接数大小如何)