Help us learn about your current experience with the documentation. Take the survey.

Elasticsearch

  • 层级:Premium, Ultimate
  • 提供:GitLab Self-Managed, GitLab Dedicated

本页介绍如何启用高级搜索。启用后,高级搜索可提供更快的搜索响应时间及 改进的搜索功能

要启用高级搜索,需完成以下步骤:

  1. 安装 Elasticsearch 或 AWS OpenSearch 集群
  2. 启用高级搜索

高级搜索将所有项目存储在同一个 Elasticsearch 索引中。不过,私有项目仅对有访问权限的用户显示在搜索结果中。

Elasticsearch 术语表

本术语表提供了与 Elasticsearch 相关术语的定义。

  • Lucene:用 Java 编写的全文搜索库。
  • 近实时(NRT):指从索引文档到其可被搜索之间的轻微延迟。
  • 集群:由一个或多个节点组成的集合,共同持有所有数据,并提供索引和搜索能力。
  • 节点:作为集群一部分的单个服务器。
  • 索引:具有相似特征的文档集合。
  • 文档:可被索引的基本信息单元。
  • 分片:索引的完全独立且功能完整的细分部分。每个分片实际上是一个 Lucene 索引。
  • 副本:复制索引的故障转移机制。

安装 Elasticsearch 或 AWS OpenSearch 集群

Elasticsearch 和 AWS OpenSearch 不包含 在 Linux 软件包中。您可以自行安装搜索集群,或使用云托管服务,例如:

您应将搜索集群安装在单独的服务器上。在 GitLab 所在服务器上运行搜索集群可能导致性能问题。

对于单节点的搜索集群,集群状态始终为黄色,因为主分片已分配。集群无法将副本分片分配给与主分片相同的节点。

在使用新的 Elasticsearch 集群投入生产前,请参阅 重要 Elasticsearch 配置

版本要求

Elasticsearch

高级搜索支持以下版本的 Elasticsearch:

GitLab 版本 Elasticsearch 版本
GitLab 18.1 及更高版本 Elasticsearch 7.x 及更高版本
GitLab 15.0 至 18.0 Elasticsearch 7.x 和 8.x
GitLab 14.0 至 14.10 Elasticsearch 6.8 至 7.x

高级搜索遵循 Elasticsearch 终止支持政策

OpenSearch

GitLab 版本 OpenSearch 版本
GitLab 18.1 及更高版本 OpenSearch 1.x 及更高版本
GitLab 17.6.3 至 18.0 OpenSearch 1.x 和 2.x
GitLab 15.5.3 至 17.6.2 OpenSearch 1.x, 2.0 至 2.17
GitLab 15.0 至 15.5.2 OpenSearch 1.x

OpenSearch 3.x 自 GitLab 18.1 开始受支持。详见 合并请求 192197

如果您的 Elasticsearch 或 OpenSearch 版本不兼容,为防止数据丢失,索引会暂停,并在 elasticsearch.log 文件中记录消息。

如果您使用的是兼容版本,连接 OpenSearch 后出现 “Elasticsearch version not compatible” 消息,请执行 恢复索引

系统要求

Elasticsearch 和 AWS OpenSearch 需要的资源比 GitLab 安装要求 更多。

内存、CPU 和存储需求取决于您索引到集群中的数据量。 heavily used 的 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 服务的访问控制

先决条件:

  • 创建 OpenSearch 域时,您的 AWS 账户中需存在名为 AWSServiceRoleForAmazonOpenSearchService服务关联角色
  • AWS OpenSearch 的域访问策略必须允许 es:ESHttp* 操作。

AWSServiceRoleForAmazonOpenSearchService所有 OpenSearch 域使用。多数情况下,当您通过 AWS 管理控制台创建首个 OpenSearch 域时,该角色会自动生成。如需手动创建服务关联角色,请参考 AWS 文档

AWS OpenSearch 服务包含三层主要安全机制:

网络

借助此安全层,创建域时可选择 公共访问,使任意客户端均可访问域终端节点;若选择 VPC 访问,客户端需连接至 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/*"
    }
  ]
}

若跨账户使用 AWS AssumeRole,则需提供 aws_role_arn。该 ARN 应为有权访问 OpenSearch 的角色。

基于身份的策略示例

以下为允许 es:ESHttp* 操作且附加至 IAM 主体的基于身份的访问策略示例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "es:ESHttp*",
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
细粒度访问控制

启用细粒度访问控制时,您需通过以下任一方式设置 主用户

设置IAM ARN作为主用户

如果使用IAM主体作为主用户,所有对集群的请求必须使用AWS签名版本4进行签名。你也可以指定一个IAM ARN,即分配给你的EC2实例的IAM角色。有关更多信息,请参阅AWS文档

若要将IAM ARN设为主用户,你必须在GitLab实例上使用带有IAM凭证的AWS OpenSearch服务:

  1. 在左侧边栏底部,选择管理员

  2. 选择设置 > 搜索

  3. 展开高级搜索

  4. AWS OpenSearch IAM凭证部分:

    1. 勾选使用带有IAM凭证的AWS OpenSearch服务复选框。
    2. AWS区域中,输入你的OpenSearch域所在区域的AWS区域(例如us-east-1)。
    3. AWS访问密钥AWS秘密访问密钥中,输入用于认证的访问密钥。

    直接在EC2实例上运行的GitLab部署(非容器化)无需输入访问密钥。你的GitLab实例会从AWS实例元数据服务(IMDS)自动获取这些密钥。

  5. 选择保存更改

创建主用户

如果在内部用户数据库中创建主用户,你可以使用HTTP基本认证向集群发送请求。有关更多信息,请参阅AWS文档

若要创建主用户,你必须在GitLab实例上配置OpenSearch域URL以及主用户名和密码:

  1. 在左侧边栏底部,选择管理员
  2. 选择设置 > 搜索
  3. 展开高级搜索
  4. OpenSearch域URL中,输入OpenSearch域端点的URL。
  5. 用户名中,输入主用户名。
  6. 密码中,输入主密码。
  7. 选择保存更改

升级到新的Elasticsearch主要版本

升级Elasticsearch时,你无需更改GitLab配置。

在升级过程中,你必须:

  • 暂停索引,以便仍能跟踪变更。
  • 禁用高级搜索,以免搜索因HTTP 500错误而失败。

当Elasticsearch集群完全升级并处于活跃状态后,恢复索引并启用高级搜索。

当你升级到GitLab 15.0及更高版本时,必须使用Elasticsearch 7.x及更高版本。

Elasticsearch仓库索引器

为索引Git仓库数据,GitLab使用gitlab-elasticsearch-indexer。对于自编译安装,请参阅安装索引器

安装索引器

你需要先安装一些依赖项,然后再构建并安装索引器本身。

安装依赖项

此项目依赖于国际组件Unicode(ICU)进行文本编码,因此在运行make之前,我们必须确保平台上的开发包已安装。

Debian / Ubuntu

在Debian或Ubuntu上安装,运行:

sudo apt install libicu-dev
CentOS / RHEL

在CentOS或RHEL上安装,运行:

sudo yum install libicu-devel
macOS

你必须先安装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

# 运行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

如果你在索引时看到类似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.classGitlab::Elastic::Indexer::Error。这些错误可能在索引Git仓库数据时发生。

启用高级搜索

前提条件:

要启用高级搜索:

  1. 在左侧边栏底部,选择管理
  2. 选择设置 > 搜索
  3. 为您的Elasticsearch集群配置高级搜索设置。暂时不要选中启用Elasticsearch搜索复选框。
  4. 索引实例
  5. 可选。检查索引状态
  6. 索引完成后,选中启用Elasticsearch搜索复选框,然后选择保存更改

当您的Elasticsearch集群在启用Elasticsearch时宕机,您可能会遇到更新问题(例如问题)——因为实例会将变更索引的任务加入队列,但无法找到有效的Elasticsearch集群。

对于存储超过50GB仓库数据的GitLab实例,请参阅Index large instances efficiently

索引实例

从用户界面

前提条件:

  • 您必须拥有实例的管理员权限。

您可以通过用户界面执行初始索引或重新创建索引。

要从用户界面启用高级搜索并索引实例:

  1. 在左侧边栏底部,选择管理
  2. 选择设置 > 搜索
  3. 选中Elasticsearch索引复选框,然后选择保存更改
  4. 选择索引实例

使用Rake任务

前提条件:

  • 您必须拥有实例的管理员权限。

要索引整个实例,使用以下Rake任务:

# 警告:此任务会删除所有现有索引

# 对于使用Linux包安装的环境
sudo gitlab-rake gitlab:elastic:index

# 警告:此任务会删除所有现有索引

# 对于自编译安装的环境
bundle exec rake gitlab:elastic:index RAILS_ENV=production

要索引特定数据,使用以下Rake任务:

# 对于使用Linux包安装的环境
sudo gitlab-rake gitlab:elastic:index_epics
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

# 对于自编译安装的环境
bundle exec rake gitlab:elastic:index_epics RAILS_ENV=production
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. 在左侧边栏底部,选择管理
  2. 选择设置 > 搜索
  3. 展开索引状态

监控后台作业状态

前提条件:

  • 您必须拥有实例的管理员权限。

要监控后台作业状态:

  1. 在左侧边栏底部,选择管理
  2. 选择监控 > 后台作业
  3. 在Sidekiq仪表板中,选择队列并等待elastic_commit_indexerelastic_wiki_indexer队列降至0。这些队列包含用于索引项目和组的代码及Wiki数据的任务。

高级搜索配置

以下 Elasticsearch 设置可用:

参数 描述
Elasticsearch indexing 启用或禁用 Elasticsearch 索引,若不存在则创建一个空索引。你可能希望启用索引但禁用搜索,以给索引充分完成的时间(例如)。另外请注意,此选项不会影响现有数据,它仅启用/禁用跟踪数据变更的后台索引器,确保新数据被索引。
Pause Elasticsearch indexing 启用或禁用临时索引暂停。这对于集群迁移/重新索引很有用。所有变更仍会被跟踪,但在恢复前不会提交到 Elasticsearch 索引中。
Search with Elasticsearch enabled 启用或禁用使用 Elasticsearch 进行搜索。
Requeue indexing workers 启用索引工作进程的自动重新排队。这通过将 Sidekiq 作业入队来提高非代码索引的吞吐量,直至所有文档处理完毕。对于较小实例或 Sidekiq 进程较少的实例,不建议重新排队索引工作进程。
URL 你的 Elasticsearch 实例的 URL。使用逗号分隔列表支持集群(例如 http://host1, https://host2:9200)。如果你的 Elasticsearch 实例受密码保护,请使用 UsernamePassword 字段。或者,使用内联凭证如 http://<username>:<password>@<elastic_host>:9200/。如果你使用 OpenSearch,仅接受端口 80443 的连接。
Username 你的 Elasticsearch 实例的用户名。
Password 你的 Elasticsearch 实例的密码。
Number of Elasticsearch shards and replicas per index 为提升性能,Elasticsearch 索引会拆分为多个分片。通常应至少使用五个分片。包含数千万文档的索引应有更多分片(参见指导)。对此值的修改需重建索引后才生效。有关扩展性和弹性信息,请参阅 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 参见 实例限制说明
非代码索引的分片数量 索引工作器的分片数量。通过排队更多并行的Sidekiq作业来提高非代码索引吞吐量。对于较小的实例或Sidekiq进程较少的实例,不建议增加分片数量。默认值为 2
最大批量请求大小(MiB) 由GitLab Ruby和基于Go的索引器进程使用。此设置表示在给定的索引过程中必须收集(并存储在内存中)多少数据,然后再将有效负载提交到Elasticsearch Bulk API。对于基于Go的GitLab索引器,应将此设置与 Bulk request concurrency 结合使用。最大批量请求大小(MiB) 必须适应运行GitLab基于Go的索引器的主机(无论是通过 gitlab-rake 命令还是Sidekiq任务)以及Elasticsearch主机的资源限制。
批量请求并发数 批量请求并发数表示可以并行运行的基于Go的GitLab索引器进程(或线程)的数量,以收集数据并随后提交到Elasticsearch Bulk API。这提高了索引性能,但会更快地填满Elasticsearch批量请求队列。此设置应与 最大批量请求大小 设置结合使用,并且需要适应运行GitLab基于Go的索引器的主机(无论是通过 gitlab-rake 命令还是Sidekiq任务)以及Elasticsearch主机的资源限制。
客户端请求超时时间 Elasticsearch HTTP客户端请求超时时间(秒)。0 表示使用系统默认的超时值,该值取决于构建GitLab应用程序所依赖的库。
代码索引并发数 允许同时运行的Elasticsearch代码索引后台作业的最大数量。此设置仅适用于仓库索引操作。
失败重试次数 Elasticsearch搜索请求的最大可能重试次数。在GitLab 17.6中引入
索引前缀 Elasticsearch索引名称的自定义前缀。默认为 gitlab。更改后,所有索引都将使用此前缀代替 gitlab(例如,custom-production-issues 而不是 gitlab-production-issues)。必须是1 - 100个字符,仅包含小写字母数字字符、连字符和下划线,且不能以连字符或下划线开头或结尾。在GitLab 18.2中引入

增加 最大批量请求大小(MiB)批量请求并发数 的值可能会对Sidekiq性能产生负面影响。若在Sidekiq日志中发现 scheduling_latency_s 持续时间增长,请将其恢复为默认值。更多信息可参考 问题322147

限制要索引的命名空间和项目数据量

该功能的可用性由功能标志控制。 有关更多信息,请参阅历史记录。

当你选中 限制要索引的命名空间和项目数据量 复选框时, 你可以指定要索引的命名空间和项目。 如果命名空间是一个组(group),这些子组及其中的项目和子组也会被索引。

当你启用此设置时:

  • 必须指定命名空间或项目才能进行完整索引。
  • 所有项目的项目记录(如项目名称和描述等元数据)始终会被索引。
  • 为支持安全报告中的过滤,所有项目和命名空间的漏洞记录始终会被索引。
  • 仅为你指定的命名空间和项目索引关联数据

如果你启用此设置后未指定任何命名空间或项目, 则仅索引项目记录,无法搜索关联数据。

已索引的命名空间

当你索引所有命名空间时,可以使用高级搜索进行全局代码和提交搜索。 当你仅索引某些命名空间时:

  • 全局搜索不包含代码或提交搜索范围。
  • 代码和提交搜索仅在单个已索引的命名空间中可用。
  • 无法跨多个已索引的命名空间执行单一代码或提交搜索。
  • 跨项目搜索在已索引的命名空间中可用。

例如,如果你索引两个独立的组,你必须分别在每个组上运行单独的代码搜索。

要启用针对有限索引的全局搜索:

  1. 在左侧边栏底部,选择 管理
  2. 选择 设置 > 搜索
  3. 展开 高级搜索
  4. 选择 启用针对有限索引的全局搜索
  5. 选择 保存更改
  6. 如果你已经索引了实例,必须重新索引实例。 这会删除现有的搜索数据,以正确启用过滤功能。

启用自定义语言分析器

先决条件:

  • 您必须拥有实例的管理员访问权限。

您可以通过使用来自Elastic的smartcnkuromoji分析插件来增强对中文和日文的支持。

要启用自定义语言分析器:

  1. 安装所需插件,有关插件安装说明,请参阅Elasticsearch文档。插件必须安装在集群的每个节点上,并且每个节点在安装后都必须重启。有关插件的列表,请参见本节后面的表格。
  2. 在左侧边栏底部,选择管理
  3. 选择设置 > 搜索
  4. 找到自定义分析器:语言支持
  5. 索引启用插件支持。
  6. 选择保存更改以使更改生效。
  7. 触发零停机时间重新索引或从头开始重新索引所有内容,以创建具有更新映射的新索引。
  8. 完成上一步后,为搜索启用插件支持。

有关应安装内容的指导,请参阅以下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. 在左侧边栏底部,选择管理

  2. 选择设置 > 搜索

  3. 清除Elasticsearch索引启用Elasticsearch搜索复选框。

  4. 选择保存更改

  5. 可选。对于仍在线的Elasticsearch实例,删除现有索引:

    # 对于使用Linux包安装的情况
    sudo gitlab-rake gitlab:elastic:delete_index
    
    # 对于自行编译的安装
    bundle exec rake gitlab:elastic:delete_index RAILS_ENV=production

恢复索引

先决条件:

  • 您必须拥有实例的管理员访问权限。

要恢复索引:

  1. 在左侧边栏底部,选择管理
  2. 选择设置 > 搜索
  3. 展开高级搜索
  4. 清除暂停Elasticsearch索引复选框。

零停机时间重新索引

这种重新索引方法背后的理念是利用Elasticsearch重新索引API和Elasticsearch索引别名功能来执行操作。我们设置了一个索引别名,该别名连接到GitLab用于读写的主primary索引。当重新索引过程开始时,我们会暂时暂停向primary索引写入数据。然后,我们创建另一个索引并调用Reindex API,将索引数据迁移到新索引。重新索引作业完成后,我们将通过将索引别名连接到它来切换到新索引,使其成为新的primary索引。最后,我们恢复写入操作,恢复正常运行。

使用零停机时间重新索引

你可以使用零停机时间重新索引来配置无法在不创建新索引并复制现有数据的情况下更改的索引设置或映射。你不应使用零停机时间重新索引来修复缺失的数据。如果数据尚未被索引,零停机时间重新索引不会向搜索集群添加数据。你必须在开始重新索引之前完成所有高级搜索迁移

触发重新索引

先决条件:

  • 你必须拥有实例的管理员访问权限。

要触发重新索引:

  1. 以管理员身份登录你的 GitLab 实例。
  2. 在左侧边栏底部,选择 Admin
  3. 选择 Settings > Search
  4. 展开 Elasticsearch 零停机时间重新索引
  5. 选择 触发集群重新索引

重新索引可能是一个耗时较长的过程,具体取决于你的 Elasticsearch 集群大小。

此过程完成后,原始索引计划在 14 天后被删除。你可以通过点击触发重新索引过程的同一页面上的 取消 按钮来取消此操作。

当重新索引正在运行时,你可以在同一区域下跟踪其进度。

触发零停机时间重新索引

先决条件:

  • 你必须拥有实例的管理员访问权限。

要触发零停机时间重新索引:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Elasticsearch 零停机时间重新索引。 可用的设置如下:
切片乘数

切片乘数计算重新索引期间的切片数量

GitLab 使用手动分片来高效且安全地控制重新索引,这允许用户仅重试失败的切片。

该乘数的默认值为 2,应用于每个索引的分片数量。例如,如果此值为 2 且你的索引有 20 个分片,则重新索引任务会被拆分为 40 个切片。

最大运行切片

最大运行切片参数的默认值为 60,对应于 Elasticsearch 重新索引期间允许并发运行的最大切片数量。

将该值设置得过高可能会对性能产生不利影响,因为你的集群可能会因搜索和写入而过载。将该值设置得过低可能会导致重新索引过程花费很长时间才能完成。

此参数的最佳值取决于你的集群规模、你是否愿意在接受一些降级的搜索性能的情况下进行重新索引,以及重新索引快速完成并恢复索引的重要性。

将最近的重新索引作业标记为失败并恢复索引

先决条件:

  • 你必须拥有实例的管理员访问权限。

要放弃未完成的重新索引作业并恢复索引:

  1. 将最近的重新索引作业标记为失败:

    # 对于使用 Linux 包安装的环境
    sudo gitlab-rake gitlab:elastic:mark_reindex_failed
    
    # 对于自行编译安装的环境
    bundle exec rake gitlab:elastic:mark_reindex_failed RAILS_ENV=production
  2. 在左侧边栏底部,选择 Admin

  3. 选择 Settings > Search

  4. 展开 高级搜索

  5. 取消选中 暂停 Elasticsearch 索引 复选框。

索引完整性

索引完整性检测并修复缺失的仓库数据。当针对组或项目的代码搜索返回无结果时,会自动使用此功能。

高级搜索迁移

重新索引迁移在后台运行,这意味着你无需手动重新索引实例。

在 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. 在左侧边栏底部选择 管理
  2. 选择 设置 > 搜索
  3. 展开 高级搜索
  4. Elasticsearch 迁移已停止 警告框内,选择 重试迁移。迁移会在后台安排重试。

若你无法让迁移成功,可考虑采用 最后手段:从头重新创建索引。这可能帮你跳过问题——因新创建的索引会跳过所有迁移,直接以最新正确模式重建索引。

所有迁移必须在重大升级前完成

在升级到主要 GitLab 版本前,你必须完成该主要版本前的最新次要版本的所有迁移。你还需解决并 重试任何已停止的迁移,再继续主要版本升级。更多信息见 升级迁移

已被删除的迁移会被 标记为过时。若你在所有待处理的高级搜索迁移完成前升级 GitLab,新版本中被删除的待处理迁移无法执行或重试。此时你必须 从头重新创建索引

可跳过的迁移

可跳过的迁移仅在满足条件时执行。例如,若迁移依赖特定版 Elasticsearch,可跳过至该版本。

若可跳过的迁移未在其被标记为过时前执行,要应用变更你必须 重新创建索引

GitLab 高级搜索 Rake 任务

Rake 任务可用于:

以下是部分可用的 Rake 任务:

任务 描述
sudo gitlab-rake gitlab:elastic:info 输出高级搜索集成的调试信息。
sudo gitlab-rake gitlab:elastic:index 在 GitLab 17.0 及更早版本中,启用 Elasticsearch 索引并运行 gitlab:elastic:recreate_indexgitlab:elastic:clear_index_statusgitlab:elastic:index_group_entitiesgitlab:elastic:index_projectsgitlab:elastic:index_snippetsgitlab:elastic:index_users
在 GitLab 17.1 及更高版本中,在后台排队一个 Sidekiq 任务。首先,该任务启用 Elasticsearch 索引并暂停索引以确保所有索引被创建。然后,该任务重新创建所有索引,清除索引状态,并排队额外的 Sidekiq 任务来索引项目和组数据、片段(snippets)以及用户。最后,恢复 Elasticsearch 索引来完成操作。引入于 GitLab 17.1 带有名为elastic_index_use_trigger_indexing 的标志。默认启用。正式发布 于 GitLab 17.3。移除了功能标志 elastic_index_use_trigger_indexing
sudo gitlab-rake gitlab:elastic:pause_indexing 暂停 Elasticsearch 索引。变更仍会被跟踪。适用于集群/索引迁移。
sudo gitlab-rake gitlab:elastic:resume_indexing 恢复 Elasticsearch 索引。
sudo gitlab-rake gitlab:elastic:index_projects 遍历所有项目,并在后台排队 Sidekiq 任务来索引它们。只能在索引创建后使用。
sudo gitlab-rake gitlab:elastic:index_group_entities 调用 gitlab:elastic:index_epicsgitlab:elastic:index_group_wikis
sudo gitlab-rake gitlab:elastic:index_epics 索引已启用 Elasticsearch 的组中的所有史诗(epics)。
sudo gitlab-rake gitlab:elastic:index_group_wikis 索引已启用 Elasticsearch 的组中的所有 Wiki。
sudo gitlab-rake gitlab:elastic:index_projects_status 确定所有项目仓库数据(代码、提交和 Wiki)的整体索引状态。状态通过将已索引项目数除以总项目数再乘以 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_indexgitlab:elastic:create_empty_index。不会排队任何索引作业。 | | sudo gitlab-rake gitlab:elastic:index_snippets | 执行Elasticsearch导入以索引片段数据。 | | sudo gitlab-rake gitlab:elastic:index_users | 将所有用户导入Elasticsearch。 | | sudo gitlab-rake gitlab:elastic:projects_not_indexed | 显示哪些项目的仓库数据未被索引。此任务不包含非仓库数据,例如问题、合并请求或里程碑。 | | sudo gitlab-rake gitlab:elastic:reindex_cluster | 安排一个零停机的集群重新索引任务。 | | sudo gitlab-rake gitlab:elastic:mark_reindex_failed | 将最近一次重新索引作业标记为失败。 | | sudo gitlab-rake gitlab:elastic:list_pending_migrations | 列出待处理的迁移。待处理的迁移包括尚未开始的、已开始但未完成的以及已暂停的迁移。 | | sudo gitlab-rake gitlab:elastic:estimate_cluster_size | 基于总仓库大小,获取代码和wiki索引大小以及集群总大小的估算值。 | | sudo gitlab-rake gitlab:elastic:estimate_shard_sizes | 基于近似的数据库计数,获取每个索引的分片大小估算值。此估算不包含仓库数据(代码、提交和wikis)。在GitLab 16.11中引入。 | | sudo gitlab-rake gitlab:elastic:enable_search_with_elasticsearch | 启用使用Elasticsearch的高级搜索。 | | sudo gitlab-rake gitlab:elastic:disable_search_with_elasticsearch | 禁用使用Elasticsearch的高级搜索。 |

环境变量

除Rake任务外,还有一些环境变量可用于修改流程:

环境变量 数据类型 功能
ID_TO 整数 指示索引器仅索引项目ID小于或等于该值的项目。
ID_FROM 整数 指示索引器仅索引项目ID大于或等于该值的项目。

索引一系列项目或特定项目

使用 ID_FROMID_TO 环境变量,你可以索引有限数量的项目。这对阶段性索引很有用。

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

由于 ID_FROMID_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 项目数据(默认)
blobs 代码
issues 问题数据
merge_requests 合并请求数据
milestones 里程碑数据
notes 注记数据
snippets 片段数据
wiki_blobs Wiki内容
users 用户
epics Epic数据

在GitLab.com和GitLab Dedicated上,漏洞记录始终会被索引到所有项目和命名空间中,以支持搜索外的功能。
GitLab Self-Managed上的漏洞记录索引已在问题525484中提出。

调优

选择最佳集群配置的指南

有关选择集群配置的基本指导,请参阅Elastic Cloud Calculator

  • 通常建议使用至少包含一个副本的2节点集群配置,这能提供容错能力。如果存储用量增长迅速,你可能需要提前规划水平扩展(添加更多节点)。
  • 不建议对搜索集群使用HDD存储,因为这会严重影响性能。最好使用SSD存储(例如NVMe或SATA SSD驱动器)。
  • 不要对大型实例使用仅协调节点。仅协调节点比数据节点小,这可能影响性能和高级搜索迁移
  • 你可以使用GitLab性能工具,对不同搜索集群规模和配置进行搜索性能基准测试。
  • 堆大小应设置为不超过物理RAM的50%。此外,它不应超过零基压缩oops的阈值。具体阈值因系统而异,但在大多数系统上26GB是安全的,有些系统也可能达到30GB。详见堆大小设置设置JVM选项
  • refresh_interval是每索引的设置。如果你不需要实时数据,可以将默认的1s调整为更大的值。这会影响你看到新鲜结果的速度。如果这对你的场景很重要,应尽可能接近默认值。
  • 如果你有大量密集型索引操作,可能需要将indices.memory.index_buffer_size提高到30%或40%。

高级搜索设置

Elasticsearch 分片数量

对于单节点集群,将每个索引的 Elasticsearch 分片数量设置为 Elasticsearch 数据节点的 CPU 核心数。

对于多节点集群,运行 Rake 任务 gitlab:elastic:estimate_shard_sizes 来确定每个索引的分片数量。该任务会返回分片和副本大小的建议,以及包含数据库数据的索引的大致文档计数。

保持平均分片大小在几 GB 到 30 GB 之间。若平均分片大小超过 30 GB,需增加该索引的分片大小并触发零停机时间重新索引。为确保集群健康,每节点的分片数量不得超过配置堆内存大小的 20 倍。例如,30 GB 堆内存的节点最多允许 600 个分片。

要更新索引的分片数量,修改设置后触发零停机时间重新索引

Elasticsearch 副本数量

对于单节点集群,将每个索引的 Elasticsearch 副本数量设为 0

对于多节点集群,将每个索引的 Elasticsearch 副本数量设为 1(每个分片对应一个副本)。该数值不能为 0,否则单个节点故障会导致索引损坏。

若启用分片分配感知,每个分片的副本总数必须能被感知属性的数量整除(通常为节点或区域数)。副本在所有感知属性间的均匀分布可保障最优容错性与负载均衡。

(1 + `number_of_replicas`) / `number_of_awareness_attributes` = 整数

要更新索引的副本数量,修改设置后触发零停机时间重新索引

高效索引大型实例

先决条件:

  • 你必须拥有该实例的管理员访问权限。

对大型实例进行索引会生成大量 Sidekiq 作业。 请确保通过以下方式为此任务做好准备: 使用可扩展的设置 或创建 额外的 Sidekiq 进程

如果启用高级搜索 因数据量过大导致问题:

  1. 配置你的 Elasticsearch 主机和端口

  2. 创建空索引:

    # 对于使用 Linux 包安装的情况
    sudo gitlab-rake gitlab:elastic:create_empty_index
    
    # 对于自行编译安装的情况
    bundle exec rake gitlab:elastic:create_empty_index RAILS_ENV=production
  3. 如果这是对 GitLab 实例的重新索引,请清除索引状态:

    # 对于使用 Linux 包安装的情况
    sudo gitlab-rake gitlab:elastic:clear_index_status
    
    # 对于自行编译安装的情况
    bundle exec rake gitlab:elastic:clear_index_status RAILS_ENV=production
  4. 选中 Elasticsearch 索引 复选框

  5. 对大型 Git 仓库进行索引可能需要较长时间。为了加快进程,你可以优化索引速度

    • 你可以临时增加 refresh_interval

    • 你可以将副本数量设置为 0。此设置控制索引每个主分片的副本数量。因此,将副本数设为 0 会有效禁用跨节点的分片复制,从而提高索引性能。这在可靠性和查询性能方面是一个重要的权衡。重要的是在初始索引完成后,记得将副本数设置为一个合理的值。

    你可以预期索引时间减少 20%。索引完成后,你可以将 refresh_intervalnumber_of_replicas 设置回所需的值。

    此步骤可选,但可能显著加快大型索引操作的速度。

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "index" : {
               "refresh_interval" : "30s",
               "number_of_replicas" : 0
           } }'
  6. 索引项目和其关联的数据:

    # 对于使用 Linux 包安装的情况
    sudo gitlab-rake gitlab:elastic:index_projects
    
    # 对于自行编译安装的情况
    bundle exec rake gitlab:elastic:index_projects RAILS_ENV=production

    这会为每个需要索引的项目排入一个 Sidekiq 作业。 你可以在 管理区监控 > 后台任务 > 队列标签页 中查看这些作业, 并选择 elastic_commit_indexer,或者你可以使用 Rake 任务查询索引状态:

    # 对于使用 Linux 包安装的情况
    sudo gitlab-rake gitlab:elastic:index_projects_status
    
    # 对于自行编译安装的情况
    bundle exec rake gitlab:elastic:index_projects_status RAILS_ENV=production
    
    索引完成度 65.55%(10000 个项目中已处理 6555 个)

    如果你希望将索引范围限制在特定项目区间,你可以提供 ID_FROMID_TO 参数:

    # 对于使用 Linux 包安装的情况
    sudo gitlab-rake gitlab:elastic:index_projects ID_FROM=1001 ID_TO=2000
    
    # 对于自行编译安装的情况
    bundle exec rake gitlab:elastic:index_projects ID_FROM=1001 ID_TO=2000 RAILS_ENV=production

    其中 ID_FROMID_TO 是项目 ID。这两个参数都是可选的。 上面的示例会对从 ID 1001 到(包括)ID 2000 的所有项目进行索引。

    有时由 gitlab:elastic:index_projects 排队的项目索引作业可能会被中断。 这可能有多种原因,但重新运行索引任务是安全的。

    你也可以使用 gitlab:elastic:clear_index_status Rake 任务强制索引器“忘记”所有进度, 从而从头开始重试索引过程。

  7. Epic、群组维基、个人片段和用户不与项目关联,必须单独索引:

    # 对于使用 Linux 包安装的情况
    sudo gitlab-rake gitlab:elastic:index_epics
    sudo gitlab-rake gitlab:elastic:index_group_wikis
    sudo gitlab-rake gitlab:elastic:index_snippets
    sudo gitlab-rake gitlab:elastic:index_users
    
    # 对于自行编译安装的情况
    bundle exec rake gitlab:elastic:index_epics 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
  1. 在索引后再次启用复制和刷新(仅在你之前增加了 refresh_interval 时执行):

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

    启用刷新后应调用强制合并。

    对于 Elasticsearch 6.x 及更高版本,在进行强制合并前,请确保索引处于只读模式:

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

    然后,启动强制合并:

    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
           } }'
  2. 索引完成后,勾选“使用 Elasticsearch 启用搜索”复选框


### 已删除文档

每当对被索引的 GitLab 对象进行修改或删除操作时(例如合并请求描述被修改、仓库默认分支中的文件被删除、项目被删除等),索引中的文档就会被删除。然而,由于这些是“软”删除,因此“已删除文档”的总数(以及浪费的空间)会增加。

Elasticsearch 会智能地合并段以移除这些已删除文档。不过,根据你的 GitLab 安装中的活动量和类型,索引中可能会有多达 50% 的浪费空间。

一般来说,我们建议让 Elasticsearch 使用默认设置自动完成合并并回收空间。来自 [Lucene 处理已删除文档的方式](https://www.elastic.co/blog/lucenes-handling-of-deleted-documents "Lucene's Handling of Deleted Documents") 的说明提到:*“总的来说,除了可能减小最大段大小外,最好保持 Lucene 的默认设置不变,不必过于担心删除何时会被回收。”*

不过,一些较大的安装可能希望调整合并策略设置:

- 考虑将 `index.merge.policy.max_merged_segment` 的大小从默认的 5 GB 减少到 2 GB 或 3 GB 左右。只有当段中有至少 50% 的删除时才会进行合并。较小的段大小允许更频繁地进行合并。

  ```shell
  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,它控制着删除被处理的 aggressiveness。但这可能导致昂贵的合并决策,所以我们建议除非你理解其中的权衡,否则不要更改此设置。

    curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
         --data '{
           "index" : {
             "merge.policy.reclaim_deletes_weight": "3.0"
           }
         }'
  • 不要执行 强制合并 来移除已删除文档。文档中的一个警告指出,这可能导致非常大的段,这些段可能永远不会被回收,并且还可能导致严重的性能或可用性问题。

为大型实例配置专用 Sidekiq 节点或进程

对于大多数实例,您无需配置专用的 Sidekiq 节点或进程。 以下步骤使用了 Sidekiq 的高级设置——称为 路由规则。 务必充分理解使用路由规则的后果,以避免完全丢失作业。

索引大型实例可能是一个耗时且资源密集的过程,可能会压垮 Sidekiq 节点和进程。这会负面影响 GitLab 的性能和可用性。

由于 GitLab 允许启动多个 Sidekiq 进程,您可以创建一个额外的进程专门用于索引一组队列(或队列组)。这样,您可以确保索引队列始终有专用的工作线程,而其他队列则有另一个专用工作线程以避免竞争。

为此,请使用 路由规则 选项,该选项允许 Sidekiq 根据 Worker 匹配查询 将作业路由到特定队列。

要处理此问题,我们通常推荐以下两种方案之一。您可以选择:

对于以下步骤,考虑 sidekiq['routing_rules'] 的配置项:

  • ["feature_category=global_search", "global_search"] 表示所有索引作业都会被路由到 global_search 队列。
  • ["*", "default"] 表示所有其他非索引作业会被路由到 default 队列。

sidekiq['queue_groups'] 中至少有一个进程必须包含 mailers 队列,否则邮件作业根本不会被处理。

路由规则 (sidekiq['routing_rules']) 必须在所有 GitLab 节点上保持一致(尤其是 GitLab Rails 和 Sidekiq 节点)。

启动多个进程时,进程数量不能超过您要分配给 Sidekiq 的 CPU 核心数。每个 Sidekiq 进程只能使用一个 CPU 核心,具体取决于可用工作负载和并发设置。更多细节,请参阅如何 运行多个 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", # 监听 global_search 队列的进程
       "default,mailers" # 监听 default 和 mailers 队列的进程
    ]
    
    sidekiq['min_concurrency'] = 20
    sidekiq['max_concurrency'] = 20

    如果您使用的是 GitLab 16.11 及更早版本,请显式禁用任何 队列选择器

    sidekiq['queue_selector'] = false
  2. 保存文件并 重新配置 GitLab 以使更改生效。

  3. 在其他所有 Rails 和 Sidekiq 节点上,确保 sidekiq['routing_rules'] 与之前的配置相同。

  4. 运行 Rake 任务来 迁移现有作业

重要的是在重新配置 GitLab 后立即运行 Rake 任务。重新配置 GitLab 后,现有作业不会处理,直到 Rake 任务开始迁移作业。

两个节点,每个节点一个进程

要在两个节点上处理这些队列组:

  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", # 监听 global_search 队列的进程
    ]
    
    sidekiq['min_concurrency'] = 20
    sidekiq['max_concurrency'] = 20

    如果您使用的是 GitLab 16.11 及更早版本,请显式禁用任何 队列选择器

    sidekiq['queue_selector'] = false
  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" # 监听 default 和 mailers 队列的进程
    ]
    
    sidekiq['min_concurrency'] = 20
    sidekiq['max_concurrency'] = 20

    如果您使用的是 GitLab 16.11 及更早版本,请显式禁用任何 队列选择器

    sidekiq['queue_selector'] = false
  4. 在所有其他 Rails 和 Sidekiq 节点上,确保 sidekiq['routing_rules'] 与之前的配置一致。

  5. 保存文件并重新配置 GitLab,使更改生效。

  6. 运行 Rake 任务来迁移现有作业

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

重要的是在重新配置 GitLab 后立即运行此 Rake 任务。重新配置 GitLab 后,现有作业不会处理,直到 Rake 任务开始迁移作业。

回退到基础搜索

有时您的 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::CommitIndexerWorkerElasticWikiIndexerWorker 再次触发项目的索引。
  3. 通过在 sidekiq.log 中搜索 ElasticDeleteProjectWorker,获取所有项目删除操作。
    你必须再次触发 ElasticDeleteProjectWorker

你也可以定期创建 Elasticsearch 快照,以减少从数据丢失中恢复所需的时间,而无需从头开始重建索引。