1

을 통과하는 동안 메모리 부족 I이 종류 RawEmailModel 및 업데이트 카운터의 모든 엔티티를 반복 할 코드를 다음앱 엔진 : 테이블

def update_emails(cursor=None, stats = {}): 
    BATCH_SIZE = 100 
    if not cursor: 
     # Start of the job 
     pass 
    next_cursor = cursor 
    more = True 
    try: 
     while more: 
      rawEmails, next_cursor, more = RawEmailModel.query().fetch_page(BATCH_SIZE, start_cursor=next_cursor) 
      ndb.get_context().clear_cache() 
      for rawEmail in rawEmails: 
       try: 
        stats[rawEmail.userId] += 1 
       except Exception: 
        stats[rawEmail.userId] = 0    
      logging.debug(stats) 
     logging.debug("Done counting") 
    except Exception as e: 
     logging.error(e) 

내가 읽어 내가 무엇을 기반으로 NDB 캐시를 삭제하고 내가 루프의 상단에있는 캐시를 지우고 계속 때 여전히 메모리가 부족 해요 왜

20:21:55.240 {u'104211720960924551911': 45622, u'105605183894399744988': 0, u'114651439835375426353': 2, u'112308898027744263560': 667, u'112185522275060884315': 804} 

F 20:22:01.389 Exceeded soft private memory limit of 128 MB with 153 MB after servicing 14 requests total 

W 20:22:01.390 While handling this request, the process that handled this request was found to be using too much memory and was terminated. This is likely to cause a new process to be used for the next request to your application. If you see this message frequently, you may have a memory leak in your application. 

을하지 않습니다 https://stackoverflow.com/a/12108891/2448805 그러나, 나는 아직도 내가 메모리가 부족 해요 말하는 오류를 얻을? 감사!

+2

RawEmailModel.query()를 while 루프 외부로 옮기는 것이 좋습니다. –

+0

하지만 모든 엔티티 (~ 100k)를 반복하면서 한 번에 100 개의 이메일을 가져 오는 것이므로 while 루프 내부에 있어야합니다. –

답변

1

많은 RawEmailModel 항목이 있고 통계 제한이 커지고 메모리 한도에 도달 한 것처럼 보입니다. ndb.get_context(). clear_cache()가 여기 도움을주지 않을 것입니다.

다른 모델을 생각해 보면 RawEmailCounterModel에서 userId 및 total_count를 필드로 사용하고 stats dict를 사용하는 대신 while 루프에서 계속 업데이트하는 것이 좋습니다.

적어도 메모리 부족 문제를 해결하는 데 도움이됩니다. 그러나 이것은 공연하지 않을 수도 있습니다.

+0

통계 dict에는 3 개의 키만 있습니다 (3 명의 사용자가 있음), 메모리가 부족하기 전에 약 30-50k 항목을 반복합니다. ~ 100k 개의 항목을 완전히 가져오고 있지만 fetch_page를 사용하면 한 번에 100 개의 항목을 가져온 다음 캐시를 지우는 것이됩니다. 그래서 나는 한 번에 단지 100 개의 엔티티 만 메모리에 있어야한다고 생각하는 이유입니다. 그래서 나는 그것이 왜 메모리가 부족했는지 궁금합니다. –

+0

당신은 RawEmailModel 엔티티 전체 컬렉션에서 고유 한 rawEmail.userId가 3 개 밖에 없다고 말씀하셨습니까? 그렇지 않으면 데이터 저장소의 고유 한 rawEmail.userId 번호로 통계를 작성해야합니다. 당신은 단지 3 명의 사용자 만 가지고 update_emails에 통계를 보낼 수 있지만, keyError가 발생할 때마다 0으로 값을 갖는 새 항목을 sat dict에 추가 할 수 있습니다. – gipsy

+1

@DebnathSinha 또 하나주의해야 할 것은 인스턴스 크기입니다. 인스턴스 당 실제 RAM 크기를 더 지불하려는 경우 인스턴스를 늘릴 수 있습니다. 이것은 확실히 당신이하고 싶은 일에 충분한 기억이 있는지 확인하는데 도움이 될 것입니다. 문제는 집시가 말하고있는 것처럼 통계가 점점 커지고 있다는 것입니다. memcache처럼 보이지 않으므로 메모리 오류를 수정하지 않습니다. – Patrice