Python分布式进程

Python分布式进程

面对多任务需求的时候,thread和process都能实现相应的功能。但更推荐使用process,因为process更稳定。并且process可以在多台机器上实现分布式的应用,而多线程thread只能在一台机器上使用多个CPU。

那在Python中我们该如何使用分布式进程完成我们的需求?

Python提供了multiprocessing模块。该模块不仅提供实现多进程process,其中子模块manager还支持将多进程分布到多台机器上。

一台机器充当任务的调度者(master进程),将任务分发到不同的进程中,通过网络通信将任务分发到不同的机器上。这里我们不需要知道manager模块如何将任务进行分发,只需要知道他的用法。

现在我们需要实现一个“不断输入数字,计算得出输入数字的平方”。

如果我们不使用分布式进程,只使用单机多进程。该如何完成?

单机多进程实现

1.初始化一个队列
2.产生数字的进程(master),并将产生的数字put到全局的队列中
3.进行平方根计算的进程(worker),将计算完成的数据输出

单机多进程实现

分布式多进程实现

当我们使用分布式多进程的时候,一个队列就不能满足我们的需求,需要两个队列masterQueue、workerQueue。我们来看一下使用分布式多进程如何完成上述需求。

1.创建master(主机)任务注册、分发进程

首先我们需要创建一个DistributedMasterProcess.py(master),它负责相关队列的初始化。


'分布式进程,使用multiprocessing.manager模块进行多进程队列的管理'
__author__ = 'click'
__date__ = '2018/7/25 下午1:55'

import time, random, queue
# 1.导入BaseManager模块(管理Queue,注册、获取。连接master)
from multiprocessing.managers import BaseManager

# 2.创建生产队列master
masterQueue = queue.Queue()
# 创建消费队列,worker
workerQueue = queue.Queue()


# 创建manager管理queue(这一步也需要有的)

class QueueManager(BaseManager):
    pass


# 3.使用baseManager将两个队列注册到网络上

QueueManager.register('get_master_queue', callable=lambda: masterQueue)
QueueManager.register('get_worker_queue', callable=lambda: workerQueue)

# 4.绑定网络端口5000,设置验证码'abc'
manager = QueueManager(address=('', 5000), authkey=b'abc')

# 启动queue
manager.start()

# 5.获取到注册到网络上的生产、消费队列

master = manager.get_master_queue()

worker = manager.get_worker_queue()
# 往生产队列中添加任务

for i in range(10):
    n = random.randint(0, 10)
    print('往master队列中添加任务 %s' % n)
    master.put(n)

# 准备从消费队列中取出
print('从消费队列获取内容')

for i in range(10):
    r = worker.get(timeout=10)
    print('消费队列worker%s' % r)

# 关闭manger
manager.shutdown()

创建一个master机器上的代码如上,按照上述步骤,逐一讲解。

1.导入manager模块

1.导入BaseManager模块(管理Queue,注册、获取。连接master)
from multiprocessing.managers import BaseManager

manager模块已经封装了相关底层的网络的操作,使用分布式时,导入我们需要重写的BaseManager类

2.创建生产队列master、工作队列worker。

# 2.创建生产队列master
masterQueue = queue.Queue()
# 创建消费队列,worker
workerQueue = queue.Queue()

创建相关队列,这里大家思考一个问题:如果有不同的任务,我们该如何处理?

3.将相关的队列注册到网络。

QueueManager.register('get_master_queue', callable=lambda: masterQueue)
QueueManager.register('get_worker_queue', callable=lambda: workerQueue)

我们只需要执行相关的注册代码,即可在网络中找到我们注册的队列。

get_master_queue

在不同的进程中获取master队列的接口。

get_worker_queue

在不同的进程中获取worker队列的接口。

callable=lambda: workerQueue

初始化的队列与相应的接口绑定

:不管是master、worker队列都只会是masetr的机器上进行初始化,其他的机器(进程)只使用,不负责初始化。

4.绑定网络端口5000,设置验证码'abc'

绑定网络端口5000,设置验证码'abc'
manager = QueueManager(address=('', 5000), authkey=b'abc')

manager绑定对外暴露的端口。

autherkey

worker与worker之间连接的秘钥

5.获取到注册到网络上的生产、消费队列

master = manager.get_master_queue()
worker = manager.get_worker_queue()

使用(3)完成注册的接口获取到我们需要使用的相关队列。之后我们就可以进行任务的添加与获取。

此时只是完成了masetr(主机)的代码编写。单单是运行master代码是不能完成任务的。我们还需要worker(分布式机器)相关的任务处理代码。

2.创建worker(分布式机器)任务处理进程

现在我们需要创建任务处理的DistributedWorkerProcess.py(worker)进程。

主要用来注册相关队列、连接master(主机)、获取相关队列、处理相关队列数据。


'生产进程'
__author__ = 'click'
__date__ = '2018/7/25 下午3:13'

import random, time, queue, sys
from multiprocessing.managers import BaseManager


# 创建BaseManager

class QueueManger(BaseManager):
    pass


# 1.向网络中注册生产,消费队列
QueueManger.register('get_master_queue')
QueueManger.register('get_worker_queue')

# 2.连接到服务器,也就是运行master_queue的机器

server_addr = '127.0.0.1'
print('连接到服务端 %s' % server_addr)
# 初始化manager
manager = QueueManger(address=(server_addr, 5000), authkey=b'abc')

# 连接到服务器
manager.connect()
# 3.获取到master队列
master = manager.get_master_queue()
# 获取到消费worker队列
worker = manager.get_worker_queue()

# 4.从master中获取任务,并放到worker队列中

for i in range(10):
    try:
        n = master.get(timeout=1)
        print('worker进程获取到master队列中的元素%s' % n)
        r = '%d * %d = %d' % (n, n, n * n)
        time.sleep(1)
        worker.put(r)
    except queue.Empty:
        print('队列为空')
# 工作进程执行完毕
print('worker执行完成')

主要的流程在master中已经经过详细的介绍,代码中也做了详细的注释,相信大家能够很轻松的理解。这里不做过多的说明。

编写完了master(主机)、worker(分布式机器)代码,我们就可以直接运行我们第一个分布式进程了。

这里我们要先启动master(主机)随后启动worker(分布式机器)。结合一下现实情况,人家都还没准备好,你就要开工了干了,出了事你是要负责的。

最后运行的结果:

master(主机)

往master队列中添加任务 0
往master队列中添加任务 2
往master队列中添加任务 10
往master队列中添加任务 6
往master队列中添加任务 7
往master队列中添加任务 4
往master队列中添加任务 6
往master队列中添加任务 3
往master队列中添加任务 2
往master队列中添加任务 4
从消费队列获取内容
消费队列worker0 * 0 = 0
消费队列worker2 * 2 = 4
消费队列worker10 * 10 = 100
消费队列worker6 * 6 = 36
消费队列worker7 * 7 = 49
消费队列worker4 * 4 = 16
消费队列worker6 * 6 = 36
消费队列worker3 * 3 = 9
消费队列worker2 * 2 = 4
消费队列worker4 * 4 = 16

worker(分布式进程)

连接到服务端 127.0.0.1
worker进程获取到master队列中的元素0
worker进程获取到master队列中的元素2
worker进程获取到master队列中的元素10
worker进程获取到master队列中的元素6
worker进程获取到master队列中的元素7
worker进程获取到master队列中的元素4
worker进程获取到master队列中的元素6
worker进程获取到master队列中的元素3
worker进程获取到master队列中的元素2
worker进程获取到master队列中的元素4
worker执行完成

通过上述的代码,我们不难发现Python提供的分布式多进程接口非常的方便。并且帮我们省去了繁琐、晦涩的网络部分,掌握起来很简单。当你有大量的任务的时候使用分布式多进程代替多线程,谁让它还有很多优点呢!

DistributedMasterProcess.py

DistributedWorkerProcess.py

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

推荐阅读更多精彩内容