2012-06-26 4 views

답변

4

mapper 사용 - 이것은 MapReduce 프레임 워크의 일부이지만 단순히 데이터 스토어 엔티티를 변경하는 경우 셔플/감소 단계가 필요하지 않으므로 첫 번째 구성 요소 인 map 만 원합니다.

+0

저는 실제로 MapReduce 프레임 워크를 사용하고 있으므로 이러한 작업을 파이프 라이닝하는 것이 좋습니다. 필자의 염려는 여러 개의 put() 작업을 병렬로 실행하는 것입니다. 성능 문제를 넘어서는 많은 엔티티가 엔티티 그룹을 공유하므로 데이터 저장소 시간 초과가 걱정됩니다. 어쨌든 파이프 라인을 만들고 여전히 put()을 집계합니까? –

+0

map-reduce api는 돌연변이 풀을 통한 배치 데이터 저장소 작업을 허용합니다. http://code.google.com/p/appengine-mapreduce/wiki/GettingStartedInPython –

3

다니엘은 정확하지만 맵퍼를 망치고 싶지 않다면 앱에 다른 라이브러리를 추가해야합니다. Task Queues을 사용하거나 SDK 1.2 이후에 포함 된 deferred library을 사용하면 더 간단합니다. .삼.

20.000 엔티티는 그렇게 극적이지 않으며이 작업이 정기적으로 수행되지는 않는다고 가정합니다 (하지만 그렇게해도 가능합니다).

다음은 NDB과 지연된 라이브러리를 사용하는 예제입니다 (DB를 사용하면 쉽게 할 수 있지만 아직 사용하지 않으면 NDB로 전환하는 것을 고려하십시오). 꽤 직선적 인 방법이지만, 제한 시간을 신경 쓰지 않아도됩니다.

def update_model(limit=1000): 
    more_cursor = None 
    more = True 
    while more: 
    model_dbs, more_cursor, more = Model.query().fetch_page(limit, start_cursor=more_cursor) 
    for model_db in model_dbs: 
     model_db.updated = True 
    ndb.put_multi(model_dbs) 
    logging.info('### %d entities were updated' % len(model_dbs)) 

class UpdateModelHandler(webapp2.RequestHandler): 
    def get(self): 
    deferred.defer(update_model, _queue='queue') 
    self.response.headers['Content-Type'] = 'text/html' 
    self.response.out.write('The task has been started!') 
+1

이 접근 방식에 대한 주요 관심사는 모든 모델이 쓰기 전에 메모리에 저장되므로 인스턴스 메모리 제한을 초과하는 것입니다. . 커서를 전달하여 주어진 수의 모델 이후에 update_model 태스크가 다른 update_model 태스크를 생성하도록하는 것이 가능합니다. –

+0

@TomerWeller 필요 없다고 생각합니다. 이것은 개입 테스트가 아니며 자신의 앱에 채택하는 것이 매우 쉽습니다. 그러니 알려주세요. – Lipis

+1

"155.32MB의 소프트 개인 메모리 제한을 초과했습니다. 총 1 건의 요청을 처리 한 후 "입니다. 엔티티 당 평균 10KB 인 18,000 개의 엔티티가 있습니다. 기본 프론트 엔드 인스턴스에 128MB의 메모리가 있고 180MB 상당의 데이터를로드하려고하므로 예상되는 오류입니다. appengine을 사용하면 155에 도달 할 수 있습니다. –