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实现一个简单作业调度系统的更多相关文章

  1. 手把手教你用redis实现一个简单的mq消息队列(java)

    众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...

  2. 用Qt写软件系列三:一个简单的系统工具(上)

    导言 继上篇<用Qt写软件系列二:QIECookieViewer>之后,有一段时间没有更新博客了.这次要写的是一个简单的系统工具,需求来自一个内部项目.功能其实很简单,就是查看当前当前系统 ...

  3. 180626-Spring之借助Redis设计一个简单访问计数器

    文章链接:https://liuyueyi.github.io/hexblog/2018/06/26/180626-Spring之借助Redis设计一个简单访问计数器/ Spring之借助Redis设 ...

  4. PHP + Redis 实现一个简单的twitter

    原文位于Redis官网http://redis.io/topics/twitter-clone Redis是NoSQL数据库中一个知名数据库,在新浪微博中亦有部署,适合固定数据量的热数据的访问. 作为 ...

  5. 使用redis设计一个简单的分布式锁

    最近看了有关redis的一些东西,了解了redis的一下命令,就记录一下: redis中的setnx命令: 关于redis的操作命令,我们一般会使用set,get等一系列操作,数据结构也有很多,这里我 ...

  6. Python之自定义封装一个简单的Log类

    参考:http://www.jb51.net/article/42626.htm 参考:http://blog.csdn.net/u011541946/article/details/70198676 ...

  7. 【python】Redis介绍及简单使用

    一.redis redis是一个key-value存储系统.和 Memcached类似,它支持存储的value类型相对更多,包括string(字符串). list(链表).set(集合).zset(s ...

  8. python (1)一个简单的爬虫: python 在windows下 创建文件夹并写入文件

    1.一个简单的爬虫:爬取豆瓣的热门电影的信息 写在前面:如何创建本来存在的文件夹并写入 t_path = "d:/py/inn" #本来不存在inn,先定义路径,然后如果不存在,则 ...

  9. 扩展Python模块系列(二)----一个简单的例子

    本节使用一个简单的例子引出Python C/C++ API的详细使用方法.针对的是CPython的解释器. 目标:创建一个Python内建模块test,提供一个功能函数distance, 计算空间中两 ...

随机推荐

  1. C# treeview绑定

    protected void Page_Load(object sender, EventArgs e)        {            if (!IsPostBack)            ...

  2. (2016北京集训十四)【xsy1556】股神小D - LCT

    题解: 题解居然是LCT……受教了 把所有区间按照端点排序,动态维护目前有重叠的区间,用LCT维护即可. 代码: #include<algorithm> #include<iostr ...

  3. [Debug]SpaceVim中neomake报错 Error while trying to load a compilation database

    回家装上archlinux,突发奇想装个SpaceVim写题 安装配置一路可以说是没有太大问题 最后在写题时出现如下问题 Error while trying to load a compilatio ...

  4. LightOJ-1074 Extended Traffic 最短路问题 注意连通性

    题目链接:https://cn.vjudge.net/problem/LightOJ-1074 题意 给一图 求最短路 若最短路<3或没有最短路,则输出'?' 思路 首先注意到可能存在负环,所以 ...

  5. HDU-2204- Eddy’s爱好 (容斥原理)

    题意 给出一个数n,问1-n中有多少个数可以表示为m^k,m,k均为正整数且k>1 (1<=n<=1^18) 题解 (一开始^以为是异或懵逼了好久....) 额,显然1这个数比较讨厌 ...

  6. C++ STL rope介绍----可持久化平衡树

    大致介绍: rope这个东西,我刚刚知道这玩意,用的不是很多,做个简单的介绍. 官方说明:我是刘邦(我估计你是看不懂的). rope就是一个用可持久化平衡树实现的“重型”string(然而它也可以保存 ...

  7. 51nod 1079 中国剩余定理模板

    中国剩余定理就是同余方程组除数为质数的特殊情况 我直接用同余方程组解了. 记得exgcd后x要更新 还有先更新b1再更新m1,顺序不能错!!(不然会影响到b1的更新) #include<cstd ...

  8. Java统计一篇文章中每个字符出现的个数

    大家可以参考下面代码,有什么疑问请留言... import java.io.BufferedReader; import java.io.FileInputStream; import java.io ...

  9. MYSQL锁表问题的解决方法

    本文实例讲述了MYSQL锁表问题的解决方法.分享给大家供大家参考,具体如下: 很多时候!一不小心就锁表!这里讲解决锁表终极方法! 案例一 mysql>show processlist; 参看sq ...

  10. [Javascript] Required function arguments in Javascript

    In Javascript, all function arguments are optional by default. That means if you ever forget to pass ...