2013-03-05 1 views
3

자주 많은 객체 집합에 대해 간단한 작업을 수행하려는 경우 문제가 발생합니다. 필자가 당연한 선택은 단순성을 위해 IPython Parallel을 사용하는 것이지만, 종종 비칠 수없는 객체를 다루어야한다. 몇 시간 동안 노력한 후에 나는 보통 한 컴퓨터에서 밤늦게 내 taks를 실행하는 것으로 사임하거나 여러 개의 파이썬 스크립트로 실행하기 위해 반 수동으로 물건을 나누는 것과 같은 어리석은 행동을합니다.IPython 병렬 처리 (또는 다른 패키지) 패칭이 안되는 객체에 따라 병렬 처리 (또는 다른 패키지)

구체적인 예를 들어, 부여 S3 버킷의 모든 키를 삭제하려고한다고 가정합니다.

은 내가 일반적으로 생각하지 않고 할 줄 것은 :

import boto 
from IPython.parallel import Client 

connection = boto.connect_s3(awskey, awssec) 
bucket = connection.get_bucket('mybucket') 

client = Client() 
loadbalancer = c.load_balanced_view() 

keyList = list(bucket.list()) 
loadbalancer.map(lambda key: key.delete(), keyList) 

문제는 boto에서 Key 오브젝트 (*) unpickable 것입니다. 이것은 나를 위해 다른 상황에서 매우 자주 발생합니다. 그것은 멀티 프로세싱, execnet 및 내가 시도한 모든 다른 프레임 워크와 libs에서도 문제입니다. (명백한 이유로 : 그들은 모두 객체를 직렬화하기 위해 동일한 pickler를 사용합니다).

여러분도 이러한 문제가 있습니까? 더 복잡한 객체를 직렬화 할 수있는 방법이 있습니까? 나는이 특별한 물건에 대해 나 자신의 pickler를 써야 하나? 만약 그렇다면, 어떻게 IPython Parallel에 그것을 사용하라고 말합니까? pickler를 쓰려면 어떻게해야합니까?

감사합니다.


(*) 나는 단순히 키 이름의 목록을 확인하고이 같은 것을 할 수 있다는 것을 알고 있어요 :

loadbalancer.map(lambda keyname: getKey(keyname).delete()) 

을하고 IPython 클러스터의 각 엔진에 getKey 함수를 정의 . 이것은 내가 자주 발견하는 좀 더 일반적인 문제의 특별한 경우에 불과합니다. 어쩌면 나쁜 예가 될 수 있습니다. 다른 방법으로 쉽게 해결할 수 있기 때문입니다.

+2

나는 작업 당신이 그들의 재미를 SO에하지 않고 충분히 당황 확신 해요! –

답변

0

그 IPython은 확실히 사람들을 모으게합니다. 그래서 제가 수집 할 수 있었던 것에서 피클 링 개체의 문제가 그들의 방법입니다. 그래서 key 메서드를 사용하여 삭제하는 대신 그것을 가져 와서 삭제하는 함수를 작성할 수 있습니다. 어쩌면 먼저 dict의 목록을 각 키의 관련 정보와 함께 얻은 다음 나중에 s3 키를 처리하는 방법을 모르기 때문에 필자에게 맡기는 함수 delete_key(dict)을 호출하십시오.

그게 가능할까요?


또는,이 작동 될 수있다 : 단순히 대신 인스턴스의 메소드를 호출의 인수로 인스턴스와 클래스의 메소드를 호출합니다. 따라서 lambda key : key.delete() 대신 lambda key : Key.delete(key)을 입력하십시오. 물론 클래스를 노드로 푸시해야하지만 문제는되지 않습니다. 최소한의 예 :

class stuff(object): 
     def __init__(self,a=1): 
      self.list = [] 
     def append(self, a): 
      self.list.append(a) 

    import IPython.parallel as p 
    c = p.Client() 
    dview = c[:] 

    li = map(stuff, [[]]*10) # creates 10 stuff instances 

    dview.map(lambda x : x.append(1), li) # should append 1 to all lists, but fails 

    dview.push({'stuff':stuff}) # push the class to the engines 
    dview.map(lambda x : stuff.append(x,1), li) # this works.