超简便Python任务队列:huey

项目地址:coleifer/huey
文档地址:huey, a little task queue

Why

其实这种需求很常见 。在跑仿真的时候,为了得到多组数据以供统计分析比对,我们需要将一些程序按照不同参数配置运行多次。为了利用现代计算机的多核性能,我们常常以多进程的方式来运行这些仿真程序以最大化利用硬件资源。

这是我开始使用huey的时候的需求,但是事实上huey的应用远不止于此。和celery类似,你可以把huey用来管理和调度异步任务,或者是用来运行周期性任务以及定时服务。

我最开始的方法是写了一个工具脚本,在这个脚本内部开了一个线程池,然后在将计算任务提交给这个线程池。但是这样有一个问题:如果我已经开始了一组计算任务,而我又希望再增加一组任务,我只能等前一组任务完全结束之后才能再开始下一组。不然前后两组任务会同时开始运行,争抢计算资源,而不是按照我设想的任务的队列的模式。

设想一个具体的例子。我的计算机是8核的,而我的一组计算任务需要以不同的参数运行16次。通过在进程内创建一个8线程容量的线程池,我可以让这16个任务进入队列序次执行,同时执行的现成数不超过8。倘若前一次的16个任务还剩余4个未运行,而我又要再增加16个计算任务,此时以这种模式,我无法将新增的任务放到前一个进程的任务队列里。如果直接强行运行,则会导致前一组任务的4个线程在运行,而后一个任务会调度出8个线程,总计12个线程,这并不能最优地使用多核。

那么这个时候我就需要一个任务队列系统来管理我的计算任务了:每次我要运行一组任务的时候,我将计算任务提交给任务队列系统,由这个系统来调度worker(worker的数量常常设定为CPU的线程数)执行。简而言之,任务队列系统提供了跨进程的队列。

其实之前我用过celery这个任务队列框架,可是celery是用起来“太重”,配置较为复杂。因此我后来选择了huey这个框架。这个框架的好处是:

  1. 配置起来非常简单
  2. 支持自动重试失败的任务

下面我来简要介绍一下这个框架的配置方法。当然更多的功能你可以前往其官网研究。

How

安装

pip install huey

配置

# worker.py
from huey import RedisHuey

huey = RedisHuey()

@huey.task()
def add_numbers(a, b):
    return a + b

使用RedisHuey需要安装redis,这个请自行Google安装方法。如果觉得Redis还不够轻量级。可以选择Sqlite作为broker,具体方法参见huey的文档,我这里不做赘述。

没错,设置就是怎么简单。huey中任务的定义围绕着huey.task这个装饰器来进行。如果相对任务做更多的功能设置,可以通过为huey.task传入更多的参数实现。例如设置自动重试:

@huey.task(retries=3)
def add_numbers(a, b):
    return a + b

此时任务如果遭遇失败,会尝试重试3次。如果重试之后仍然失败则会抛出异常。

启动Huey Worker

huey提供了huey_consumer.py这个脚本来快捷启动worker。命令的基本使用方式如下:

huey_consumer.py worker.huey -k process -w 4

注意其中的worker.huey,你需要在worker.py的目录下执行这个脚本,而worker.huey是你import这个对象需要的路径形式。其余常用的flag定义如下:

-w n                 worker的数量
-k process/thread/greenlet    worker使用线程还是进程还是greenlet
-v           log输出详细的debug信息
-0          

使用Worker

在做好上述配置之后,将计算任务发送给worker执行的过程同普通的函数调用并没有什么分别。

from worker import huey, add_numbers

add_numbers(1, 2)

尽管看起来和普通的函数调用无异,但其实huey在背后将函数及其参数序列化后通过Redis这个broker,提交给了huey_consumer进程。这个进程在反向解析出函数和参数后,调度worker来执行这个函数。值得注意的是,这里的函数调用就变成了异步的,而在调用者侧函数调用的返回结果,则成为一个特殊打包对象,我们可以通过这个对象来获取任务执行的结果。

from worker import huey, add_numbers

res = add_numbers(1, 2)
add_result = res(blocking=True)  # get 3 

小结

以上是对huey这个任务队列工具的简单介绍,适合之前没有接触过任务队列工具的朋友入门的。事实上huey还为我们提供了更多的功能,包括周期性任务调度,延时调用,以及计算任务的暂停,取消和重新调度,consumer事件管理等等。关于这些内容我会后续更新文章介绍。

这里我给大家提供一个较为通用的用来执行一个Bash命令行命令的worker模板:

import subprocess
import os

from huey import RedisHuey

huey = RedisHuey()
@huey.task(retries=3)
def run_bash_task(cmd, std_out, working_dir):
    print("Entring %s" % working_dir)
    print("Running command %s, stdout to %s" % (cmd, std_out))
    os.chdir(working_dir)
    if std_out is None:
        subprocess.check_call(cmd)
    else:
        with open(std_out, "w") as f:
            subprocess.check_call(cmd, stdout=f)
    print("finish task %s\n" % cmd)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351