파일 중복 없이 효율적인 버전 관리 구축하기
모든 버전이나 포크(fork)에 대해 파일 전체 복사본을 저장하는 것은 공간을 낭비합니다. 10개의 파일이 있는 프로젝트에서 한 줄만 수정하더라도, 10개의 파일을 모두 다시 저장할 필요는 없습니다.
LaTeX Writer 프로젝트를 개발하면서 이 문제에 직면했습니다. 높은 저장 비용 없이 버전 관리와 프로젝트 포킹을 처리할 방법이 필요했습니다.
GitHub이 어떻게 작동하는지 살펴보았습니다. GitHub은 변경 사항이 생길 때마다 전체 저장소(repository)를 저장하지 않습니다. 콘텐츠를 별도로 저장하고, 파일과 커밋을 연결하기 위해 참조(reference)를 사용합니다.
세 가지 주요 구성 요소를 사용하여 시스템을 구축했습니다:
- Metadata: 프로젝트, 소유자 및 폴더의 ID를 저장합니다.
- File Records: 파일 이름과 콘텐츠에 대한 링크를 저장합니다.
- Blobs: 실제 콘텐츠가 저장되는 곳입니다.
이 시스템은 콘텐츠 해싱(content hashing)을 통해 작동합니다. 파일을 저장할 때, 시스템은 콘텐츠를 기반으로 고유한 ID를 생성합니다. 만약 해당 콘텐츠가 이미 존재한다면, 시스템은 기존의 Blob을 재사용합니다. 새로운 것을 생성하지 않습니다.
이 방식은 포크를 쉽고 저렴하게 만듭니다. 프로젝트를 포크할 때:
- 시스템은 새로운 Project ID를 생성합니다.
- 파일과 폴더를 위한 새로운 메타데이터를 생성합니다.
- 새로운 메타데이터가 기존의 Blobs를 가리키도록 합니다.
포크 과정에서 실제 파일 콘텐츠는 복사되지 않습니다. 작은 메타데이터 레코드만 복제될 뿐입니다.
포크를 편집할 때도 프로세스는 효율적으로 유지됩니다:
- 콘텐츠를 변경합니다.
- 시스템이 새로운 콘텐츠를 해싱합니다.
- 해당 콘텐츠가 정확히 일치하는 것이 없을 때만 새로운 Blob을 생성합니다.
- 포크의 메타데이터는 새로운 Blob을 가리킵니다.
- 원본 프로젝트는 여전히 기존 Blob을 가리킵니다.
이 방법은 다음과 같은 여러 이점을 제공합니다:
- 콘텐츠 중복 제거(deduplication)로 방대한 양의 공간을 절약합니다.
- 포킹이 즉각적으로 이루어집니다.
- 버전 관리가 체계적으로 유지됩니다.
- 데이터베이스 증가 속도가 완만하게 유지됩니다.
과도한 저장 공간 오버헤드 없이 GitHub과 유사한 기능을 사용할 수 있습니다.