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 devops secure -

GitLab Secret Detection ADR 003: 하위 프로세스 내에서 스캔 실행

컨텍스트

스파이크 중에 Pre-receive Secret Detection을 위한 정규식을 평가하는 과정에서 Ruby의 RE2 라이브러리를 사용하는 것이 가장 우수한 것으로 나타났습니다. Ruby는 수용 가능한 정규식 성능을 가지고 있지만, 언어의 제한 사항으로 인해 메모리 소비가 더 많고 멀티 스레딩과 Ractors(3.1+)를 지원하더라도 병렬성이 부족합니다. 이들은 I/O 바운드 작업을 병렬로 처리하는 데 적합하지만 CPU 바운드 작업에는 적합하지 않습니다.

메모리 소비를 주요 경로에서 실행하는 Pre-receive Secret Detection 기능의 하나의 고민 사항은 특히 스캔에 관여하는 정규식 작업으로 인한 메모리 소비입니다. 커밋 블롭의 각 줄에서 실행되는 300여 가지 이상의 정규식 기반 규칙 패턴으로 스캔하는 경우, 메모리는 커밋 블롭의 크기의 약 2-3배로 증가할 수 있습니다1. 스캔 작업이 완료되더라도 차지한 메모리는 가비지 컬렉터가 트리거될 때까지 해제되지 않습니다. 결과적으로 서버는 메모리 부족 상태가 될 수 있습니다.

원래의 토론 이슈에서 이러한 고민 사항과 더 많은 배경을 다룹니다.

접근 방법

스캔이 메모리를 해제하는 데는 루비가 GC를 트리거할 때까지 기다리는 대신 별도 프로세스에서 스캔을 실행함으로써 메모리 소비 문제를 어느 정도 해결할 수 있습니다.

기술적 해결책

프로세스 수명주기를 관리하는 동안 고려해야 할 몇 가지 시나리오가 있습니다. 이를 제대로 처리하지 않으면 제어할 수 없는 고아 프로세스가 발생하여 메모리를 절약하는 전체 목적을 무효화시킬 수 있습니다. 이 부담을 부모 및 자식 프로세스 간 통신, 종료 신호 처리, 프로세스 수 제한 설정 등을 제공하는 루비 라이브러리인 Parallel에 맡깁니다. 이는 우리의 필요를 충족하는 데 적합한 솔루션으로, 여러 프로세스를 통해 작업을 실행할 수 있는 간단한 인터페이스를 제공하고 있습니다. 또한 병렬성을 지원하여 본 문서에서 다루지 않은 다른 문제를 해결합니다.

하위 프로세스 내의 작업 범위

새로운 프로세스를 생성함으로써 추가적인 지연 오버헤드가 발생하므로 하위 프로세스 내에서 어떤 작업을 실행할 지를 결정하는 것이 중요합니다. 예를 들어, 각 블롭에서 스캔을 별도 프로세스에서 실행하는 것은 메인 프로세스에서 실행하는 것보다 약 2.5배 느립니다. 반면, 각 커밋 요청에 대해 하나의 하위 프로세스를 할당하는 것은 모든 블롭의 스캔이 단일 프로세스 내에서 실행되기 때문에 모든 스캔이 완료될 때까지 빠르게 메모리를 해제할 수 없어 문제점으로 돌아갈 수 있습니다.

버킷 방식: 이 두 가지 극단 사이의 절충안은 누적 크기가 고정된 청크 크기(우리의 경우에는 2MiB)에 적어도 일치하는 모든 블롭을 그룹화한 다음 아래에 설명된 것처럼 각 그룹을 별도의 하위 프로세스 내에서 실행하는 것입니다.

버킷화된 하위 프로세스

첨언

  • 하위 프로세스 내에서 작업을 실행하는 것은 위에서 언급한 문제에 대한 마법의 해답이 아닙니다. 이 접근 방법도 너무 많은 요청이 동시에 발생하는 경우에 실패할 수 있습니다.

  • 프로세스 생성에는 항상 지연 오버헤드가 발생합니다. 작은 커밋의 경우에는 스캔 작업의 대기 시간이 주 프로세스에서 실행하는 것보다 느릴 수 있습니다.

  • 현재 요청 당 포크된 프로세스의 병렬성 요소 또는 수는 현재 5개의 프로세스로 제한되어 있으며, 이를 초과하는 경우 대기 중인 요청이 리소스 고갈을 피하기 위해 대기열에 남게 합니다.

^참조를 위해 임계값이 곧 여기에 추가될 예정입니다.