원문 캡처 · github.blog
원문 캡처 · github.blog

GitHub는 여러 지역에 복제된 저장소의 쓰기 병목을 줄이기 위해 합의(quorum) 처리 범위를 저장소 전체에서 개별 참조(reference)로 바꾸고 있다. GitHub의 내부 테스트에서는 서로 다른 참조에 쓰는 작업의 처리량이 3~4배 높아졌으며, 이 변경으로 가장 바쁜 저장소도 Azure로 이전할 수 있다고 밝혔다.

GitHub에 따르면 Git 트래픽이 빠르게 늘면서 저장소의 99.99999%는 자사 데이터센터와 Azure 양쪽에 복제돼 있다. 나머지 저장소는 플랫폼에서 가장 바쁜 저장소들이다. 현재 구조에서는 합의가 쓰기 작업을 저장소 단위로 직렬화하고, 정상 상태인 복제본 모두의 응답을 기다린다. Azure 복제본은 데이터센터에서 약 1,000마일 떨어져 있어 왕복에 약 25ms가 걸리며, 쓰기마다 여러 차례 왕복이 필요하다. 저장소 전체에 잠금을 걸기 때문에 가장 느린 복제본이 쓰기 지연과 처리량 한도를 좌우한다.

GitHub가 바꾸려는 핵심은 서로 다른 참조에 대한 쓰기를 동시에 처리하는 것이다. Git의 일관성 요구는 참조별로 적용되므로, 같은 참조를 갱신하는 작업끼리는 순서를 지키되 서로 다른 참조에 쓰는 작업은 기다리지 않게 한다. GitHub는 현실적인 트래픽을 반영한 내부 테스트에서 서로 다른 참조에 대한 쓰기가 더 낮은 지연으로 3~4배 높은 처리량을 보였다고 설명했다.

현재 대부분의 저장소는 복제본 5개 가운데 2개를 Azure에 두고 있으며, Azure가 전체 Git 트래픽의 약 절반을 처리한다. GitHub는 저장소 데이터를 Azure Blob Storage에 내구성 있게 저장한 뒤 읽기와 쓰기를 분리하는 작업도 진행 중이다. 합의에 참여하는 가상 쓰기 복제본은 쓰기를 객체 저장소에 기록하고 읽기는 제공하지 않는다. 이 복제본이 있으면 합의에 참여하지 않는 가상 읽기 복제본을 필요에 따라 늘릴 수 있다. GitHub의 분산 부하 테스트에서는 기존 구조가 먼저 한계에 도달했지만, 가상 읽기 복제본을 대상으로 했을 때는 테스트 도구가 먼저 한계에 도달했다고 밝혔다.

가상 읽기 복제본은 현재 객체 저장소와 백그라운드에서 상태를 맞추므로 모든 읽기 작업에 적합하지 않다. GitHub는 모든 종류의 읽기를 지원하려면 복제본이 뒤처진 동안 바뀐 참조와 데이터만 가져오는 방식이 필요하다고 설명했다. 쓰기 처리량도 합의 구조가 여전히 한계로 남아 있으며, GitHub는 다음 단계에서 쓰기 순서를 더 빠르게 정하고 내구성 있는 참조 상태와 압축·가비지 컬렉션의 확장 문제를 다룰 계획이다.

이번 변경과 저장소 이전의 배경은 GitHub의 앞선 글에서 확인할 수 있다.