用python作分布式定时器

分布式任务系统 (Python)

github地址 https://github.com/thomashuang/Lilac/blob/master/README.rstpython

这里将介绍Liac的设计架构,首先分布式任务系统的定义是在多台服务器执行定时任务。mysql

实现技术

  1. 分布式定时调度,能够同时在不一样服务执行。
  2. 使用Leader/Follower Pattern 多线程模式。
  3. 只是周期定时,crontab定时,定点任务。
  4. 重试失败任务。
  5. 线程安全db api,支持读写分离模式
  6. 使用data-mapper模式
  7. web ui化管理工具(使用MVC,基于 mako gevent cherrypy)

定时任务的类型

一次性定时任务

在未来某个时间点须要执行一次git

周期性任务

对于周期性任务最为简单的就是间隔性执行任务,好比每五分钟须要执行一次。github

如何作到分布式任务

从分布式的理解来看,须要一种机制保证正常给各个任务执行服务准确及时的分派任务,并却要减小各个服务之间竞争。因而最简单的任务执行者向任务管理服务所要当前能够执行服务。回分派相关任务,当执行任务完须要汇报给任务调度管理服务,并筹划任务下一步的状态。但这里设计原理并不是如此,对于任务管理器而言,只是做任务的的长久序列化,对于怎么提取,任务的执行状态(完成,失败,重试等),都由任务执行者决定。web

分派流程

  1. 定时服务生成惟一task标识符,依据下次执行时间在db标记任务。
  2. 依据task标识符获取可执行任务。
  3. 执行任务,保存刷新最新状态。

使用MYSQL如何作到任务的分派

使用关联数据数据,而非内存数据库好比heaq作任务调度,可能有些开始让人难以理解。如今有不少任务执行服务,在领取任务时,首先生成一个一个具备惟一性标识的(uuid)的对mysql的cron表作更新 UPDATE cron set task_id=$identify WHERE task_id IS NULL AND next_run<now() LIMIT $take_size; 这样标识了当前服务的可执行的任务。而后使用SELECT × FROM cron WHERE task_id=$identify, 因而就能拉当前服务能够执行任务。而后对于任务的是什么,该怎么执行。sql

任务线程池的设计与优化

对于scheduler任务的执行,由于一次认领多个任务,最初是想使用生产消费者模式,若是master线程与工人线程共享队列,会形成任务竞争激烈。因而优化成每一个工人线程拥有本身的任务队列,master线程轮询分派任务,但这样,减小了线程对资源的竞争,但在空闲时,若是没有特殊处理可能形成cpu的占用。最后使用的是一种leader follower的变种。master线程仅负责分派任务。 follower将在挂起与任务执行(processing)状态转换。另外这样可能任务众多,若是线程池没有空闲线程怎么办,办法是将这些任务放入一个闲置队列,加入一个心跳(定时器)线程负责闲置任务的再次分配。对于python而言,真正的优化在于减小任务空闲时对cpu的抢占。数据库

数据层

最初设计时,考虑到对多数据库的支持。首先使用记录(activerecord)模式,这种模式把模型与数据落地放置与同一个类,随着业务的复杂后,模式优点愈来愈小,形成数据落地层行为与模型行为的混淆。为了维护性与后期的拓展性。最终采用了data-mapper模式,这样在拓展多数据库支持时,仅仅考虑数据落地层的接口重写,一样也为后期的数据库接口优化提供了空间。api

值得一提的是,在使用mysql做为数据库,由于使用mysqldb因此须要简单的封装一个链接池,并简化接口的使用。db模块有三个重要的接口setup 将帮助设置数据库, query将用于select的查询,execute是用来作增删改的语句,由于这样更方便数据库的读写分离。安全

setup

setup将用来注册数据库,若是指定slave为true,这个数据库将会注册到读数据库
key用来标示数据库,默认注册到default。
须要注意的是你必须先注册一个master数据库才能注册从数据库。服务器

query

用于select的查询语句,指定many时将会使用mydqldb的fetchmany接口,key用来标示数据库,默认为default。

execute

对于insert语句将会返回lastwordid
而update与delete将会是rowcount。

web 管理平台

web管理平台使用的cherrypy与routes mako实现,考虑到cherrypy也许有些慢。因而给cherypy打上猴子补丁,而使用gevent的wsgiserver。 功能基本实现了简单的用户角色和任务管理功能。

相关文章
相关标签/搜索