Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

主动探查停机-恢复解决方案 #27

Open
flycash opened this issue Sep 10, 2024 · 5 comments
Open

主动探查停机-恢复解决方案 #27

flycash opened this issue Sep 10, 2024 · 5 comments

Comments

@flycash
Copy link
Contributor

flycash commented Sep 10, 2024

在我们的主动探查机制里面,有一个问题:
假设说我当次任务在节点 A 上被调度,理论上来说,它也可以应该在 A 上探查。但是如果此时 A 节点宕机了,那么后续即使 A 节点恢复了,它也无法继续探查。因为目前我们的探查是基于内存实现的,虽然有执行记录,但是 A 节点恢复之后无法从执行记录里面找到哪些是自己需要继续探查的。

我们可以进一步借助抢占机制来解决这个问题。

在我们抢占的时候,有一个条件是如果一个任务已经被抢占了,但是更新时间超过了最大续约时间。换句话来说,没人给它续约。这个时候我们就有道理认为,这个节点之前抢占了这个任务,但是并没有正常释放。

这个时候,在找到这样一个任务之后,就要先去看一眼这个任务最近的一次执行记录,是否已经结束。如果没有结束,那么就要发起探查。而后根据结果来考虑:

  • 如果探查结果是依旧在运行中,那么自己应该放弃调度,只保留探查
  • 如果探查结果是已经结束了(不管成功还是失败),那么应该调度一次新的运行。当然在这里还有另外一种思路,是如果要是上次结束的时间到当下的时间比较短(比如说 30 分钟运行一次的,但是上一次结束才过了十分钟),也不调度,而是直接释放任务,并且更新下一次调度时间。
@junwense
Copy link
Contributor

你这个想法有点奇怪,那要还是要有getTasks的抽象,把任务都查出来,进行探查或者抢占,然后就比较尴尬了,可能其他节点也会查出这个任务来

@flycash
Copy link
Contributor Author

flycash commented Sep 10, 2024

不会的,因为你抢占只会有一个节点抢占成功。你可以理解为,是在已有抢占成功的基础上,看看非正常释放任务,上一次有咩有执行完毕

@pojiang20
Copy link

目前main和dev都没办法跑起来,有能跑的分支吗?

@yanleiwang
Copy link
Contributor

yanleiwang commented Sep 19, 2024

类似这样吗?

	if t.LastStatus == mysql.TaskStatusRunning {
		// 根据 Task.ID 获取 execute id
		execution, err := p.executionDAO.GetByTid(ctx, t.ID)
		if err != nil {
			return
		}
		// 再根据 eid 查询 上次执行情况
		ch := exec.Explore(ctx, execution.ID, t)
		select {
		case res, ok := <-ch:
			if !ok {
				return
			}
			switch res.Status {
			// 还在执行的任务
			case executor.StatusRunning:
				//TODO 只定时探查 不调度
				return
			default:
			}
		case <-ctx.Done():
			return
		}
	}
	// 正常调度 执行

@flycash
Copy link
Contributor Author

flycash commented Sep 20, 2024

是的。不过我们没有这个 LastStatus 的字段,理论上来说,我们抢占是先查询出来了 Task,而后再抢占,所以查询出来的状态本身就是 Running。抢占只是改了数据库的,但是已经查询出来的没改

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants