-
새로운 고급 검색 마이그레이션 생성
- 스크립트 사용
- 매뉴얼으로
- 건너뛴 마이그레이션
-
마이그레이션 도우미
Elastic::MigrationBackfillHelper
Elastic::MigrationUpdateMappingsHelper
Elastic::MigrationRemoveFieldsHelper
Elastic::MigrationObsolete
Elastic::MigrationCreateIndex
Search::Elastic::MigrationReindexBasedOnSchemaVersion
Search::Elastic::MigrationDeleteBasedOnSchemaVersion
Search::Elastic::MigrationDatabaseBackfillHelper
Elastic::MigrationHelper
Elastic::MigrationWorker
가 지원하는 마이그레이션 옵션
- 마이그레이션을 통한 다운 타임 회피
- 마이그레이션 유행 계산
- 고급 검색 마이그레이션의 최선의 실행 방법
- 주요 버전 업그레이드시 고급 검색 마이그레이션 삭제
고급 검색 마이그레이션 스타일 가이드
새로운 고급 검색 마이그레이션 생성
스크립트 사용
- GitLab 16.3에서 소개됨.
scripts/elastic-migration
을 실행하고 프롬프트에 따라 다음을 생성합니다:
- 마이그레이션을 정의하는 마이그레이션 파일:
ee/elastic/migrate/YYYYMMDDHHMMSS_migration_name.rb
- 마이그레이션을 테스트하는 스펙 파일:
ee/spec/elastic/migrate/YYYYMMDDHHMMSS_mi-gration_name_spec.rb
- 마이그레이션을 식별하는 사전 파일:
ee/elastic/docs/YYYYMMDDHHMMSS_migration_name.yml
매뉴얼으로
- GitLab 13.6에서 소개됨.
ee/elastic/migrate/
폴더에서 파일 이름 형식인 YYYYMMDDHHMMSS_migration_name.rb
을 만듭니다. 이 형식은 Rails 데이터베이스 마이그레이션과 동일합니다.
# frozen_string_literal: true
class MigrationName < Elastic::Migration
# 중요: Elastic 인덱스 매핑에 대한 모든 업데이트는 각각의 설정 파일에 복제해야 합니다:
# - `Elastic::Latest::Config`는 주요 인덱스에 대해
# - `Elastic::Latest::<Type>Config`는 독립형 인덱스에 대해
def migrate
end
# 마이그레이션이 완료되었는지 확인합니다
# 완료된 경우 true를 반환하고, 그렇지 않으면 false를 반환합니다
def completed?
end
end
적용된 마이그레이션은 gitlab-#{RAILS_ENV}-migrations
인덱스에 저장됩니다. 실행되지 않은 모든 마이그레이션은 Elastic::MigrationWorker
크론 워커에 의해 순차적으로 적용됩니다.
Elastic 인덱스 매핑을 업데이트하려면 해당 파일에 구성을 적용합니다:
- 주요 인덱스의 경우:
Elastic::Latest::Config
. - 독립형 인덱스의 경우:
Elastic::Latest::<Type>Config
.
마이그레이션은 재시도 제한과 실패 및 중단 표시(한국어 웹사이트에만 적용) 기능을 가질 수 있습니다. 마이그레이션 재시도를 지원하기 위해 필요한 모든 데이터 또는 인덱스 정리는 마이그레이션에서 처리해야 합니다.
건너뛴 마이그레이션
skip_if
프록 추가를 통해 마이그레이션을 건너뛸 수 있습니다. 이 프록는 true
또는 false
로 평가됩니다:
class MigrationName < Elastic::Migration
skip_if ->() { true|false }
조건이 false
인 경우에만 마이그레이션이 실행됩니다. 건너뛴 마이그레이션은 대기 중인 마이그레이션의 일부로 표시되지 않습니다.
건너뛴 마이그레이션을 더 이상 사용하지 않도록 표시할 수 있지만, 이러한 마이그레이션은 항상 건너뛰어야 하므로 skip_if
조건을 유지해야 합니다. 한 번 건너뛴 마이그레이션이 폐기되면 처음부터 인덱스를 다시 만드는 방법 이외에 변경을 적용할 방법이 없습니다.
건너뛴 마이그레이션의 문서 파일을 다음 속성과 함께 업데이트하세요:
skippable: true
skip_condition: '<description>'
마이그레이션 도우미
ee/app/workers/concerns/elastic/
에서 다음 마이그레이션 도우미를 사용할 수 있습니다:
Elastic::MigrationBackfillHelper
인덱스의 특정 필드를 다시 채웁니다. 대부분의 경우, 필드에 대한 매핑은 이미 추가되어 있어야 합니다.
field_name
메서드와 DOCUMENT_TYPE
상수를 사용하여 단일 필드를 다시 채우려면 필요합니다.
class MigrationName < Elastic::Migration
include Elastic::MigrationBackfillHelper
DOCUMENT_TYPE = Issue
private
def field_name
:schema_version
end
end
하나 이상의 필드가 널이라면, field_names
메서드와 DOCUMENT_TYPE
상수를 사용하여 여러 필드를 다시 채워야 합니다.
class MigrationName < Elastic::Migration
include Elastic::MigrationBackfillHelper
DOCUMENT_TYPE = Issue
private
def field_names
%w[schema_version visibility_level]
end
end
Elastic::MigrationUpdateMappingsHelper
지정된 매핑을 사용하여 인덱스의 매핑을 업데이트합니다.
new_mappings
메서드와 DOCUMENT_TYPE
상수가 필요합니다.
class MigrationName < Elastic::Migration
include Elastic::MigrationUpdateMappingsHelper
DOCUMENT_TYPE = Issue
private
def new_mappings
{
schema_version: {
type: 'short'
}
}
end
end
Elastic::MigrationRemoveFieldsHelper
인덱스에서 지정된 필드를 제거합니다.
index_name
, document_type
메서드가 필요합니다. 제거할 필드가 하나인 경우 field_to_remove
메서드를 추가하고, 그 외에는 배열로 구성된 fields_to_remove
를 추가해야 합니다.
batched!
를 사용하여 document_type
와 일치하는 문서가 Elasticsearch에 지정된 필드를 가지고 있는지 확인합니다. 문서가 존재하는 경우, update_by_query
를 수행하기 위해 Painless 스크립트를 사용합니다.
class MigrationName < Elastic::Migration
include Elastic::MigrationRemoveFieldsHelper
batched!
throttle_delay 1.minute
private
def index_name
User.__elasticsearch__.index_name
end
def document_type
'user'
end
def fields_to_remove
%w[two_factor_enabled has_projects]
end
end
기본 배치 크기는 10,000
입니다. 이 값을 재정의하려면 BATCH_SIZE
를 지정하세요:
class MigrationName < Elastic::Migration
include Elastic::MigrationRemoveFieldsHelper
batched!
BATCH_SIZE = 100
...
end
Elastic::MigrationObsolete
더 이상 필요하지 않은 마이그레이션을 폐기 처리합니다.
class MigrationName < Elastic::Migration
include Elastic::MigrationObsolete
end
건너뛴 마이그레이션을 폐기 처리할 때, skip_if
조건을 유지해야 합니다.
Elastic::MigrationCreateIndex
새로운 인덱스를 생성합니다.
다음이 필요합니다:
-
target_class
및document_type
메서드 - 해당 클래스에 대한 매핑 및 인덱스 설정은
ee/lib/elastic/latest/
및ee/lib/elastic/v12p1/
에서 수행해야 합니다.
class MigrationName < Elastic::Migration
include Elastic::MigrationCreateIndex
retry_on_failure
def document_type
:epic
end
def target_class
Epic
end
end
Search::Elastic::MigrationReindexBasedOnSchemaVersion
지정된 문서 유형을 저장하는 인덱스에 대한 모든 문서를 다시 색인하고 schema_version
을 업데이트합니다.
DOCUMENT_TYPE
및 NEW_SCHEMA_VERSION
상수가 필요합니다.
인덱스 매핑에는 YYMM
형식의 schema_version
정수 필드가 있어야 합니다.
class MigrationName < Elastic::Migration
include Search::Elastic::MigrationReindexBasedOnSchemaVersion
batched!
batch_size 9_000
throttle_delay 1.minute
DOCUMENT_TYPE = WorkItem
NEW_SCHEMA_VERSION = 23_08
UPDATE_BATCH_SIZE = 100
end
Search::Elastic::MigrationDeleteBasedOnSchemaVersion
지정된 문서 유형을 저장하는 인덱스에서 지정된 값보다 작은 schema_version
을 가진 모든 문서를 삭제합니다.
DOCUMENT_TYPE
상수와 schema_version
메서드가 필요합니다.
인덱스 매핑에는 YYMM
형식의 schema_version
정수 필드가 있어야 합니다.
class MigrationName < Elastic::Migration
include ::Search::Elastic::MigrationDeleteBasedOnSchemaVersion
DOCUMENT_TYPE = Issue
batch_size 10_000
batched!
throttle_delay 1.minute
retry_on_failure
def schema_version
23_12
end
end
Search::Elastic::MigrationDatabaseBackfillHelper
데이터베이스의 모든 문서를 elastic search 색인에 다시 색인하며 limited_indexing
설정을 준수합니다.
DOCUMENT_TYPE
상수 및 respect_limited_indexing?
메서드가 필요합니다.
class MigrationName < Elastic::Migration
include ::Search::Elastic::MigrationDatabaseBackfillHelper
batch_size 10_000
batched!
throttle_delay 1.minute
retry_on_failure
DOCUMENT_TYPE = Issue
def respect_limited_indexing?
true
end
end
Elastic::MigrationHelper
이전 예제와 맞지 않는 마이그레이션을 처리할 때 사용할 수 있는 메서드를 포함합니다.
class MigrationName < Elastic::Migration
include Elastic::MigrationHelper
def migrate
...
end
def completed?
...
end
end
Elastic::MigrationWorker
가 지원하는 마이그레이션 옵션
Elastic::MigrationWorker
가 지원하는 다음 마이그레이션 옵션을 지원합니다:
-
batched!
- 마이그레이션을 일괄로 실행할 수 있게 합니다. 설정한 경우Elastic::MigrationWorker
해당 옵션에 의해 설정된 지연 시간으로 자체를 다시 대기열에 넣습니다. 일괄 처리는migrate
메서드에서 처리해야 합니다. 이 설정은 다시 대기열에 넣기 만을 제어합니다. -
batch_size
-batched!
마이그레이션 실행 중 수정된 문서 수를 설정합니다. 이 크기는 업데이트를 충분히 완료할 수있는 값으로 설정해야 합니다. 이것은 아래서 설명하는throttle_delay
옵션과 함께 조정될 수 있습니다. 이 일괄 처리는 해당 설정을 사용하는 사용자 정의migrate
메서드에서 또는Elastic::MigrationBackfillHelper
이 설정을 사용하는migrate
메서드에서 처리합니다. 기본 값은 1000문서입니다. -
throttle_delay
- 일괄 실행 간의 대기 시간을 설정합니다. 각 마이그레이션 일괄 처리에 충분한 시간을 제공하기 위해 이 시간은 충분히 길어야합니다. 또한, 5분 미만이어야합니다.Elastic::MigrationWorker
cron worker가 실행되는 주기입니다. 기본 값은 3분입니다. -
pause_indexing!
- 마이그레이션이 실행되는 동안 색인을 중지합니다. 이 설정은 마이그레이션이 실행되기 전에 색인 설정을 기록하고, 마이그레이션이 완료되면 해당 값으로 다시 설정합니다. -
space_requirements!
- 마이그레이션이 실행될 때 클러스터에 충분한 여유 공간이 있는지 확인합니다. 저장 공간이 필요한 경우, 실행될 때 해당 마이그레이션이 중단됩니다. 마이그레이션이 필요한 공간을 바이트 단위로 정의하여space_required_bytes
메서드를 정의함으로써 이 설정을 제공해야합니다. -
retry_on_failure
- 실패 시 재시도 기능을 활성화합니다. 기본적으로 마이그레이션을 30번 재시도합니다. 재시도 횟수를 사용자 정의하려면max_attempts
인수를 전달하십시오:retry_on_failure max_attempts: 10
# frozen_string_literal: true
class BatchedMigrationName < Elastic::Migration
# 일괄로 실행될 마이그레이션임을 선언합니다
batched!
throttle_delay 10.minutes
pause_indexing!
space_requirements!
retry_on_failure
# ...
end
마이그레이션을 통한 다운 타임 회피
마이그레이션 되돌리기
GitLab.com에서 마이그레이션이 실패하거나 중단된 경우, 마이그레이션을 도입한 변경 사항을 되돌리는 것이 좋습니다. 이렇게 함으로써 Self-Managed형 고객이 손상된 마이그레이션을 받지 않게하고 되감기가 필요한 경우를 줄입니다.
Merge 시기
릴리스 후 1주일 내에 마이그레이션을 Merge하지 않는 것이 좋습니다. 이렇게 함으로써 마이그레이션이 실패하거나 예상대로 작동하지 않는 경우 되감기 시간을 확보할 수 있습니다. 최종 주에 아직 개발 중이거나 검토중인 마이그레이션은 다음 마일스톤으로 이동해야합니다.
다중 버전 호환성
고급 검색 마이그레이션은 다른 GitLab 변경 사항과 마찬가지로 응용 프로그램의 여러 버전이 동시에 실행될 경우를 지원해야합니다.
배포 순서에 따라 마이그레이션이 시작되거나 마쳤는데 그 때까지 응용 프로그램 코드를 실행중인 서버가 여전히 있을 수 있습니다. 이를 고려해야하며 모든 고급 검색 마이그레이션이 배포가 완료된 후에 시작함을 확실히가능할 때까지 이것을 고려해야합니다.
고위험 마이그레이션
Elasticsearch는 트랜잭션을 지원하지 않으므로 항상 응용 프로그램이되있는 상황을 수용할 수있게 마이그레이션을 설계해야합니다. 코드가 마이그레이션이 시작된 후 또는 완료된 후에 되감기된 경우에 이러한 이유 때문에 일반적으로 파괴적인 작업(예 : 데이터 이동 후 삭제)은 마이그레이션이 성공적으로 완료된 후에 다른 Merge Request으로 연기해야합니다. Self-Managed형 고객을위한 안전을 위해 중요한 데이터 손실이있을 수있는 경우 다른 릴리스로 연기해야합니다.
마이그레이션 유행 계산
GitLab.com에서 마이그레이션이 실행될 때 소요 시간을 이해하는 것이 중요합니다. 마이그레이션이 처리 할 문서 수를 유도하십시오. 이 숫자는 데이터베이스 쿼리 또는 기존 Elasticsearch 색인에서 얻을 수 있습니다. 다음 공식을 사용하여 실행 시간을 계산하십시오:
> batch_size = 9_000
=> 9000
> throttle_delay = 1.minute
=> 1 minute
> number_of_documents = 15_536_906
=> 15536906
> (number_of_documents / batch_size) * throttle_delay
=> 1726 minutes
> (number_of_documents / batch_size) * throttle_delay / 1.hour
=> 28
고급 검색 마이그레이션의 최선의 실행 방법
다음과 같은 최선의 실행 방법을 따르십시오:
- 각 문서 유형에 대한 모든 마이그레이션을 순서대로 정렬하여,
Elastic::MigrationUpdateMappingsHelper
를 사용하는 마이그레이션을 사용하기 전에Elastic::MigrationBackfillHelper
를 사용하는 마이그레이션을 실행합니다. 응용 프로그램별 마이그레이션이 미적용 상태인 경우 동일한 문서를 여러 번 재색인하는 것을 피하고 백필 시간을 줄일 수 있습니다. - 일괄 처리 작업할 때 일괄 처리 크기를 9,000 문서 미만으로 유지하십시오. 일괄 처리 프로그램은 1분마다 실행되며 10,000 개의 문서를 처리합니다. 따라서 일괄 처리 프로그램은 다른 마이그레이션 일괄 처리가 시도되기 전에 기록을 처리할 시간이 있습니다.
- 마이그레이션이 완료되는지 확인하기 전에 색인을 새로 고칠때문에 문서 수가 최신 상태인지 확인해야합니다.
- 각 마이그레이션에 마이그레이션이 시작될 때, 완료 확인이 발생할 때, 마이그레이션이 완료되었을 때의 로그를 추가하십시오. 마이그레이션 문제를 디버깅할 때 이러한 로그가 유용합니다.
- Elasticsearch Reindex API 작업을 사용하는 경우 모든 색인을 일시 중지하십시오.
- 마이그레이션이 실패할 수있는 경우 재시도 제한을 추가하십시오. 문제가 발생하는 경우 마이그레이션을 중단시키도록하여 마이그레이션이 잘못되지 않도록하십시오.
주요 버전 업그레이드시 고급 검색 마이그레이션 삭제
일반적으로 고급 검색 마이그레이션은 장기간 동안 여러 코드 경로를 지원해야하므로 이러한 마이그레이션을 안전하게 제거할 수 있는 시기를 선택하는 것이 중요합니다.
GitLab 주요 버전 업그레이드를 안전한 시기로 선택하여 완전히 마이그레이션되지 않은 색인에 대한 역방향 호환성을 제거합니다. 이러한 작업을 시기함은 업그레이드 문서에 문서화되어 있습니다. 우리는 또한 마이그레이션 코드를 중단된 마이그레이션으로 교체하고 이러한 코드를 지원하지 않는 마이그레이션에 대한 테스트를 제거하여 다음과 같이 선택하는 것이 좋습니다. - 고급 검색 마이그레이션을 유지 관리 할 필요가 없습니다. - 더 이상 지원하지 않는 마이그레이션을 위한 테스트를 실행하지 않아도됩니다. - 해당 마이그레이션이 마저된 migration이 없는 경우 직접 버전에 업그레이드하는 사용자는 처음부터 재색인을 해야한다는 메시지가 표시됩니다.
더 안전하게 하기 위해, 주요 업그레이드 이전 마지막 부속 버전을 추가합니다. 따라서 %13.12
에서만 추가된 마이그레이션이 아닌 마이그레이션은 삭제하지 않습니다. 이렇게 하면 GitLab.com에 추가된 마이그레이션이 여러 주가 걸릴 수 있기 때문에
%14.0
으로 업그레이드하기 전에 %13.12
에서 마이그레이션이 완료되지 않습니다. 이러한 추가적인 안전망은 GitLab.com 배포가 자동화되어 있으며이를 방지하기 위한 자동화 된 확인이없기 때문에 정말 안전합니다. 추가로, 자동화 된 확인이 있더라도 고급 검색 마이그레이션을 위해 GitLab.com 배포를 차단하는 것이 합리적이지 않으며, 또 다른 주가 걸릴 것이기 때문에 유지하고 싶지 않습니다.
마이그레이션을 오래된 것으로 표시하는 프로세스
대상 버전을 업그레이드하기 2개의 이전 마이너 버전에서 생성된 각 마이그레이션에 대해, 우리는 다음을 수행합니다:
- GitLab.com에서 마이그레이션이 실제로 성공적으로 완료되었는지 확인합니다.
-
마이그레이션의 내용을 다음과 같이 대체합니다:
include Elastic::MigrationObsolete
- 사용 가능한 마이그레이션을 오래된 것으로 표시할 때,
skip_if
조건을 유지합니다. - 이 마이그레이션을 지원하는 모든 특정 파일을 삭제합니다.
-
.rubocop_todo/
디렉터리에서 해당 마이그레이션에 대한 참조가 없는지 확인합니다. - 이 마이그레이션의 역 호환성을 처리하는 모든 로직을 제거합니다. 이를 찾으려면
Elastic::DataMigrationService.migration_has_finished?(:migration_name_in_lowercase)
를 찾으면 됩니다. - 이러한 변경 사항이 있는 Merge Request을 만듭니다. 주의해야 할 점은 주요 릴리스가 시작되기 전에 실수로 이를 Merge하지 않아야 합니다.
마이그레이션을 제거하는 프로세스
- 현재 주요 릴리스 이전에 오래된 것으로 표시된 마이그레이션을 선택합니다.
- 위 단계가 모든 오래된 마이그레이션을 포함하는 경우, 적용되지 않은 마이그레이션이 있는 고객을 위해 마지막으로 하나의 마이그레이션을 보호장치로 유지합니다.
- 해당 마이그레이션 파일 및 특정 파일을 삭제합니다.
-
.rubocop_todo/
디렉터리에서 해당 마이그레이션에 대한 참조가 없는지 확인합니다. - Merge Request을 만들고 해당 요청을 글로벌 검색팀의 팀원에게 할당합니다.