기존 보드에서 가져오기(import) 테스트를 진행 중입니다. 가져와야 할 게시물이 약 2,500만 개(일반 게시물 + 비공개 대화) 정도 되는데, 처리 속도를 높이기 위해 가져오기 스크립트를 여러 개 복제해 동시에 실행하고 토픽 부하를 분산했습니다. 며칠 동안은 문제가 없었지만, 시간이 지날수록 각 프로세스의 메모리 사용량이 서서히 증가해 각각 약 2GB까지 올라가는 것을 확인했습니다. 그러다 결국 서버 메모리가 고갈되어 MySQL 소스 데이터베이스가 약 1,600만 게시물 지점에서 강제 종료되었습니다.
시스템 메모리를 24GB에서 32GB로 늘렸지만, 이제 가져오기 프로세스를 1개만 다시 시작하여 중단된 위치부터 이어서 실행하려고 해도, 게시물을 실제로 가져오기 시작하기도 전에 해당 프로세스가 약 10GB의 메모리를 차지하고 있습니다. 이전에 8개의 가져오기 프로세스를 동시에 실행할 수 있었는데, 이제는 더 큰 메모리 풀에서도 2개만 실행할 수 있습니다. 클린 설치 시의 메모리 사용량과 실패 후 가져오기를 재개할 때의 메모리 사용량 사이에 이렇게 큰 차이가 나는 이유는 무엇일까요? 가져오기 프로세스를 다시 빠르게 진행할 수 있도록 이 메모리 사용량을 줄이는 방법이 있을까요? 128GB~256GB 메모리를 갖춘 서버는 비용이 prohibitively 비싸고(그리고 가져오기 이후에는 필요하지 않으므로) 적합하지 않으며, 가져오기 프로세스를 2개만 실행하게 되면 완료까지 몇 주가 걸릴 것입니다.
메모리 사용량은 실제 게시글 처리 단계가 아니라, 가져오기 스크립트 시작 시의 “기존 게시글 불러오는 중…”(또는 주제) 섹션에서 모두 발생하는 것으로 보입니다. 제가 확인한 바로는, 해당 섹션은 데이터베이스에서 게시글 및 주제 정보를 가져오기 때문에 정규식(regex)이 관여될 이유가 없습니다.
@posts와@topics 변수는 “topic_lookup_from_imported_post_id” 메서드 등에 사용되는 것으로 보입니다. 이는 이해가 되지만, 스크립트가 처음 실행되었을 때 메모리 사용량은 현재 확인되는 수준에 훨씬 못 미쳤음에도 불구하고 해당 메서드들은 여전히 정상적으로 작동하고 있습니다.
벌크 임포트 스크립트에 대해 알고 있는 것이 없습니다. import_scripts 디렉터리 어딘가에 있는 건가요?
네, 바로 그 부분에서 어려움을 겪고 있습니다. 8개의 임포트 프로세스를 실행하던 초기 임포트 단계에서는 비교적 문제가 없었으나, 시스템이 메모리를 모두 소진할 때까지 그랬습니다. 이제 임포트 프로세스를 다시 시작하여 중단된 부분부터 계속 진행하려고 하면, 각 프로세스가 처음 충돌했을 때보다 약 5배 많은 메모리를 사용하게 됩니다.
적절한 테스트를 수행하고 이 마이그레이션이 실제로 언제 수행될지에 대한 기대치를 설정하려면 전체 임포트를 완료해야 합니다. 현재로서는 성능과 같은 사항에 대해 무엇을 기대해야 할지 명확한 이해가 없습니다. 또한 1,600만 건의 게시물을 처리한 시점에서도 데이터베이스 크기가 이미 현재 데이터베이스보다 50% 이상 큰 것을 발견했는데, 이는 다소 놀라운 부분입니다. 긴 임포트 시간은 이를 불가능하게 만들지는 않지만, 기대치가 주 단위가 아니라 일 단위로 설정된다면 훨씬 편리할 것입니다.
토픽과 게시글의 경우, 토픽과 그 이전의 모든 게시글이 이미 가져와지지 않은 상태에서는 해당 토픽의 게시글을 가져올 수 없으므로 병렬 가져오기를 실행하는 것은 사실상 불가능합니다. 사용자와 토픽에 대해서는 병렬 프로세스를 사용할 수 있다고 생각하지만, 게시글에 대해서는 병렬 가져오기를 허용하도록 스크립트를 다시 작성하여 특정 토픽의 모든 게시글을 한꺼번에 가져오도록 해야 합니다. 이는 분명히 가능하지만, 제가 사용해 온 스크립트 중 어느 것도 그렇게 동작하지는 않습니다. 하지만 여전히 RAM에 구식에서 최신으로의 ID 매핑을 유지해야 하는 문제가 남게 됩니다.
이 접근 방식에 대해 지금까지는 문제가 없는 것 같습니다. 다만, 가져오기(import) 이후에 실행되는 일부 메서드에서 문제가 발생할 수 있을 것 같습니다. 그래서 그 시점 이후에는 모든 처리를 중단하고, 나머지 작업을 깔끔하게 처리할 수 있도록 단일 스레드 실행을 수행하는 것이 좋을 것 같습니다.
그럼에도 불구하고, 가져오기 ID 링크를 다른 방식으로 처리하라는 제안은 어떤 경우에도 좋은 아이디어일 것입니다. 스크립트 실행이 끝날 때까지 변수에 임의로 큰 양의 데이터를 유지하는 것은 매우 비효율적이기 때문입니다.