海豚调度Dolphinscheduler源码分析(三)
今天继续分析海豚调度的源码
上回分析的是dolphinscheduler-service模块zookeeper相关的代码
这回分析是dolphinscheduler-server模块zookeeper相关的代码
ZkMasterClient master服务zk客户端类
类继承的关系如下:
这个类的方法如下:
方法介绍:
- start() 根据路径dolphinscheduler/lock/failover/master 创建一个分布式锁,并进行初始化,检查是否有master节点竞争锁,确保只有一个主master,如果只有一个master节点,那么无法进行master服务的故障转移
- dataChange() 变更zk节点
- removeZKNodePath(String path, ZKNodeType zkNodeType, boolean failover) 移除zookeeper 节点,并在/dead路径添加节点,并会判断是否需要容错
- handleDeadServer() 父类方法,就是处理宕机服务的zookeeper路径,将获取节点删除,添加/dead路径数据
- failoverServerWhenDown() 当服务宕机后,转移服务,分为master服务和server服务
- checkTaskInstanceNeedFailover()
- failoverWorker() 将worker上的task任务进行故障转移
- 如果是yarn任务,干掉yarn任务
- 将任务状态变更为需要故障转移
- 当工作节点全部为null时,将所有任务进行故障转移
zk分布式锁获取代码如下:
对于InterProcessMutex,Curator
是ZooKeeper
的一个客户端框架,其中封装了分布式互斥锁
的实现,最为常用的是InterProcessMutex
InterProcessMutex
基于Zookeeper
实现了分布式的公平可重入互斥锁
,类似于单个JVM进程内的ReentrantLock(fair=true)
全局同步的可重入分布式锁,任何时刻不会有两个客户端同时持有该锁。Reentrant和JDK的ReentrantLock类似, 意味着同一个客户端在拥有锁的同时,可以多次获取,不会被阻塞
相关链接:https://blog.csdn.net/hosaos/article/details/89521537
相关链接:https://www.cnblogs.com/a-du/p/9876314.html
相关链接:https://blog.csdn.net/qq_34021712/article/details/82878396
主要方法:
注意点,调用acquire()方法后需相应调用release()来释放锁
/**
* remove zookeeper node path
zookeeper分布式锁详解
在分布式环境中 ,为了保证数据的一致性,经常在程序的某个运行点(例如,减库存操作或者流水号生成等)需要进行同步控制。以一个"流水号生成"的场景为例,普通的后台应用通常都是使用时间戳来生成流水号,但是在用户访问量很大的情况下,可能会出现并发问题。下面通过示例程序就演示一个典型的并发问题:
输出结果如下:
不难发现,生成的10个订单不少都是重复的,如果是实际的生产环境中,这显然没有满足我们的也无需求。究其原因,就是因为在没有进行同步的情况下,出现了并发问题。下面我们来看看如何使用Curator实现分布式锁功能。
Shared Reentrant Lock(分布式可重入锁)
全局同步的可重入分布式锁,任何时刻不会有两个客户端同时持有该锁。Reentrant和JDK的ReentrantLock类似, 意味着同一个客户端在拥有锁的同时,可以多次获取,不会被阻塞。
相关的类
InterProcessMutex
使用
创建InterProcessMutex实例
InterProcessMutex提供了两个构造方法,传入一个CuratorFramework实例和一个要使用的节点路径,InterProcessMutex还允许传入一个自定义的驱动类,默认是使用StandardLockInternalsDriver。
获取锁
使用acquire方法获取锁,acquire方法有两种:
获取锁,一直阻塞到获取到锁为止。获取锁的线程在获取锁后仍然可以调用acquire() 获取锁(可重入)。 锁获取使用完后,调用了几次acquire(),就得调用几次release()释放。
与acquire()类似,等待time * unit时间获取锁,如果仍然没有获取锁,则直接返回false。
释放锁
使用release()方法释放锁
线程通过acquire()获取锁时,可通过release()进行释放,如果该线程多次调用 了acquire()获取锁,则如果只调用 一次release()该锁仍然会被该线程持有。
注意:同一个线程中InterProcessMutex实例是可重用的,也就是不需要在每次获取锁的时候都new一个InterProcessMutex实例,用同一个实例就好。
锁撤销
InterProcessMutex 支持锁撤销机制,可通过调用makeRevocable()将锁设为可撤销的,当另一线程希望你释放该锁时,实例里的listener会被调用。 撤销机制是协作的。
示例代码(官网)
共享资源
使用锁操作资源
客户端
起五个线程,即五个窗口卖票,五个客户端分别有50张票可以卖,先是尝试获取锁,操作资源后,释放锁。
转自:https://blog.csdn.net/qq_34021712/article/details/82878396
__EOF__

本文链接:https://www.cnblogs.com/erlou96/p/16878444.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏