用python做分布式定时器
分布式任务系统 (Python)
github地址 https://github.com/thomashuang/Lilac/blob/master/README.rst
这里将介绍Liac的设计架构,首先分布式任务系统的定义是在多台服务器执行定时任务。
实现技术
- 分布式定时调度,可以同时在不同服务执行。
- 使用Leader/Follower Pattern 多线程模式。
- 只是周期定时,crontab定时,定点任务。
- 重试失败任务。
- 线程安全db api,支持读写分离模式
- 使用data-mapper模式
- web ui化管理工具(使用MVC,基于 mako gevent cherrypy)

定时任务的类型
一次性定时任务
在将来某个时间点需要执行一次
周期性任务
对于周期性任务最为简单的就是间隔性执行任务,比如每五分钟需要执行一次。
如何做到分布式任务
从分布式的理解来看,需要一种机制保证正常给各个任务执行服务准确及时的分派任务,并却要减少各个服务之间竞争。于是最简单的任务执行者向任务管理服务所要当前可以执行服务。回分派相关任务,当执行任务完需要汇报给任务调度管理服务,并筹划任务下一步的状态。但这里设计原理并非如此,对于任务管理器而言,只是作任务的的长久序列化,对于怎么提取,任务的执行状态(完成,失败,重试等),都由任务执行者决定。
分派流程
- 定时服务生成唯一task标识符,依据下次执行时间在db标记任务。
- 依据task标识符获取可执行任务。
- 执行任务,保存刷新最新状态。
使用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, 于是就能拉当前服务可以执行任务。然后对于任务的是什么,该怎么执行。
任务线程池的设计与优化
对于scheduler任务的执行,因为一次认领多个任务,最初是想使用生产消费者模式,如果master线程与工人线程共享队列,会造成任务竞争激烈。于是优化成每个工人线程拥有自己的任务队列,master线程轮询分派任务,但这样,减少了线程对资源的竞争,但在空闲时,如果没有特殊处理可能造成cpu的占用。最后使用的是一种leader follower的变种。master线程仅负责分派任务。 follower将在挂起与任务执行(processing)状态转换。另外这样可能任务众多,如果线程池没有空闲线程怎么办,办法是将这些任务放入一个闲置队列,加入一个心跳(定时器)线程负责闲置任务的再次分配。对于python而言,真正的优化在于减少任务空闲时对cpu的抢占。
数据层
最初设计时,考虑到对多数据库的支持。首先使用记录(activerecord)模式,这种模式把模型与数据落地放置与同一个类,随着业务的复杂后,模式优势越来越小,造成数据落地层行为与模型行为的混淆。为了维护性与后期的拓展性。最终采用了data-mapper模式,这样在拓展多数据库支持时,仅仅考虑数据落地层的接口重写,同样也为后期的数据库接口优化提供了空间。
值得一提的是,在使用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。 功能基本实现了简单的用户角色和任务管理功能。
用python做分布式定时器的更多相关文章
- 12岁的少年教你用Python做小游戏
首页 资讯 文章 频道 资源 小组 相亲 登录 注册 首页 最新文章 经典回顾 开发 设计 IT技术 职场 业界 极客 创业 访谈 在国外 - 导航条 - 首页 最新文章 经典回顾 开发 ...
- 使用AKKA做分布式爬虫的思路
上周公司其它小组在讨论做分布式爬虫,我也思考了一下.提了一个方案,就是使用akka分布式rpc框架来做,自己写master和worker程序,client向master提交begin任务或者其它爬虫需 ...
- Python 并行分布式框架 Celery
Celery 简介 除了redis,还可以使用另外一个神器---Celery.Celery是一个异步任务的调度工具. Celery 是 Distributed Task Queue,分布式任务队列,分 ...
- 你用 Python 做过什么有趣的数据挖掘项目?
有网友在知乎提问:「你用 Python 做过什么有趣的数据挖掘项目?」 我最近刚开始学习 Python, numpy, scipy 等, 想做一些数据方面的项目,但是之前又没有这方面的经验.所以想知道 ...
- SpringBoot-ElasticJob封装快速上手使用(分布式定时器)
elastic-job-spring-boot qq交流群:812321371 1 简介 Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Ela ...
- python从写定时器学习Thread
目录 python从写定时器学习Thread Timer 对象 粗陋的循环定时器 更 pythonic 循环定时器 FAQ python从写定时器学习Thread python 如何写一个定时器,循环 ...
- 【转】Python 并行分布式框架 Celery
原文链接:https://blog.csdn.net/freeking101/article/details/74707619 Celery 官网:http://www.celeryproject.o ...
- Redis++:Redis做分布式锁真的靠谱吗
Redis做分布式锁真的靠谱吗 Redis的分布式锁可以通过Lua进行实现,通过setnx和expire命令连用的方式 || 也可以使用高版本的方法同时设置失效时间,但是假如在以下情况下,就会造成无锁 ...
- ASP.NET MVC 中应用Windows服务以及Webservice服务开发分布式定时器
ASP.NET MVC 中应用Windows服务以及Webservice服务开发分布式定时器一:闲谈一下:1.现在任务跟踪管理系统已经开发快要结束了,抽一点时间来写一下,想一想自己就有成就感啊!! ...
随机推荐
- h5-35-ajax轮询实现推送效果
data.txt { "number1":1200, } index.html <!DOCTYPE html> <html> <head> &l ...
- 145 Binary Tree Postorder Traversal 二叉树的后序遍历
给定一棵二叉树,返回其节点值的后序遍历.例如:给定二叉树 [1,null,2,3], 1 \ 2 / 3返回 [3,2,1].注意: 递归方法很简单,你可以使用迭代方法来解 ...
- (027)[技术资料]业余制作Windows图标
这几天一直在纠结一件事,想给软件制作一个简单的图标,以前(2014-10-4 11:00)制作的是下面这个,多重ICO,最大尺寸256,无压缩(windows允许图标尺寸在大于256时按PNG方式进行 ...
- python中的sort和sorted
共同点 都有三个参数, cmp用户自定义(指定函数),每个元素都会调用,效率没key高 key带一个参数的函数,用来为每个元素提取比较值 reverse=True 翻转 sort sort作用的 ...
- 【C#】枚举
枚举 public static class CommonEnums { public enum people { /// <summary> ///男人 /// </summary ...
- jmeter+ant+jenkins
前提:需要先配置下面两个环境,严格按照本人的配置去配,要不然后面你会看不懂 (1)ant+jmeter集成:http://blog.csdn.net/qq_23101033/article/detai ...
- swift 泛型的类型约束
总结: 1.类型约束只能添加到泛型参量上面 2.关联类型是泛型参量: 3.关联类型可以通过 协议.关联类型名称的形式引用: func allItemsMatch<C1: Container, C ...
- 7-Java-C(骰子游戏)
题目描述: 我们来玩一个游戏. 同时掷出3个普通骰子(6个面上的数字分别是1~6). 如果其中一个骰子上的数字等于另外两个的和,你就赢了. 下面的程序计算出你能获胜的精确概率(以既约分数表示) pub ...
- 屏幕卫士模式系统APP开发
利用php的socket编程来直接给接口发送数据来模拟post的操作,(黎灿:I8O..2853..296O 可电可V)线上线下和物流结合在一起,才会产生新零售. 2016年阿里云栖大会上,阿里巴巴马 ...
- final关键字所修饰的类有什么特点
Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量. final类不能被继承,没有子类,final类中的方法默认是final的. final方法 ...