InfoGrab DocsInfoGrab Docs

임포터 설계 원칙

보안#

  • 업로드된 파일은 검증해야 합니다. 예시는 다음과 같습니다.
  • 임포터는 HTTP 호출을 수행하는 서드파티 Ruby gem을 추가해서는 안 됩니다. 임포터는 통합과 동일한 Ruby gem 정책을 따릅니다. 임포터의 Ruby gem 사용에 관한 자세한 내용은 해당 페이지를 참고합니다.
  • 모든 HTTP 호출은 Import::Clients::HTTP를 사용해야 하며, 이 클라이언트는 다음과 같은 특징이 있습니다.
    • HTTP 호출에 네트워크 설정이 적용되도록 보장합니다.
    • 추가적인 보안 강화 기능을 제공합니다.
    • 안전한 HTTP 호출에 대한 단일 진실 공급원(Single Source Of Truth, SSOT)입니다.
    • 모든 응답 크기가 검증되도록 보장합니다.

로깅#

  • 로그에는 github, bitbucket, bitbucket_server와 같은 임포터 유형이 포함돼야 합니다. 가져오기 소스 전체 목록은 Gitlab::ImportSources에서 확인할 수 있습니다.
  • 로그에는 디버깅에 도움이 될 만한 정보를 포함해야 합니다.
    • id, iid와 같은 객체 식별자 및 객체 유형
    • 오류 또는 상태 메시지
  • 로그에는 다음을 포함해 민감 정보나 개인 정보를 담아서는 안 됩니다.
    • 사용자 이름
    • 이메일 주소
  • 해당하는 경우 UI에 오류를 표시할 수 있도록 Gitlab::Import::ImportFailureService에서 오류를 추적해야 합니다.
  • 이 MR에서 보여 주듯이, 핵심 식별자가 누락되면 개발 환경에서 로깅이 오류를 발생시켜야 합니다.
  • 각 레코드를 가져오기 전후로 해당 레코드의 식별자를 담은 로그 한 줄을 남겨야 합니다.

성능#

  • 중복된 데이터베이스 쿼리와 API 호출을 방지하기 위해 기본 TTL 24시간의 캐시를 사용해야 합니다.
  • 컬렉션을 순회하는 워커에는 중단되더라도 멈춘 지점부터 다시 시작할 수 있도록 진행 상황 포인터를 갖춰야 합니다.
  • 쓰기 부하가 큰 워커는 데이터베이스 포화를 막기 위해 defer_on_database_health_signal을 구현해야 합니다. 다만 작성 시점 기준으로 알려진 문제 때문에 이를 사용할 수 없습니다.
  • 리소스 포화를 막기 위해 워커 동시성에 제한을 적용해야 합니다. 예시는 Bitbucket의 ParallelScheduling 클래스에서 확인할 수 있습니다.
  • 임포터는 특히 새 기능을 구현하거나 기능 플래그를 활성화할 때 스테이징 환경에서 대규모로 테스트해야 합니다.

복원력#

  • 워커는 멱등성을 갖춰야 실패 시 안전하게 재시도할 수 있습니다.
  • 워커는 동시 배치 제한을 존중하는 지연 시간을 두고 다시 큐에 넣어야 합니다.
  • 개별 워커가 오래 실행돼서는 안 됩니다. 오래 실행되는 워커는 배포로 인해 Sidekiq에 의해 중단되거나, StuckProjectImportJobsWorker가 멈춘 가져오기의 일부로 잘못 판단해 실패 처리할 수 있습니다.
    • 워커가 오래 실행돼야 한다면 StuckProjectImportJobsWorker에 의해 종료되지 않도록 Gitlab::Import::RefreshImportJidWorker로 JID를 갱신해야 합니다. Sidekiq의 max_retries_after_interruption 값을 높여야 할 수도 있습니다. GitHub 임포터 구현을 참고합니다.
  • 캐시된 값에 의존하는 워커는 캐시 미스가 발생했을 때 데이터를 가져올 대체 수단을 구현해야 합니다.
    • 가능하고 성능에 무리가 없다면 데이터를 다시 가져옵니다.
    • 누락된 값을 무리 없이 처리합니다.
  • 오래 실행되는 워커에는 worker_resource_boundary :memory를 표시해 종료 유예 시간이 2시간인 샤드에 배치해야 합니다. 긴 종료 유예 시간이 빠른 워커 작성을 대신하지는 못합니다. Apdex SLO 준수 여부는 I&I 팀 Grafana 대시보드에서 모니터링할 수 있습니다.
  • 데이터를 생성하는 워커는 레코드 하나를 가져오지 못했다고 해서 가져오기 전체를 실패시켜서는 안 됩니다. 적절한 오류를 기록하고, 오류의 성격에 따라 재시도 여부를 판단해야 합니다.
  • 가져오기 Stage 워커(StageMethods를 포함)와 Advance Stage 워커(Gitlab::Import::AdvanceStage를 포함)는 시스템 중단에 더 잘 견디도록 retries: 6을 설정해야 합니다. 지수 백오프를 적용하면 재시도 6회는 약 20분에 해당합니다. 그보다 재시도 횟수가 많으면 가져오기가 지나치게 지연됩니다.
  • 가져오기의 일부만 재시도할 수 있어야 합니다. 예를 들어 대상 프로젝트 전체를 덮어쓰지 않고 누락된 이슈만 다시 가져올 수 있어야 합니다.

일관성#

  • 임포터는 레코드를 저장한 뒤 콜백을 실행해야 합니다. 문제가 되는 콜백은 가져오기 단위로 개별 비활성화할 수 있습니다.
    • Importable 모듈을 포함합니다.
    • importing? 인 경우 콜백을 건너뛰도록 설정합니다.
    • 가져오는 객체에 importing 값을 설정합니다.
  • 레코드를 일괄 삽입해야 한다면 콜백을 수동으로 실행하는 방안을 검토합니다.

임포터 설계 원칙

GitLab v19.4
원문 보기

보안#

  • 업로드된 파일은 검증해야 합니다. 예시는 다음과 같습니다.
  • 임포터는 HTTP 호출을 수행하는 서드파티 Ruby gem을 추가해서는 안 됩니다. 임포터는 통합과 동일한 Ruby gem 정책을 따릅니다. 임포터의 Ruby gem 사용에 관한 자세한 내용은 해당 페이지를 참고합니다.
  • 모든 HTTP 호출은 Import::Clients::HTTP를 사용해야 하며, 이 클라이언트는 다음과 같은 특징이 있습니다.
    • HTTP 호출에 네트워크 설정이 적용되도록 보장합니다.
    • 추가적인 보안 강화 기능을 제공합니다.
    • 안전한 HTTP 호출에 대한 단일 진실 공급원(Single Source Of Truth, SSOT)입니다.
    • 모든 응답 크기가 검증되도록 보장합니다.

로깅#

  • 로그에는 github, bitbucket, bitbucket_server와 같은 임포터 유형이 포함돼야 합니다. 가져오기 소스 전체 목록은 Gitlab::ImportSources에서 확인할 수 있습니다.
  • 로그에는 디버깅에 도움이 될 만한 정보를 포함해야 합니다.
    • id, iid와 같은 객체 식별자 및 객체 유형
    • 오류 또는 상태 메시지
  • 로그에는 다음을 포함해 민감 정보나 개인 정보를 담아서는 안 됩니다.
    • 사용자 이름
    • 이메일 주소
  • 해당하는 경우 UI에 오류를 표시할 수 있도록 Gitlab::Import::ImportFailureService에서 오류를 추적해야 합니다.
  • 이 MR에서 보여 주듯이, 핵심 식별자가 누락되면 개발 환경에서 로깅이 오류를 발생시켜야 합니다.
  • 각 레코드를 가져오기 전후로 해당 레코드의 식별자를 담은 로그 한 줄을 남겨야 합니다.

성능#

  • 중복된 데이터베이스 쿼리와 API 호출을 방지하기 위해 기본 TTL 24시간의 캐시를 사용해야 합니다.
  • 컬렉션을 순회하는 워커에는 중단되더라도 멈춘 지점부터 다시 시작할 수 있도록 진행 상황 포인터를 갖춰야 합니다.
  • 쓰기 부하가 큰 워커는 데이터베이스 포화를 막기 위해 defer_on_database_health_signal을 구현해야 합니다. 다만 작성 시점 기준으로 알려진 문제 때문에 이를 사용할 수 없습니다.
  • 리소스 포화를 막기 위해 워커 동시성에 제한을 적용해야 합니다. 예시는 Bitbucket의 ParallelScheduling 클래스에서 확인할 수 있습니다.
  • 임포터는 특히 새 기능을 구현하거나 기능 플래그를 활성화할 때 스테이징 환경에서 대규모로 테스트해야 합니다.

복원력#

  • 워커는 멱등성을 갖춰야 실패 시 안전하게 재시도할 수 있습니다.
  • 워커는 동시 배치 제한을 존중하는 지연 시간을 두고 다시 큐에 넣어야 합니다.
  • 개별 워커가 오래 실행돼서는 안 됩니다. 오래 실행되는 워커는 배포로 인해 Sidekiq에 의해 중단되거나, StuckProjectImportJobsWorker가 멈춘 가져오기의 일부로 잘못 판단해 실패 처리할 수 있습니다.
    • 워커가 오래 실행돼야 한다면 StuckProjectImportJobsWorker에 의해 종료되지 않도록 Gitlab::Import::RefreshImportJidWorker로 JID를 갱신해야 합니다. Sidekiq의 max_retries_after_interruption 값을 높여야 할 수도 있습니다. GitHub 임포터 구현을 참고합니다.
  • 캐시된 값에 의존하는 워커는 캐시 미스가 발생했을 때 데이터를 가져올 대체 수단을 구현해야 합니다.
    • 가능하고 성능에 무리가 없다면 데이터를 다시 가져옵니다.
    • 누락된 값을 무리 없이 처리합니다.
  • 오래 실행되는 워커에는 worker_resource_boundary :memory를 표시해 종료 유예 시간이 2시간인 샤드에 배치해야 합니다. 긴 종료 유예 시간이 빠른 워커 작성을 대신하지는 못합니다. Apdex SLO 준수 여부는 I&I 팀 Grafana 대시보드에서 모니터링할 수 있습니다.
  • 데이터를 생성하는 워커는 레코드 하나를 가져오지 못했다고 해서 가져오기 전체를 실패시켜서는 안 됩니다. 적절한 오류를 기록하고, 오류의 성격에 따라 재시도 여부를 판단해야 합니다.
  • 가져오기 Stage 워커(StageMethods를 포함)와 Advance Stage 워커(Gitlab::Import::AdvanceStage를 포함)는 시스템 중단에 더 잘 견디도록 retries: 6을 설정해야 합니다. 지수 백오프를 적용하면 재시도 6회는 약 20분에 해당합니다. 그보다 재시도 횟수가 많으면 가져오기가 지나치게 지연됩니다.
  • 가져오기의 일부만 재시도할 수 있어야 합니다. 예를 들어 대상 프로젝트 전체를 덮어쓰지 않고 누락된 이슈만 다시 가져올 수 있어야 합니다.

일관성#

  • 임포터는 레코드를 저장한 뒤 콜백을 실행해야 합니다. 문제가 되는 콜백은 가져오기 단위로 개별 비활성화할 수 있습니다.
    • Importable 모듈을 포함합니다.
    • importing? 인 경우 콜백을 건너뛰도록 설정합니다.
    • 가져오는 객체에 importing 값을 설정합니다.
  • 레코드를 일괄 삽입해야 한다면 콜백을 수동으로 실행하는 방안을 검토합니다.