멀티리포 vs 모노리포

들어가며

본 문서는 소스 형상 관리 시스템상에서 소스 리포지토리를 관리하는 방법인 멀티리포모노리포를 비교하고 분석하여, 개발 조직이 어떤 방식을 선택해야 하는지 정보를 제공한다.

멀티리포, 모노리포 선택의 필요성

멀티리포, 모노리포에 선택에 대해 고민하기에 앞서, 왜 우리가 이들에 관심을 가져야 하는지 알아야 한다. 그 이유는 프로젝트의 최초 생성과 변화 과정을 들여다보면 알 수 있다.

초기 프로젝트 구조

프로젝트 초기에는 모노리딕 시스템으로 서비스를 구현하게 된다. 프로젝트의 크기가 크지 않고, 개발자의 수도 적기 때문에 모든 것을 한곳에서 처리하는 것이 효율적이다. 이 경우 시스템 자체가 쪼개어지지 않고 하나이기 때문에 리포지토리 역시 하나로 관리하게 된다.

프로젝트 거대화에 따른 마이크로 서비스 구성

프로젝트가 거대화되면서 모노리딕 시스템은 문제를 야기한다. 대표적으로 높은 결합도와 낮은 응집력을 예로 들 수 있다. 이를 해결하기 위해서 개발 조직은 시스템의 각 부분을 도메인 별로 분리해서 마이크로 서비스로 구성하기 시작한다. 이때 개발 조직은 쪼개진 각 서비스를 하나의 리포지토리에서 관리할지, 각자 다른 리포지토리에서 관리할지 고민하게 된다.

멀티리포 vs 모노리포

리포지토리를 관리하는 방법은 시스템의 각 모듈을 개별 리포지토리에서 관리할 것인지, 하나의 리포지토리에서 관리할 것인지에 따라서 달라진다. 이때 나눠서 관리하는 것을 멀티리포, 하나로 관리하는 것을 모노리포라 정의한다.

멀티리포

시스템의 서비스별로 리포지토리를 각자 만들어서 관리한다.
서비스 간의 연동이 소스 단위로 이루어지지 않는다.
각 서비스가 별도의 폴더로 구성된다.

장점

  • 강한 오너쉽 확보
    • 리포지토리 별로 오너를 지정
  • 마스터의 코드가 깨질 여지가 적음
    • 코드 베이스가 아예 나뉘어 있음
    • 서로 간의 작업 충돌로 마스터 코드가 깨질 가능성이 적음
  • 형상 관리, CI 속도가 빠름
    • 리포지토리의 크기가 작기 때문에, 리파지토리 훅을 기반으로 동작하는 도구들의 속도가 빨라짐

단점

  • 코드 재사용이 쉽지 않으므로, 중복 코드 가능성이 높아짐
    • 다른 리포지토리의 코드를 사용하기 위해서 해야 할 작업이 좀 있음
  • 하나의 피쳐 개발을 위해 여러 리포지토리에 머지를 해야 함
  • 코드 리뷰가 나누어짐
  • 버전 연동이 깨질 위험이 있음
    • 하나의 브레이킹 체인지가 다른 리포지토리로 즉시 전파되지 않음
  • 디펜던시 헬
    • 프로젝트가 거대화됨에 따라 의존 그래프가 매우 복잡해지게 됨
    • 서로의 코드에 변화가 생길 때 이를 대처하기 쉽지 않음

모노리포

시스템의 각 서비스를 모두 하나의 리포지토리에서 일괄 관리한다.
서비스 간의 연동이 소스 단위로 이루어진다.
최상위 폴더부터 트리 구조로 서비스 폴더가 구성된다.

장점

  • 지속적인 소스의 무결성 보장
    • 리포지토리는 항상 모든 서비스가 연동된 올바른 상태를 유지함
  • 통합된 버전 관리
    • 모든 서비스가 연동된 상태에서 손쉽게 하나의 버전으로 관리 가능
  • 코드의 공유와 재사용이 용이
    • 소스 단위의 연동이 이루어진 상태
  • 의존성 관리가 쉬움
    • 전체 서비스의 의존 관계가 한 리포지토리에서 확인 및 설정 가능
  • 원자 단위 변화
    • 변화가 여러 스텝이 아니라 한 리포지토리에서 한 스텝으로 이루어짐
  • 여러 프로젝트팀 간의 협업이 쉬움
    • 하나의 리포지토리에서 함께 작업하며, 여러 서비스에 손쉽게 접근 가능
  • 유연한 팀 바운더리 설정과 코드 오너쉽을 가져갈 수 있음
    • 하나의 리포지토리, 하나의 서비스에 제한된 코드 오너쉽을 유지하지 않아도 됨
  • 통합 CI 및 테스트
    • 모든 소스가 연동된 상태. CI 및 테스트 구성이 손쉬움
  • 전체 코드가 트리 구조로 명확히 보임
  • 한 번의 코드 리뷰에 모든 변화가 요약

단점

  • 무분별한 의존성 연결 가능
    • 의존성 연결이 쉽기 때문에 오히려 과도한 의존 관계가 나타날 수 있음
  • 형상 관리 및 CI 속도 저하
    • 리포지토리의 크기가 크기 때문에, 리파지토리 훅을 기반으로 동작하는 도구들의 속도가 느려짐

주요 특징 비교

코드 오너쉽

코드 오너쉽의 경우 모노리포, 멀티리포의 측면보다는 마이크로 서비스의 구축 여부가 더 중요하다. 각 서비스가 도메인에 맞게 잘 분리가 되어 있다면, 서비스별로 오너쉽을 부여할 수 있을 것이다.

모노리딕 시스템에서는 아직 서비스의 분리가 미비하고, 하나의 서비스 안에서 여러 부분으로 오너쉽을 나눠 가져야만 한다. 이 때문에 코드의 오너쉽이 모호하게 분리된다. 이를 해결하기 위한 가장 좋은 방법은 마이크로 서비스로 시스템을 나누는 것이고, 그것이 힘들다면 도구의 도움을 받아서 폴더별로 코드의 오너를 지정하는 방법이 있다.

브레이킹 체인지 전파

멀티리포의 경우 각 리포지토리 별로 소스를 관리하기 때문에 브레이킹 체인지가 일어났을 경우 이를 의존하는 모듈에 자동으로 변화가 전파되지 않는다. 반대로, 모노리포의 경우 하나의 소스에서 작업을 진행하기 때문에 브레이킹 체인지가 발생했을 경우, 즉시 에러로 검출이 가능하다.

코드 리뷰

멀티리포의 경우 여러 리포지토리에 변경이 필요한 피쳐 작업이 있을 때, 코드 리뷰 또한 여러 리포지토리로 퍼트려야 한다. 모노리포의 경우 하나의 리포지토리에서 하나의 작업으로 처리가 되므로 코드 리뷰 효과가 명확하게 진행이 된다.

의존성 관리

모노리포의 경우 모든 소스가 한 리포지토리에서 관리되므로, 의존성 관리에 유리하다. 모든 의존 관계를 한 리포지토리에서 확인 가능하며, 관련 설정 파일도 한곳에서 모아서 관리가 가능하다. 반대로 멀티리포는 각 리포지토리가 자신의 의존관계만을 알고 있기 때문에 전체적인 의존관계를 파악하기 쉽지 않다.

버전 관리

멀티리포와 모노리포의 장단점이 존재한다. 멀티리포의 경우 서비스별로 형상 관리가 유지되기 때문에, 버전 관리를 서비스 단위로 독립적으로 하는 데 유리하다. 하지만 이는 위에서 살펴보았듯이 각 서비스 간의 버전 충돌 문제를 야기한다. 모노리포의 경우 각 서비스의 통합 버전 관리가 기본 베이스가 된다. 모든 소스가 연동된 상태에서 버전 관리가 이루어지기 때문에 서비스별로 버전 전략을 다르게 가져가며 배포에 어려움이 있다. 이러한 세밀한 버전 관리의 경우 브랜치 전략을 고도화하고, 도구의 도움을 받아 해결해야 한다.

도구 속도

멀티리포가 더 유리하다. 멀티리포는 각 작은 리포지토리별로 각자 도구들이 동작하게 되며, 작업의 단위가 작아지기 때문에 속도가 더 빠르다. 하지만, 이는 리포지토리 내에서도 특정 부분에 대해서만 형상 관리, CI 등을 제공하는 툴을 사용해서 해결할 수 있다.

결론

모노리포, 멀티리포는 간단히 생각하면 리포지토리를 어떻게 나눌 것이냐에 대한 방법론이다. 하지만 깊게 들여다보면 각각의 장단점이 존재하고 있고 주요 특징별로 고려해야 할 부분이 상당수 존재한다.

그렇다면 개발 조직은 위 방법 중 어떠한 것을 선택해야 하는가? 그 선택의 기준은 현재 혹은 미래에 계획 중인 시스템 구조가 무엇인지, 그리고 그에 맞는 것이 무엇인지 고민하는 것이다. 만약, 구조가 여러 모듈로 쪼개져 있고 의존관계가 복잡하지 않은 경우 멀티리포가 관리에 더 편할 수도 있다. 하지만, 시스템의 규모 및 개발 조직이 거대화되고 있다면, 그로 인해 의존성 그래프가 급격히 복잡해질 것으로 예측된다면, 모노리포가 관리에 더 유용할 수 있다.

참고 자료

기업별 모노리포 사례

기타