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, 计算空间中两 ...
随机推荐
- 联想lenovo 家用电脑安装win7 无法引导问题(新电脑安装系统时提示File:\Boot\BCD错误解决方案)
安装方式 : 1.进入 PE 2.用 EasyimageX 恢复 GHO镜像 3.重启后出现 原因: 主要 是安装win7 时,格式 化选择为GUID模式. 处理: win7 以后,格式华时选择MB ...
- ubuntu 装tensorflow出现 conda install ERROR missing write permission错误
通过搜索tensorflow然后运行,例如:$ conda install --channel https://conda.anaconda.org/jjh_cio_testing tensorflo ...
- javascript取前n天的日期两种方法
方法一: var d = new Date(); d = new Date(d.getFullYear(),d.getMonth(),d.getDate()-n); 方法二: var now = ne ...
- 洛谷 P1524 十字绣
P1524 十字绣 题目背景 考古学家发现了一块布,布上做有针线活,叫做“十字绣”,即交替地在布的两面穿线. 题目描述 布是一个n*m的网格,线只能在网格的顶点处才能从布的一面穿到另一面.每一段线都覆 ...
- Maven搭建之后的设置
Maven搭建之后的设置 1,设置环境变量M2_HOME=D:\Java\apache-maven-3.3.9, MAVEN_OPTS=-Xms128m -Xmx512m 在path中,添加D:\Ja ...
- Java集合源代码剖析(一)【集合框架概述、ArrayList、LinkedList、Vector】
Java集合框架概述 Java集合工具包位于Java.util包下.包括了非常多经常使用的数据结构,如数组.链表.栈.队列.集合.哈希表等.学习Java集合框架下大致能够分为例如以下五个部分:List ...
- lvs中dr模式配置脚本
1 dr模式介绍 1.1 lvs的安装 安装具体解释:http://blog.csdn.net/CleverCode/article/details/50586957. 1.2 lvs模式 lvs有三 ...
- [转]GLTF-3D图形界的JPEG
GLTF简介 1.glTF(GL TransmissionFormat),即图形语言交换格式,它是一种3D内容的格式标准,由Khronos Group管理(Khronos Group还管理着OpenG ...
- C内存管理一 概述
我们写了这么多年的程序猿.可能理论方面还比不上大学生.有人 "嘘"我了,假设有能回答下面几个问题的同学请举手: 1.面试常常遇到:同学请说说堆栈的差别? 2.同学请说说一个函数在堆 ...
- 单点登录(二)使用Cookie+File实现单点登录登出(附源代码)
上一篇文章<单点登录(一)使用Cookie+File实现单点登录>中,我们实现了单点登录的功能. 本文作为上一篇文章的扩展部分,加入"单点登出"功能. 源代码下载:链接 ...