2011-12-29 3 views
4

ActiveRecord를 사용하여 한 데이터베이스의 테이블에서 다른 데이터베이스의 다른 테이블로 일부 데이터를 대량 마이그레이션합니다. 약 4 백만 행.ActiveRecord 대량 데이터, 메모리가 영원히 증가합니다.

나는 find_each를 사용하여 일괄 적으로 가져옵니다. 그런 다음 가져온 각 레코드에 약간의 논리를 적용하여 다른 데이터베이스에 씁니다. 나는 직접적으로 한 장씩 쓰려고 노력했다. 멋진 activerecord-import gem을 사용하여 일괄 적으로 쓰기도했다.

그러나 중 하나 인 인 경우, 내 루비 프로세스 메모리 사용량이 내보내기/가져 오기 전 기간 동안 상당히 증가하고 있습니다. 나는 find_each를 사용하여 1000 개의 일괄 처리를 사용하고 있다고 생각하지만, 한 번에 1000 개가 넘는 메모리가 있어야합니다 ...하지만 아니요, 가져 오는 각 레코드는 프로세스가 끝날 때까지 메모리를 영원히 소모하는 것 같습니다.

아이디어가 있으십니까? ActiveRecord가 내가 어딘가에서 숨길 수있는 어떤 것을 캐싱하고 있습니까?

갱신 1월 17일 2012

나는이 포기하는 것 같네요. 나는 시도했다 : * 반드시 모든 것을 만들기에 싸여있는 ActiveRecord::Base.uncached do * ActiveRecord::IdentityMap.enabled = false (나는 그것을 명확하게 문서화 아니에요 있지만, 현재의 스레드에 대한 신원지도를 해제해야하고, 내가 신원 맵 ISN 생각 생각 추가 어떤 식 으로든 현재 레일스에서는 기본적으로 켜져 있습니다.)

어느 쪽도 그다지 효과가없는 것 같아요, 메모리는 여전히 새어 나옵니다.

나는 다음 정기 명시 적으로 추가 :

    메모리 누수의 속도를 느리게 보인다
  • GC.start

하지만, 메모리 누수가 여전히 궁극적으로 모든 메모리와 폭격을 배출 (발생).

그래서 나는 포기하고 있다고 생각하고 현재 AR을 사용하여 하나의 데이터베이스에서 수백만 행을 읽고 다른 행에 그것을 삽입하는 것은 불가능합니다. 아마도 MySQL의 특정 코드 (즉, 내 데이터베이스) 또는 AR의 다른 곳 또는 누가 알고 있는지 메모리 누수가 있습니다.

+0

코드를 보지 않아도 나는 가장 실마리가 없습니다. –

+0

코드는 설명 된 내용을 처리하는 것으로 꽤 직관적입니다. 여기에 실제 파일이 있습니다. 주변 설정 및 AR 모델의 동적 생성없이 간단한 데모 케이스를 제공 할 수 있습니다.https://github.com/team-umlaut/umlaut/blob/e583824dd15520c146e3cd020d762591b179803d/lib/tasks/umlaut_migrate_permalinks.rake – jrochkind

+0

안녕하세요, @jrochkind가이 문제에 대한 해결책을 찾았습니까? 나도 같은 문제에 직면하고있다. 미리 감사드립니다! – apandey846

답변

1

각 작업 단위를 Resque 대기열에 대기시키는 것이 좋습니다. 나는 루비가 이러한 큰 배열을 반복 할 때 몇 가지 단점이 있음을 발견했다.

대기열에서 ID별로 작업을 처리하는 주 스레드가 하나 있고 대기열에 대기중인 작업자가 여러 명 있으면 작업을 완료 할 수 있습니다.

나는이 방법을 약 300k 레코드에 사용 했으므로 아마도 수백만 개까지 확장 할 수 있습니다.

0

bulk_queue.clear은 arrya의 길이를 0으로 설정하기 때문에 GC가이를 지울 수 없기 때문에 라인 # 86에서 bulk_queue = []으로 변경하십시오.

관련 문제