Python使用Redis实现一个简单作业调度系统
Python使用Redis实现一个简单作业调度系统
概述
Redis作为内存数据库的一个典型代表,已经在非常多应用场景中被使用,这里仅就Redis的pub/sub功能来说说如何通过此功能来实现一个简单的作业调度系统。这里仅仅是想展现一个简单的想法,所以还是有非常多须要考虑的东西没有包含在这个样例中。比方错误处理,持久化等。
以下是实现上的想法
- MyMaster:集群的master节点程序。负责产生作业,派发作业和获取执行结果。
- MySlave:集群的计算节点程序。每一个计算节点一个,负责获取作业并执行,并将结果发送会master节点。
- channel CHANNEL_DISPATCH:每一个slave节点订阅一个channel。比方“CHANNEL_DISPATCH_[idx或机器名]”,master会向此channel中publish被dispatch的作业。
- channel CHANNEL_RESULT:用来保存作业结果的channel,master和slave共享此channel,master订阅此channel来获取作业执行结果,每一个slave负责将作业执行结果公布到此channel中。
Master代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import threading
import random
import redis
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_DB = 0
CHANNEL_DISPATCH = 'CHANNEL_DISPATCH'
CHANNEL_RESULT = 'CHANNEL_RESULT'
class MyMaster():
def __init__(self):
pass
def start(self):
MyServerResultHandleThread().start()
MyServerDispatchThread().start()
class MyServerDispatchThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
r = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB)
for i in range(1, 100):
channel = CHANNEL_DISPATCH + '_' + str(random.randint(1, 3))
print("Dispatch job %s to %s" % (str(i), channel))
ret = r.publish(channel, str(i))
if ret == 0:
print("Dispatch job %s failed." % str(i))
time.sleep(5)
class MyServerResultHandleThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
r = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB)
p = r.pubsub()
p.subscribe(CHANNEL_RESULT)
for message in p.listen():
if message['type'] != 'message':
continue
print("Received finished job %s" % message['data'])
if __name__ == "__main__":
MyMaster().start()
time.sleep(10000)
说明
- MyMaster类 - master主程序,用来启动dispatch和resulthandler的线程
- MyServerDispatchThread类 - 派发作业线程。产生作业并派发到计算节点
- MyServerResultHandleThread类 - 作业执行结果处理线程。从channel里获取作业结果并显示
Slave代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from datetime import datetime
import time
import threading
import random
import redis
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_DB = 0
CHANNEL_DISPATCH = 'CHANNEL_DISPATCH'
CHANNEL_RESULT = 'CHANNEL_RESULT'
class MySlave():
def __init__(self):
pass
def start(self):
for i in range(1, 4):
MyJobWorkerThread(CHANNEL_DISPATCH + '_' + str(i)).start()
class MyJobWorkerThread(threading.Thread):
def __init__(self, channel):
threading.Thread.__init__(self)
self.channel = channel
def run(self):
r = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB)
p = r.pubsub()
p.subscribe(self.channel)
for message in p.listen():
if message['type'] != 'message':
continue
print("%s: Received dispatched job %s " % (self.channel, message['data']))
print("%s: Run dispatched job %s " % (self.channel, message['data']))
time.sleep(2)
print("%s: Send finished job %s " % (self.channel, message['data']))
ret = r.publish(CHANNEL_RESULT, message['data'])
if ret == 0:
print("%s: Send finished job %s failed." % (self.channel, message['data']))
if __name__ == "__main__":
MySlave().start()
time.sleep(10000)
说明
- MySlave类 - slave节点主程序,用来启动MyJobWorkerThread的线程
- MyJobWorkerThread类 - 从channel里获取派发的作业并将执行结果发送回master
測试
- 首先执行MySlave来定义派发作业channel。
- 然后执行MyMaster派发作业并显示执行结果。
转载请以链接形式标明本文地址
本文地址:http://blog.csdn.net/kongxx/article/details/50952090
Python使用Redis实现一个简单作业调度系统的更多相关文章
- 手把手教你用redis实现一个简单的mq消息队列(java)
众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...
- 用Qt写软件系列三:一个简单的系统工具(上)
导言 继上篇<用Qt写软件系列二:QIECookieViewer>之后,有一段时间没有更新博客了.这次要写的是一个简单的系统工具,需求来自一个内部项目.功能其实很简单,就是查看当前当前系统 ...
- 180626-Spring之借助Redis设计一个简单访问计数器
文章链接:https://liuyueyi.github.io/hexblog/2018/06/26/180626-Spring之借助Redis设计一个简单访问计数器/ Spring之借助Redis设 ...
- PHP + Redis 实现一个简单的twitter
原文位于Redis官网http://redis.io/topics/twitter-clone Redis是NoSQL数据库中一个知名数据库,在新浪微博中亦有部署,适合固定数据量的热数据的访问. 作为 ...
- 使用redis设计一个简单的分布式锁
最近看了有关redis的一些东西,了解了redis的一下命令,就记录一下: redis中的setnx命令: 关于redis的操作命令,我们一般会使用set,get等一系列操作,数据结构也有很多,这里我 ...
- Python之自定义封装一个简单的Log类
参考:http://www.jb51.net/article/42626.htm 参考:http://blog.csdn.net/u011541946/article/details/70198676 ...
- 【python】Redis介绍及简单使用
一.redis redis是一个key-value存储系统.和 Memcached类似,它支持存储的value类型相对更多,包括string(字符串). list(链表).set(集合).zset(s ...
- python (1)一个简单的爬虫: python 在windows下 创建文件夹并写入文件
1.一个简单的爬虫:爬取豆瓣的热门电影的信息 写在前面:如何创建本来存在的文件夹并写入 t_path = "d:/py/inn" #本来不存在inn,先定义路径,然后如果不存在,则 ...
- 扩展Python模块系列(二)----一个简单的例子
本节使用一个简单的例子引出Python C/C++ API的详细使用方法.针对的是CPython的解释器. 目标:创建一个Python内建模块test,提供一个功能函数distance, 计算空间中两 ...
随机推荐
- NOIp2018模拟赛四十一
现在是下午15:36,我已经改完题了...刷新纪录 A题叫B,B题叫A是什么操作??? 我离200只差一个SBFA.jpg 成绩:0+100+10=110 被虐啦...今天九个阿克的Orz.A题是个神 ...
- phpstudy创建新站点-默认打不开
phpstudy中Apache中httpd.conf中如下语句前#要有 #Include conf/extra/httpd-vhosts.conf
- Markdown语法简记
目录 一.标题 1. 六个级别的标题 2. 主.副两级标题 二.根据标题生成文档结构大纲 三.字体 1. 斜体 2. 粗体 3. 倾斜加粗 4. 行首缩进 5. 删除线 四.引用块 五.代码块 1. ...
- electron 新手教程 打包 exe
1.安装nodejs(会自动安装npm) 2.桌面新建文件夹 your-app (下面目录结构) your-app/ ├── package.json ├── main.js └── inde ...
- useradd: cannot open /etc/passwd
[root@ftp ~]# useradd -g ftp -s/sbin/nologin liwmuseradd: cannot open /etc/passwd [root@ftp ~]# user ...
- 【codeforces 411B】Multi-core Processor
[题目链接]:http://codeforces.com/problemset/problem/411/B [题意] 处理器有n个核;然后有k个存储单元; 有m轮工作;每轮工作都会给每个核确定一个数字 ...
- How to customize Skin Gallery - Remove / rename skins and groups
1. REMOVE (HIDE) A SPECIFIC SKIN Traverse through the gallery group collection, then through its gal ...
- 关于ValueAnimation以及Interpolator +Drawable实现的自己定义动画效果
ValueAnimation : Android中的属性动画,他跟objectAnimation是比补间动画拥有更强大的功能,能够操作对象.所以我们能够在自 定义View中通过他们来实现些特别的功能. ...
- Java学习书目
Java学习书目 拜读了:http://www.importnew.com/26932.html#comment-636554
- windows 下面的grep awk 命令
windows 下面的grep awk 命令 grep 学习了:http://blog.csdn.net/chengfans/article/details/53784936 awk学习了:http: ...