This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned on this page are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
proposed @jcai-gitlab @toon devops systems 2023-05-19

저렴한 저장소로 데이터 오프로드

요약

Git 데이터 저장 비용을 관리하는 것은 우리 비즈니스의 중요한 부분입니다. Git 데이터를 저렴한 저장소로 오프로드하면 저장 비용을 절약할 수 있습니다.

동기

GitLab에서는 데이터 접근 속도를 빠르게 유지하기 위해 대부분의 Git 데이터를 SSD에 저장합니다. 이는 우리가 빈번하게 접근해야 하는 데이터에 대해 의미가 있습니다. 그러나 저장 비용이 데이터 성장과 함께 증가하기 때문에, 우리는 어떤 종류의 데이터를 SSD에 유지하고 어떤 종류의 데이터를 저렴한 저장소로 오프로드할 수 있는지에 대해 더 현명하게 선택할 수 있습니다.

예를 들어, 대용량 파일(또는 Git 용어로 “blob”이라고 함)은 일반적으로 수정되지 않습니다. 왜냐하면 일반적으로 비텍스트 파일(이미지, 비디오, 이진 파일 등)이기 때문입니다. 종종, 이러한 대형 blob이 포함된 저장소에는 Git LFS가 사용되어 Git 서버에 큰 파일을 푸시하지 않도록 합니다. 그러나 이는 클라이언트 측 설정에 의존합니다.

또는, 프로젝트가 “풀린” 상태이고 오랜 시간 동안 액세스되지 않았다면, 해당 프로젝트에 대해 빠른 저장소에 지불할 필요가 없습니다.

대신, 우리는 해당 풀린 프로젝트의 모든 blob을 저렴한 저장소에 둘 수 있습니다. 이렇게 하면 애플리케이션은 여전히 커밋 히스토리와 트리에 접근할 수 있어서 프로젝트 탐색 경험이 영향을 받지 않지만, 파일은 거의 액세스되지 않기 때문에 느린 저장소에 있습니다.

만약 우리가 Git 데이터를 다른 범주로 분리하는 방법을 가졌다면, 우리는 특정 데이터를 보다 저렴한 보조 위치로 오프로드할 수 있었을 것입니다. 예를 들어, 우리는 더 크게 액세스되지 않을 수도 있는 대형 파일을 나머지 Git 데이터와 구분하여 HDD에 저장할 수 있었습니다.

요구 사항

해당 솔루션에 대한 일련의 요구 사항과 불변 사항이 있습니다.

저장 비용 절약

마지막으로, 이 솔루션은 저장 비용을 절약해야 합니다. 저렴한 저장소로 일부 Git 데이터를 분리함으로써 이러한 절약에 기여할 수 있습니다.

저렴한 저장소에 데이터를 오프로드하는 것에 따른 예상 절약과 추가 비용의 평가가 필요합니다. 여기에 고려해야 할 몇 가지 기준이 있습니다:

  • X보다 큰 모든 대형 blob을 HDD에 넣으면 어느 정도의 비용 절약이 있을까요?
  • 모든 풀린 프로젝트 blob을 HDD에 넣으면 얼마나 절약이 되는가요?
  • 추가 CPU/메모리 비용 측면에서 오프로드 메커니즘 실행의 운영적 오버헤드는 어떻게 되나요?
  • 네트워크 오버헤드는 어떻게 되나요? 예를 들어, 대형 blob을 검색하기 위해 네트워크를 통해 다른 노드로 추가 라운드트립이 있나요?
  • 액세스 비용, 예를 들어, blob이 객체 저장소에 저장될 때.

Gitaly의 하위 소비자에게 불투명

이 기능은 순수한 저장소 최적화이며 잠재적인 성능 감소를 제외하고는 Gitaly의 하위 소비자에게 영향을 미치지 않아야 합니다. 예를 들어, GitLab 애플리케이션은 이 기능을 지원하기 위해 로직을 변경할 필요가 없어야 합니다.

이 기능은 Gitaly를 호출하는 모든 사용자에게 완전히 보이지 않아야 합니다. Rails 또는 다른 하위 소비자들은 이에 대해 알 필요가 없고 이를 어떠한 방식으로 관리할 필요가 없어야 합니다.

운영적으로 간단함

Git 데이터를 처리할 때, 리포지토리 손상의 위험을 최소화하기 위해 가능한 한 간단하게 유지하고 Git 자체 외부의 움직이는 부분을 최소화하고 싶습니다. 리포지토리 데이터를 수정하는 어떠한 로직도 Git 자체에서 상위화 되어야 합니다.

제안

각 리포지토리에 대해 Git 대체 메커니즘을 통해 연결된 별도의 객체 데이터베이스(ODB)를 유지할 것입니다.

이러한 보조 ODB를 위해 일부 Git 객체를 필터링하는 선택지를 가질 것입니다. Git 필터에 기반한 옵션이 있습니다.

특정 제한에 따라 대형 blob을 추가 ODB에 넣거나 모든 blob을 추가 ODB에 넣을 수 있습니다.

디자인 및 구현 세부 정보

Git

우리는 ‘git-repack(1)’에 기능을 추가해야 합니다. 이 기능을 통해 다른 종류의 blob을 서로 다른 객체 데이터베이스에 세분화할 수 있게 될 것입니다. 이 노력은 이 이슈에서 추적하고 있습니다.

Gitaly

Gitaly 하우스키퍼링 중에 우리는 다음을 수행할 수 있습니다:

  1. 각 리포지토리에 대해 git-repack(1)을 사용하여 pack 파일을 주 저장소의 객체 데이터베이스와 보조 객체 데이터베이스에 작성합니다. 각 리포지토리에 대해 자체적인 보조 객체 데이터베이스가 있으며, 일정 기준에 따라 blob을 오프로드합니다.
  2. .git/objects/info/alternates 파일이 (1)단계에서 생성된 보조 객체 데이터베이스를 가리키도록 합니다.

기준

객체를 다른 객체 데이터베이스로 오프로드할지 여부는 다음 중 하나 이상의 기준에 따라 결정됩니다.

티어별

무료 프로젝트는 저렴한 저장소로 많은 blob을 오프로드할 수 있고, 얼티밋 프로젝트는 모든 객체를 가장 빠른 저장소에 둘 것입니다.

과거의 기록에 따라

오래 전에 추가된 blob이 최근 커밋에서 언급되지 않으면, 새로운 blob은 주 스토리지에 남아 있는 동안 offloaded될 수 있습니다.

크기별로

크기가 큰 blob은 비싼 저장 공간을 줄이는 빠른 방법이므로, 저렴한 저장 공간으로 이동하는 것이 우선시될 수 있습니다.

액세스 빈도

자주 사용되는 프로젝트는 빠른 저장 공간에 완전히 남아 있는 반면, 비활성화된 프로젝트는 그들의 blob이 offloaded될 수 있습니다.

오픈 질문

객체를 어떻게 삭제하나요?

도달할 수 없는 객체를 삭제하려면, 리팩이 주 ODB와 보조 ODB 둘 다를 인식하고, 말물 객체를 삭제할 수 있어야 합니다. 이 그림은 메인 ODB 또는 보조 ODB에 객체 풀이 있는 경우에 복잡해집니다.

잠재적인 해결책: Git을 수정하여 보조 ODB에서 객체를 삭제하는 방법

리팩을 수정하여 보조 ODB에서 도달할 수 없는 객체를 삭제할 수 있는 능력을 부여해야 합니다. 리팩 설정인 repack.alternates.*를 추가하여 보조 디렉토리와의 상호작용을 지정할 수 있습니다. 예를 들어, 우리는 repack.alternates.explodeUnreachable를 추가하여 리팩이 연결된 모든 보조 ODB에서 -A처럼 행동하도록 지시할 수 있습니다.

객체 풀과의 상호작용은 어떻게 되나요?

대체물을 사용할 때, 이것이 객체 풀과 어떻게 상호작용하나요? 객체 풀도 보조 저장소로 데이터를 offload합니까? 객체 풀의 구성원은요? 가장 복잡한 경우에는 하나의 리포지토리에 네 가지 다른 객체 데이터베이스가 있는데, 이것은 복잡성을 증가시킬 수 있습니다.

아마도 –keep-pack–honor-pack-keep 옵션을 사용하여 일부 팩 파일을 “유지”로 표시할 수 있습니다.

잠재적인 해결책: 객체 풀이 blob을 offload하지 못하도록 허용하지 않음

너무 복잡성을 추가하지 않기 위해, 우리는 객체 풀이 blob을 offload하지 못하도록 결정할 수 있습니다. 대신, 객체 풀과 중복을 방지하기 위해 리포지토리에서 blob을 offload하는 하우스키퍼를 설계할 수 있습니다. 이론적으로는, 이로 인해 offloaded된 blob이 객체 풀에 들어가지 않을 것입니다.

Raft + WAL과 어떻게 작동하나요?

이 메커니즘이 Raft와 전방 로그(WAL)와 어떻게 상호작용하나요?

WAL은 느린 복사 작업을 피하기 위해 하드 링크와 복사 없는 이동을 사용합니다. 그러나 이것은 서로 다른 파일 시스템 사이에서는 작동하지 않습니다. 언젠가는 리팩 등도 로그를 통해 지날 가능성이 매우 높습니다. 파일 시스템 간의 데이터 이동은 트랜잭션 처리 지연을 야기할 수 있습니다.

이상적으로는 노드 내부의 대체 사용을 유지하고 나머지 클러스터에 이 복잡성을 노출시키지 않아야 합니다. 이는 배치 결정 시 사용 가능한 공간을 고려해야 한다는 도전입니다. 두 저장소의 용량 중 낮은 용량만 표시함으로써 내부적으로 유지할 수 있지만, 효율적인 저장소 사용으로 이어질 수도 있습니다.

디자인에 대한 문제점

추가된 복잡성

우리가 시스템에 또 다른 객체 풀을 추가할 때, 시스템에 복잡성이 추가됩니다. 특히, 리포지토리 복제와 관련하여 추가 복잡성이 생깁니다.

시간이 지남에 따른 비용 변화 가능성

다양한 저장 유형의 비용은 시간이 지남에 따라 변할 수 있습니다. 이를 예상하기 위해 이에 대한 적응이 쉬워야 합니다.

실패 가능성 증가

별도의 저장 장치에 일부 blob이 있을 때, 대형 blob을 호스팅하는 장치가 고장 나는 또 다른 실패 시나리오가 추가됩니다.

대체 솔루션

전체 프로젝트를 저렴한 저장 공간에 배치

저렴한 저장 공간에 Git 데이터를 배치하는 대신, Rails 애플리케이션은 프로젝트 전체를 마운트된 HDD 드라이브로 이동할 수 있습니다.

가능한 최적화

이러한 저렴한 저장 공간을 가진 컴퓨터에 더 많은 RAM을 제공하면 페이지 캐시 사용으로 인한 느린 읽기/쓰기 속도를 다루는 데 도움이 될 수 있습니다. 그러나 이것이 전반적으로 더 저렴한 해결책으로 나타날지는 확실하지 않습니다.