InfoGrab DocsInfoGrab Docs

Elasticsearch 고급 검색

요약

이 페이지에서는 고급 검색을 활성화하는 방법을 설명합니다. 고급 검색을 활성화하려면 다음 작업이 필요합니다. 고급 검색은 모든 프로젝트를 동일한 Elasticsearch 인덱스에 저장합니다. 이 용어집에서는 Elasticsearch와 관련된 용어를 정의합니다.

이 페이지에서는 고급 검색을 활성화하는 방법을 설명합니다. 활성화하면 고급 검색은 더 빠른 검색 응답 시간과 향상된 검색 기능을 제공합니다.

고급 검색을 활성화하려면 다음 작업이 필요합니다.

  1. Elasticsearch 또는 AWS OpenSearch 클러스터를 설치합니다.
  2. 고급 검색을 활성화합니다.
Note

고급 검색은 모든 프로젝트를 동일한 Elasticsearch 인덱스에 저장합니다. 다만 비공개 프로젝트는 접근 권한이 있는 사용자에게만 검색 결과에 표시됩니다.

Elasticsearch 용어집#

이 용어집에서는 Elasticsearch와 관련된 용어를 정의합니다.

  • Lucene: Java로 작성된 전문 검색 라이브러리입니다.
  • 니어 리얼 타임(NRT): 문서를 인덱싱한 시점부터 해당 문서를 검색할 수 있게 되는 시점까지의 짧은 지연을 의미합니다.
  • 클러스터: 모든 데이터를 보관하면서 인덱싱 및 검색 기능을 제공하기 위해 함께 동작하는 하나 이상의 노드 집합입니다.
  • 노드: 클러스터의 일부로 동작하는 단일 서버입니다.
  • 인덱스: 어느 정도 유사한 특성을 가진 문서의 집합입니다.
  • 문서: 인덱싱할 수 있는 정보의 기본 단위입니다.
  • 샤드: 인덱스를 나눈 독립적인 하위 단위로, 그 자체로 완전한 기능을 갖춥니다. 각 샤드는 실제로 하나의 Lucene 인덱스입니다.
  • 레플리카: 인덱스를 복제하는 장애 조치 메커니즘입니다.

Elasticsearch 또는 AWS OpenSearch 클러스터 설치#

Elasticsearch와 AWS OpenSearch는 Linux 패키지에 포함되어 있지 않습니다. 검색 클러스터를 직접 설치하거나 다음과 같은 클라우드 호스팅 서비스를 사용할 수 있습니다.

검색 클러스터는 별도의 서버에 설치해야 합니다. GitLab과 같은 서버에서 검색 클러스터를 실행하면 성능 문제가 발생할 수 있습니다.

노드가 하나인 검색 클러스터에서는 프라이머리 샤드만 할당되므로 클러스터 상태가 항상 yellow 입니다. 클러스터는 프라이머리 샤드와 같은 노드에 레플리카 샤드를 할당할 수 없습니다.

Note

새 Elasticsearch 클러스터를 프로덕션에서 사용하기 전에 중요 Elasticsearch 구성을 참고합니다.

버전 호환성#

Elasticsearch#

Warning

Elasticsearch 7.x 지원은 GitLab 18.10에서 더 이상 사용되지 않으며 20.0에서 제거될 예정입니다.

고급 검색은 다음 버전의 Elasticsearch와 호환됩니다.

GitLab 버전 Elasticsearch 버전
19.1 이상 8.x 및 9.x
15.0 ~ 19.0 7.x 및 8.x
14.0 ~ 14.10 6.8 ~ 7.x

GitLab.com은 Elasticsearch 9.x를 사용합니다. 성능과 최신 기능, 상위 호환성을 확보하려면 Elasticsearch 9.x를 사용합니다.

고급 검색은 Elasticsearch end-of-life 정책을 따릅니다.

OpenSearch#

고급 검색은 다음 버전의 OpenSearch와 호환됩니다.

GitLab 버전 OpenSearch 버전
18.1 이상 1.x 이상
17.6.3 ~ 18.0 1.x 및 2.x
15.5.3 ~ 17.6.2 1.x, 2.0 ~ 2.17
15.0 ~ 15.5.2 1.x

고급 검색은 OpenSearch 유지 보수 정책을 따릅니다.

시스템 요구 사항#

Elasticsearch와 AWS OpenSearch는 GitLab 설치 요구 사항보다 더 많은 리소스를 필요로 합니다.

메모리, CPU, 스토리지 요구 사항은 클러스터에 인덱싱하는 데이터 양에 따라 달라집니다. 사용량이 많은 Elasticsearch 클러스터에는 더 많은 리소스가 필요할 수 있습니다. estimate_cluster_size Rake 태스크는 전체 리포지터리 크기를 사용해 고급 검색에 필요한 스토리지 용량을 추정합니다.

접근 요구 사항#

GitLab은 요구 사항과 사용하는 백엔드 서비스에 따라 HTTP 인증 방식과 역할 기반 인증 방식을 모두 지원합니다.

Elasticsearch의 역할 기반 접근 제어#

Elasticsearch는 클러스터 보안을 강화하는 역할 기반 접근 제어를 제공합니다. Elasticsearch 클러스터에 접근해 작업을 수행하려면 Admin 영역에 구성된 Username에 다음 권한을 부여하는 역할이 있어야 합니다. Username은 GitLab에서 검색 클러스터로 요청을 보냅니다.

자세한 내용은 Elasticsearch 역할 기반 접근 제어와 Elasticsearch 보안 권한을 참고합니다.

{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": ["gitlab-*"],
      "privileges": [
        "create_index",
        "delete_index",
        "view_index_metadata",
        "read",
        "manage",
        "write"
      ]
    }
  ]
}

AWS OpenSearch Service 접근 제어#

사전 요구 사항:

  • OpenSearch 도메인을 생성할 때 AWS 계정에 AWSServiceRoleForAmazonOpenSearchService라는 이름의 서비스 연결 역할이 있어야 합니다.
  • AWS OpenSearch의 도메인 접근 정책이 es:ESHttp* 작업을 허용해야 합니다.

AWSServiceRoleForAmazonOpenSearchService는 모든 OpenSearch 도메인에서 사용됩니다. 대부분의 경우 AWS Management Console로 첫 번째 OpenSearch 도메인을 생성할 때 이 역할이 자동으로 생성됩니다. 서비스 연결 역할을 직접 생성하려면 AWS 문서를 참고합니다.

AWS OpenSearch Service에는 세 가지 주요 보안 계층이 있습니다.

네트워크#

이 보안 계층에서는 도메인을 생성할 때 Public access를 선택해 모든 클라이언트의 요청이 도메인 엔드포인트에 도달하도록 할 수 있습니다. VPC access를 선택하면 요청이 엔드포인트에 도달하도록 클라이언트가 VPC에 연결되어 있어야 합니다.

자세한 내용은 AWS 문서를 참고합니다.

도메인 접근 정책#

GitLab은 AWS OpenSearch에 대해 다음과 같은 도메인 접근 제어 방식을 지원합니다.

리소스 기반 정책 예시

다음은 es:ESHttp* 작업을 허용하는 리소스 기반(도메인) 접근 정책의 예시입니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "es:ESHttp*"
      ],
      "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*"
    }
  ]
}

다음은 특정 IAM 주체에 대해서만 es:ESHttp* 작업을 허용하는 리소스 기반(도메인) 접근 정책의 예시입니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:user/test-user"
        ]
      },
      "Action": [
        "es:ESHttp*"
      ],
      "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*"
    }
  ]
}
Note

계정 간에 AWS AssumeRole을 사용하는 경우 aws_role_arn을 지정해야 합니다. ARN은 OpenSearch에 접근할 권한이 있는 역할이어야 합니다.

ID 기반 정책 예시

다음은 es:ESHttp* 작업을 허용하도록 IAM 주체에 연결한 ID 기반 접근 정책의 예시입니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "es:ESHttp*",
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
세분화된 접근 제어#

세분화된 접근 제어를 활성화하면 다음 중 한 가지 방법으로 마스터 사용자를 설정해야 합니다.

IAM ARN을 마스터 사용자로 설정

IAM 주체를 마스터 사용자로 사용하는 경우 클러스터로 보내는 모든 요청은 AWS Signature Version 4로 서명해야 합니다. EC2 인스턴스에 할당한 IAM 역할의 IAM ARN을 지정할 수도 있습니다. 자세한 내용은 AWS 문서를 참고합니다.

사전 요구 사항:

  • 관리자 접근 권한이 있어야 합니다.

IAM ARN을 마스터 사용자로 설정하려면 GitLab 인스턴스에서 IAM 자격 증명으로 AWS OpenSearch Service를 사용해야 합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.

  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.

  3. Advanced search를 확장합니다.

  4. AWS OpenSearch IAM credentials 섹션에서 다음을 수행합니다.

    1. Use AWS OpenSearch Service with IAM credentials 체크박스를 선택합니다.

    2. AWS region에 OpenSearch 도메인이 위치한 AWS 리전을 입력합니다(예: us-east-1).

    3. AWS access key와 AWS secret access key에 인증에 사용할 액세스 키를 입력합니다.

      [!note] 컨테이너가 아니라 EC2 인스턴스에서 직접 실행되는 GitLab 배포는 액세스 키를 입력하지 않아도 됩니다. GitLab 인스턴스가 이 키를 AWS Instance Metadata Service (IMDS)에서 자동으로 가져옵니다.

  5. Save changes를 선택합니다.

마스터 사용자 생성

내부 사용자 데이터베이스에 마스터 사용자를 생성하면 HTTP 기본 인증으로 클러스터에 요청을 보낼 수 있습니다. 자세한 내용은 AWS 문서를 참고합니다.

사전 요구 사항:

  • 관리자 접근 권한이 있어야 합니다.

마스터 사용자를 생성하려면 GitLab 인스턴스에서 OpenSearch 도메인 URL과 마스터 사용자 이름 및 비밀번호를 구성해야 합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 확장합니다.
  4. OpenSearch domain URL에 OpenSearch 도메인 엔드포인트의 URL을 입력합니다.
  5. Username에 마스터 사용자 이름을 입력합니다.
  6. Password에 마스터 비밀번호를 입력합니다.
  7. Save changes를 선택합니다.

새 Elasticsearch 버전으로 업그레이드#

사전 요구 사항:

Elasticsearch를 새 마이너 버전이나 메이저 버전으로 업그레이드할 때는 GitLab 구성을 변경하지 않아도 됩니다. Elasticsearch 클러스터 업그레이드가 완료되어 동작 중이면 다음을 수행합니다.

  1. 클러스터 연결, 인덱스, 검색 동작을 검증합니다.

    sudo gitlab-rake gitlab:elastic:index_and_search_validation
    
  2. 인덱싱을 재개합니다.

  3. 선택 사항. 인덱싱 상태를 확인합니다. 검색 결과를 정확하게 얻으려면, 특히 Elasticsearch 인스턴스가 한동안 오프라인이었던 경우 인덱싱이 완료되었는지 확인합니다.

  4. 고급 검색으로 검색하기를 활성화합니다.

Elasticsearch 리포지터리 인덱서#

GitLab은 Git 리포지터리 데이터를 인덱싱하는 데 gitlab-elasticsearch-indexer를 사용합니다. 자체 컴파일 설치의 경우 인덱서 설치를 참고합니다.

인덱서 설치#

먼저 의존성을 설치한 다음 인덱서를 빌드하고 설치합니다.

의존성 설치#

이 프로젝트는 텍스트 인코딩에 International Components for Unicode(ICU)를 사용하므로 make를 실행하기 전에 사용하는 플랫폼의 개발 패키지가 설치되어 있는지 확인합니다.

Debian / Ubuntu#

Debian 또는 Ubuntu에 설치하려면 다음을 실행합니다.

sudo apt install libicu-dev
CentOS / RHEL#

CentOS 또는 RHEL에 설치하려면 다음을 실행합니다.

sudo yum install libicu-devel
macOS#
Note

먼저 Homebrew를 설치해야 합니다.

macOS에 설치하려면 다음을 실행합니다.

brew install icu4c
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:$PKG_CONFIG_PATH"

빌드 및 설치#

인덱서를 빌드하고 설치하려면 다음을 실행합니다.

indexer_path=/home/git/gitlab-elasticsearch-indexer

# Run the installation task for gitlab-elasticsearch-indexer:
sudo -u git -H bundle exec rake gitlab:indexer:install[$indexer_path] RAILS_ENV=production
cd $indexer_path && sudo make install

gitlab-elasticsearch-indexer는 /usr/local/bin에 설치됩니다.

PREFIX 환경 변수로 설치 경로를 변경할 수 있습니다. 변경하는 경우 sudo에 -E 플래그를 함께 전달합니다.

예시:

PREFIX=/usr sudo -E make install

설치를 마친 다음에는 Elasticsearch를 활성화합니다.

Note

인덱싱 중에 Permission denied - /home/git/gitlab-elasticsearch-indexer/와 같은 오류가 나타나면 gitlab.yml 파일의 production -> elasticsearch -> indexer_path 설정을 바이너리가 설치된 위치인 /usr/local/bin/gitlab-elasticsearch-indexer로 지정해야 할 수 있습니다.

인덱싱 오류 확인#

GitLab Elasticsearch Indexer에서 발생한 오류는 elasticsearch.log 파일과 sidekiq.log 파일에 json.exception.class가 Gitlab::Elastic::Indexer::Error 인 항목으로 기록됩니다. 이러한 오류는 Git 리포지터리 데이터를 인덱싱할 때 발생할 수 있습니다.

고급 검색 활성화#

사전 요구 사항:

고급 검색을 활성화하려면 다음을 수행합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Elasticsearch 클러스터에 맞게 고급 검색 설정을 구성합니다. 이 단계에서는 아직 Search with advanced search 체크박스를 선택하지 않습니다.
  4. 인스턴스를 인덱싱합니다.
  5. 선택 사항. 인덱싱 상태를 확인합니다.
  6. 인덱싱이 완료되면 Search with advanced search 체크박스를 선택한 다음 Save changes를 선택합니다.
Note

Elasticsearch가 활성화된 상태에서 Elasticsearch 클러스터가 중단되면 인스턴스가 변경 사항을 인덱싱할 job을 큐에 넣고도 유효한 Elasticsearch 클러스터를 찾지 못하므로 이슈와 같은 문서를 업데이트하는 데 문제가 발생할 수 있습니다.

리포지터리 데이터가 50 GB를 넘는 GitLab 인스턴스는 대규모 인스턴스를 효율적으로 인덱싱을 참고합니다.

인스턴스 인덱싱#

사용자 인터페이스에서 인덱싱#

히스토리

사전 요구 사항:

  • 인스턴스에 대한 관리자 접근 권한이 있어야 합니다.

사용자 인터페이스에서 최초 인덱싱을 수행하거나 인덱스를 다시 생성할 수 있습니다.

사용자 인터페이스에서 고급 검색을 활성화하고 인스턴스를 인덱싱하려면 다음을 수행합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Turn on indexing for advanced search 체크박스를 선택한 다음 Save changes를 선택합니다.
  4. Index the instance를 선택합니다.

Rake 태스크로 인덱싱#

사전 요구 사항:

  • 인스턴스에 대한 관리자 접근 권한이 있어야 합니다.

인스턴스 전체를 인덱싱하려면 다음 Rake 태스크를 사용합니다.

# WARNING: This task deletes all existing indices
# For installations that use the Linux package
sudo gitlab-rake gitlab:elastic:index

# WARNING: This task deletes all existing indices
# For self-compiled installations
bundle exec rake gitlab:elastic:index RAILS_ENV=production

특정 데이터를 인덱싱하려면 다음 Rake 태스크를 사용합니다.

# For installations that use the Linux package
sudo gitlab-rake gitlab:elastic:index_work_items
sudo gitlab-rake gitlab:elastic:index_group_wikis
sudo gitlab-rake gitlab:elastic:index_namespaces
sudo gitlab-rake gitlab:elastic:index_projects
sudo gitlab-rake gitlab:elastic:index_snippets
sudo gitlab-rake gitlab:elastic:index_users

# For self-compiled installations
bundle exec rake gitlab:elastic:index_work_items RAILS_ENV=production
bundle exec rake gitlab:elastic:index_group_wikis RAILS_ENV=production
bundle exec rake gitlab:elastic:index_namespaces RAILS_ENV=production
bundle exec rake gitlab:elastic:index_projects RAILS_ENV=production
bundle exec rake gitlab:elastic:index_snippets RAILS_ENV=production
bundle exec rake gitlab:elastic:index_users RAILS_ENV=production

인덱싱 상태 확인#

사전 요구 사항:

  • 인스턴스에 대한 관리자 접근 권한이 있어야 합니다.

인덱싱 상태를 확인하려면 다음을 수행합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search indexing status를 확장합니다.

백그라운드 job 상태 모니터링#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

인덱싱 진행 상황을 모니터링하려면 백그라운드 job의 상태를 확인할 수도 있습니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Monitoring > Background jobs를 선택합니다.
  3. Sidekiq 대시보드에서 Busy를 선택하고 다음 인덱싱 job을 확인합니다.
    • 코드와 커밋은 Search::Elastic::CommitIndexerWorker 입니다.
    • 위키 데이터는 ElasticWikiIndexerWorker 입니다.

고급 검색으로 검색 사용 설정#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색으로 검색을 사용 설정하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Search with advanced search 체크박스를 선택합니다.
  4. Save changes를 선택합니다.

고급 검색으로 코드 검색 사용 설정#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색으로 코드 검색을 사용 설정하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Code search with advanced search 체크박스를 선택합니다.
  4. Save changes를 선택합니다.

고급 검색 구성#

다음 Elasticsearch 설정을 사용할 수 있습니다.

매개변수 설명
Turn on indexing for advanced search 인덱싱을 켜거나 끄고, 인덱스가 아직 없으면 빈 인덱스를 생성합니다. 예를 들어 인덱스가 완전히 완성될 시간을 확보하기 위해 인덱싱은 켜고 검색은 꺼 둘 수 있습니다. 또한 이 옵션은 기존 데이터에 영향을 주지 않습니다. 데이터 변경을 추적하고 새 데이터가 인덱싱되도록 하는 백그라운드 인덱서만 활성화하거나 비활성화합니다.
Pause indexing for advanced search 고급 검색 인덱싱을 일시 중지합니다. 클러스터 마이그레이션이나 재인덱싱에 유용합니다. 모든 변경 사항은 계속 추적되지만, 재개하기 전까지는 인덱스에 커밋되지 않습니다.
Search with advanced search 검색과 고급 취약점 관리에서 고급 검색 기능을 켜거나 끕니다.
Code search with advanced search 고급 검색을 사용한 코드 검색을 켜거나 끕니다. 이 설정을 끄면 Elasticsearch 인스턴스에서 모든 코드가 삭제됩니다. 이 설정을 다시 켜려면 코드를 전체 재인덱싱해야 합니다. 정확한 코드 검색이 활성화되어 있다면 리소스를 절약하기 위해 이 설정을 꺼야 합니다.
Requeue indexing workers 인덱싱 워커의 자동 재큐잉을 켭니다. 모든 문서가 처리될 때까지 Sidekiq job을 큐에 넣어 코드 외 인덱싱 처리량을 개선합니다. 소규모 인스턴스나 Sidekiq 프로세스가 적은 인스턴스에는 인덱싱 워커 재큐잉을 권장하지 않습니다.
URL Elasticsearch 인스턴스의 URL 입니다. 클러스터링을 지원하려면 쉼표로 구분한 목록을 사용합니다(예: http://host1, https://host2:9200). Elasticsearch 인스턴스가 암호로 보호되어 있으면 Username과 Password 필드를 사용합니다. 또는 http://<username>:<password>@<elastic_host>:9200/와 같이 인라인 자격 증명을 사용합니다. OpenSearch를 사용하는 경우 80과 443 포트를 통한 연결만 허용됩니다.
Username Elasticsearch 인스턴스의 username 입니다.
Password Elasticsearch 인스턴스의 암호입니다.
Number of Elasticsearch shards and replicas per index Elasticsearch 인덱스는 성능상의 이유로 여러 샤드로 분할됩니다. 일반적으로 최소 5개의 샤드를 사용해야 합니다. 문서가 수천만 건인 인덱스에는 더 많은 샤드가 필요합니다(안내 참고). 이 값을 변경해도 인덱스를 다시 생성하기 전까지는 적용되지 않습니다. 확장성과 복원력에 대한 자세한 내용은 Elasticsearch 문서를 참고합니다. 각 Elasticsearch 샤드는 여러 개의 복제본을 가질 수 있습니다. 이 복제본은 샤드의 완전한 사본이며 쿼리 성능을 높이거나 하드웨어 장애에 대한 복원력을 제공합니다. 이 값을 늘리면 인덱스에 필요한 전체 디스크 공간도 늘어납니다. 각 인덱스마다 샤드와 복제본 수를 설정할 수 있습니다.
Limit the amount of namespace and project data to index 이 설정을 활성화하면 인덱싱할 네임스페이스와 프로젝트를 지정할 수 있습니다. 나머지 네임스페이스와 프로젝트는 데이터베이스 검색을 사용합니다. 이 설정을 활성화하고도 네임스페이스나 프로젝트를 지정하지 않으면 프로젝트 레코드만 인덱싱됩니다. 자세한 내용은 인덱싱할 네임스페이스 및 프로젝트 데이터 양 제한을 참고합니다.
Use AWS OpenSearch Service with IAM credentials AWS IAM 인증, AWS EC2 인스턴스 프로파일 자격 증명, AWS ECS 태스크 자격 증명 중 하나로 OpenSearch 요청에 서명합니다. AWS 호스팅 OpenSearch 도메인 액세스 정책 구성에 대한 자세한 내용은 Amazon OpenSearch Service의 자격 증명 및 액세스 관리를 참고합니다.
AWS Region OpenSearch Service가 위치한 AWS 리전입니다.
AWS Access Key AWS 액세스 키입니다.
AWS Secret Access Key AWS 시크릿 액세스 키입니다.
Maximum file size indexed 인스턴스 제한의 설명을 참고합니다.
Maximum field length 인스턴스 제한의 설명을 참고합니다.
Indexing timeout (minutes) 프로젝트당 인덱싱 타임아웃(분)입니다.
Number of shards for non-code indexing 인덱싱 워커 샤드 수입니다. 병렬 Sidekiq job을 더 많이 큐에 넣어 코드 외 인덱싱 처리량을 개선합니다. 소규모 인스턴스나 Sidekiq 프로세스가 적은 인스턴스에는 샤드 수를 늘리지 않는 편이 좋습니다. 기본값은 2 입니다.
Maximum bulk request size (MiB) GitLab의 Ruby 및 Go 기반 인덱서 프로세스가 사용합니다. 이 설정은 Elasticsearch Bulk API에 페이로드를 제출하기 전에 특정 인덱싱 프로세스에서 얼마나 많은 데이터를 수집(및 메모리에 저장)해야 하는지를 나타냅니다. GitLab Go 기반 인덱서에서는 이 설정을 Bulk request concurrency와 함께 사용해야 합니다. **Maximum bulk request size (MiB)**는 Elasticsearch 호스트와, gitlab-rake 명령 또는 Sidekiq 작업으로 GitLab Go 기반 인덱서를 실행하는 호스트 양쪽의 리소스 제약을 모두 수용해야 합니다.
Bulk request concurrency Bulk request concurrency는 Elasticsearch Bulk API에 제출할 데이터를 수집하기 위해 GitLab Go 기반 인덱서 프로세스(또는 스레드)를 몇 개까지 병렬로 실행할 수 있는지를 나타냅니다. 이 값을 늘리면 인덱싱 성능은 향상되지만 Elasticsearch 벌크 요청 큐가 더 빨리 채워집니다. 이 설정은 Maximum bulk request size (MiB) 설정과 함께 사용해야 하며, Elasticsearch 호스트와 gitlab-rake 명령 또는 Sidekiq 작업으로 GitLab Go 기반 인덱서를 실행하는 호스트 양쪽의 리소스 제약을 수용해야 합니다.
Client request timeout Elasticsearch HTTP 클라이언트 요청 타임아웃 값(초)입니다. 값이 0 이면 기본 타임아웃인 30초를 사용합니다. 이 한도를 초과하는 검색 요청은 애플리케이션 서버가 요청을 종료한 뒤 500으로 실패하는 대신 HTTP 408을 반환합니다. Elasticsearch 쿼리가 평소 30초 이상 걸린다면 더 큰 값을 설정합니다. 애플리케이션 서버는 60초에 요청을 종료하므로 60보다 큰 값은 설정하지 않습니다. 타임아웃을 더 길게 두려면 30과 55 사이의 값을 설정해야 합니다.
Code indexing concurrency 동시에 실행할 수 있는 Elasticsearch 코드 인덱싱 백그라운드 job의 최대 개수입니다. 리포지터리 인덱싱 작업에만 적용됩니다.
Retry on failure Elasticsearch 검색 요청의 최대 재시도 횟수입니다. GitLab 17.6에서 도입되었습니다.
Index prefix Elasticsearch 인덱스 이름에 사용할 사용자 지정 접두사입니다. 기본값은 gitlab 입니다. 이 값을 변경하면 모든 인덱스가 gitlab 대신 이 접두사를 사용합니다(예: gitlab-production-issues 대신 custom-production-issues). 1~100자여야 하고 소문자 영숫자, 하이픈, 밑줄만 포함할 수 있으며 하이픈이나 밑줄로 시작하거나 끝날 수 없습니다. GitLab 18.2에서 도입되었습니다.
Warning

**Maximum bulk request size (MiB)**와 Bulk request concurrency의 값을 늘리면 Sidekiq 성능에 부정적인 영향을 줄 수 있습니다. Sidekiq 로그에서 scheduling_latency_s 값이 늘어나면 두 값을 기본값으로 되돌립니다. 자세한 내용은 이슈 322147을 참고합니다.

인덱싱할 네임스페이스 및 프로젝트 데이터 양 제한#

히스토리
  • 취약점 레코드 인덱싱이 vulnerability_es_ingestion이라는 기능 플래그와 함께 GitLab 18.1의 GitLab.com 및 GitLab Dedicated에 도입되었습니다. 기본적으로 비활성화되어 있습니다.
  • 취약점 레코드 인덱싱이 GitLab 18.2의 GitLab.com 및 GitLab Dedicated에서 일반 공급되었습니다. 기능 플래그 vulnerability_es_ingestion은 제거되었습니다.
Feature flag

이 기능의 사용 가능 여부는 기능 플래그로 제어됩니다. 자세한 내용은 히스토리를 참고합니다.

Limit the amount of namespace and project data to index 체크박스를 선택하면 인덱싱할 네임스페이스와 프로젝트를 지정할 수 있습니다. 네임스페이스가 그룹이면 하위 그룹과 해당 하위 그룹의 프로젝트도 함께 인덱싱됩니다.

이 설정을 활성화하면 다음과 같이 동작합니다.

  • 전체 인덱싱을 하려면 네임스페이스나 프로젝트를 지정해야 합니다.
  • 프로젝트 레코드(프로젝트 이름과 설명 같은 메타데이터)는 항상 모든 프로젝트에 대해 인덱싱됩니다.
  • 취약점 레코드는 보안 리포트의 필터링을 지원하기 위해 항상 모든 프로젝트와 네임스페이스에 대해 인덱싱됩니다.
  • 연관 데이터는 지정한 네임스페이스와 프로젝트에 대해서만 인덱싱됩니다.
Warning

이 설정을 활성화한 뒤 네임스페이스나 프로젝트를 지정하지 않으면 프로젝트 레코드만 인덱싱되며 연관 데이터는 검색할 수 없습니다.

인덱싱된 네임스페이스#

히스토리
  • 제한된 인덱싱에 대한 전역 검색이 advanced_global_search_for_limited_indexing이라는 기능 플래그와 함께 GitLab 13.4에 도입되었습니다. 기본적으로 비활성화되어 있습니다.
  • GitLab 14.2에서 GitLab.com에 활성화되었습니다.
  • 제한된 인덱싱에 대한 전역 검색이 GitLab 17.11에서 advanced_global_search_for_limited_indexing 플래그 대신 UI 옵션으로 일반 공급되었습니다.

모든 네임스페이스를 인덱싱하면 전역 코드 검색과 커밋 검색에 고급 검색을 사용할 수 있습니다. 일부 네임스페이스만 인덱싱하면 다음과 같습니다.

  • 전역 검색에는 코드 또는 커밋 검색 범위가 포함되지 않습니다.
  • 코드 및 커밋 검색은 인덱싱된 네임스페이스 하나에서만 사용할 수 있습니다.
  • 인덱싱된 여러 네임스페이스를 아우르는 단일 코드 또는 커밋 검색은 불가능합니다.
  • 인덱싱된 네임스페이스 안에서는 프로젝트 간 검색을 사용할 수 있습니다.

예를 들어 서로 다른 두 그룹을 인덱싱했다면 각 그룹에서 코드 검색을 따로 실행해야 합니다.

제한된 인덱싱에 대한 전역 검색을 사용 설정하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 펼칩니다
  4. Enable global search for limited indexing를 선택합니다.
  5. Save changes를 선택합니다.
  6. 인스턴스를 이미 인덱싱했다면 인스턴스를 재인덱싱해야 합니다. 이때 기존 검색 데이터가 삭제되며, 필터링이 올바르게 동작하게 됩니다.

사용자 지정 언어 분석기 사용 설정#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

Elastic의 smartcn 및 kuromoji 분석 플러그인을 사용하면 중국어와 일본어 지원을 개선할 수 있습니다.

사용자 지정 언어 분석기를 사용 설정하려면 다음 단계를 따릅니다.

  1. 필요한 플러그인을 설치합니다. 플러그인 설치 방법은 Elasticsearch 문서를 참고합니다. 플러그인은 클러스터의 모든 노드에 설치해야 하며, 설치 후 각 노드를 재시작해야 합니다. 플러그인 목록은 이 절 뒤의 표를 참고합니다.
  2. 오른쪽 위 모서리에서 Admin을 선택합니다.
  3. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  4. Custom analyzers: language support를 찾습니다.
  5. Indexing에 대한 플러그인 지원을 활성화합니다.
  6. 변경 사항을 적용하려면 Save changes를 선택합니다.
  7. 무중단 재인덱싱을 트리거하거나 전체를 처음부터 재인덱싱하여 갱신된 매핑으로 새 인덱스를 생성합니다.
  8. 이전 단계가 완료된 후 Searching에 대한 플러그인 지원을 활성화합니다.

무엇을 설치할지에 대한 안내는 다음 Elasticsearch 언어 플러그인 옵션을 참고합니다.

매개변수 설명
Enable Chinese (smartcn) custom analyzer: Indexing 새로 생성되는 인덱스에 smartcn 사용자 지정 분석기를 사용해 중국어 지원을 활성화하거나 비활성화합니다.
Enable Chinese (smartcn) custom analyzer: Search 고급 검색에 smartcn 필드를 사용할지 여부를 활성화하거나 비활성화합니다. 플러그인을 설치하고 사용자 지정 분석기 인덱싱을 활성화한 뒤 인덱스를 다시 생성한 다음에만 활성화합니다.
Enable Japanese (kuromoji) custom analyzer: Indexing 새로 생성되는 인덱스에 kuromoji 사용자 지정 분석기를 사용해 일본어 지원을 활성화하거나 비활성화합니다.
Enable Japanese (kuromoji) custom analyzer: Search 고급 검색에 kuromoji 필드를 사용할지 여부를 활성화하거나 비활성화합니다. 플러그인을 설치하고 사용자 지정 분석기 인덱싱을 활성화한 뒤 인덱스를 다시 생성한 다음에만 활성화합니다.

고급 검색 비활성화#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색을 비활성화하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.

  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.

  3. Turn on indexing for advanced search와 Search with advanced search 체크박스를 지웁니다.

  4. Save changes를 선택합니다.

  5. 선택 사항. 아직 온라인 상태인 Elasticsearch 인스턴스에서는 기존 인덱스를 삭제합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:delete_index
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:delete_index RAILS_ENV=production
    

고급 검색으로 검색 비활성화#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색으로 검색을 비활성화하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Search with advanced search 체크박스를 지웁니다.
  4. Save changes를 선택합니다.

고급 검색으로 코드 검색 비활성화#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색으로 코드 검색을 비활성화하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Code search with advanced search 체크박스를 지웁니다.
  4. Save changes를 선택합니다.

인덱싱 일시 중지#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

인덱싱을 일시 중지하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 펼칩니다.
  4. Pause indexing for advanced search 체크박스를 선택합니다.
  5. Save changes를 선택합니다.

인덱싱 재개#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

인덱싱을 재개하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 펼칩니다.
  4. Pause indexing for advanced search 체크박스를 지웁니다.
  5. Save changes를 선택합니다.

무중단 재인덱싱#

이 재인덱싱 방식은 Elasticsearch reindex API 와 Elasticsearch 인덱스 별칭 기능을 사용해 작업을 수행합니다. 인덱스 별칭은 GitLab 이 읽기와 쓰기에 사용하는 primary 인덱스에 연결됩니다. 재인덱싱 프로세스가 시작되면 primary 인덱스에 대한 쓰기가 일시적으로 중지됩니다. 그런 다음 다른 인덱스가 생성되고 Reindex API가 호출되어 인덱스 데이터를 새 인덱스로 마이그레이션합니다. 재인덱싱 job 이 완료되면 인덱스 별칭이 새 인덱스로 전환되고, 그 인덱스가 새 primary 인덱스가 됩니다. 마지막으로 쓰기가 재개되고 평상시 동작이 이어집니다.

무중단 재인덱싱 사용#

새 인덱스를 만들어 기존 데이터를 복사하지 않고는 변경할 수 없는 인덱스 설정이나 매핑을 구성할 때 무중단 재인덱싱을 사용할 수 있습니다. 누락된 데이터를 복구하는 용도로는 무중단 재인덱싱을 사용하지 않아야 합니다. 무중단 재인덱싱은 아직 인덱싱되지 않은 데이터를 검색 클러스터에 추가하지 않습니다. 재인덱싱을 시작하기 전에 모든 고급 검색 마이그레이션을 완료해야 합니다.

재인덱싱 트리거#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

재인덱싱을 트리거하려면 다음 단계를 따릅니다.

  1. 관리자로 GitLab 인스턴스에 로그인합니다.
  2. 오른쪽 위 모서리에서 Admin을 선택합니다.
  3. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  4. Advanced search zero-downtime reindexing을 펼칩니다.
  5. Trigger cluster reindexing을 선택합니다.

재인덱싱은 Elasticsearch 클러스터 크기에 따라 오래 걸릴 수 있습니다.

이 프로세스가 완료되면 원래 인덱스는 14일 후 삭제되도록 예약됩니다. 재인덱싱 프로세스를 트리거한 같은 페이지에서 Cancel 버튼을 눌러 이 동작을 취소할 수 있습니다.

재인덱싱이 실행되는 동안 같은 절에서 진행 상황을 확인할 수 있습니다.

무중단 재인덱싱 트리거#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

무중단 재인덱싱을 트리거하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.

  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.

  3. Advanced search zero-downtime reindexing을 펼칩니다. 다음 설정을 사용할 수 있습니다.

슬라이스 배수#

슬라이스 배수는 재인덱싱 중 슬라이스 수를 계산합니다.

GitLab은 재인덱싱을 효율적이고 안전하게 제어하기 위해 수동 슬라이싱을 사용하며, 이를 통해 사용자는 실패한 슬라이스만 재시도할 수 있습니다.

배수의 기본값은 2 이며 인덱스당 샤드 수에 적용됩니다. 예를 들어 이 값이 2 이고 인덱스에 샤드가 20개 있으면 재인덱싱 작업은 40개의 슬라이스로 나뉩니다.

최대 실행 슬라이스 수#

최대 실행 슬라이스 수 매개변수의 기본값은 60 이며, Elasticsearch 재인덱싱 중 동시에 실행할 수 있는 슬라이스의 최대 개수를 의미합니다.

이 값을 너무 높게 설정하면 클러스터가 검색과 쓰기로 크게 포화되어 성능에 악영향을 줄 수 있습니다. 이 값을 너무 낮게 설정하면 재인덱싱 프로세스가 완료되기까지 매우 오래 걸릴 수 있습니다.

적절한 값은 클러스터 크기, 재인덱싱 중 검색 성능 저하를 어느 정도 감수할 수 있는지, 그리고 재인덱싱을 빨리 끝내고 인덱싱을 재개하는 것이 얼마나 중요한지에 따라 달라집니다.

가장 최근 재인덱싱 job을 실패로 표시하고 인덱싱 재개#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

완료되지 않은 재인덱싱 job을 중단하고 인덱싱을 재개하려면 다음 단계를 따릅니다.

  1. 가장 최근 재인덱싱 job을 실패로 표시합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:mark_reindex_failed
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:mark_reindex_failed RAILS_ENV=production
    
  2. 오른쪽 위 모서리에서 Admin을 선택합니다.

  3. 왼쪽 사이드바에서 Settings > Search를 선택합니다.

  4. Advanced search를 펼칩니다.

  5. Pause indexing for advanced search 체크박스를 지웁니다.

인덱스 무결성#

인덱스 무결성은 누락된 리포지터리 데이터를 감지하고 복구합니다. 이 기능은 그룹이나 프로젝트로 범위를 지정한 코드 검색이 결과를 반환하지 않을 때 자동으로 사용됩니다.

고급 검색 마이그레이션#

재인덱싱 마이그레이션은 백그라운드에서 실행되므로 인스턴스를 수동으로 재인덱싱할 필요가 없습니다.

GitLab 18.0 이상에서는 elastic_migration_worker_enabled 애플리케이션 설정으로 마이그레이션 워커를 활성화하거나 비활성화할 수 있습니다. 기본적으로 마이그레이션 워커는 활성화되어 있습니다.

마이그레이션 딕셔너리 파일#

모든 마이그레이션에는 ee/elastic/docs/ 폴더에 다음 정보를 담은 딕셔너리 파일이 있습니다.

name:
version:
description:
group:
milestone:
introduced_by_url:
obsolete:
marked_obsolete_by_url:
marked_obsolete_in_milestone:

예를 들어 이 정보를 사용해 마이그레이션이 언제 도입되었는지, 또는 언제 사용 중단으로 표시되었는지 확인할 수 있습니다.

대기 중인 마이그레이션 확인#

대기 중인 고급 검색 마이그레이션을 확인하려면 다음 명령을 실행합니다.

curl "$CLUSTER_URL/gitlab-production-migrations/_search?size=100&q=*" | jq .

다음과 비슷한 결과가 반환됩니다.

{
  "took": 14,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "gitlab-production-migrations",
        "_type": "_doc",
        "_id": "20230209195404",
        "_score": 1,
        "_source": {
          "completed": true
        }
      }
    ]
  }
}

마이그레이션 문제를 디버깅하려면 elasticsearch.log 파일을 확인합니다.

중단된 마이그레이션 재시도#

일부 마이그레이션에는 재시도 한도가 있습니다. 재시도 한도 안에 마이그레이션을 끝내지 못하면 마이그레이션이 중단되고 고급 검색 통합 설정에 알림이 표시됩니다.

마이그레이션이 중단된 원인을 디버깅하고 재시도 전에 필요한 변경을 적용하려면 elasticsearch.log 파일을 확인하는 것이 좋습니다.

실패 원인을 해결했다고 판단되면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 펼칩니다.
  4. Advanced search migration halted 알림 상자 안에서 Retry migration을 선택합니다. 마이그레이션이 백그라운드에서 재시도되도록 예약됩니다.

마이그레이션을 성공시킬 수 없다면 마지막 수단으로 인덱스를 처음부터 다시 만드는 방법을 고려할 수 있습니다. 새로 만든 인덱스는 올바른 최신 스키마로 다시 생성되어 모든 마이그레이션을 건너뛰므로, 이렇게 하면 문제를 우회할 수 있습니다.

메이저 업그레이드 전에 모든 마이그레이션을 완료해야 합니다#

GitLab 메이저 버전으로 업그레이드하기 전에, 해당 메이저 버전 직전의 최신 마이너 버전까지 존재하는 모든 마이그레이션을 완료해야 합니다. 또한 메이저 버전 업그레이드를 진행하기 전에 중단된 마이그레이션을 해결하고 재시도해야 합니다. 자세한 내용은 업그레이드를 위한 마이그레이션을 참고합니다.

제거된 마이그레이션은 사용 중단으로 표시됩니다. 대기 중인 고급 검색 마이그레이션이 모두 완료되기 전에 GitLab을 업그레이드하면, 새 버전에서 제거된 대기 중 마이그레이션은 실행하거나 재시도할 수 없습니다. 이 경우 인덱스를 처음부터 다시 만들어야 합니다.

gitlab:check Rake 태스크에는 All migrations must be finished before doing a major upgrade라는 검사가 포함되어 있습니다. 고급 검색 인덱싱이 켜져 있을 때 이 검사는 대기 중인 마이그레이션이 없으면 yes를 보고합니다. 대기 중인 마이그레이션이 있으면 no와 대기 중인 마이그레이션 수를 보고합니다. 인덱싱이 꺼져 있으면 검사를 건너뜁니다.

이 검사는 다음과 같이 동작합니다.

  • 상태만 보고합니다.
  • 업그레이드를 중지, 일시 중지, 롤백하지 않습니다.
  • gitlab:check 또는 gitlab:app:check Rake 태스크를 실행할 때만 실행됩니다.

검사가 no를 보고하더라도 Rake 태스크는 상태 0으로 종료되므로, 종료 코드로 업그레이드를 통제할 수 없습니다.

대기 중인 마이그레이션 수에는 시작하지 않았거나, 진행 중이거나, 중단된 마이그레이션이 포함되지만 건너뛸 수 있는 마이그레이션은 포함되지 않습니다. 이 검사도 gitlab:elastic:list_pending_migrations Rake 태스크도 대기 중인 마이그레이션 중 어떤 것이 중단되었는지 알려 주지 않습니다. gitlab:elastic:info Rake 태스크는 현재 마이그레이션이 중단되었는지 보고하지만, 현재 마이그레이션만 보고합니다. 중단된 마이그레이션을 확인하고 재시도해 볼 수 있습니다.

마이그레이션이 계속 대기 중이고 gitlab:elastic:list_pending_migrations가 이를 [Obsolete]로 표시한다면, 마이그레이션이 완료되기를 기다리는 대신 인덱스를 다시 만들어야 합니다.

건너뛸 수 있는 마이그레이션#

건너뛸 수 있는 마이그레이션은 조건이 충족될 때만 실행됩니다. 예를 들어 마이그레이션이 특정 Elasticsearch 버전에 의존한다면, 해당 버전에 도달할 때까지 건너뛸 수 있습니다.

건너뛸 수 있는 마이그레이션이 사용 중단으로 표시될 때까지 실행되지 않았다면, 변경 사항을 적용하기 위해 인덱스를 다시 만들어야 합니다.

GitLab 고급 검색 Rake 태스크#

다음 작업에 사용할 수 있는 Rake 태스크가 있습니다.

사용할 수 있는 Rake 태스크는 다음과 같습니다.

태스크 설명
sudo gitlab-rake gitlab:elastic:info 고급 검색 통합의 디버깅 정보를 출력합니다.
sudo gitlab-rake gitlab:elastic:index GitLab 17.0 이하에서는 고급 검색용 인덱싱을 켜고 gitlab:elastic:recreate_index, gitlab:elastic:clear_index_status, gitlab:elastic:index_group_entities, gitlab:elastic:index_projects, gitlab:elastic:index_snippets, gitlab:elastic:index_users를 실행합니다.
GitLab 17.1 이상에서는 백그라운드에 Sidekiq job을 큐에 넣습니다. 이 job은 먼저 고급 검색용 인덱싱을 켠 다음, 모든 인덱스가 생성되도록 인덱싱을 일시 중지합니다. 그다음 모든 인덱스를 다시 생성하고 인덱싱 상태를 초기화한 뒤, 프로젝트·그룹 데이터와 스니펫, 사용자를 인덱싱할 Sidekiq job을 추가로 큐에 넣습니다. 마지막으로 고급 검색용 인덱싱을 재개해 작업을 완료합니다. GitLab 17.1에서 elastic_index_use_trigger_indexing이라는 기능 플래그와 함께 도입되었습니다. 기본적으로 활성화됩니다. GitLab 17.3에서 정식 기능이 되었습니다. 기능 플래그 elastic_index_use_trigger_indexing은 제거되었습니다.
sudo gitlab-rake gitlab:elastic:pause_indexing 고급 검색용 인덱싱을 일시 중지합니다. 변경 사항은 계속 추적됩니다. 클러스터·인덱스 마이그레이션에 유용합니다.
sudo gitlab-rake gitlab:elastic:resume_indexing 고급 검색용 인덱싱을 재개합니다.
sudo gitlab-rake gitlab:elastic:index_and_search_validation 모든 인덱스에 대해 클러스터 연결, 인덱스, 검색 동작을 검증합니다. GitLab 18.3에서 도입되었습니다.
sudo gitlab-rake gitlab:elastic:index_projects 모든 프로젝트를 순회하면서 백그라운드에서 인덱싱할 Sidekiq job을 큐에 넣습니다. 인덱스가 생성된 뒤에만 사용할 수 있습니다.
sudo gitlab-rake gitlab:elastic:index_group_entities gitlab:elastic:index_work_items와 gitlab:elastic:index_group_wikis를 호출하고, 그룹 마일스톤을 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_work_items Elasticsearch가 활성화된 그룹의 모든 작업 항목을 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_namespaces 모든 루트 네임스페이스를 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_group_wikis Elasticsearch가 활성화된 그룹의 모든 위키를 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_snippets 스니펫 데이터를 인덱싱하는 Elasticsearch 가져오기를 수행합니다.
sudo gitlab-rake gitlab:elastic:index_users 모든 사용자를 Elasticsearch로 가져옵니다.
sudo gitlab-rake gitlab:elastic:index_vulnerabilities 모든 취약점을 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_sbom_occurrence_refs 모든 SBOM 발생 참조를 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_projects_status 모든 프로젝트 리포지터리 데이터(코드, 커밋, 위키)의 전체 인덱싱 상태를 확인합니다. 상태는 인덱싱된 프로젝트 수를 전체 프로젝트 수로 나눈 뒤 100을 곱해 계산합니다. 이 태스크는 이슈, 머지 리퀘스트, 마일스톤 같은 리포지터리 외 데이터는 포함하지 않습니다.
sudo gitlab-rake gitlab:elastic:index_groups_status 모든 그룹 리포지터리 데이터(그룹 위키)의 전체 인덱싱 상태를 확인합니다. 상태는 인덱싱된 그룹 수를 전체 그룹 수로 나눈 뒤 100을 곱해 계산합니다. 이 태스크는 에픽, 머지 리퀘스트, 마일스톤 같은 리포지터리 외 데이터는 포함하지 않습니다.
sudo gitlab-rake gitlab:elastic:clear_index_status 모든 프로젝트의 IndexStatus 인스턴스를 전부 삭제합니다. 이 명령은 인덱스를 완전히 지우므로 주의해서 사용해야 합니다.
sudo gitlab-rake gitlab:elastic:create_empty_index 빈 인덱스(기본 인덱스와 별도의 이슈 인덱스)를 생성하고, Elasticsearch 쪽에 아직 없는 경우에만 각각에 별칭을 할당합니다.
sudo gitlab-rake gitlab:elastic:delete_index Elasticsearch 인스턴스에서 GitLab 인덱스와 별칭이 있으면 제거합니다.
sudo gitlab-rake gitlab:elastic:recreate_index gitlab:elastic:delete_index와 gitlab:elastic:create_empty_index를 묶은 래퍼 태스크입니다. 인덱싱 job은 큐에 넣지 않습니다.
sudo gitlab-rake gitlab:elastic:projects_not_indexed 리포지터리 데이터가 인덱싱되지 않은 프로젝트를 표시합니다. 이 태스크는 이슈, 머지 리퀘스트, 마일스톤 같은 리포지터리 외 데이터는 포함하지 않습니다.
sudo gitlab-rake gitlab:elastic:groups_not_indexed 리포지터리 데이터가 인덱싱되지 않은 그룹을 표시합니다. 이 태스크는 이슈, 머지 리퀘스트, 마일스톤 같은 리포지터리 외 데이터는 포함하지 않습니다.
sudo gitlab-rake gitlab:elastic:reindex_cluster 무중단 클러스터 재인덱싱 태스크를 예약합니다.
sudo gitlab-rake gitlab:elastic:mark_reindex_failed 가장 최근 재인덱싱 job을 실패로 표시합니다.
sudo gitlab-rake gitlab:elastic:list_pending_migrations 대기 중인 마이그레이션을 나열합니다. 대기 중인 마이그레이션에는 아직 시작하지 않은 것, 시작했지만 끝나지 않은 것, 중단된 것이 포함됩니다.
sudo gitlab-rake gitlab:elastic:estimate_cluster_size 전체 리포지터리 크기를 기준으로 코드·위키 인덱스 크기와 전체 클러스터 크기를 추정합니다.
sudo gitlab-rake gitlab:elastic:estimate_shard_sizes 대략적인 데이터베이스 레코드 수를 기준으로 각 인덱스의 샤드 크기를 추정합니다. 이 추정치에는 리포지터리 데이터(코드, 커밋, 위키)가 포함되지 않습니다.
sudo gitlab-rake gitlab:elastic:enable_search_with_elasticsearch Elasticsearch 기반 고급 검색을 활성화합니다.
sudo gitlab-rake gitlab:elastic:disable_search_with_elasticsearch Elasticsearch 기반 고급 검색을 비활성화합니다.

환경 변수#

Rake 태스크 외에도 처리 과정을 조정하는 데 사용할 수 있는 환경 변수가 있습니다.

환경 변수 데이터 타입 기능
ID_TO Integer 인덱서가 해당 값 이하의 프로젝트만 인덱싱하도록 지정합니다.
ID_FROM Integer 인덱서가 해당 값 이상의 프로젝트만 인덱싱하도록 지정합니다.

프로젝트 범위 또는 특정 프로젝트 인덱싱#

ID_FROM과 ID_TO 환경 변수를 사용하면 제한된 수의 프로젝트만 인덱싱할 수 있습니다. 인덱싱을 단계적으로 진행할 때 유용합니다.

root@git:~# sudo gitlab-rake gitlab:elastic:index_projects ID_FROM=1 ID_TO=100

ID_FROM과 ID_TO는 이상·이하 비교를 사용하므로, 두 값을 같은 프로젝트 ID로 설정하면 프로젝트 하나만 인덱싱할 수 있습니다.

root@git:~# sudo gitlab-rake gitlab:elastic:index_projects ID_FROM=5 ID_TO=5
Indexing project repositories...I, [2019-03-04T21:27:03.083410 #3384]  INFO -- : Indexing GitLab User / test (ID=33)...
I, [2019-03-04T21:27:05.215266 #3384]  INFO -- : Indexing GitLab User / test (ID=33) is done!

고급 검색 인덱스 스코프#

검색을 수행할 때 GitLab 인덱스는 다음 스코프를 사용합니다.

스코프 이름 검색 대상
commits 커밋 데이터
projects 프로젝트 데이터(기본값)
groups 그룹 데이터
blobs 코드
work_items 작업 항목 데이터
merge_requests 머지 리퀘스트 데이터
milestones 마일스톤 데이터
notes 노트 데이터
snippets 스니펫 데이터
wiki_blobs 위키 콘텐츠
users 사용자

GitLab.com과 GitLab Dedicated에서는 검색 외 기능을 지원하기 위해 모든 프로젝트와 네임스페이스의 취약점 레코드를 항상 인덱싱합니다. GitLab Self-Managed에서 취약점 레코드를 인덱싱하는 방안은 이슈 525484에서 제안되었습니다.

튜닝#

최적 클러스터 구성 선택 지침#

클러스터 구성 선택에 관한 기본 지침은 Elastic Cloud Calculator도 참고합니다.

  • 일반적으로 복제본 하나를 둔 2노드 이상의 클러스터 구성을 사용하면 복원력을 확보할 수 있습니다. 스토리지 사용량이 빠르게 늘고 있다면 수평 확장(노드 추가)을 미리 계획하는 편이 좋습니다.
  • 검색 클러스터에 HDD 스토리지를 사용하면 성능이 떨어지므로 권장하지 않습니다. SSD 스토리지(예: NVMe 또는 SATA SSD 드라이브)를 사용하는 편이 좋습니다.
  • 대형 인스턴스에는 coordinating-only 노드를 사용하지 않아야 합니다. coordinating-only 노드는 데이터 노드보다 작아 성능과 고급 검색 마이그레이션에 영향을 줄 수 있습니다.
  • GitLab Performance Tool로 검색 클러스터 크기와 구성을 달리하며 검색 성능을 벤치마킹할 수 있습니다.
  • Heap size는 물리 RAM의 50% 를 넘지 않게 설정합니다. 또한 zero-based compressed oops 임계값을 넘지 않아야 합니다. 정확한 임계값은 시스템마다 다르지만 대부분의 시스템에서 26GB는 안전하며, 일부 시스템에서는 30GB까지 가능합니다. 자세한 내용은 Heap size settings와 Setting JVM options를 참고합니다.
  • refresh_interval은 인덱스별 설정입니다. 데이터를 실시간으로 볼 필요가 없다면 기본값 1s보다 큰 값으로 조정할 수 있습니다. 이 값은 최신 결과가 얼마나 빨리 보이는지를 좌우합니다. 실시간성이 중요하다면 기본값에 최대한 가깝게 유지합니다.
  • 인덱싱 작업이 많다면 indices.memory.index_buffer_size를 30% 또는 40% 로 올릴 수 있습니다.

고급 검색 설정#

Elasticsearch 샤드 수#

히스토리
  • gitlab:elastic:estimate_shard_sizes가 GitLab 18.3에서 리포지터리 데이터를 포함하는 인덱스의 크기 산정까지 다루도록 변경되었습니다.

단일 노드 클러스터에서는 인덱스당 Elasticsearch 샤드 수를 Elasticsearch 데이터 노드의 CPU 코어 수와 같게 설정합니다.

다중 노드 클러스터에서는 Rake 태스크 gitlab:elastic:estimate_shard_sizes를 실행해 각 인덱스의 샤드 수를 확인합니다. 이 태스크는 샤드·복제본 크기 권장값과 데이터베이스 데이터를 담은 인덱스의 대략적인 문서 수를 반환합니다.

평균 샤드 크기는 수 GB에서 30GB 사이로 유지합니다. 평균 샤드 크기가 30GB를 넘으면 해당 인덱스의 샤드 크기를 늘리고 무중단 재인덱싱을 실행합니다. 클러스터를 정상 상태로 유지하려면 노드당 샤드 수가 설정된 힙 크기의 20배를 넘지 않아야 합니다. 예를 들어 힙이 30GB 인 노드는 샤드가 최대 600개여야 합니다.

인덱스의 샤드 수를 변경하려면 설정을 바꾼 뒤 무중단 재인덱싱을 실행합니다.

Elasticsearch 복제본 수#

단일 노드 클러스터에서는 인덱스당 Elasticsearch 복제본 수를 0으로 설정합니다.

다중 노드 클러스터에서는 인덱스당 Elasticsearch 복제본 수를 1로 설정합니다(샤드마다 복제본 하나). 노드 하나가 유실되면 인덱스가 손상되므로 이 값은 0 이 아니어야 합니다.

샤드 할당 어웨어니스가 활성화되어 있으면, 샤드당 전체 사본 수가 어웨어니스 속성 수(대개 노드 또는 존)로 나누어떨어져야 합니다. 샤드 사본이 모든 어웨어니스 속성에 고르게 분산되어야 장애 내성과 부하 분산이 제대로 확보됩니다.

(1 + `number_of_replicas`) / `number_of_awareness_attributes` = whole number

인덱스의 복제본 수를 변경하려면 설정을 바꾼 뒤 무중단 재인덱싱을 실행합니다.

대규모 인스턴스 효율적 인덱싱#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.
Warning

대규모 인스턴스를 인덱싱하면 Sidekiq job 이 많이 생성됩니다. 확장 가능한 구성을 갖추거나 추가 Sidekiq 프로세스를 만들어 이 작업에 대비합니다.

Geo 기본 노드와 보조 노드는 동일한 Elasticsearch 클러스터를 가리킵니다. 다만 Elasticsearch 인덱싱 워커는 기본 사이트의 Sidekiq 노드에서만 실행됩니다.

따라서 추가 Sidekiq 프로세스는 기본 사이트의 Sidekiq 노드에 구성해야 합니다.

인덱싱되는 데이터양이 많아 고급 검색 활성화가 문제를 일으키는 경우:

  1. Elasticsearch 호스트와 포트를 구성합니다.

  2. 빈 인덱스를 생성합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:create_empty_index
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:create_empty_index RAILS_ENV=production
    
  3. GitLab 인스턴스를 재인덱싱하는 경우에는 인덱스 상태를 초기화합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:clear_index_status
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:clear_index_status RAILS_ENV=production
    
  4. Turn on indexing for advanced search 체크박스를 선택합니다.

  5. 대규모 Git 리포지터리 인덱싱은 시간이 오래 걸릴 수 있습니다. 속도를 높이려면 인덱싱 속도를 위해 튜닝할 수 있습니다.

    • refresh_interval 값을 일시적으로 늘릴 수 있습니다.

    • 복제본 수를 0으로 설정할 수 있습니다. 이 설정은 인덱스의 각 주 샤드가 가지는 사본 수를 제어합니다. 따라서 복제본이 0 이면 노드 간 샤드 복제가 사실상 중단되어 인덱싱 성능이 올라갑니다. 신뢰성과 쿼리 성능 측면에서 중요한 트레이드오프이므로, 최초 인덱싱이 끝난 뒤에는 복제본 수를 적절한 값으로 되돌려야 합니다.

    인덱싱 시간은 20% 정도 줄어듭니다. 인덱싱이 끝나면 refresh_interval과 number_of_replicas를 원하는 값으로 되돌립니다.

    [!note] 이 단계는 선택 사항이지만 대규모 인덱싱 작업의 속도를 크게 높일 수 있습니다.

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "index" : {
               "refresh_interval" : "30s",
               "number_of_replicas" : 0
           } }'
    
  6. 프로젝트와 연관 데이터를 인덱싱합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:index_projects
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:index_projects RAILS_ENV=production
    

    이 명령은 인덱싱이 필요한 프로젝트마다 Sidekiq job을 큐에 넣습니다. 인덱싱 상태는 Rake 태스크로 조회할 수 있습니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:index_projects_status
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:index_projects_status RAILS_ENV=production
    
    Indexing is 65.55% complete (6555/10000 projects). Considers only code, commits, and wikis.
    

    인덱싱 대상을 특정 프로젝트 범위로 제한하려면 ID_FROM과 ID_TO 파라미터를 지정할 수 있습니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:index_projects ID_FROM=1001 ID_TO=2000
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:index_projects ID_FROM=1001 ID_TO=2000 RAILS_ENV=production
    

    여기서 ID_FROM과 ID_TO는 프로젝트 ID 이며, 두 파라미터 모두 선택 사항입니다. 앞의 예시는 ID 1001부터 ID 2000 까지(해당 ID 포함) 모든 프로젝트를 인덱싱합니다.

    [!note] gitlab:elastic:index_projects가 큐에 넣은 프로젝트 인덱싱 job 이 중단되는 경우가 있습니다. 원인은 여러 가지일 수 있지만, 인덱싱 태스크를 다시 실행하는 것은 언제나 안전합니다.

    gitlab:elastic:clear_index_status Rake 태스크로 인덱서가 모든 진행 상황을 "잊도록" 강제할 수도 있습니다. 그러면 인덱싱 과정을 처음부터 다시 시도합니다.

  7. 작업 항목, 그룹 위키, 개인 스니펫, 사용자는 프로젝트에 연결되지 않으므로 별도로 인덱싱해야 합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:index_work_items
    sudo gitlab-rake gitlab:elastic:index_group_wikis
    sudo gitlab-rake gitlab:elastic:index_snippets
    sudo gitlab-rake gitlab:elastic:index_users
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:index_work_items RAILS_ENV=production
    bundle exec rake gitlab:elastic:index_group_wikis RAILS_ENV=production
    bundle exec rake gitlab:elastic:index_snippets RAILS_ENV=production
    bundle exec rake gitlab:elastic:index_users RAILS_ENV=production
    
  8. 인덱싱이 끝나면 복제와 리프레시를 다시 활성화합니다(앞서 refresh_interval을 늘린 경우에만).

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "index" : {
               "number_of_replicas" : 1,
               "refresh_interval" : "1s"
           } }'
    

    리프레시를 활성화한 뒤에는 force merge를 호출해야 합니다.

    Elasticsearch 6.x 이상에서는 force merge를 진행하기 전에 인덱스가 읽기 전용 모드인지 확인합니다.

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "settings": {
             "index.blocks.write": true
           } }'
    

    그다음 force merge를 시작합니다.

    curl --request POST 'localhost:9200/gitlab-production/_forcemerge?max_num_segments=5'
    

    그다음 인덱스를 다시 읽기·쓰기 모드로 되돌립니다.

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "settings": {
             "index.blocks.write": false
           } }'
    
  9. 인덱싱이 끝나면 Search with advanced search 체크박스를 선택합니다.

전용 Sidekiq 노드 또는 프로세스로 대규모 인스턴스 인덱싱#

Warning

대부분의 인스턴스에서는 전용 Sidekiq 노드나 프로세스를 구성하지 않아도 됩니다. 다음 단계는 라우팅 규칙이라는 Sidekiq 고급 설정을 사용합니다. job 이 통째로 유실되지 않도록 라우팅 규칙 사용에 따른 영향을 충분히 이해해야 합니다.

대규모 인스턴스 인덱싱은 시간이 오래 걸리고 리소스를 많이 쓰는 작업이어서 Sidekiq 노드와 프로세스에 과부하를 줄 수 있습니다. 이는 GitLab의 성능과 가용성에 악영향을 줍니다.

GitLab은 여러 Sidekiq 프로세스를 실행할 수 있으므로, 특정 큐 집합(큐 그룹) 인덱싱을 전담하는 프로세스를 추가로 만들 수 있습니다. 이렇게 하면 인덱싱 큐에는 항상 전담 워커가 배정되고, 나머지 큐는 또 다른 전담 워커가 처리해 경합을 피할 수 있습니다.

이를 위해 워커 매칭 쿼리를 기준으로 Sidekiq 이 job을 특정 큐로 라우팅하도록 하는 라우팅 규칙 옵션을 사용합니다.

Note

라우팅 규칙(sidekiq['routing_rules'])은 모든 GitLab 노드(특히 GitLab Rails 노드와 Sidekiq 노드)에서 동일해야 합니다.

다음 두 가지 방법 중 하나를 선택할 수 있습니다.

다음 단계에서는 sidekiq['routing_rules'] 항목을 이렇게 가정합니다.

  • 모든 인덱싱 job을 global_search 큐로 보내는 ["feature_category=global_search", "global_search"].
  • 인덱싱 외 나머지 job을 모두 default 큐로 보내는 ["*", "default"].

sidekiq['queue_groups']의 프로세스 중 최소 하나에는 mailers 큐가 포함되어야 합니다. 그렇지 않으면 메일러 job 이 전혀 처리되지 않습니다.

Warning

여러 프로세스를 실행할 때 프로세스 수는 Sidekiq에 할당하려는 CPU 코어 수를 넘을 수 없습니다. Sidekiq 프로세스 하나는 사용 가능한 워크로드와 동시성 설정에 따라 CPU 코어를 하나만 사용할 수 있습니다. 자세한 내용은 여러 Sidekiq 프로세스 실행을 참고합니다.

단일 노드, 두 프로세스#

한 노드에 인덱싱용 Sidekiq 프로세스와 인덱싱 외 Sidekiq 프로세스를 모두 만들려면 다음과 같이 진행합니다.

  1. Sidekiq 노드에서 /etc/gitlab/gitlab.rb 파일을 다음과 같이 변경합니다.

    sidekiq['enable'] = true
    
    sidekiq['routing_rules'] = [
       ["feature_category=global_search", "global_search"],
       ["*", "default"],
    ]
    
    sidekiq['queue_groups'] = [
       "global_search", # process that listens to global_search queue
       "default,mailers" # process that listens to default and mailers queue
    ]
    
    sidekiq['concurrency'] = 20
    
  2. 파일을 저장하고 변경 사항을 적용하기 위해 GitLab을 재구성합니다.

  3. 다른 모든 Rails 노드와 Sidekiq 노드에서 sidekiq['routing_rules']가 위 구성과 동일한지 확인합니다.

  4. Rake 태스크를 실행해 기존 job을 마이그레이션합니다.

Note

GitLab을 재구성한 직후에 Rake 태스크를 실행해야 합니다. GitLab을 재구성한 뒤에는 Rake 태스크가 job 마이그레이션을 시작하기 전까지 기존 job 이 처리되지 않습니다.

두 노드, 각각 한 프로세스#

이 큐 그룹들을 두 노드에서 처리하려면 다음과 같이 진행합니다.

  1. 인덱싱용 Sidekiq 프로세스를 구성하려면 인덱싱용 Sidekiq 노드에서 /etc/gitlab/gitlab.rb 파일을 다음과 같이 변경합니다.

    sidekiq['enable'] = true
    
    sidekiq['routing_rules'] = [
       ["feature_category=global_search", "global_search"],
       ["*", "default"],
    ]
    
    sidekiq['queue_groups'] = [
      "global_search", # process that listens to global_search queue
    ]
    
    sidekiq['concurrency'] = 20
    
  2. 파일을 저장하고 변경 사항을 적용하기 위해 GitLab을 재구성합니다.

  3. 인덱싱 외 Sidekiq 프로세스를 구성하려면 인덱싱 외 Sidekiq 노드에서 /etc/gitlab/gitlab.rb 파일을 다음과 같이 변경합니다.

    sidekiq['enable'] = true
    
    sidekiq['routing_rules'] = [
       ["feature_category=global_search", "global_search"],
       ["*", "default"],
    ]
    
    sidekiq['queue_groups'] = [
       "default,mailers" # process that listens to default and mailers queue
    ]
    
    sidekiq['concurrency'] = 20
    
  4. 다른 모든 Rails 노드와 Sidekiq 노드에서 sidekiq['routing_rules']가 위 구성과 동일한지 확인합니다.

  5. 파일을 저장하고 변경 사항을 적용하기 위해 GitLab을 재구성합니다.

  6. Rake 태스크를 실행해 기존 job을 마이그레이션합니다.

    sudo gitlab-rake gitlab:sidekiq:migrate_jobs:retry gitlab:sidekiq:migrate_jobs:schedule gitlab:sidekiq:migrate_jobs:queued
    
Note

GitLab을 재구성한 직후에 Rake 태스크를 실행해야 합니다. GitLab을 재구성한 뒤에는 Rake 태스크가 job 마이그레이션을 시작하기 전까지 기존 job 이 처리되지 않습니다.

삭제된 문서#

인덱싱된 GitLab 객체가 변경되거나 삭제될 때마다, 예를 들어 머지 리퀘스트 설명이 변경되거나 리포지터리의 기본 브랜치에서 파일이 삭제되거나 프로젝트가 삭제될 때마다 인덱스의 문서가 삭제됩니다. 다만 이는 "소프트" 삭제이므로 전체 "삭제된 문서" 수가 늘어나고 그만큼 공간이 낭비됩니다.

Elasticsearch는 세그먼트를 지능적으로 병합해 이런 삭제된 문서를 제거합니다. 다만 GitLab 설치 환경의 활동량과 유형에 따라 인덱스에서 최대 50% 의 공간이 낭비될 수도 있습니다.

일반적으로는 기본 설정 그대로 Elasticsearch가 알아서 병합하고 공간을 회수하도록 두는 편이 좋습니다. Lucene's Handling of Deleted Documents에서는 "전반적으로, 최대 세그먼트 크기를 줄이는 정도를 제외하면 Lucene 기본값을 그대로 두고 삭제가 언제 회수되는지에 너무 신경 쓰지 않는 편이 가장 좋다" 고 설명합니다.

다만 규모가 큰 설치 환경에서는 병합 정책 설정을 조정하고 싶을 수 있습니다.

  • index.merge.policy.max_merged_segment 크기를 기본값 5GB에서 2GB 또는 3GB 정도로 줄이는 방안을 검토합니다. 병합은 세그먼트에 삭제가 50% 이상 쌓였을 때만 일어납니다. 세그먼트 크기가 작을수록 병합이 더 자주 일어납니다.

    curl --request PUT localhost:9200/gitlab-production/_settings ---header 'Content-Type: application/json' \
         --data '{
           "index" : {
             "merge.policy.max_merged_segment": "2gb"
           }
         }'
    
  • 삭제를 얼마나 적극적으로 처리할지 제어하는 index.merge.policy.reclaim_deletes_weight도 조정할 수 있습니다. 다만 병합 비용이 큰 결정으로 이어질 수 있으므로, 트레이드오프를 이해하지 못했다면 변경하지 않아야 합니다.

    curl --request PUT localhost:9200/gitlab-production/_settings ---header 'Content-Type: application/json' \
         --data '{
           "index" : {
             "merge.policy.reclaim_deletes_weight": "3.0"
           }
         }'
    
  • 삭제된 문서를 제거하려고 force merge를 실행하지 않아야 합니다. 문서의 경고에 따르면 영영 회수되지 않을 수 있는 아주 큰 세그먼트가 생기고, 성능이나 가용성에도 심각한 문제를 일으킬 수 있습니다.

기본 검색으로 되돌리기#

Elasticsearch 인덱스 데이터에 문제가 생길 수 있으므로, GitLab은 검색 결과가 없고 해당 스코프에서 기본 검색이 지원되는 경우 "기본 검색"으로 되돌릴 수 있게 합니다. 이 "기본 검색"은 인스턴스에 고급 검색이 아예 활성화되지 않은 것처럼 동작하며, 다른 데이터 소스(PostgreSQL 데이터, Git 데이터 등)를 사용해 검색합니다.

재해 복구#

Elasticsearch는 GitLab의 보조 데이터 저장소입니다. Elasticsearch에 저장된 모든 데이터는 다른 데이터 소스, 특히 PostgreSQL과 Gitaly에서 다시 만들어 낼 수 있습니다. Elasticsearch 데이터 저장소가 손상된 경우 전체를 처음부터 다시 인덱싱할 수 있습니다.

Elasticsearch 인덱스가 너무 크면 전체를 처음부터 다시 인덱싱하는 동안 다운타임이 지나치게 길어질 수 있습니다. Elasticsearch 인덱스의 불일치를 자동으로 찾아 재동기화할 수는 없지만, 로그에서 누락된 업데이트를 확인할 수 있습니다. 데이터를 더 빠르게 복구하려면 다음 작업을 다시 실행할 수 있습니다.

  1. elasticsearch.log에서 track_items를 검색해 동기화된 비 리포지터리 업데이트 전체를 찾습니다. 해당 항목은 ::Elastic::ProcessBookkeepingService.track!를 통해 다시 전송해야 합니다.
  2. elasticsearch.log에서 indexing_commit_range를 검색해 리포지터리 업데이트 전체를 찾습니다. IndexStatus#last_commit/last_wiki_commit을 로그에 있는 가장 오래된 from_sha로 설정한 다음, Search::Elastic::CommitIndexerWorker와 ElasticWikiIndexerWorker로 해당 프로젝트를 다시 인덱싱하도록 트리거합니다.
  3. sidekiq.log에서 ElasticDeleteProjectWorker를 검색해 프로젝트 삭제 전체를 찾습니다. ElasticDeleteProjectWorker를 다시 트리거해야 합니다.

전체를 처음부터 다시 인덱싱하지 않고 데이터 손실을 복구하는 데 걸리는 시간을 줄이려면 Elasticsearch 스냅숏을 정기적으로 만들 수도 있습니다.

Elasticsearch 고급 검색

GitLab v19.5
Tier: Premium, Ultimate
Offering: GitLab Self-Managed, GitLab Dedicated
원문 보기

요약

이 페이지에서는 고급 검색을 활성화하는 방법을 설명합니다. 고급 검색을 활성화하려면 다음 작업이 필요합니다. 고급 검색은 모든 프로젝트를 동일한 Elasticsearch 인덱스에 저장합니다. 이 용어집에서는 Elasticsearch와 관련된 용어를 정의합니다.

이 페이지에서는 고급 검색을 활성화하는 방법을 설명합니다. 활성화하면 고급 검색은 더 빠른 검색 응답 시간과 향상된 검색 기능을 제공합니다.

고급 검색을 활성화하려면 다음 작업이 필요합니다.

  1. Elasticsearch 또는 AWS OpenSearch 클러스터를 설치합니다.
  2. 고급 검색을 활성화합니다.
Note

고급 검색은 모든 프로젝트를 동일한 Elasticsearch 인덱스에 저장합니다. 다만 비공개 프로젝트는 접근 권한이 있는 사용자에게만 검색 결과에 표시됩니다.

Elasticsearch 용어집#

이 용어집에서는 Elasticsearch와 관련된 용어를 정의합니다.

  • Lucene: Java로 작성된 전문 검색 라이브러리입니다.
  • 니어 리얼 타임(NRT): 문서를 인덱싱한 시점부터 해당 문서를 검색할 수 있게 되는 시점까지의 짧은 지연을 의미합니다.
  • 클러스터: 모든 데이터를 보관하면서 인덱싱 및 검색 기능을 제공하기 위해 함께 동작하는 하나 이상의 노드 집합입니다.
  • 노드: 클러스터의 일부로 동작하는 단일 서버입니다.
  • 인덱스: 어느 정도 유사한 특성을 가진 문서의 집합입니다.
  • 문서: 인덱싱할 수 있는 정보의 기본 단위입니다.
  • 샤드: 인덱스를 나눈 독립적인 하위 단위로, 그 자체로 완전한 기능을 갖춥니다. 각 샤드는 실제로 하나의 Lucene 인덱스입니다.
  • 레플리카: 인덱스를 복제하는 장애 조치 메커니즘입니다.

Elasticsearch 또는 AWS OpenSearch 클러스터 설치#

Elasticsearch와 AWS OpenSearch는 Linux 패키지에 포함되어 있지 않습니다. 검색 클러스터를 직접 설치하거나 다음과 같은 클라우드 호스팅 서비스를 사용할 수 있습니다.

검색 클러스터는 별도의 서버에 설치해야 합니다. GitLab과 같은 서버에서 검색 클러스터를 실행하면 성능 문제가 발생할 수 있습니다.

노드가 하나인 검색 클러스터에서는 프라이머리 샤드만 할당되므로 클러스터 상태가 항상 yellow 입니다. 클러스터는 프라이머리 샤드와 같은 노드에 레플리카 샤드를 할당할 수 없습니다.

Note

새 Elasticsearch 클러스터를 프로덕션에서 사용하기 전에 중요 Elasticsearch 구성을 참고합니다.

버전 호환성#

Elasticsearch#

Warning

Elasticsearch 7.x 지원은 GitLab 18.10에서 더 이상 사용되지 않으며 20.0에서 제거될 예정입니다.

고급 검색은 다음 버전의 Elasticsearch와 호환됩니다.

GitLab 버전 Elasticsearch 버전
19.1 이상 8.x 및 9.x
15.0 ~ 19.0 7.x 및 8.x
14.0 ~ 14.10 6.8 ~ 7.x

GitLab.com은 Elasticsearch 9.x를 사용합니다. 성능과 최신 기능, 상위 호환성을 확보하려면 Elasticsearch 9.x를 사용합니다.

고급 검색은 Elasticsearch end-of-life 정책을 따릅니다.

OpenSearch#

고급 검색은 다음 버전의 OpenSearch와 호환됩니다.

GitLab 버전 OpenSearch 버전
18.1 이상 1.x 이상
17.6.3 ~ 18.0 1.x 및 2.x
15.5.3 ~ 17.6.2 1.x, 2.0 ~ 2.17
15.0 ~ 15.5.2 1.x

고급 검색은 OpenSearch 유지 보수 정책을 따릅니다.

시스템 요구 사항#

Elasticsearch와 AWS OpenSearch는 GitLab 설치 요구 사항보다 더 많은 리소스를 필요로 합니다.

메모리, CPU, 스토리지 요구 사항은 클러스터에 인덱싱하는 데이터 양에 따라 달라집니다. 사용량이 많은 Elasticsearch 클러스터에는 더 많은 리소스가 필요할 수 있습니다. estimate_cluster_size Rake 태스크는 전체 리포지터리 크기를 사용해 고급 검색에 필요한 스토리지 용량을 추정합니다.

접근 요구 사항#

GitLab은 요구 사항과 사용하는 백엔드 서비스에 따라 HTTP 인증 방식과 역할 기반 인증 방식을 모두 지원합니다.

Elasticsearch의 역할 기반 접근 제어#

Elasticsearch는 클러스터 보안을 강화하는 역할 기반 접근 제어를 제공합니다. Elasticsearch 클러스터에 접근해 작업을 수행하려면 Admin 영역에 구성된 Username에 다음 권한을 부여하는 역할이 있어야 합니다. Username은 GitLab에서 검색 클러스터로 요청을 보냅니다.

자세한 내용은 Elasticsearch 역할 기반 접근 제어와 Elasticsearch 보안 권한을 참고합니다.

{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": ["gitlab-*"],
      "privileges": [
        "create_index",
        "delete_index",
        "view_index_metadata",
        "read",
        "manage",
        "write"
      ]
    }
  ]
}

AWS OpenSearch Service 접근 제어#

사전 요구 사항:

  • OpenSearch 도메인을 생성할 때 AWS 계정에 AWSServiceRoleForAmazonOpenSearchService라는 이름의 서비스 연결 역할이 있어야 합니다.
  • AWS OpenSearch의 도메인 접근 정책이 es:ESHttp* 작업을 허용해야 합니다.

AWSServiceRoleForAmazonOpenSearchService는 모든 OpenSearch 도메인에서 사용됩니다. 대부분의 경우 AWS Management Console로 첫 번째 OpenSearch 도메인을 생성할 때 이 역할이 자동으로 생성됩니다. 서비스 연결 역할을 직접 생성하려면 AWS 문서를 참고합니다.

AWS OpenSearch Service에는 세 가지 주요 보안 계층이 있습니다.

네트워크#

이 보안 계층에서는 도메인을 생성할 때 Public access를 선택해 모든 클라이언트의 요청이 도메인 엔드포인트에 도달하도록 할 수 있습니다. VPC access를 선택하면 요청이 엔드포인트에 도달하도록 클라이언트가 VPC에 연결되어 있어야 합니다.

자세한 내용은 AWS 문서를 참고합니다.

도메인 접근 정책#

GitLab은 AWS OpenSearch에 대해 다음과 같은 도메인 접근 제어 방식을 지원합니다.

리소스 기반 정책 예시

다음은 es:ESHttp* 작업을 허용하는 리소스 기반(도메인) 접근 정책의 예시입니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "es:ESHttp*"
      ],
      "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*"
    }
  ]
}

다음은 특정 IAM 주체에 대해서만 es:ESHttp* 작업을 허용하는 리소스 기반(도메인) 접근 정책의 예시입니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:user/test-user"
        ]
      },
      "Action": [
        "es:ESHttp*"
      ],
      "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*"
    }
  ]
}
Note

계정 간에 AWS AssumeRole을 사용하는 경우 aws_role_arn을 지정해야 합니다. ARN은 OpenSearch에 접근할 권한이 있는 역할이어야 합니다.

ID 기반 정책 예시

다음은 es:ESHttp* 작업을 허용하도록 IAM 주체에 연결한 ID 기반 접근 정책의 예시입니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "es:ESHttp*",
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
세분화된 접근 제어#

세분화된 접근 제어를 활성화하면 다음 중 한 가지 방법으로 마스터 사용자를 설정해야 합니다.

IAM ARN을 마스터 사용자로 설정

IAM 주체를 마스터 사용자로 사용하는 경우 클러스터로 보내는 모든 요청은 AWS Signature Version 4로 서명해야 합니다. EC2 인스턴스에 할당한 IAM 역할의 IAM ARN을 지정할 수도 있습니다. 자세한 내용은 AWS 문서를 참고합니다.

사전 요구 사항:

  • 관리자 접근 권한이 있어야 합니다.

IAM ARN을 마스터 사용자로 설정하려면 GitLab 인스턴스에서 IAM 자격 증명으로 AWS OpenSearch Service를 사용해야 합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.

  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.

  3. Advanced search를 확장합니다.

  4. AWS OpenSearch IAM credentials 섹션에서 다음을 수행합니다.

    1. Use AWS OpenSearch Service with IAM credentials 체크박스를 선택합니다.

    2. AWS region에 OpenSearch 도메인이 위치한 AWS 리전을 입력합니다(예: us-east-1).

    3. AWS access key와 AWS secret access key에 인증에 사용할 액세스 키를 입력합니다.

      [!note] 컨테이너가 아니라 EC2 인스턴스에서 직접 실행되는 GitLab 배포는 액세스 키를 입력하지 않아도 됩니다. GitLab 인스턴스가 이 키를 AWS Instance Metadata Service (IMDS)에서 자동으로 가져옵니다.

  5. Save changes를 선택합니다.

마스터 사용자 생성

내부 사용자 데이터베이스에 마스터 사용자를 생성하면 HTTP 기본 인증으로 클러스터에 요청을 보낼 수 있습니다. 자세한 내용은 AWS 문서를 참고합니다.

사전 요구 사항:

  • 관리자 접근 권한이 있어야 합니다.

마스터 사용자를 생성하려면 GitLab 인스턴스에서 OpenSearch 도메인 URL과 마스터 사용자 이름 및 비밀번호를 구성해야 합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 확장합니다.
  4. OpenSearch domain URL에 OpenSearch 도메인 엔드포인트의 URL을 입력합니다.
  5. Username에 마스터 사용자 이름을 입력합니다.
  6. Password에 마스터 비밀번호를 입력합니다.
  7. Save changes를 선택합니다.

새 Elasticsearch 버전으로 업그레이드#

사전 요구 사항:

Elasticsearch를 새 마이너 버전이나 메이저 버전으로 업그레이드할 때는 GitLab 구성을 변경하지 않아도 됩니다. Elasticsearch 클러스터 업그레이드가 완료되어 동작 중이면 다음을 수행합니다.

  1. 클러스터 연결, 인덱스, 검색 동작을 검증합니다.

    sudo gitlab-rake gitlab:elastic:index_and_search_validation
    
  2. 인덱싱을 재개합니다.

  3. 선택 사항. 인덱싱 상태를 확인합니다. 검색 결과를 정확하게 얻으려면, 특히 Elasticsearch 인스턴스가 한동안 오프라인이었던 경우 인덱싱이 완료되었는지 확인합니다.

  4. 고급 검색으로 검색하기를 활성화합니다.

Elasticsearch 리포지터리 인덱서#

GitLab은 Git 리포지터리 데이터를 인덱싱하는 데 gitlab-elasticsearch-indexer를 사용합니다. 자체 컴파일 설치의 경우 인덱서 설치를 참고합니다.

인덱서 설치#

먼저 의존성을 설치한 다음 인덱서를 빌드하고 설치합니다.

의존성 설치#

이 프로젝트는 텍스트 인코딩에 International Components for Unicode(ICU)를 사용하므로 make를 실행하기 전에 사용하는 플랫폼의 개발 패키지가 설치되어 있는지 확인합니다.

Debian / Ubuntu#

Debian 또는 Ubuntu에 설치하려면 다음을 실행합니다.

sudo apt install libicu-dev
CentOS / RHEL#

CentOS 또는 RHEL에 설치하려면 다음을 실행합니다.

sudo yum install libicu-devel
macOS#
Note

먼저 Homebrew를 설치해야 합니다.

macOS에 설치하려면 다음을 실행합니다.

brew install icu4c
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:$PKG_CONFIG_PATH"

빌드 및 설치#

인덱서를 빌드하고 설치하려면 다음을 실행합니다.

indexer_path=/home/git/gitlab-elasticsearch-indexer

# Run the installation task for gitlab-elasticsearch-indexer:
sudo -u git -H bundle exec rake gitlab:indexer:install[$indexer_path] RAILS_ENV=production
cd $indexer_path && sudo make install

gitlab-elasticsearch-indexer는 /usr/local/bin에 설치됩니다.

PREFIX 환경 변수로 설치 경로를 변경할 수 있습니다. 변경하는 경우 sudo에 -E 플래그를 함께 전달합니다.

예시:

PREFIX=/usr sudo -E make install

설치를 마친 다음에는 Elasticsearch를 활성화합니다.

Note

인덱싱 중에 Permission denied - /home/git/gitlab-elasticsearch-indexer/와 같은 오류가 나타나면 gitlab.yml 파일의 production -> elasticsearch -> indexer_path 설정을 바이너리가 설치된 위치인 /usr/local/bin/gitlab-elasticsearch-indexer로 지정해야 할 수 있습니다.

인덱싱 오류 확인#

GitLab Elasticsearch Indexer에서 발생한 오류는 elasticsearch.log 파일과 sidekiq.log 파일에 json.exception.class가 Gitlab::Elastic::Indexer::Error 인 항목으로 기록됩니다. 이러한 오류는 Git 리포지터리 데이터를 인덱싱할 때 발생할 수 있습니다.

고급 검색 활성화#

사전 요구 사항:

고급 검색을 활성화하려면 다음을 수행합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Elasticsearch 클러스터에 맞게 고급 검색 설정을 구성합니다. 이 단계에서는 아직 Search with advanced search 체크박스를 선택하지 않습니다.
  4. 인스턴스를 인덱싱합니다.
  5. 선택 사항. 인덱싱 상태를 확인합니다.
  6. 인덱싱이 완료되면 Search with advanced search 체크박스를 선택한 다음 Save changes를 선택합니다.
Note

Elasticsearch가 활성화된 상태에서 Elasticsearch 클러스터가 중단되면 인스턴스가 변경 사항을 인덱싱할 job을 큐에 넣고도 유효한 Elasticsearch 클러스터를 찾지 못하므로 이슈와 같은 문서를 업데이트하는 데 문제가 발생할 수 있습니다.

리포지터리 데이터가 50 GB를 넘는 GitLab 인스턴스는 대규모 인스턴스를 효율적으로 인덱싱을 참고합니다.

인스턴스 인덱싱#

사용자 인터페이스에서 인덱싱#

히스토리

사전 요구 사항:

  • 인스턴스에 대한 관리자 접근 권한이 있어야 합니다.

사용자 인터페이스에서 최초 인덱싱을 수행하거나 인덱스를 다시 생성할 수 있습니다.

사용자 인터페이스에서 고급 검색을 활성화하고 인스턴스를 인덱싱하려면 다음을 수행합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Turn on indexing for advanced search 체크박스를 선택한 다음 Save changes를 선택합니다.
  4. Index the instance를 선택합니다.

Rake 태스크로 인덱싱#

사전 요구 사항:

  • 인스턴스에 대한 관리자 접근 권한이 있어야 합니다.

인스턴스 전체를 인덱싱하려면 다음 Rake 태스크를 사용합니다.

# WARNING: This task deletes all existing indices
# For installations that use the Linux package
sudo gitlab-rake gitlab:elastic:index

# WARNING: This task deletes all existing indices
# For self-compiled installations
bundle exec rake gitlab:elastic:index RAILS_ENV=production

특정 데이터를 인덱싱하려면 다음 Rake 태스크를 사용합니다.

# For installations that use the Linux package
sudo gitlab-rake gitlab:elastic:index_work_items
sudo gitlab-rake gitlab:elastic:index_group_wikis
sudo gitlab-rake gitlab:elastic:index_namespaces
sudo gitlab-rake gitlab:elastic:index_projects
sudo gitlab-rake gitlab:elastic:index_snippets
sudo gitlab-rake gitlab:elastic:index_users

# For self-compiled installations
bundle exec rake gitlab:elastic:index_work_items RAILS_ENV=production
bundle exec rake gitlab:elastic:index_group_wikis RAILS_ENV=production
bundle exec rake gitlab:elastic:index_namespaces RAILS_ENV=production
bundle exec rake gitlab:elastic:index_projects RAILS_ENV=production
bundle exec rake gitlab:elastic:index_snippets RAILS_ENV=production
bundle exec rake gitlab:elastic:index_users RAILS_ENV=production

인덱싱 상태 확인#

사전 요구 사항:

  • 인스턴스에 대한 관리자 접근 권한이 있어야 합니다.

인덱싱 상태를 확인하려면 다음을 수행합니다.

  1. 오른쪽 상단에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search indexing status를 확장합니다.

백그라운드 job 상태 모니터링#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

인덱싱 진행 상황을 모니터링하려면 백그라운드 job의 상태를 확인할 수도 있습니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Monitoring > Background jobs를 선택합니다.
  3. Sidekiq 대시보드에서 Busy를 선택하고 다음 인덱싱 job을 확인합니다.
    • 코드와 커밋은 Search::Elastic::CommitIndexerWorker 입니다.
    • 위키 데이터는 ElasticWikiIndexerWorker 입니다.

고급 검색으로 검색 사용 설정#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색으로 검색을 사용 설정하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Search with advanced search 체크박스를 선택합니다.
  4. Save changes를 선택합니다.

고급 검색으로 코드 검색 사용 설정#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색으로 코드 검색을 사용 설정하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Code search with advanced search 체크박스를 선택합니다.
  4. Save changes를 선택합니다.

고급 검색 구성#

다음 Elasticsearch 설정을 사용할 수 있습니다.

매개변수 설명
Turn on indexing for advanced search 인덱싱을 켜거나 끄고, 인덱스가 아직 없으면 빈 인덱스를 생성합니다. 예를 들어 인덱스가 완전히 완성될 시간을 확보하기 위해 인덱싱은 켜고 검색은 꺼 둘 수 있습니다. 또한 이 옵션은 기존 데이터에 영향을 주지 않습니다. 데이터 변경을 추적하고 새 데이터가 인덱싱되도록 하는 백그라운드 인덱서만 활성화하거나 비활성화합니다.
Pause indexing for advanced search 고급 검색 인덱싱을 일시 중지합니다. 클러스터 마이그레이션이나 재인덱싱에 유용합니다. 모든 변경 사항은 계속 추적되지만, 재개하기 전까지는 인덱스에 커밋되지 않습니다.
Search with advanced search 검색과 고급 취약점 관리에서 고급 검색 기능을 켜거나 끕니다.
Code search with advanced search 고급 검색을 사용한 코드 검색을 켜거나 끕니다. 이 설정을 끄면 Elasticsearch 인스턴스에서 모든 코드가 삭제됩니다. 이 설정을 다시 켜려면 코드를 전체 재인덱싱해야 합니다. 정확한 코드 검색이 활성화되어 있다면 리소스를 절약하기 위해 이 설정을 꺼야 합니다.
Requeue indexing workers 인덱싱 워커의 자동 재큐잉을 켭니다. 모든 문서가 처리될 때까지 Sidekiq job을 큐에 넣어 코드 외 인덱싱 처리량을 개선합니다. 소규모 인스턴스나 Sidekiq 프로세스가 적은 인스턴스에는 인덱싱 워커 재큐잉을 권장하지 않습니다.
URL Elasticsearch 인스턴스의 URL 입니다. 클러스터링을 지원하려면 쉼표로 구분한 목록을 사용합니다(예: http://host1, https://host2:9200). Elasticsearch 인스턴스가 암호로 보호되어 있으면 Username과 Password 필드를 사용합니다. 또는 http://<username>:<password>@<elastic_host>:9200/와 같이 인라인 자격 증명을 사용합니다. OpenSearch를 사용하는 경우 80과 443 포트를 통한 연결만 허용됩니다.
Username Elasticsearch 인스턴스의 username 입니다.
Password Elasticsearch 인스턴스의 암호입니다.
Number of Elasticsearch shards and replicas per index Elasticsearch 인덱스는 성능상의 이유로 여러 샤드로 분할됩니다. 일반적으로 최소 5개의 샤드를 사용해야 합니다. 문서가 수천만 건인 인덱스에는 더 많은 샤드가 필요합니다(안내 참고). 이 값을 변경해도 인덱스를 다시 생성하기 전까지는 적용되지 않습니다. 확장성과 복원력에 대한 자세한 내용은 Elasticsearch 문서를 참고합니다. 각 Elasticsearch 샤드는 여러 개의 복제본을 가질 수 있습니다. 이 복제본은 샤드의 완전한 사본이며 쿼리 성능을 높이거나 하드웨어 장애에 대한 복원력을 제공합니다. 이 값을 늘리면 인덱스에 필요한 전체 디스크 공간도 늘어납니다. 각 인덱스마다 샤드와 복제본 수를 설정할 수 있습니다.
Limit the amount of namespace and project data to index 이 설정을 활성화하면 인덱싱할 네임스페이스와 프로젝트를 지정할 수 있습니다. 나머지 네임스페이스와 프로젝트는 데이터베이스 검색을 사용합니다. 이 설정을 활성화하고도 네임스페이스나 프로젝트를 지정하지 않으면 프로젝트 레코드만 인덱싱됩니다. 자세한 내용은 인덱싱할 네임스페이스 및 프로젝트 데이터 양 제한을 참고합니다.
Use AWS OpenSearch Service with IAM credentials AWS IAM 인증, AWS EC2 인스턴스 프로파일 자격 증명, AWS ECS 태스크 자격 증명 중 하나로 OpenSearch 요청에 서명합니다. AWS 호스팅 OpenSearch 도메인 액세스 정책 구성에 대한 자세한 내용은 Amazon OpenSearch Service의 자격 증명 및 액세스 관리를 참고합니다.
AWS Region OpenSearch Service가 위치한 AWS 리전입니다.
AWS Access Key AWS 액세스 키입니다.
AWS Secret Access Key AWS 시크릿 액세스 키입니다.
Maximum file size indexed 인스턴스 제한의 설명을 참고합니다.
Maximum field length 인스턴스 제한의 설명을 참고합니다.
Indexing timeout (minutes) 프로젝트당 인덱싱 타임아웃(분)입니다.
Number of shards for non-code indexing 인덱싱 워커 샤드 수입니다. 병렬 Sidekiq job을 더 많이 큐에 넣어 코드 외 인덱싱 처리량을 개선합니다. 소규모 인스턴스나 Sidekiq 프로세스가 적은 인스턴스에는 샤드 수를 늘리지 않는 편이 좋습니다. 기본값은 2 입니다.
Maximum bulk request size (MiB) GitLab의 Ruby 및 Go 기반 인덱서 프로세스가 사용합니다. 이 설정은 Elasticsearch Bulk API에 페이로드를 제출하기 전에 특정 인덱싱 프로세스에서 얼마나 많은 데이터를 수집(및 메모리에 저장)해야 하는지를 나타냅니다. GitLab Go 기반 인덱서에서는 이 설정을 Bulk request concurrency와 함께 사용해야 합니다. **Maximum bulk request size (MiB)**는 Elasticsearch 호스트와, gitlab-rake 명령 또는 Sidekiq 작업으로 GitLab Go 기반 인덱서를 실행하는 호스트 양쪽의 리소스 제약을 모두 수용해야 합니다.
Bulk request concurrency Bulk request concurrency는 Elasticsearch Bulk API에 제출할 데이터를 수집하기 위해 GitLab Go 기반 인덱서 프로세스(또는 스레드)를 몇 개까지 병렬로 실행할 수 있는지를 나타냅니다. 이 값을 늘리면 인덱싱 성능은 향상되지만 Elasticsearch 벌크 요청 큐가 더 빨리 채워집니다. 이 설정은 Maximum bulk request size (MiB) 설정과 함께 사용해야 하며, Elasticsearch 호스트와 gitlab-rake 명령 또는 Sidekiq 작업으로 GitLab Go 기반 인덱서를 실행하는 호스트 양쪽의 리소스 제약을 수용해야 합니다.
Client request timeout Elasticsearch HTTP 클라이언트 요청 타임아웃 값(초)입니다. 값이 0 이면 기본 타임아웃인 30초를 사용합니다. 이 한도를 초과하는 검색 요청은 애플리케이션 서버가 요청을 종료한 뒤 500으로 실패하는 대신 HTTP 408을 반환합니다. Elasticsearch 쿼리가 평소 30초 이상 걸린다면 더 큰 값을 설정합니다. 애플리케이션 서버는 60초에 요청을 종료하므로 60보다 큰 값은 설정하지 않습니다. 타임아웃을 더 길게 두려면 30과 55 사이의 값을 설정해야 합니다.
Code indexing concurrency 동시에 실행할 수 있는 Elasticsearch 코드 인덱싱 백그라운드 job의 최대 개수입니다. 리포지터리 인덱싱 작업에만 적용됩니다.
Retry on failure Elasticsearch 검색 요청의 최대 재시도 횟수입니다. GitLab 17.6에서 도입되었습니다.
Index prefix Elasticsearch 인덱스 이름에 사용할 사용자 지정 접두사입니다. 기본값은 gitlab 입니다. 이 값을 변경하면 모든 인덱스가 gitlab 대신 이 접두사를 사용합니다(예: gitlab-production-issues 대신 custom-production-issues). 1~100자여야 하고 소문자 영숫자, 하이픈, 밑줄만 포함할 수 있으며 하이픈이나 밑줄로 시작하거나 끝날 수 없습니다. GitLab 18.2에서 도입되었습니다.
Warning

**Maximum bulk request size (MiB)**와 Bulk request concurrency의 값을 늘리면 Sidekiq 성능에 부정적인 영향을 줄 수 있습니다. Sidekiq 로그에서 scheduling_latency_s 값이 늘어나면 두 값을 기본값으로 되돌립니다. 자세한 내용은 이슈 322147을 참고합니다.

인덱싱할 네임스페이스 및 프로젝트 데이터 양 제한#

히스토리
  • 취약점 레코드 인덱싱이 vulnerability_es_ingestion이라는 기능 플래그와 함께 GitLab 18.1의 GitLab.com 및 GitLab Dedicated에 도입되었습니다. 기본적으로 비활성화되어 있습니다.
  • 취약점 레코드 인덱싱이 GitLab 18.2의 GitLab.com 및 GitLab Dedicated에서 일반 공급되었습니다. 기능 플래그 vulnerability_es_ingestion은 제거되었습니다.
Feature flag

이 기능의 사용 가능 여부는 기능 플래그로 제어됩니다. 자세한 내용은 히스토리를 참고합니다.

Limit the amount of namespace and project data to index 체크박스를 선택하면 인덱싱할 네임스페이스와 프로젝트를 지정할 수 있습니다. 네임스페이스가 그룹이면 하위 그룹과 해당 하위 그룹의 프로젝트도 함께 인덱싱됩니다.

이 설정을 활성화하면 다음과 같이 동작합니다.

  • 전체 인덱싱을 하려면 네임스페이스나 프로젝트를 지정해야 합니다.
  • 프로젝트 레코드(프로젝트 이름과 설명 같은 메타데이터)는 항상 모든 프로젝트에 대해 인덱싱됩니다.
  • 취약점 레코드는 보안 리포트의 필터링을 지원하기 위해 항상 모든 프로젝트와 네임스페이스에 대해 인덱싱됩니다.
  • 연관 데이터는 지정한 네임스페이스와 프로젝트에 대해서만 인덱싱됩니다.
Warning

이 설정을 활성화한 뒤 네임스페이스나 프로젝트를 지정하지 않으면 프로젝트 레코드만 인덱싱되며 연관 데이터는 검색할 수 없습니다.

인덱싱된 네임스페이스#

히스토리
  • 제한된 인덱싱에 대한 전역 검색이 advanced_global_search_for_limited_indexing이라는 기능 플래그와 함께 GitLab 13.4에 도입되었습니다. 기본적으로 비활성화되어 있습니다.
  • GitLab 14.2에서 GitLab.com에 활성화되었습니다.
  • 제한된 인덱싱에 대한 전역 검색이 GitLab 17.11에서 advanced_global_search_for_limited_indexing 플래그 대신 UI 옵션으로 일반 공급되었습니다.

모든 네임스페이스를 인덱싱하면 전역 코드 검색과 커밋 검색에 고급 검색을 사용할 수 있습니다. 일부 네임스페이스만 인덱싱하면 다음과 같습니다.

  • 전역 검색에는 코드 또는 커밋 검색 범위가 포함되지 않습니다.
  • 코드 및 커밋 검색은 인덱싱된 네임스페이스 하나에서만 사용할 수 있습니다.
  • 인덱싱된 여러 네임스페이스를 아우르는 단일 코드 또는 커밋 검색은 불가능합니다.
  • 인덱싱된 네임스페이스 안에서는 프로젝트 간 검색을 사용할 수 있습니다.

예를 들어 서로 다른 두 그룹을 인덱싱했다면 각 그룹에서 코드 검색을 따로 실행해야 합니다.

제한된 인덱싱에 대한 전역 검색을 사용 설정하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 펼칩니다
  4. Enable global search for limited indexing를 선택합니다.
  5. Save changes를 선택합니다.
  6. 인스턴스를 이미 인덱싱했다면 인스턴스를 재인덱싱해야 합니다. 이때 기존 검색 데이터가 삭제되며, 필터링이 올바르게 동작하게 됩니다.

사용자 지정 언어 분석기 사용 설정#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

Elastic의 smartcn 및 kuromoji 분석 플러그인을 사용하면 중국어와 일본어 지원을 개선할 수 있습니다.

사용자 지정 언어 분석기를 사용 설정하려면 다음 단계를 따릅니다.

  1. 필요한 플러그인을 설치합니다. 플러그인 설치 방법은 Elasticsearch 문서를 참고합니다. 플러그인은 클러스터의 모든 노드에 설치해야 하며, 설치 후 각 노드를 재시작해야 합니다. 플러그인 목록은 이 절 뒤의 표를 참고합니다.
  2. 오른쪽 위 모서리에서 Admin을 선택합니다.
  3. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  4. Custom analyzers: language support를 찾습니다.
  5. Indexing에 대한 플러그인 지원을 활성화합니다.
  6. 변경 사항을 적용하려면 Save changes를 선택합니다.
  7. 무중단 재인덱싱을 트리거하거나 전체를 처음부터 재인덱싱하여 갱신된 매핑으로 새 인덱스를 생성합니다.
  8. 이전 단계가 완료된 후 Searching에 대한 플러그인 지원을 활성화합니다.

무엇을 설치할지에 대한 안내는 다음 Elasticsearch 언어 플러그인 옵션을 참고합니다.

매개변수 설명
Enable Chinese (smartcn) custom analyzer: Indexing 새로 생성되는 인덱스에 smartcn 사용자 지정 분석기를 사용해 중국어 지원을 활성화하거나 비활성화합니다.
Enable Chinese (smartcn) custom analyzer: Search 고급 검색에 smartcn 필드를 사용할지 여부를 활성화하거나 비활성화합니다. 플러그인을 설치하고 사용자 지정 분석기 인덱싱을 활성화한 뒤 인덱스를 다시 생성한 다음에만 활성화합니다.
Enable Japanese (kuromoji) custom analyzer: Indexing 새로 생성되는 인덱스에 kuromoji 사용자 지정 분석기를 사용해 일본어 지원을 활성화하거나 비활성화합니다.
Enable Japanese (kuromoji) custom analyzer: Search 고급 검색에 kuromoji 필드를 사용할지 여부를 활성화하거나 비활성화합니다. 플러그인을 설치하고 사용자 지정 분석기 인덱싱을 활성화한 뒤 인덱스를 다시 생성한 다음에만 활성화합니다.

고급 검색 비활성화#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색을 비활성화하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.

  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.

  3. Turn on indexing for advanced search와 Search with advanced search 체크박스를 지웁니다.

  4. Save changes를 선택합니다.

  5. 선택 사항. 아직 온라인 상태인 Elasticsearch 인스턴스에서는 기존 인덱스를 삭제합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:delete_index
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:delete_index RAILS_ENV=production
    

고급 검색으로 검색 비활성화#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색으로 검색을 비활성화하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Search with advanced search 체크박스를 지웁니다.
  4. Save changes를 선택합니다.

고급 검색으로 코드 검색 비활성화#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

GitLab에서 고급 검색으로 코드 검색을 비활성화하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Code search with advanced search 체크박스를 지웁니다.
  4. Save changes를 선택합니다.

인덱싱 일시 중지#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

인덱싱을 일시 중지하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 펼칩니다.
  4. Pause indexing for advanced search 체크박스를 선택합니다.
  5. Save changes를 선택합니다.

인덱싱 재개#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

인덱싱을 재개하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 펼칩니다.
  4. Pause indexing for advanced search 체크박스를 지웁니다.
  5. Save changes를 선택합니다.

무중단 재인덱싱#

이 재인덱싱 방식은 Elasticsearch reindex API 와 Elasticsearch 인덱스 별칭 기능을 사용해 작업을 수행합니다. 인덱스 별칭은 GitLab 이 읽기와 쓰기에 사용하는 primary 인덱스에 연결됩니다. 재인덱싱 프로세스가 시작되면 primary 인덱스에 대한 쓰기가 일시적으로 중지됩니다. 그런 다음 다른 인덱스가 생성되고 Reindex API가 호출되어 인덱스 데이터를 새 인덱스로 마이그레이션합니다. 재인덱싱 job 이 완료되면 인덱스 별칭이 새 인덱스로 전환되고, 그 인덱스가 새 primary 인덱스가 됩니다. 마지막으로 쓰기가 재개되고 평상시 동작이 이어집니다.

무중단 재인덱싱 사용#

새 인덱스를 만들어 기존 데이터를 복사하지 않고는 변경할 수 없는 인덱스 설정이나 매핑을 구성할 때 무중단 재인덱싱을 사용할 수 있습니다. 누락된 데이터를 복구하는 용도로는 무중단 재인덱싱을 사용하지 않아야 합니다. 무중단 재인덱싱은 아직 인덱싱되지 않은 데이터를 검색 클러스터에 추가하지 않습니다. 재인덱싱을 시작하기 전에 모든 고급 검색 마이그레이션을 완료해야 합니다.

재인덱싱 트리거#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

재인덱싱을 트리거하려면 다음 단계를 따릅니다.

  1. 관리자로 GitLab 인스턴스에 로그인합니다.
  2. 오른쪽 위 모서리에서 Admin을 선택합니다.
  3. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  4. Advanced search zero-downtime reindexing을 펼칩니다.
  5. Trigger cluster reindexing을 선택합니다.

재인덱싱은 Elasticsearch 클러스터 크기에 따라 오래 걸릴 수 있습니다.

이 프로세스가 완료되면 원래 인덱스는 14일 후 삭제되도록 예약됩니다. 재인덱싱 프로세스를 트리거한 같은 페이지에서 Cancel 버튼을 눌러 이 동작을 취소할 수 있습니다.

재인덱싱이 실행되는 동안 같은 절에서 진행 상황을 확인할 수 있습니다.

무중단 재인덱싱 트리거#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

무중단 재인덱싱을 트리거하려면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.

  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.

  3. Advanced search zero-downtime reindexing을 펼칩니다. 다음 설정을 사용할 수 있습니다.

슬라이스 배수#

슬라이스 배수는 재인덱싱 중 슬라이스 수를 계산합니다.

GitLab은 재인덱싱을 효율적이고 안전하게 제어하기 위해 수동 슬라이싱을 사용하며, 이를 통해 사용자는 실패한 슬라이스만 재시도할 수 있습니다.

배수의 기본값은 2 이며 인덱스당 샤드 수에 적용됩니다. 예를 들어 이 값이 2 이고 인덱스에 샤드가 20개 있으면 재인덱싱 작업은 40개의 슬라이스로 나뉩니다.

최대 실행 슬라이스 수#

최대 실행 슬라이스 수 매개변수의 기본값은 60 이며, Elasticsearch 재인덱싱 중 동시에 실행할 수 있는 슬라이스의 최대 개수를 의미합니다.

이 값을 너무 높게 설정하면 클러스터가 검색과 쓰기로 크게 포화되어 성능에 악영향을 줄 수 있습니다. 이 값을 너무 낮게 설정하면 재인덱싱 프로세스가 완료되기까지 매우 오래 걸릴 수 있습니다.

적절한 값은 클러스터 크기, 재인덱싱 중 검색 성능 저하를 어느 정도 감수할 수 있는지, 그리고 재인덱싱을 빨리 끝내고 인덱싱을 재개하는 것이 얼마나 중요한지에 따라 달라집니다.

가장 최근 재인덱싱 job을 실패로 표시하고 인덱싱 재개#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.

완료되지 않은 재인덱싱 job을 중단하고 인덱싱을 재개하려면 다음 단계를 따릅니다.

  1. 가장 최근 재인덱싱 job을 실패로 표시합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:mark_reindex_failed
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:mark_reindex_failed RAILS_ENV=production
    
  2. 오른쪽 위 모서리에서 Admin을 선택합니다.

  3. 왼쪽 사이드바에서 Settings > Search를 선택합니다.

  4. Advanced search를 펼칩니다.

  5. Pause indexing for advanced search 체크박스를 지웁니다.

인덱스 무결성#

인덱스 무결성은 누락된 리포지터리 데이터를 감지하고 복구합니다. 이 기능은 그룹이나 프로젝트로 범위를 지정한 코드 검색이 결과를 반환하지 않을 때 자동으로 사용됩니다.

고급 검색 마이그레이션#

재인덱싱 마이그레이션은 백그라운드에서 실행되므로 인스턴스를 수동으로 재인덱싱할 필요가 없습니다.

GitLab 18.0 이상에서는 elastic_migration_worker_enabled 애플리케이션 설정으로 마이그레이션 워커를 활성화하거나 비활성화할 수 있습니다. 기본적으로 마이그레이션 워커는 활성화되어 있습니다.

마이그레이션 딕셔너리 파일#

모든 마이그레이션에는 ee/elastic/docs/ 폴더에 다음 정보를 담은 딕셔너리 파일이 있습니다.

name:
version:
description:
group:
milestone:
introduced_by_url:
obsolete:
marked_obsolete_by_url:
marked_obsolete_in_milestone:

예를 들어 이 정보를 사용해 마이그레이션이 언제 도입되었는지, 또는 언제 사용 중단으로 표시되었는지 확인할 수 있습니다.

대기 중인 마이그레이션 확인#

대기 중인 고급 검색 마이그레이션을 확인하려면 다음 명령을 실행합니다.

curl "$CLUSTER_URL/gitlab-production-migrations/_search?size=100&q=*" | jq .

다음과 비슷한 결과가 반환됩니다.

{
  "took": 14,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "gitlab-production-migrations",
        "_type": "_doc",
        "_id": "20230209195404",
        "_score": 1,
        "_source": {
          "completed": true
        }
      }
    ]
  }
}

마이그레이션 문제를 디버깅하려면 elasticsearch.log 파일을 확인합니다.

중단된 마이그레이션 재시도#

일부 마이그레이션에는 재시도 한도가 있습니다. 재시도 한도 안에 마이그레이션을 끝내지 못하면 마이그레이션이 중단되고 고급 검색 통합 설정에 알림이 표시됩니다.

마이그레이션이 중단된 원인을 디버깅하고 재시도 전에 필요한 변경을 적용하려면 elasticsearch.log 파일을 확인하는 것이 좋습니다.

실패 원인을 해결했다고 판단되면 다음 단계를 따릅니다.

  1. 오른쪽 위 모서리에서 Admin을 선택합니다.
  2. 왼쪽 사이드바에서 Settings > Search를 선택합니다.
  3. Advanced search를 펼칩니다.
  4. Advanced search migration halted 알림 상자 안에서 Retry migration을 선택합니다. 마이그레이션이 백그라운드에서 재시도되도록 예약됩니다.

마이그레이션을 성공시킬 수 없다면 마지막 수단으로 인덱스를 처음부터 다시 만드는 방법을 고려할 수 있습니다. 새로 만든 인덱스는 올바른 최신 스키마로 다시 생성되어 모든 마이그레이션을 건너뛰므로, 이렇게 하면 문제를 우회할 수 있습니다.

메이저 업그레이드 전에 모든 마이그레이션을 완료해야 합니다#

GitLab 메이저 버전으로 업그레이드하기 전에, 해당 메이저 버전 직전의 최신 마이너 버전까지 존재하는 모든 마이그레이션을 완료해야 합니다. 또한 메이저 버전 업그레이드를 진행하기 전에 중단된 마이그레이션을 해결하고 재시도해야 합니다. 자세한 내용은 업그레이드를 위한 마이그레이션을 참고합니다.

제거된 마이그레이션은 사용 중단으로 표시됩니다. 대기 중인 고급 검색 마이그레이션이 모두 완료되기 전에 GitLab을 업그레이드하면, 새 버전에서 제거된 대기 중 마이그레이션은 실행하거나 재시도할 수 없습니다. 이 경우 인덱스를 처음부터 다시 만들어야 합니다.

gitlab:check Rake 태스크에는 All migrations must be finished before doing a major upgrade라는 검사가 포함되어 있습니다. 고급 검색 인덱싱이 켜져 있을 때 이 검사는 대기 중인 마이그레이션이 없으면 yes를 보고합니다. 대기 중인 마이그레이션이 있으면 no와 대기 중인 마이그레이션 수를 보고합니다. 인덱싱이 꺼져 있으면 검사를 건너뜁니다.

이 검사는 다음과 같이 동작합니다.

  • 상태만 보고합니다.
  • 업그레이드를 중지, 일시 중지, 롤백하지 않습니다.
  • gitlab:check 또는 gitlab:app:check Rake 태스크를 실행할 때만 실행됩니다.

검사가 no를 보고하더라도 Rake 태스크는 상태 0으로 종료되므로, 종료 코드로 업그레이드를 통제할 수 없습니다.

대기 중인 마이그레이션 수에는 시작하지 않았거나, 진행 중이거나, 중단된 마이그레이션이 포함되지만 건너뛸 수 있는 마이그레이션은 포함되지 않습니다. 이 검사도 gitlab:elastic:list_pending_migrations Rake 태스크도 대기 중인 마이그레이션 중 어떤 것이 중단되었는지 알려 주지 않습니다. gitlab:elastic:info Rake 태스크는 현재 마이그레이션이 중단되었는지 보고하지만, 현재 마이그레이션만 보고합니다. 중단된 마이그레이션을 확인하고 재시도해 볼 수 있습니다.

마이그레이션이 계속 대기 중이고 gitlab:elastic:list_pending_migrations가 이를 [Obsolete]로 표시한다면, 마이그레이션이 완료되기를 기다리는 대신 인덱스를 다시 만들어야 합니다.

건너뛸 수 있는 마이그레이션#

건너뛸 수 있는 마이그레이션은 조건이 충족될 때만 실행됩니다. 예를 들어 마이그레이션이 특정 Elasticsearch 버전에 의존한다면, 해당 버전에 도달할 때까지 건너뛸 수 있습니다.

건너뛸 수 있는 마이그레이션이 사용 중단으로 표시될 때까지 실행되지 않았다면, 변경 사항을 적용하기 위해 인덱스를 다시 만들어야 합니다.

GitLab 고급 검색 Rake 태스크#

다음 작업에 사용할 수 있는 Rake 태스크가 있습니다.

사용할 수 있는 Rake 태스크는 다음과 같습니다.

태스크 설명
sudo gitlab-rake gitlab:elastic:info 고급 검색 통합의 디버깅 정보를 출력합니다.
sudo gitlab-rake gitlab:elastic:index GitLab 17.0 이하에서는 고급 검색용 인덱싱을 켜고 gitlab:elastic:recreate_index, gitlab:elastic:clear_index_status, gitlab:elastic:index_group_entities, gitlab:elastic:index_projects, gitlab:elastic:index_snippets, gitlab:elastic:index_users를 실행합니다.
GitLab 17.1 이상에서는 백그라운드에 Sidekiq job을 큐에 넣습니다. 이 job은 먼저 고급 검색용 인덱싱을 켠 다음, 모든 인덱스가 생성되도록 인덱싱을 일시 중지합니다. 그다음 모든 인덱스를 다시 생성하고 인덱싱 상태를 초기화한 뒤, 프로젝트·그룹 데이터와 스니펫, 사용자를 인덱싱할 Sidekiq job을 추가로 큐에 넣습니다. 마지막으로 고급 검색용 인덱싱을 재개해 작업을 완료합니다. GitLab 17.1에서 elastic_index_use_trigger_indexing이라는 기능 플래그와 함께 도입되었습니다. 기본적으로 활성화됩니다. GitLab 17.3에서 정식 기능이 되었습니다. 기능 플래그 elastic_index_use_trigger_indexing은 제거되었습니다.
sudo gitlab-rake gitlab:elastic:pause_indexing 고급 검색용 인덱싱을 일시 중지합니다. 변경 사항은 계속 추적됩니다. 클러스터·인덱스 마이그레이션에 유용합니다.
sudo gitlab-rake gitlab:elastic:resume_indexing 고급 검색용 인덱싱을 재개합니다.
sudo gitlab-rake gitlab:elastic:index_and_search_validation 모든 인덱스에 대해 클러스터 연결, 인덱스, 검색 동작을 검증합니다. GitLab 18.3에서 도입되었습니다.
sudo gitlab-rake gitlab:elastic:index_projects 모든 프로젝트를 순회하면서 백그라운드에서 인덱싱할 Sidekiq job을 큐에 넣습니다. 인덱스가 생성된 뒤에만 사용할 수 있습니다.
sudo gitlab-rake gitlab:elastic:index_group_entities gitlab:elastic:index_work_items와 gitlab:elastic:index_group_wikis를 호출하고, 그룹 마일스톤을 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_work_items Elasticsearch가 활성화된 그룹의 모든 작업 항목을 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_namespaces 모든 루트 네임스페이스를 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_group_wikis Elasticsearch가 활성화된 그룹의 모든 위키를 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_snippets 스니펫 데이터를 인덱싱하는 Elasticsearch 가져오기를 수행합니다.
sudo gitlab-rake gitlab:elastic:index_users 모든 사용자를 Elasticsearch로 가져옵니다.
sudo gitlab-rake gitlab:elastic:index_vulnerabilities 모든 취약점을 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_sbom_occurrence_refs 모든 SBOM 발생 참조를 인덱싱합니다.
sudo gitlab-rake gitlab:elastic:index_projects_status 모든 프로젝트 리포지터리 데이터(코드, 커밋, 위키)의 전체 인덱싱 상태를 확인합니다. 상태는 인덱싱된 프로젝트 수를 전체 프로젝트 수로 나눈 뒤 100을 곱해 계산합니다. 이 태스크는 이슈, 머지 리퀘스트, 마일스톤 같은 리포지터리 외 데이터는 포함하지 않습니다.
sudo gitlab-rake gitlab:elastic:index_groups_status 모든 그룹 리포지터리 데이터(그룹 위키)의 전체 인덱싱 상태를 확인합니다. 상태는 인덱싱된 그룹 수를 전체 그룹 수로 나눈 뒤 100을 곱해 계산합니다. 이 태스크는 에픽, 머지 리퀘스트, 마일스톤 같은 리포지터리 외 데이터는 포함하지 않습니다.
sudo gitlab-rake gitlab:elastic:clear_index_status 모든 프로젝트의 IndexStatus 인스턴스를 전부 삭제합니다. 이 명령은 인덱스를 완전히 지우므로 주의해서 사용해야 합니다.
sudo gitlab-rake gitlab:elastic:create_empty_index 빈 인덱스(기본 인덱스와 별도의 이슈 인덱스)를 생성하고, Elasticsearch 쪽에 아직 없는 경우에만 각각에 별칭을 할당합니다.
sudo gitlab-rake gitlab:elastic:delete_index Elasticsearch 인스턴스에서 GitLab 인덱스와 별칭이 있으면 제거합니다.
sudo gitlab-rake gitlab:elastic:recreate_index gitlab:elastic:delete_index와 gitlab:elastic:create_empty_index를 묶은 래퍼 태스크입니다. 인덱싱 job은 큐에 넣지 않습니다.
sudo gitlab-rake gitlab:elastic:projects_not_indexed 리포지터리 데이터가 인덱싱되지 않은 프로젝트를 표시합니다. 이 태스크는 이슈, 머지 리퀘스트, 마일스톤 같은 리포지터리 외 데이터는 포함하지 않습니다.
sudo gitlab-rake gitlab:elastic:groups_not_indexed 리포지터리 데이터가 인덱싱되지 않은 그룹을 표시합니다. 이 태스크는 이슈, 머지 리퀘스트, 마일스톤 같은 리포지터리 외 데이터는 포함하지 않습니다.
sudo gitlab-rake gitlab:elastic:reindex_cluster 무중단 클러스터 재인덱싱 태스크를 예약합니다.
sudo gitlab-rake gitlab:elastic:mark_reindex_failed 가장 최근 재인덱싱 job을 실패로 표시합니다.
sudo gitlab-rake gitlab:elastic:list_pending_migrations 대기 중인 마이그레이션을 나열합니다. 대기 중인 마이그레이션에는 아직 시작하지 않은 것, 시작했지만 끝나지 않은 것, 중단된 것이 포함됩니다.
sudo gitlab-rake gitlab:elastic:estimate_cluster_size 전체 리포지터리 크기를 기준으로 코드·위키 인덱스 크기와 전체 클러스터 크기를 추정합니다.
sudo gitlab-rake gitlab:elastic:estimate_shard_sizes 대략적인 데이터베이스 레코드 수를 기준으로 각 인덱스의 샤드 크기를 추정합니다. 이 추정치에는 리포지터리 데이터(코드, 커밋, 위키)가 포함되지 않습니다.
sudo gitlab-rake gitlab:elastic:enable_search_with_elasticsearch Elasticsearch 기반 고급 검색을 활성화합니다.
sudo gitlab-rake gitlab:elastic:disable_search_with_elasticsearch Elasticsearch 기반 고급 검색을 비활성화합니다.

환경 변수#

Rake 태스크 외에도 처리 과정을 조정하는 데 사용할 수 있는 환경 변수가 있습니다.

환경 변수 데이터 타입 기능
ID_TO Integer 인덱서가 해당 값 이하의 프로젝트만 인덱싱하도록 지정합니다.
ID_FROM Integer 인덱서가 해당 값 이상의 프로젝트만 인덱싱하도록 지정합니다.

프로젝트 범위 또는 특정 프로젝트 인덱싱#

ID_FROM과 ID_TO 환경 변수를 사용하면 제한된 수의 프로젝트만 인덱싱할 수 있습니다. 인덱싱을 단계적으로 진행할 때 유용합니다.

root@git:~# sudo gitlab-rake gitlab:elastic:index_projects ID_FROM=1 ID_TO=100

ID_FROM과 ID_TO는 이상·이하 비교를 사용하므로, 두 값을 같은 프로젝트 ID로 설정하면 프로젝트 하나만 인덱싱할 수 있습니다.

root@git:~# sudo gitlab-rake gitlab:elastic:index_projects ID_FROM=5 ID_TO=5
Indexing project repositories...I, [2019-03-04T21:27:03.083410 #3384]  INFO -- : Indexing GitLab User / test (ID=33)...
I, [2019-03-04T21:27:05.215266 #3384]  INFO -- : Indexing GitLab User / test (ID=33) is done!

고급 검색 인덱스 스코프#

검색을 수행할 때 GitLab 인덱스는 다음 스코프를 사용합니다.

스코프 이름 검색 대상
commits 커밋 데이터
projects 프로젝트 데이터(기본값)
groups 그룹 데이터
blobs 코드
work_items 작업 항목 데이터
merge_requests 머지 리퀘스트 데이터
milestones 마일스톤 데이터
notes 노트 데이터
snippets 스니펫 데이터
wiki_blobs 위키 콘텐츠
users 사용자

GitLab.com과 GitLab Dedicated에서는 검색 외 기능을 지원하기 위해 모든 프로젝트와 네임스페이스의 취약점 레코드를 항상 인덱싱합니다. GitLab Self-Managed에서 취약점 레코드를 인덱싱하는 방안은 이슈 525484에서 제안되었습니다.

튜닝#

최적 클러스터 구성 선택 지침#

클러스터 구성 선택에 관한 기본 지침은 Elastic Cloud Calculator도 참고합니다.

  • 일반적으로 복제본 하나를 둔 2노드 이상의 클러스터 구성을 사용하면 복원력을 확보할 수 있습니다. 스토리지 사용량이 빠르게 늘고 있다면 수평 확장(노드 추가)을 미리 계획하는 편이 좋습니다.
  • 검색 클러스터에 HDD 스토리지를 사용하면 성능이 떨어지므로 권장하지 않습니다. SSD 스토리지(예: NVMe 또는 SATA SSD 드라이브)를 사용하는 편이 좋습니다.
  • 대형 인스턴스에는 coordinating-only 노드를 사용하지 않아야 합니다. coordinating-only 노드는 데이터 노드보다 작아 성능과 고급 검색 마이그레이션에 영향을 줄 수 있습니다.
  • GitLab Performance Tool로 검색 클러스터 크기와 구성을 달리하며 검색 성능을 벤치마킹할 수 있습니다.
  • Heap size는 물리 RAM의 50% 를 넘지 않게 설정합니다. 또한 zero-based compressed oops 임계값을 넘지 않아야 합니다. 정확한 임계값은 시스템마다 다르지만 대부분의 시스템에서 26GB는 안전하며, 일부 시스템에서는 30GB까지 가능합니다. 자세한 내용은 Heap size settings와 Setting JVM options를 참고합니다.
  • refresh_interval은 인덱스별 설정입니다. 데이터를 실시간으로 볼 필요가 없다면 기본값 1s보다 큰 값으로 조정할 수 있습니다. 이 값은 최신 결과가 얼마나 빨리 보이는지를 좌우합니다. 실시간성이 중요하다면 기본값에 최대한 가깝게 유지합니다.
  • 인덱싱 작업이 많다면 indices.memory.index_buffer_size를 30% 또는 40% 로 올릴 수 있습니다.

고급 검색 설정#

Elasticsearch 샤드 수#

히스토리
  • gitlab:elastic:estimate_shard_sizes가 GitLab 18.3에서 리포지터리 데이터를 포함하는 인덱스의 크기 산정까지 다루도록 변경되었습니다.

단일 노드 클러스터에서는 인덱스당 Elasticsearch 샤드 수를 Elasticsearch 데이터 노드의 CPU 코어 수와 같게 설정합니다.

다중 노드 클러스터에서는 Rake 태스크 gitlab:elastic:estimate_shard_sizes를 실행해 각 인덱스의 샤드 수를 확인합니다. 이 태스크는 샤드·복제본 크기 권장값과 데이터베이스 데이터를 담은 인덱스의 대략적인 문서 수를 반환합니다.

평균 샤드 크기는 수 GB에서 30GB 사이로 유지합니다. 평균 샤드 크기가 30GB를 넘으면 해당 인덱스의 샤드 크기를 늘리고 무중단 재인덱싱을 실행합니다. 클러스터를 정상 상태로 유지하려면 노드당 샤드 수가 설정된 힙 크기의 20배를 넘지 않아야 합니다. 예를 들어 힙이 30GB 인 노드는 샤드가 최대 600개여야 합니다.

인덱스의 샤드 수를 변경하려면 설정을 바꾼 뒤 무중단 재인덱싱을 실행합니다.

Elasticsearch 복제본 수#

단일 노드 클러스터에서는 인덱스당 Elasticsearch 복제본 수를 0으로 설정합니다.

다중 노드 클러스터에서는 인덱스당 Elasticsearch 복제본 수를 1로 설정합니다(샤드마다 복제본 하나). 노드 하나가 유실되면 인덱스가 손상되므로 이 값은 0 이 아니어야 합니다.

샤드 할당 어웨어니스가 활성화되어 있으면, 샤드당 전체 사본 수가 어웨어니스 속성 수(대개 노드 또는 존)로 나누어떨어져야 합니다. 샤드 사본이 모든 어웨어니스 속성에 고르게 분산되어야 장애 내성과 부하 분산이 제대로 확보됩니다.

(1 + `number_of_replicas`) / `number_of_awareness_attributes` = whole number

인덱스의 복제본 수를 변경하려면 설정을 바꾼 뒤 무중단 재인덱싱을 실행합니다.

대규모 인스턴스 효율적 인덱싱#

사전 요구 사항:

  • 인스턴스의 관리자 액세스 권한이 있어야 합니다.
Warning

대규모 인스턴스를 인덱싱하면 Sidekiq job 이 많이 생성됩니다. 확장 가능한 구성을 갖추거나 추가 Sidekiq 프로세스를 만들어 이 작업에 대비합니다.

Geo 기본 노드와 보조 노드는 동일한 Elasticsearch 클러스터를 가리킵니다. 다만 Elasticsearch 인덱싱 워커는 기본 사이트의 Sidekiq 노드에서만 실행됩니다.

따라서 추가 Sidekiq 프로세스는 기본 사이트의 Sidekiq 노드에 구성해야 합니다.

인덱싱되는 데이터양이 많아 고급 검색 활성화가 문제를 일으키는 경우:

  1. Elasticsearch 호스트와 포트를 구성합니다.

  2. 빈 인덱스를 생성합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:create_empty_index
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:create_empty_index RAILS_ENV=production
    
  3. GitLab 인스턴스를 재인덱싱하는 경우에는 인덱스 상태를 초기화합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:clear_index_status
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:clear_index_status RAILS_ENV=production
    
  4. Turn on indexing for advanced search 체크박스를 선택합니다.

  5. 대규모 Git 리포지터리 인덱싱은 시간이 오래 걸릴 수 있습니다. 속도를 높이려면 인덱싱 속도를 위해 튜닝할 수 있습니다.

    • refresh_interval 값을 일시적으로 늘릴 수 있습니다.

    • 복제본 수를 0으로 설정할 수 있습니다. 이 설정은 인덱스의 각 주 샤드가 가지는 사본 수를 제어합니다. 따라서 복제본이 0 이면 노드 간 샤드 복제가 사실상 중단되어 인덱싱 성능이 올라갑니다. 신뢰성과 쿼리 성능 측면에서 중요한 트레이드오프이므로, 최초 인덱싱이 끝난 뒤에는 복제본 수를 적절한 값으로 되돌려야 합니다.

    인덱싱 시간은 20% 정도 줄어듭니다. 인덱싱이 끝나면 refresh_interval과 number_of_replicas를 원하는 값으로 되돌립니다.

    [!note] 이 단계는 선택 사항이지만 대규모 인덱싱 작업의 속도를 크게 높일 수 있습니다.

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "index" : {
               "refresh_interval" : "30s",
               "number_of_replicas" : 0
           } }'
    
  6. 프로젝트와 연관 데이터를 인덱싱합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:index_projects
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:index_projects RAILS_ENV=production
    

    이 명령은 인덱싱이 필요한 프로젝트마다 Sidekiq job을 큐에 넣습니다. 인덱싱 상태는 Rake 태스크로 조회할 수 있습니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:index_projects_status
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:index_projects_status RAILS_ENV=production
    
    Indexing is 65.55% complete (6555/10000 projects). Considers only code, commits, and wikis.
    

    인덱싱 대상을 특정 프로젝트 범위로 제한하려면 ID_FROM과 ID_TO 파라미터를 지정할 수 있습니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:index_projects ID_FROM=1001 ID_TO=2000
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:index_projects ID_FROM=1001 ID_TO=2000 RAILS_ENV=production
    

    여기서 ID_FROM과 ID_TO는 프로젝트 ID 이며, 두 파라미터 모두 선택 사항입니다. 앞의 예시는 ID 1001부터 ID 2000 까지(해당 ID 포함) 모든 프로젝트를 인덱싱합니다.

    [!note] gitlab:elastic:index_projects가 큐에 넣은 프로젝트 인덱싱 job 이 중단되는 경우가 있습니다. 원인은 여러 가지일 수 있지만, 인덱싱 태스크를 다시 실행하는 것은 언제나 안전합니다.

    gitlab:elastic:clear_index_status Rake 태스크로 인덱서가 모든 진행 상황을 "잊도록" 강제할 수도 있습니다. 그러면 인덱싱 과정을 처음부터 다시 시도합니다.

  7. 작업 항목, 그룹 위키, 개인 스니펫, 사용자는 프로젝트에 연결되지 않으므로 별도로 인덱싱해야 합니다.

    # For installations that use the Linux package
    sudo gitlab-rake gitlab:elastic:index_work_items
    sudo gitlab-rake gitlab:elastic:index_group_wikis
    sudo gitlab-rake gitlab:elastic:index_snippets
    sudo gitlab-rake gitlab:elastic:index_users
    
    # For self-compiled installations
    bundle exec rake gitlab:elastic:index_work_items RAILS_ENV=production
    bundle exec rake gitlab:elastic:index_group_wikis RAILS_ENV=production
    bundle exec rake gitlab:elastic:index_snippets RAILS_ENV=production
    bundle exec rake gitlab:elastic:index_users RAILS_ENV=production
    
  8. 인덱싱이 끝나면 복제와 리프레시를 다시 활성화합니다(앞서 refresh_interval을 늘린 경우에만).

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "index" : {
               "number_of_replicas" : 1,
               "refresh_interval" : "1s"
           } }'
    

    리프레시를 활성화한 뒤에는 force merge를 호출해야 합니다.

    Elasticsearch 6.x 이상에서는 force merge를 진행하기 전에 인덱스가 읽기 전용 모드인지 확인합니다.

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "settings": {
             "index.blocks.write": true
           } }'
    

    그다음 force merge를 시작합니다.

    curl --request POST 'localhost:9200/gitlab-production/_forcemerge?max_num_segments=5'
    

    그다음 인덱스를 다시 읽기·쓰기 모드로 되돌립니다.

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "settings": {
             "index.blocks.write": false
           } }'
    
  9. 인덱싱이 끝나면 Search with advanced search 체크박스를 선택합니다.

전용 Sidekiq 노드 또는 프로세스로 대규모 인스턴스 인덱싱#

Warning

대부분의 인스턴스에서는 전용 Sidekiq 노드나 프로세스를 구성하지 않아도 됩니다. 다음 단계는 라우팅 규칙이라는 Sidekiq 고급 설정을 사용합니다. job 이 통째로 유실되지 않도록 라우팅 규칙 사용에 따른 영향을 충분히 이해해야 합니다.

대규모 인스턴스 인덱싱은 시간이 오래 걸리고 리소스를 많이 쓰는 작업이어서 Sidekiq 노드와 프로세스에 과부하를 줄 수 있습니다. 이는 GitLab의 성능과 가용성에 악영향을 줍니다.

GitLab은 여러 Sidekiq 프로세스를 실행할 수 있으므로, 특정 큐 집합(큐 그룹) 인덱싱을 전담하는 프로세스를 추가로 만들 수 있습니다. 이렇게 하면 인덱싱 큐에는 항상 전담 워커가 배정되고, 나머지 큐는 또 다른 전담 워커가 처리해 경합을 피할 수 있습니다.

이를 위해 워커 매칭 쿼리를 기준으로 Sidekiq 이 job을 특정 큐로 라우팅하도록 하는 라우팅 규칙 옵션을 사용합니다.

Note

라우팅 규칙(sidekiq['routing_rules'])은 모든 GitLab 노드(특히 GitLab Rails 노드와 Sidekiq 노드)에서 동일해야 합니다.

다음 두 가지 방법 중 하나를 선택할 수 있습니다.

다음 단계에서는 sidekiq['routing_rules'] 항목을 이렇게 가정합니다.

  • 모든 인덱싱 job을 global_search 큐로 보내는 ["feature_category=global_search", "global_search"].
  • 인덱싱 외 나머지 job을 모두 default 큐로 보내는 ["*", "default"].

sidekiq['queue_groups']의 프로세스 중 최소 하나에는 mailers 큐가 포함되어야 합니다. 그렇지 않으면 메일러 job 이 전혀 처리되지 않습니다.

Warning

여러 프로세스를 실행할 때 프로세스 수는 Sidekiq에 할당하려는 CPU 코어 수를 넘을 수 없습니다. Sidekiq 프로세스 하나는 사용 가능한 워크로드와 동시성 설정에 따라 CPU 코어를 하나만 사용할 수 있습니다. 자세한 내용은 여러 Sidekiq 프로세스 실행을 참고합니다.

단일 노드, 두 프로세스#

한 노드에 인덱싱용 Sidekiq 프로세스와 인덱싱 외 Sidekiq 프로세스를 모두 만들려면 다음과 같이 진행합니다.

  1. Sidekiq 노드에서 /etc/gitlab/gitlab.rb 파일을 다음과 같이 변경합니다.

    sidekiq['enable'] = true
    
    sidekiq['routing_rules'] = [
       ["feature_category=global_search", "global_search"],
       ["*", "default"],
    ]
    
    sidekiq['queue_groups'] = [
       "global_search", # process that listens to global_search queue
       "default,mailers" # process that listens to default and mailers queue
    ]
    
    sidekiq['concurrency'] = 20
    
  2. 파일을 저장하고 변경 사항을 적용하기 위해 GitLab을 재구성합니다.

  3. 다른 모든 Rails 노드와 Sidekiq 노드에서 sidekiq['routing_rules']가 위 구성과 동일한지 확인합니다.

  4. Rake 태스크를 실행해 기존 job을 마이그레이션합니다.

Note

GitLab을 재구성한 직후에 Rake 태스크를 실행해야 합니다. GitLab을 재구성한 뒤에는 Rake 태스크가 job 마이그레이션을 시작하기 전까지 기존 job 이 처리되지 않습니다.

두 노드, 각각 한 프로세스#

이 큐 그룹들을 두 노드에서 처리하려면 다음과 같이 진행합니다.

  1. 인덱싱용 Sidekiq 프로세스를 구성하려면 인덱싱용 Sidekiq 노드에서 /etc/gitlab/gitlab.rb 파일을 다음과 같이 변경합니다.

    sidekiq['enable'] = true
    
    sidekiq['routing_rules'] = [
       ["feature_category=global_search", "global_search"],
       ["*", "default"],
    ]
    
    sidekiq['queue_groups'] = [
      "global_search", # process that listens to global_search queue
    ]
    
    sidekiq['concurrency'] = 20
    
  2. 파일을 저장하고 변경 사항을 적용하기 위해 GitLab을 재구성합니다.

  3. 인덱싱 외 Sidekiq 프로세스를 구성하려면 인덱싱 외 Sidekiq 노드에서 /etc/gitlab/gitlab.rb 파일을 다음과 같이 변경합니다.

    sidekiq['enable'] = true
    
    sidekiq['routing_rules'] = [
       ["feature_category=global_search", "global_search"],
       ["*", "default"],
    ]
    
    sidekiq['queue_groups'] = [
       "default,mailers" # process that listens to default and mailers queue
    ]
    
    sidekiq['concurrency'] = 20
    
  4. 다른 모든 Rails 노드와 Sidekiq 노드에서 sidekiq['routing_rules']가 위 구성과 동일한지 확인합니다.

  5. 파일을 저장하고 변경 사항을 적용하기 위해 GitLab을 재구성합니다.

  6. Rake 태스크를 실행해 기존 job을 마이그레이션합니다.

    sudo gitlab-rake gitlab:sidekiq:migrate_jobs:retry gitlab:sidekiq:migrate_jobs:schedule gitlab:sidekiq:migrate_jobs:queued
    
Note

GitLab을 재구성한 직후에 Rake 태스크를 실행해야 합니다. GitLab을 재구성한 뒤에는 Rake 태스크가 job 마이그레이션을 시작하기 전까지 기존 job 이 처리되지 않습니다.

삭제된 문서#

인덱싱된 GitLab 객체가 변경되거나 삭제될 때마다, 예를 들어 머지 리퀘스트 설명이 변경되거나 리포지터리의 기본 브랜치에서 파일이 삭제되거나 프로젝트가 삭제될 때마다 인덱스의 문서가 삭제됩니다. 다만 이는 "소프트" 삭제이므로 전체 "삭제된 문서" 수가 늘어나고 그만큼 공간이 낭비됩니다.

Elasticsearch는 세그먼트를 지능적으로 병합해 이런 삭제된 문서를 제거합니다. 다만 GitLab 설치 환경의 활동량과 유형에 따라 인덱스에서 최대 50% 의 공간이 낭비될 수도 있습니다.

일반적으로는 기본 설정 그대로 Elasticsearch가 알아서 병합하고 공간을 회수하도록 두는 편이 좋습니다. Lucene's Handling of Deleted Documents에서는 "전반적으로, 최대 세그먼트 크기를 줄이는 정도를 제외하면 Lucene 기본값을 그대로 두고 삭제가 언제 회수되는지에 너무 신경 쓰지 않는 편이 가장 좋다" 고 설명합니다.

다만 규모가 큰 설치 환경에서는 병합 정책 설정을 조정하고 싶을 수 있습니다.

  • index.merge.policy.max_merged_segment 크기를 기본값 5GB에서 2GB 또는 3GB 정도로 줄이는 방안을 검토합니다. 병합은 세그먼트에 삭제가 50% 이상 쌓였을 때만 일어납니다. 세그먼트 크기가 작을수록 병합이 더 자주 일어납니다.

    curl --request PUT localhost:9200/gitlab-production/_settings ---header 'Content-Type: application/json' \
         --data '{
           "index" : {
             "merge.policy.max_merged_segment": "2gb"
           }
         }'
    
  • 삭제를 얼마나 적극적으로 처리할지 제어하는 index.merge.policy.reclaim_deletes_weight도 조정할 수 있습니다. 다만 병합 비용이 큰 결정으로 이어질 수 있으므로, 트레이드오프를 이해하지 못했다면 변경하지 않아야 합니다.

    curl --request PUT localhost:9200/gitlab-production/_settings ---header 'Content-Type: application/json' \
         --data '{
           "index" : {
             "merge.policy.reclaim_deletes_weight": "3.0"
           }
         }'
    
  • 삭제된 문서를 제거하려고 force merge를 실행하지 않아야 합니다. 문서의 경고에 따르면 영영 회수되지 않을 수 있는 아주 큰 세그먼트가 생기고, 성능이나 가용성에도 심각한 문제를 일으킬 수 있습니다.

기본 검색으로 되돌리기#

Elasticsearch 인덱스 데이터에 문제가 생길 수 있으므로, GitLab은 검색 결과가 없고 해당 스코프에서 기본 검색이 지원되는 경우 "기본 검색"으로 되돌릴 수 있게 합니다. 이 "기본 검색"은 인스턴스에 고급 검색이 아예 활성화되지 않은 것처럼 동작하며, 다른 데이터 소스(PostgreSQL 데이터, Git 데이터 등)를 사용해 검색합니다.

재해 복구#

Elasticsearch는 GitLab의 보조 데이터 저장소입니다. Elasticsearch에 저장된 모든 데이터는 다른 데이터 소스, 특히 PostgreSQL과 Gitaly에서 다시 만들어 낼 수 있습니다. Elasticsearch 데이터 저장소가 손상된 경우 전체를 처음부터 다시 인덱싱할 수 있습니다.

Elasticsearch 인덱스가 너무 크면 전체를 처음부터 다시 인덱싱하는 동안 다운타임이 지나치게 길어질 수 있습니다. Elasticsearch 인덱스의 불일치를 자동으로 찾아 재동기화할 수는 없지만, 로그에서 누락된 업데이트를 확인할 수 있습니다. 데이터를 더 빠르게 복구하려면 다음 작업을 다시 실행할 수 있습니다.

  1. elasticsearch.log에서 track_items를 검색해 동기화된 비 리포지터리 업데이트 전체를 찾습니다. 해당 항목은 ::Elastic::ProcessBookkeepingService.track!를 통해 다시 전송해야 합니다.
  2. elasticsearch.log에서 indexing_commit_range를 검색해 리포지터리 업데이트 전체를 찾습니다. IndexStatus#last_commit/last_wiki_commit을 로그에 있는 가장 오래된 from_sha로 설정한 다음, Search::Elastic::CommitIndexerWorker와 ElasticWikiIndexerWorker로 해당 프로젝트를 다시 인덱싱하도록 트리거합니다.
  3. sidekiq.log에서 ElasticDeleteProjectWorker를 검색해 프로젝트 삭제 전체를 찾습니다. ElasticDeleteProjectWorker를 다시 트리거해야 합니다.

전체를 처음부터 다시 인덱싱하지 않고 데이터 손실을 복구하는 데 걸리는 시간을 줄이려면 Elasticsearch 스냅숏을 정기적으로 만들 수도 있습니다.