我在Python2.7中使用multiprocessing.Process构建了一个并行工作的进程;理论上,它在拥有大量vCPU的EC2集群上工作得非常快,但是它的伸缩性并不像我预期的那样好。我在一台96 vCPU的机器(一个m5.24xlarge实例)上运行代码,但是当我尝试并行运行90个vCPU时,在一个4 5+的机器上被并行化的函数运行大约45分钟,而所有的子进程都需要几个小时才能完成。
我曾考虑过使用池函数来摆脱发生的批处理,但被调用的函数运行了大约200个模型,这些模型确实可以运行很长时间(有时会陷入奇怪的优化循环),所以我有一个额外的进程在后台运行,一旦它每10分钟有3小时的处理器时间,它就会开始向子进程发送软Ctrl+C命令,以确保任何单个子进程的处理不会持续太长时间。
在子进程完成之前,运行子进程的每个vCPU的利用率都在40 %到99%之间。我的问题是,为什么在迁移到更大的实例时,多处理不能线性扩展?我保留了5个vCPU来运行任何后台进程,所以它不会停滞不前。
from multiprocessing import Process
import datetime
import Prod_Modeling_Pipeline as PMP
import boto3
import pandas
import time
import numpy
import os
#Define locations
bucketName = 'bucketgoeshere'
output_location = '/home/ec2-user/'
#Pull ATM Setter Over
client = boto3.client('s3')
transfer = boto3.s3.transfer.S3Transfer(client=client)
transfer.download_file(bucketName,'Root_Folder/Control_Files/'+'execution_file.csv', output_location+'execution_file.csv')
#Read-in id list
execution_data = pandas.read_csv(output_location+'execution_file.csv')
ids = execution_data['id']
ni = 90
id_row = [['AAA']*ni for _ in xrange(int(numpy.ceil(len(tids)/float(ni))))]
for i in xrange(len(ids)):
id_row[i/ni][i%ni] = ids[i]
Date = datetime.date.today().strftime('%Y-%m-%d')
totalstart = time.time()
for q in xrange(len(tid_row)):
processes = []
for m in xrange(len(tid_row[q])):
temp = tid_row[q]
try:
p = Process(target=PMP.Model_Function, args=(temp[m],Date,'VALIDATION'))
p.start()
processes.append(p)
time.sleep(1)
print("Started "+temp[m]+" as "+str(os.getpid()))
except:
print("Invalid Run")
for p in processes:
p.join()
print(processes)
print (time.time() - totalstart)发布于 2018-07-19 21:08:03
我想我现在明白为什么它不是线性缩放了。这一切都归结为t2 EC2实例和m EC2实例之间的时钟速度。对于较小的实例,最大时钟速度要高得多。小型t2s高达3.3 GHz,m类实例高达2.5 GHz。
(https://aws.amazon.com/ec2/instance-types/)
当您更改为更大的实例类型时,这将限制可伸缩性,因为您已移动到较慢的最大时钟速度。
这并不是我上面所有的问题,但它解释了时间增加的一部分。
另一部分似乎是由于使用共享处理器,所以即使EC2应该占用较少的时间,我的组织中的其他人也在占用处理能力。不确定如何在公司约束下解决这个问题。
https://stackoverflow.com/questions/51383343
复制相似问题