分散式架構
一台電腦的運算能力再強也有其極限. 因此若能把不同的任務分散給其他台電腦處理, 待處理完畢後再把結果集合在某一台, 這就是分散式架構. 比如比特幣挖礦, 外星人尋找計畫, DNA密碼破解, 這些都是把演算法投入到別台電腦計算, 再將結果返回主電腦.
要達到分散式的目的, 使用多執行緒是行不通的, 只能靠多行程來運作. 也就是在同一台或不同台電腦, 啟動相同的程式碼.
managers
不同行程之間的資料溝通, 在上一章節裏有提到, 可以使用Queue來達成. 但如果是跨電腦使用網路連線呢? 其實還是使用Queue, 但必需將Queue經過managers包裝成網路版的Queue.
底下的代碼, 分成master.py及slave.py. 這二支程式可以分別在不同的電腦上執行, 並透過 port : 5000 來進行連線溝通, 有點像是在寫點對點的訊息溝通功能. 不過請注意, 這二支程式, 只能在Linux之下執行喔. Windows不能執行.
首先在master.py中就是我們認為的Server端, 使用queue.Queue()產生一個 local_queue物件. 這個物件目前還只是在本機之中. 然後用QueueManager.register, 利用manager將local_queue包裝成網路版的queue, 並且在Server裏註冊. 註明了當下達 ‘get_queue’時, 就會傳回網路版的queue. 接下來產生一個管理器manager, 註明port, 認証key. 當manager.start(), Server及開始啟動服務. 注意一下, 將值放入queue中, 不可直接放入local_queue裏, 而是要放入被包裝過的server_queue中. 最後要使用a=input()讓程式停下來, 不然直接結束程式的話, Server就跟著停止.
#Master.py
import random, time, queue
from multiprocessing.managers import BaseManager
local_queue=queue.Queue()
class QueueManager(BaseManager):
pass
QueueManager.register('get_queue', callable=lambda : local_queue)
manager=QueueManager(address=('', 5000), authkey=b'abc')
manager.start()
server_queue=manager.get_queue()
for i in range(10):
n=random.randint(0,10000)
print('Put task_queue %d' % n)
server_queue.put(n)
print("Please input any key......")
a=input()
manager.shutdown()
print('master exit')
而在slave裏, 就是我們所稱的Client端. 指明要連線的IP, 及認証key, 進行連線後, 用get_queue()取得Server端的queue, 然後就可以依序將queue裏的值取出
#slave.py
import time, sys, queue
from multiprocessing.managers import BaseManager
class QueueManager(BaseManager):
pass
QueueManager.register('get_queue')
server_addr='mahaljsp.asuscomm.com'
print('Connecting to server %s....' % server_addr)
manager=QueueManager(address=(server_addr,5000), authkey=b'abc')
manager.connect()
server_queue=manager.get_queue()
for i in range(10):
try:
r=server_queue.get(timeout=1)
print('Result : %d' % r)
time.sleep(1)
except Queue.Empty:
print('task queue is empty.')
todo