分布式计划任务设计与实现

分布式计划任务设计与实现

目录

  • 1. 什么是分布式计划任务
  • 2. 为什么采用分布式计划任务
  • 3. 何时使用分布式计划任务
  • 4. 分布式计划任务的部署
  • 5. 谁来写分布式计划任务
  • 6. 怎么实现分布式计划任务
    • 6.1. 分布式互斥锁
    • 6.2. 队列
    • 6.3. 其他

1. 什么是分布式计划任务

首先我们解释一下计划任务,计划任务是指有计划的定时运行或者周期性运行的程序,我们最常见的就是Linux “crontab”与Windows “计划任务程序”,我们也常常借助他们实现我们的计划任务,因它们的时间调度程序非常成熟,无需我们再开发一套。

2. 为什么采用分布式计划任务

起初,我们也跟大多数人一样采用crontab调度程序,但随着项目越来越大,系统越来越复杂,就抱漏出许多问题。

首先是高可用HA需求,当运行计划任务的服务器一旦出现故障,所有的计划任务将停止工作。

其次是性能问题,越来越多的大型计划任务程序出现,对CPU/IO密集操作,单个节点已经不能满足我们的需求。

让计划任务7*24*365不间断运行,必需有一套行之有效的方案才行,我意识到必须开发一个全新的分布式计划任务框架,这样开发人员无需关注怎样实现分布式运行,集中写任务即可。

我首先提出这个框架必需具备几个特性:

分布式计划任务需具备以下特性

  1. 故障转移,我们至少使用两个节点,当一个节点出现问题,通过健康状态检查程序,另一个节点会自动接管任务。
  2. 分布式运行,一个任务可以运行在多个节点之上,能够同时运行,能够调整运行的前后顺序,能够并发互斥控制。
  3. 节点可动态调整,最少两个节点,可以随时新增节点,卸载节点。
  4. 状态共享,任务可能会涉及的通信,例如状态同步等等。

3. 何时使用分布式计划任务

何时使用分布式计划任务

  1. 遇到性能问题,遇到性能问题你可能首先想到的是分服务器,但很多应用不具备跨服务器运行。
  2. 高可用,一个节点出现故障,另一个节点将接管并继续运行。
  3. 灾备,你可以将两个或两个以上的计划任务节点分别部署在两个以上的机房,通过HA特性任何一个机房出现故障,其他机房仍会继续运行。

4. 分布式计划任务的部署

两个节点部署

两个节点可以实现“主”、“备”方案,队列(排队)运行方案与并行方案,其中并行方案又分为不同运行于异步运行,还涉及到互斥运行。

两个以上节点部署

多节点建议采用队列运行方案,并行方案,但不建议使用互斥并行方案(浪费资源)

5. 谁来写分布式计划任务

当我们的分布式计划任务框架一旦完成,任务的编写部分非常轻松,只需继承框架程序便具备分布式运行的特性。

6. 怎么实现分布式计划任务

计划任务是一个相当复杂的一块,有操作系统计划任务,有运用程序计划任务,有基于TCP/IP的访问的,有基于命令行访问的,有定时执行的,有周期运行的,还有基于某些条件触发运行的。总之解决计划任务灾备,要比web,cache, database 复杂的多。

图 1. 分时方案

严格划分时间片,交替运行计划任务,当主系统宕机后,备用系统仍然工作,只不过处理周期拉长了。缺点:周期延长了

图 2. HA 高可用方案

正常情况下主系统工作,备用系统守候,心跳检测发现主系统出现故障,备用传统启动。缺点:单一系统,不能负载均衡,只能垂直扩展(硬件升级),无法水平扩展

图 3. 多路心跳方案

上面的HA是三层的基于VIP技术实现,下面这个方案我采用多路心跳,做服务级,进程级,IP与端口级别的心跳检测,做正常情况下主系统工作,备用系统守候,心跳检测发现主系统出现故障,备用传统启动,当再次检测到主系统工作,将执行权交回主系统.缺点:开发复杂,程序健壮性要求高

图 4. 任务抢占方案

A,B 两台服务器同时工作,启动需要一前一后,谁先启动谁率先加锁,其他服务器只能等待,他们同时对互斥锁进行监控,一旦发现锁被释放,其他服务谁先抢到谁运行,运行前首先加排他锁。 优点:可以进一步优化实现多服务器横向扩展。 缺点:开发复杂,程序健壮性要求高,有时会出现不释放锁的问题。

图 5. 任务轮循或任务轮循+抢占排队方案

任务轮循或任务轮循+抢占排队方案

  1. 每个服务器首次启动时加入队列。
  2. 每次任务运行首先判断自己是否是当前可运行任务,如果是便运行。
  3. 否则检查自己是否在队列中,如果在,便推出,如果不在队列中,便加入队列。

6.1. 分布式互斥锁

互斥锁也叫排它锁,用于并发时管理多进程或多线程同一时刻只能有一个进程或者线程操作一个功能。如果你理解什么是互斥锁,便很容易理解分布式锁。

我们将进程,线程中的锁延伸到互联网上,实现对一个节点运行的进程或线程加锁,解锁操作。这样便能控制节点上进程或线程的并发。

			+------------------+                             +------------------+
| Server A         |                             | Server B         |
+------------------+      +---------------+      +------------------+
| Thread-1         |      | Cluster Mutex |      | Thread-1         |
| Thread-2         |----> +---------------+ <----| Thread-2         |
| Thread-3         |      | A Thread-2    |      | Thread-3         |
+------------------+      +---------------+      +------------------+
                                  |
                                  V
                          +---------------+
                          | Cluster Mutex | 
                          +---------------+
                          | A Thread-2    |
                          +---------------+			

上图中有两台服务器上运行任务,其中Server A 的 Thread-2 做了加锁操作,其他程序必须等待它释放锁才能运行。

你会问如果 Server A 宕机怎么办,是否会一直处于被锁状态?我的答案是每个锁都有一个超时阀值,一旦超时便自动解锁。

另外我们还要考虑“域”的问题,你也可以叫它命令空间,主要是防止锁出现同名被覆盖。

6.2. 队列

排队运行

			+------------------+                             +------------------+
| Server A         |                             | Server B         |
+------------------+      +---------------+      +------------------+
| Thread-1         |      | Task Queue A  |      | Thread-1         |
| Thread-2         |----> +---------------+ <----| Thread-2         |
| Thread-3         |      | A Thread-2    |      | Thread-3         |
+------------------+      | B Thread-1    |      +------------------+
                          | B Thread-3    |
                          | A Thread-3    |
                          +---------------+
                                  |
                                  | <sync>
                                  V
                          +---------------+
                          | Task Queue B  |
                          +---------------+
                          | A Thread-2    |
                          | B Thread-1    |
                          | B Thread-3    |
                          | A Thread-3    |
                          +---------------+			

从上图中我可以看到Task Queue中排队情况,运行是自上而下的。

注意Task Queue 需要两个节点,它们是主从结构,A 节点实时向 B 节点同步sh状态。如果 A 节点出现故障, B 节点立即取代 A 节点。

6.3. 其他

计划任务可以分布式运行了,但并不能保证万无一失,配套其他服务器也要做调整。例如数据库,缓存等等。

原文发布于微信公众号 - Netkiller(netkiller-ebook)

原文发表时间:2016-05-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏友弟技术工作室

docker拾遗-之再入坑

1516
来自专栏云计算爱好者

云计算技术原理

由于云计算分为IaaS、PaaS和SaaS三种类型,不同的厂家又提供了不同的解决方案,目前还没有一个统一的技术体系结构,对读者了解云计算的原理构成...

2039
来自专栏公有云大数据平台弹性MapReduce

简单了解公平调度器的一些队列设置

在腾讯云EMR的用户日常反馈中,经常会遇到因为YARN的队列配置不合理导致资源利用率不高,任务提交不上的问题,所以有了以下的文章,方便用户在日常按照一定的需求将...

1042
来自专栏IT技术精选文摘

Apache Kafka性能优化

什么是Apache Kafka? Apache Kafka是一个发布-订阅消息系统。 由LinkedIn发起,于2011年初开源。 LinkedIn开发Kafk...

2316
来自专栏IT可乐

Java 多线程详解(一)------概念的引入

  这是讲解 Java 多线程的第一章,我们在进入讲解之前,需要对以下几个概念有所了解。 1、并发和并行 并行:指两个或多个时间在同一时刻发生(同时发生); ...

1695
来自专栏IT技术精选文摘

redis架构演变与redis-cluster群集读写方案

redis-cluster是近年来redis架构不断改进中的相对较好的redis高可用方案。本文涉及到近年来redis多实例架构的演变过程,包括普通主从架构(M...

472
来自专栏咸鱼与梦想

Spring Cloud 系列-Ribbon

负载均衡(Load Balance): 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高...

11
来自专栏散尽浮华

GlusterFS分布式存储学习总结

分布式文件系统 分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源并不直接与本地节点相连,而是分布于计算网络中的一个...

3467
来自专栏用户2442861的专栏

高性能服务器程序框架

http://blog.csdn.net/zs634134578/article/details/19806429

212
来自专栏乐沙弥的世界

Percona XtraDB Cluster集群线程模型

Percona XtraDB集群创建一组线程来为其操作提供服务,这些线程与现有的MySQL线程无关。有三个主要线程组:

570

扫描关注云+社区