在Python程式中實現分布式進程的教程

來源:互聯網
上載者:User
在Thread和Process中,應當優選Process,因為Process更穩定,而且,Process可以分布到多台機器上,而Thread最多隻能分布到同一台機器的多個CPU上。

Python的multiprocessing模組不但支援多進程,其中managers子模組還支援把多進程分布到多台機器上。一個服務進程可以作為調度者,將任務分布到其他多個進程中,依靠網路通訊。由於managers模組封裝很好,不必瞭解網路通訊的細節,就可以很容易地編寫分布式多進程程式。

舉個例子:如果我們已經有一個通過Queue通訊的多進程程式在同一台機器上運行,現在,由於處理任務的進程任務繁重,希望把發送任務的進程和處理任務的進程分布到兩台機器上。怎麼用分布式進程實現?

原有的Queue可以繼續使用,但是,通過managers模組把Queue通過網路暴露出去,就可以讓其他機器的進程訪問Queue了。

我們先看服務進程,服務進程負責啟動Queue,把Queue註冊到網路上,然後往Queue裡面寫入任務:

# taskmanager.pyimport random, time, Queuefrom multiprocessing.managers import BaseManager# 發送任務的隊列:task_queue = Queue.Queue()# 接收結果的隊列:result_queue = Queue.Queue()# 從BaseManager繼承的QueueManager:class QueueManager(BaseManager):  pass# 把兩個Queue都註冊到網路上, callable參數關聯了Queue對象:QueueManager.register('get_task_queue', callable=lambda: task_queue)QueueManager.register('get_result_queue', callable=lambda: result_queue)# 綁定連接埠5000, 設定驗證碼'abc':manager = QueueManager(address=('', 5000), authkey='abc')# 啟動Queue:manager.start()# 獲得通過網路訪問的Queue對象:task = manager.get_task_queue()result = manager.get_result_queue()# 放幾個任務進去:for i in range(10):  n = random.randint(0, 10000)  print('Put task %d...' % n)  task.put(n)# 從result隊列讀取結果:print('Try get results...')for i in range(10):  r = result.get(timeout=10)  print('Result: %s' % r)# 關閉:manager.shutdown()

請注意,當我們在一台機器上寫多進程程式時,建立的Queue可以直接拿來用,但是,在分布式多進程環境下,新增工作到Queue不可以直接對原始的task_queue進行操作,那樣就繞過了QueueManager的封裝,必須通過manager.get_task_queue()獲得的Queue介面添加。

然後,在另一台機器上啟動任務進程(本機上啟動也可以):

# taskworker.pyimport time, sys, Queuefrom multiprocessing.managers import BaseManager# 建立類似的QueueManager:class QueueManager(BaseManager):  pass# 由於這個QueueManager只從網路上擷取Queue,所以註冊時只提供名字:QueueManager.register('get_task_queue')QueueManager.register('get_result_queue')# 串連到伺服器,也就是運行taskmanager.py的機器:server_addr = '127.0.0.1'print('Connect to server %s...' % server_addr)# 連接埠和驗證碼注意保持與taskmanager.py設定的完全一致:m = QueueManager(address=(server_addr, 5000), authkey='abc')# 從網路連接:m.connect()# 擷取Queue的對象:task = m.get_task_queue()result = m.get_result_queue()# 從task隊列取任務,並把結果寫入result隊列:for i in range(10):  try:    n = task.get(timeout=1)    print('run task %d * %d...' % (n, n))    r = '%d * %d = %d' % (n, n, n*n)    time.sleep(1)    result.put(r)  except Queue.Empty:    print('task queue is empty.')# 處理結束:print('worker exit.')

任務進程要通過網路連接到服務進程,所以要指定服務進程的IP。

現在,可以試試分布式進程的工作效果了。先啟動taskmanager.py服務進程:

$ python taskmanager.py Put task 3411...Put task 1605...Put task 1398...Put task 4729...Put task 5300...Put task 7471...Put task 68...Put task 4219...Put task 339...Put task 7866...Try get results...

taskmanager進程發送完任務後,開始等待result隊列的結果。現在啟動taskworker.py進程:

$ python taskworker.py 127.0.0.1Connect to server 127.0.0.1...run task 3411 * 3411...run task 1605 * 1605...run task 1398 * 1398...run task 4729 * 4729...run task 5300 * 5300...run task 7471 * 7471...run task 68 * 68...run task 4219 * 4219...run task 339 * 339...run task 7866 * 7866...worker exit.

taskworker進程結束,在taskmanager進程中會繼續列印出結果:

Result: 3411 * 3411 = 11634921Result: 1605 * 1605 = 2576025Result: 1398 * 1398 = 1954404Result: 4729 * 4729 = 22363441Result: 5300 * 5300 = 28090000Result: 7471 * 7471 = 55815841Result: 68 * 68 = 4624Result: 4219 * 4219 = 17799961Result: 339 * 339 = 114921Result: 7866 * 7866 = 61873956

這個簡單的Manager/Worker模型有什麼用?其實這就是一個簡單但真正的分散式運算,把代碼稍加改造,啟動多個worker,就可以把任務分布到幾台甚至幾十台機器上,比如把計算n*n的代碼換成發送郵件,就實現了郵件隊列的非同步發送。

QueueObject Storage Service在哪?注意到taskworker.py中根本沒有建立Queue的代碼,所以,QueueObject Storage Service在taskmanager.py進程中:

而Queue之所以能通過網路訪問,就是通過QueueManager實現的。由於QueueManager管理的不止一個Queue,所以,要給每個Queue的網路調用介面起個名字,比如get_task_queue。

authkey有什麼用?這是為了保證兩台機器正常通訊,不被其他機器惡意幹擾。如果taskworker.py的authkey和taskmanager.py的authkey不一致,肯定串連不上。
小結

Python的分布式進程介面簡單,封裝良好,適合需要把繁重任務分布到多台機器的環境下。

注意Queue的作用是用來傳遞任務和接收結果,每個任務的描述資料量要盡量小。比如發送一個處理記錄檔的任務,就不要發送幾百兆的記錄檔本身,而是發送記錄檔存放的完整路徑,由Worker進程再去共用的磁碟上讀取檔案。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.