2013-06-07 7 views
3

내 문제는 다음과 같습니다. 내 응용 프로그램은 Python에서 Boto 라이브러리를 사용하여 S3에 여러 파일을 동시에 업로드해야합니다. 나는 2 가지 해결책을 찾았지만 각각의 함축 된 의미는 잘 모르겠습니다. 일부 고려 사항 :파일 업로드를위한 파이썬 병렬 처리

  • 이 EC2 마이크로 인스턴스 때문에 메모리 부족,
  • 보통 1-10 파일을 한 번에 업로드 할 필요가 낮은 CPU에서 실행되지만 더

솔루션이 될 수 있습니다 , 가장 빠르다가 가장 느린 :

1) from threading import Thread으로 "수동으로"스레드를 만듭니다. 이것은 aprox에서 실행됩니다. 0.02 초. multiprocessing 모듈에서 사용 ThreadPool

from boto.s3.connection import S3Connection 
from threading import Thread 
import time 

filenames = ['1.json', '2.json', '3.json', '4.json', '5.json', '6.json', '7.json', '8.json', '9.json', '10.json'] 
def upload(myfile): 
     conn = S3Connection(aws_access_key_id=AWS_KEY, aws_secret_access_key=AWS_SECRET) 
     bucket = conn.get_bucket("parallel_upload_tests") 
     key = bucket.new_key(myfile).set_contents_from_string('some content') 
     return myfile 

for fname in filenames: 
     t = Thread(target = upload, args=(fname,)).start() 

2). 이것은 aprox를 취합니다. 0.3 초를 실행한다 (약 10 배 느리게)

from boto.s3.connection import S3Connection 
from multiprocessing.pool import ThreadPool 
import time 

filenames = ['1.json', '2.json', '3.json', '4.json', '5.json', '6.json', '7.json', '8.json', '9.json', '10.json'] 
def upload(myfile): 
     conn = S3Connection(aws_access_key_id=AWS_KEY, aws_secret_access_key=AWS_SECRET) 
     bucket = conn.get_bucket("parallel_upload_tests") 
     key = bucket.new_key(myfile).set_contents_from_string('some content') 
     return myfile 

pool = ThreadPool(processes=16) 
pool.map(upload, filenames) 
  • 스레드 풀 배 느린하게 이들 두 방법의 차이는 무엇 ?
  • 다른 접근법이나 권장 사항에 대한 제안 사항이 있습니까?

고맙습니다.

편집 : multiprocessing에는 pool (아마도 새 프로세스를 생성 함)과 ThreadPool (아마도 스레드 작업자를 생성 함)이 있다는 것을 깨달았습니다. 나는 약간 혼란 스럽다.

답변

2

파이썬은 OS 스레드를 사용합니다. CPU 바운드 작업에 대해서는 아무 것도 얻지 않지만 스레드는 IO 바운드 작업에 적합합니다. GIL, the Global Interpreter Lock은 출시 된 IO에 대한 것입니다.

multiprocessing 모듈은 CPU 바인딩 작업용으로 설계되었습니다. 귀하의 경우 16 개의 새로운 프로세스를 시작합니다. 시간이 필요해. 일반적으로 CPU가있는 것보다 더 많은 작업자/프로세스를 굳히는 것은 의미가 없습니다. 내 어림셈은 number_of_workers = number_of_cpus - 1입니다. 또한, 프로세스 간 통신을 위해 pickle을 사용하여 통신합니다. 업로드를 여러 번 연속해야 할 경우 여러 명의 직원을 시작하여 계속 유지하고 계속해서 다시 사용할 수 있습니다. 이는 각 업로드에 대해 눈에 띄는 계산을 수행하는 한 새 프로세스를 시작하는 오버 헤드를 정당화 할 수 있습니다. 귀하의 경우에 대해 프로파일 링해야합니다.

세 번째 옵션은 비동기로 전환하는 것입니다. 예를 들어 Twisted을 사용할 수 있습니다. 콜백을 사용해야하므로 코드를 다시 구성해야합니다.

+0

감사합니다. EC2의 가장 작은 기계에서 이것을 실행할 것이므로'다중 처리 (multiprocessing) '모듈을 사용하는 것이 타당하지 않을 수 있습니다. 옵션 # 1이 가장 빠르기 때문에 값 비싼 것 말고는 OS 쓰레드를 만들 때의 함정은 무엇입니까? 이렇게 많은 스레드가 권장됩니까? (20 개의 업로드가있는 경우 20 개의 스레드를 만드는 것이 옳지 않은 것 같습니다 ...) –

+0

이것은 많은 요소에 따라 다릅니다. 가장 간단한 방법은 그것을 시험해 보는 것입니다. 2, 4, 8, 16 ....보다 스레드없이 실행하십시오. json 파일에 대해 다른 크기를 사용하십시오. 물론 다른 시간대에 다양한 옵션을 사용하여 실제 네트워크에서 다른 네트워크 트래픽이 예상되는 상황을 파악하십시오. 성능은 모두 측정에 관한 것입니다. 내 직감으로 여러 번 잘못했다. 현실적인 경우 하드 번호를 생성해야합니다. –

+0

좋아요. 귀하의 답변을 반향 [이] (http://stackoverflow.com/questions/481970/how-many-threads-is-too-many), 실제로. 마지막으로 [스레드 객체 용 문서] (http://docs.python.org/2/library/threading.html#thread-objects)에는 "[스레드가] run() 메소드 종료 "합니다. 올바르게 이해하면 스레드가 파일 업로드를 완료 한 후에 명시 적으로 정리할 필요가 없습니다. –