InfoGrab DocsInfoGrab Docs

임포터 설계 원칙

요약

BulkImports::FileDownloadService ImportExport::CommandLineUtil 임포터는 HTTP 호출을 수행하는 서드파티 Ruby gem을 추가해서는 안 됩니다. 모든 HTTP 호출은 반드시 Import::Clients::HTTP를 사용해야 합니다.

보안#

  • 업로드된 파일은 반드시 유효성을 검사해야 합니다. 예시:

BulkImports::FileDownloadService

  • ImportExport::CommandLineUtil

  • 임포터는 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에서 오류를 추적해야 합니다.

  • 개발 환경에서 주요 식별자가 누락된 경우 로깅이 오류를 발생시켜야 합니다. 이는 이 머지 리퀘스트에서 시연되어 있습니다.

  • 각 레코드를 임포트하기 전후에 해당 레코드의 식별자를 포함한 로그 라인을 생성해야 합니다.

성능#

  • 중복 데이터베이스 쿼리 및 API 호출을 방지하기 위해 기본 TTL이 24시간인 캐시를 사용해야 합니다.

  • 컬렉션을 순회하는 Worker는 중단된 경우 중단된 지점부터 다시 시작할 수 있는 진행 포인터를 갖추어야 합니다.

ID 추적을 사용한 예시

  • 페이지 카운터를 사용한 예시

  • 쓰기 작업이 많은 Worker는 데이터베이스 과부하를 방지하기 위해 defer_on_database_health_signal을 구현해야 합니다. 다만, 작성 시점 기준으로 알려진 이슈로 인해 현재 이를 사용할 수 없습니다.

  • 리소스 포화를 방지하기 위해 Worker 동시성에 제한을 적용해야 합니다. Bitbucket의 ParallelScheduling 클래스에서 예시를 확인할 수 있습니다.

  • 임포터는 특히 새로운 기능을 구현하거나 기능 플래그를 활성화할 때 스테이징 환경에서 대규모로 테스트해야 합니다.

복원력#

  • Worker는 실패 시 안전하게 재시도할 수 있도록 멱등성을 가져야 합니다.

  • Worker는 동시 배치 제한을 준수하는 지연을 두고 재큐(re-enqueue)되어야 합니다.

  • 개별 Worker는 오랫동안 실행되어서는 안 됩니다. 오랫동안 실행되는 Worker는 배포로 인해 Sidekiq에 의해 중단되거나, StuckProjectImportJobsWorker에 의해 중단된 임포트의 일부로 잘못 식별되어 실패 처리될 수 있습니다.

Worker가 오랫동안 실행되어야 하는 경우, StuckProjectImportJobsWorker에 의해 종료되는 것을 방지하기 위해 Gitlab::Import::RefreshImportJidWorker를 사용하여 JID를 갱신해야 합니다. 또한 Sidekiq의 max_retries_after_interruption을 높여야 할 수도 있습니다. GitHub 임포터 구현을 참고하세요.

  • 캐시된 값에 의존하는 Worker는 캐시 미스(cache miss) 발생 시 데이터를 가져오기 위한 폴백(fall-back) 메커니즘을 구현해야 합니다.

가능하고 성능상 허용되는 경우 데이터를 다시 가져옵니다.

  • 누락된 값을 정상적으로 처리합니다.

  • 오래 실행되는 Worker는 두 시간의 종료 유예 기간을 가진 샤드에 배치되도록 worker_resource_boundary :memory로 주석을 달아야 합니다. 긴 종료 유예 기간은 빠른 Worker 작성을 대체하는 것이 아닙니다. Apdex SLO 준수는 I&I 팀 Grafana 대시보드에서 모니터링할 수 있습니다.

  • 데이터를 생성하는 Worker는 단일 레코드 임포트가 실패하더라도 전체 임포트를 실패 처리해서는 안 됩니다. 적절한 오류를 로깅하고 오류의 특성에 따라 재시도 여부를 결정해야 합니다.

  • Import Stage Worker(StageMethods 포함)와 Advance Stage Worker(Gitlab::Import::AdvanceStage 포함)는 시스템 중단에 대한 복원력을 높이기 위해 retries: 6을 설정해야 합니다. 지수 백오프(exponential back-off)를 적용하면 6번의 재시도는 약 20분에 걸쳐 이루어집니다. 그 이상의 재시도 횟수는 임포트를 너무 오래 지연시킵니다.

  • 임포트의 일부를 재시도할 수 있어야 합니다. 예를 들어, 전체 대상 프로젝트를 덮어쓰지 않고 누락된 이슈만 재임포트할 수 있어야 합니다.

일관성#

  • 임포터는 레코드 저장 후 콜백을 실행해야 합니다. 문제가 있는 콜백은 임포트별로 개별적으로 비활성화할 수 있습니다:

Importable 모듈을 포함합니다.

  • importing?인 경우 콜백을 건너뛰도록 구성합니다.

  • 임포트 중인 객체에 importing 값을 설정합니다.

  • 레코드를 일괄 삽입해야 하는 경우 콜백을 수동으로 실행하는 것을 고려합니다.

임포터 설계 원칙

GitLab v19.1
원문 보기
요약

BulkImports::FileDownloadService ImportExport::CommandLineUtil 임포터는 HTTP 호출을 수행하는 서드파티 Ruby gem을 추가해서는 안 됩니다. 모든 HTTP 호출은 반드시 Import::Clients::HTTP를 사용해야 합니다.

보안#

  • 업로드된 파일은 반드시 유효성을 검사해야 합니다. 예시:

BulkImports::FileDownloadService

  • ImportExport::CommandLineUtil

  • 임포터는 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에서 오류를 추적해야 합니다.

  • 개발 환경에서 주요 식별자가 누락된 경우 로깅이 오류를 발생시켜야 합니다. 이는 이 머지 리퀘스트에서 시연되어 있습니다.

  • 각 레코드를 임포트하기 전후에 해당 레코드의 식별자를 포함한 로그 라인을 생성해야 합니다.

성능#

  • 중복 데이터베이스 쿼리 및 API 호출을 방지하기 위해 기본 TTL이 24시간인 캐시를 사용해야 합니다.

  • 컬렉션을 순회하는 Worker는 중단된 경우 중단된 지점부터 다시 시작할 수 있는 진행 포인터를 갖추어야 합니다.

ID 추적을 사용한 예시

  • 페이지 카운터를 사용한 예시

  • 쓰기 작업이 많은 Worker는 데이터베이스 과부하를 방지하기 위해 defer_on_database_health_signal을 구현해야 합니다. 다만, 작성 시점 기준으로 알려진 이슈로 인해 현재 이를 사용할 수 없습니다.

  • 리소스 포화를 방지하기 위해 Worker 동시성에 제한을 적용해야 합니다. Bitbucket의 ParallelScheduling 클래스에서 예시를 확인할 수 있습니다.

  • 임포터는 특히 새로운 기능을 구현하거나 기능 플래그를 활성화할 때 스테이징 환경에서 대규모로 테스트해야 합니다.

복원력#

  • Worker는 실패 시 안전하게 재시도할 수 있도록 멱등성을 가져야 합니다.

  • Worker는 동시 배치 제한을 준수하는 지연을 두고 재큐(re-enqueue)되어야 합니다.

  • 개별 Worker는 오랫동안 실행되어서는 안 됩니다. 오랫동안 실행되는 Worker는 배포로 인해 Sidekiq에 의해 중단되거나, StuckProjectImportJobsWorker에 의해 중단된 임포트의 일부로 잘못 식별되어 실패 처리될 수 있습니다.

Worker가 오랫동안 실행되어야 하는 경우, StuckProjectImportJobsWorker에 의해 종료되는 것을 방지하기 위해 Gitlab::Import::RefreshImportJidWorker를 사용하여 JID를 갱신해야 합니다. 또한 Sidekiq의 max_retries_after_interruption을 높여야 할 수도 있습니다. GitHub 임포터 구현을 참고하세요.

  • 캐시된 값에 의존하는 Worker는 캐시 미스(cache miss) 발생 시 데이터를 가져오기 위한 폴백(fall-back) 메커니즘을 구현해야 합니다.

가능하고 성능상 허용되는 경우 데이터를 다시 가져옵니다.

  • 누락된 값을 정상적으로 처리합니다.

  • 오래 실행되는 Worker는 두 시간의 종료 유예 기간을 가진 샤드에 배치되도록 worker_resource_boundary :memory로 주석을 달아야 합니다. 긴 종료 유예 기간은 빠른 Worker 작성을 대체하는 것이 아닙니다. Apdex SLO 준수는 I&I 팀 Grafana 대시보드에서 모니터링할 수 있습니다.

  • 데이터를 생성하는 Worker는 단일 레코드 임포트가 실패하더라도 전체 임포트를 실패 처리해서는 안 됩니다. 적절한 오류를 로깅하고 오류의 특성에 따라 재시도 여부를 결정해야 합니다.

  • Import Stage Worker(StageMethods 포함)와 Advance Stage Worker(Gitlab::Import::AdvanceStage 포함)는 시스템 중단에 대한 복원력을 높이기 위해 retries: 6을 설정해야 합니다. 지수 백오프(exponential back-off)를 적용하면 6번의 재시도는 약 20분에 걸쳐 이루어집니다. 그 이상의 재시도 횟수는 임포트를 너무 오래 지연시킵니다.

  • 임포트의 일부를 재시도할 수 있어야 합니다. 예를 들어, 전체 대상 프로젝트를 덮어쓰지 않고 누락된 이슈만 재임포트할 수 있어야 합니다.

일관성#

  • 임포터는 레코드 저장 후 콜백을 실행해야 합니다. 문제가 있는 콜백은 임포트별로 개별적으로 비활성화할 수 있습니다:

Importable 모듈을 포함합니다.

  • importing?인 경우 콜백을 건너뛰도록 구성합니다.

  • 임포트 중인 객체에 importing 값을 설정합니다.

  • 레코드를 일괄 삽입해야 하는 경우 콜백을 수동으로 실행하는 것을 고려합니다.