성장하는 코드베이스를 확장 가능하게 관리하기 위한 두 가지 대안(멀티 레포와 모노레포)을 비교하고, 멀티 레포가 변화 전파를 어렵게 만들어 장기적으로 취약해질 수 있는 이유를 설명한다.
2022년 3월 9일 · 읽는 데 3분
Pants 공동 제작자이자 메인테이너

조직의 코드베이스 아키텍처를 책임지고 있다면, 어느 시점엔가 이 성장을 확장 가능(scalable)하게 관리하기 위해 단호한 선택을 해야 합니다. 선택할 수 있는 대표적인 아키텍처 대안은 두 가지가 있습니다…
📰
이 글은 Software Development Times에 원문이 처음 게재되었습니다(2022년 1월 18일). 허가를 받아 재수록합니다.
코드베이스는 그것을 만드는 사람들만큼이나 다양하고, 고유하며, 흥미롭습니다. 하지만 거의 모든 코드베이스가 공통으로 갖는 특징이 하나 있습니다. 바로 시간이 지날수록 성장한다는 점입니다(사람이 아니라 코드베이스가요). 팀은 커지고, 요구사항은 늘어나며, 시간은 말할 것도 없이 계속 흐릅니다. 그 결과 더 많은 개발자가 더 많은 일을 하기 위해 더 많은 코드를 작성하게 됩니다. 물론 우리 모두가 대규모 코드를 통째로 삭제하는 기쁨을 경험해 본 적이 있지만, 그런 일이 코드베이스 전체 규모의 증가를 상쇄하는 경우는 드뭅니다.
조직의 코드베이스 아키텍처를 책임지고 있다면, 언젠가는 이 성장을 확장 가능하게 관리하기 위해 매우 분명한 선택을 내려야 합니다. 그리고 선택지로 흔히 거론되는 아키텍처는 두 가지입니다.
첫째는 “멀티 레포(multi-repo)” 아키텍처입니다. 하위 팀(subteam) 또는 프로젝트의 경계를 기준으로 코드베이스를 점점 더 많은 작은 저장소(repo)로 쪼개는 방식입니다. 둘째는 “모노레포(monorepo)” 로, 여러 프로젝트와 라이브러리의 코드를 하나의 크고 계속 성장하는 저장소에 유지하고, 여러 팀이 그 저장소 전반에서 협업하는 방식입니다.
멀티 레포 접근법은 처음에는 매력적으로 보일 수 있습니다. 구현이 아주 쉬워 보이기 때문입니다. 필요할 때마다 저장소를 더 만들기만 하면 됩니다! 처음에는 특별한 도구가 필요해 보이지도 않고, 개별 팀이 자신들의 코드를 관리하는 방식에 더 큰 자율성을 부여할 수도 있습니다.
하지만 실제로는 멀티 레포 아키텍처가 깨지기 쉽고(brittle), 일관성이 없으며, 변화에 저항하는(change-resistant) 코드베이스로 이어지는 경우가 많습니다. 이는 다시 엔지니어링 조직 내부에서의 사일로화(siloing) 를 부추길 수 있습니다. 반대로, 그리고 어쩌면 직관과 달리, 모노레포 접근법은 장기적으로 더 나은 확장 해법이 되는 경우가 많습니다. 즉 더 유연하고, 더 협업적이며, 장기적인 스케일링에 유리한 해법입니다.
왜 그럴까요? 코드베이스 아키텍처에서 어려운 문제는, 의존성이 존재하는 상황에서 변화를 관리하는 일, 그리고 그 반대로 변화가 존재하는 상황에서 의존성을 관리하는 일 이라는 점을 생각해 봅시다. 그런데 멀티 레포 아키텍처에서는 저장소들이 다른 저장소의 코드를 게시(publish)되고 버전이 매겨진(versioned) 아티팩트 형태로 소비(consume)합니다. 이 방식은 변화 전파(change propagation)를 훨씬 어렵게 만듭니다.
구체적으로, 소비하고 있는 저장소 B에 우리가(저장소 A의 소유자) 원하는 변경이 필요해지면 어떤 일이 벌어질까요? 먼저 저장소 B의 게이트키퍼(gatekeeper) 를 찾아 변경을 받아들이고 새 버전으로 게시하도록 설득해야 합니다. 그리고 이상적인 세상이라면 누군가가 저장소 B의 다른 모든 소비자를 찾아 이 새 버전으로 업그레이드한 다음 다시 게시해야 합니다. 이제 우리는 그 최초 소비자들의 소비자들을 찾아, 이 새 버전에 맞춰 그들 또한 업그레이드하고 재게시해야 합니다. 그리고 이런 과정이 재귀적으로, 끝도 없이(ad nauseam) 반복됩니다.
태그: