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

Zoekt

  • Tier: Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed
  • Status: Beta

This feature is in beta and subject to change without notice. For more information, see epic 9404. To provide feedback on this feature, leave a comment on issue 420920.

Zoekt 是一个专为代码搜索设计的开源搜索引擎。

通过此集成,您可以在 GitLab 中使用 精确代码搜索 代替 高级搜索 来搜索代码。 您可以使用精确匹配和正则表达式模式在组或仓库中搜索代码。

安装 Zoekt

先决条件:

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

要在 GitLab 中启用精确代码搜索, 您必须至少连接一个 Zoekt 节点到该实例。 支持以下 Zoekt 安装方法:

以下安装方法仅用于测试,不适用于生产环境:

启用精确代码搜索

先决条件:

  • 您必须拥有该实例的管理员权限。
  • 您必须安装 Zoekt

要在 GitLab 中启用精确代码搜索

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. 选中 Enable indexingEnable searching 复选框。
  5. 选择 Save changes

检查索引状态

先决条件:

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

索引性能取决于 Zoekt 索引器节点上的 CPU 和内存限制。 要检查索引状态:

运行此 Rake 任务:

gitlab-rake gitlab:zoekt:info

要让数据每 10 秒自动刷新一次,请运行以下任务:

gitlab-rake "gitlab:zoekt:info[10]"

Rails console 中,运行以下命令:

Search::Zoekt::Index.group(:state).count
Search::Zoekt::Repository.group(:state).count
Search::Zoekt::Task.group(:state).count

暂停索引

先决条件:

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

要暂停精确代码搜索的索引:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. 选中 Pause indexing 复选框。
  5. 选择 Save changes

当您暂停精确代码搜索的索引时,您仓库中的所有更改都会被排队。 要恢复索引,请清除 Pause indexing for exact code search 复选框。

自动索引根命名空间

先决条件:

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

您可以自动索引现有的和新创建的根命名空间。 要自动索引所有根命名空间:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. 选中 Index root namespaces automatically 复选框。
  5. 选择 Save changes

当您启用此设置时,GitLab 会为以下所有项目创建索引任务:

  • 所有组和子组
  • 任何新的根命名空间

项目被索引后,GitLab 只会在检测到仓库更改时创建增量索引。

当您禁用此设置时:

  • 现有的根命名空间保持索引状态。
  • 新的根命名空间不再被索引。

缓存搜索结果

先决条件:

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

您可以缓存搜索结果以获得更好的性能。 此功能默认启用,缓存结果时间为五分钟。

要缓存搜索结果:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. 选中 Cache search results for five minutes 复选框。
  5. 选择 Save changes

设置并发索引任务数

先决条件:

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

您可以设置 Zoekt 节点的并发索引任务数,相对于其 CPU 容量。

更高的乘数意味着可以同时运行更多任务,这会 提高索引吞吐量,但会增加 CPU 使用量。 默认值为 1.0(每个 CPU 核心一个任务)。

您可以根据节点的性能和工作负载调整此值。 要设置并发索引任务数:

  1. 在左侧边栏底部,选择 Admin

  2. 选择 Settings > Search

  3. 展开 Exact code search configuration

  4. Indexing CPU to tasks multiplier 文本框中,输入一个值。

    例如,如果 Zoekt 节点有 4 个 CPU 核心,乘数为 1.5, 则该节点的并发任务数为 6

  5. 选择 Save changes

设置每个索引任务的并行进程数

先决条件:

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

您可以设置每个索引任务的并行进程数。

更高的数字会减少索引时间,但会增加 CPU 和内存使用量。 默认值为 1(每个索引任务一个进程)。

您可以根据节点的性能和工作负载调整此值。 要设置每个索引任务的并行进程数:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. Number of parallel processes per indexing task 文本框中,输入一个值。
  5. 选择 Save changes

设置每次索引部署的命名空间数量

先决条件:

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

您可以设置每次 RolloutWorker 作业的初始索引命名空间数量。 默认值为 32。 您可以根据节点的性能和工作负载调整此值。

要设置每次索引部署的命名空间数量:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. Number of namespaces per indexing rollout 文本框中, 输入一个大于零的数字。
  5. 选择 Save changes

定义离线节点的自动删除时间

先决条件:

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

您可以在特定时间段后自动删除离线的 Zoekt 节点, 以及它们相关的索引、仓库和任务。 默认值为 12h(12 小时)。

使用此设置来管理您的 Zoekt 基础设施,防止出现孤立资源。 要定义离线节点的自动删除时间:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. Offline nodes automatically deleted after 文本框中,输入一个值 (例如,30m(30 分钟)、2h(2 小时)或 1d(1 天))。 要禁用自动删除,设置为 0
  5. 选择 Save changes

定义项目的索引超时时间

先决条件:

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

您可以定义项目的索引超时时间。 默认值为 30m(30 分钟)。

要定义项目的索引超时时间:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. Indexing timeout per project 文本框中,输入一个值 (例如,30m(30 分钟)、2h(2 小时)或 1d(1 天))。
  5. 选择 Save changes

设置项目中可被索引的最大文件数

先决条件:

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

您可以设置项目中可被索引的最大文件数。 默认分支中文件数超过此限制的项目不会被索引。

默认值为 500,000

您可以根据节点的性能和工作负载调整此值。 要设置项目中可被索引的最大文件数:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. Maximum number of files per project to be indexed 文本框中,输入一个大于零的数字。
  5. 选择 Save changes

定义失败命名空间的重试间隔

先决条件:

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

您可以定义之前失败的命名空间的重试间隔。 默认值为 1d(1 天)。 值为 0 表示失败的命名空间永不重试。

要定义失败命名空间的重试间隔:

  1. 在左侧边栏底部,选择 Admin
  2. 选择 Settings > Search
  3. 展开 Exact code search configuration
  4. Retry interval for failed namespaces 文本框中,输入一个值 (例如,30m(30 分钟)、2h(2 小时)或 1d(1 天))。
  5. 选择 Save changes

在独立服务器上运行 Zoekt

先决条件:

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

要在与 GitLab 不同的服务器上运行 Zoekt:

  1. 更改 Gitaly 监听接口
  2. 安装 Zoekt

规格建议

以下建议在某些部署中可能过度配置。 您应该监控您的部署以确保:

  • 不会发生内存不足事件。
  • CPU 限制不会过度。
  • 索引性能满足您的要求。

根据您特定的工作负载特征调整资源,包括:

  • 仓库大小和复杂性
  • 活跃开发人员数量
  • 代码更改频率
  • 索引模式

节点

为了获得最佳性能,正确配置 Zoekt 节点的大小至关重要。 由于资源分配和管理的不同,Kubernetes 和 VM 部署的规格建议也有所不同。

Kubernetes 部署

下表显示了基于索引存储需求的 Kubernetes 部署推荐资源:

磁盘 Webserver CPU Webserver 内存 Indexer CPU Indexer 内存
128 GB 1 16 GiB 1 6 GiB
256 GB 1.5 32 GiB 1 8 GiB
512 GB 2 64 GiB 1 12 GiB
1 TB 3 128 GiB 1.5 24 GiB
2 TB 4 256 GiB 2 32 GiB

为了更精细地管理资源,您可以为不同的容器分别分配 CPU 和内存。

对于 Kubernetes 部署:

  • 不要为 Zoekt 容器设置 CPU 限制。 CPU 限制可能在索引突发期间导致不必要的限制, 这会显著影响性能。 相反,依赖资源请求来保证最低 CPU 可用性, 并确保容器在可用且需要时使用额外的 CPU。
  • 设置适当的内存限制以防止资源争用 和内存不足情况。
  • 使用高性能存储类以获得更好的索引性能。 GitLab.com 在 GCP 上使用 pd-balanced,它平衡了性能和成本。 等效选项包括 AWS 上的 gp3 和 Azure 上的 Premium_LRS

VM 和裸机部署

下表显示了基于索引存储需求的 VM 和裸机部署推荐资源:

磁盘 VM 大小 总 CPU 总内存 AWS GCP Azure
128 GB Small 2 核心 16 GB r5.large n1-highmem-2 Standard_E2s_v3
256 GB Medium 4 核心 32 GB r5.xlarge n1-highmem-4 Standard_E4s_v3
512 GB Large 4 核心 64 GB r5.2xlarge n1-highmem-8 Standard_E8s_v3
1 TB X-Large 8 核心 128 GB r5.4xlarge n1-highmem-16 Standard_E16s_v3
2 TB 2X-Large 16 核心 256 GB r5.8xlarge n1-highmem-32 Standard_E32s_v3

您可以将这些资源仅分配给整个节点。

对于 VM 和裸机部署:

  • 监控 CPU、内存和磁盘使用情况以识别瓶颈。 Webserver 和 indexer 进程共享相同的 CPU 和内存资源。
  • 考虑使用 SSD 存储以获得更好的索引性能。
  • 确保 GitLab 和 Zoekt 节点之间的数据传输有足够的网络带宽。

存储

Zoekt 的存储需求因仓库特征而异,包括大型和二进制文件的数量。

作为起点,您可以将 Zoekt 存储估算为 Gitaly 存储的一半。 例如,如果您的 Gitaly 存储为 1 TB,您可能需要大约 500 GB 的 Zoekt 存储。

要监控 Zoekt 节点的使用情况,请参阅检查索引状态。 如果由于磁盘空间不足导致命名空间未被索引,请考虑添加或扩展节点。

安全和认证

Zoekt 实现了多层认证系统来保护 GitLab、Zoekt 索引器和 Zoekt Webserver 组件之间的通信。 所有通信通道都强制执行认证。

所有认证方法都使用 GitLab Shell 密钥。 认证失败尝试会返回 401 Unauthorized 响应。

Zoekt 索引器到 GitLab

Zoekt 索引器使用 JSON Web Token (JWT) 向 GitLab 进行身份验证, 以检索索引任务并发送完成回调。

此方法使用 .gitlab_shell_secret 进行签名和验证。 令牌在 Gitlab-Shell-Api-Request 头中发送。 端点包括:

  • GET /internal/search/zoekt/:uuid/heartbeat 用于任务检索
  • POST /internal/search/zoekt/:uuid/callback 用于状态更新

此方法确保 Zoekt 索引器节点和 GitLab 之间的任务分发 和状态报告的安全轮询。

GitLab 到 Zoekt Webserver

JWT 认证

GitLab 使用 JSON Web Token (JWT) 向 Zoekt Webserver 进行身份验证, 以执行搜索查询。 JWT 令牌提供有时间限制、加密签名的认证, 与其他 GitLab 认证模式一致。

此方法使用 Gitlab::Shell.secret_token 和 HS256 算法(HMAC with SHA-256)。 令牌在 Authorization: Bearer <jwt_token> 头中发送, 并在五分钟后过期以限制暴露。

端点包括 /webserver/api/search/webserver/api/v2/search。 JWT 声明是颁发者 (gitlab) 和受众 (gitlab-zoekt)。

基本认证

GitLab 通过 NGINX 使用 HTTP 基本认证向 Zoekt Webserver 进行身份验证, 以执行搜索查询。 基本认证主要用于 GitLab Helm chart 和 Kubernetes 部署。

此方法使用 Kubernetes secrets 中配置的用户名和密码。 端点包括 Zoekt Webserver 上的 /webserver/api/search/webserver/api/v2/search

故障排除

使用 Zoekt 时,您可能会遇到以下问题。

命名空间未被索引

当您启用设置时,新的命名空间会自动被索引。 如果命名空间未被自动索引,请检查 Sidekiq 日志以查看作业是否正在处理。 Search::Zoekt::SchedulingWorker 负责索引命名空间。

Rails console 会话 中,您可以检查:

  • Zoekt 未启用的命名空间:

    Namespace.group_namespaces.root_namespaces_without_zoekt_enabled_namespace
  • Zoekt 索引的状态:

    Search::Zoekt::Index.all.pluck(:state, :namespace_id)

要手动索引命名空间,请运行以下命令:

namespace = Namespace.find_by_full_path('<top-level-group-to-index>')
Search::Zoekt::EnabledNamespace.find_or_create_by(namespace: namespace)

错误:SilentModeBlockedError

当您尝试运行精确代码搜索时,可能会收到 SilentModeBlockedError。 当 GitLab 实例上启用了静默模式时,会出现此问题。

要解决此问题,请确保静默模式已禁用。

错误:connections to all backends failing

application_json.log 中,您可能会收到以下错误:

connections to all backends failing; last error: UNKNOWN: ipv4:1.2.3.4:5678: Trying to connect an http1.x server

要解决此问题,请检查您是否在使用任何代理。 如果在使用,请将 GitLab 服务器的 IP 地址设置为 no_proxy

gitlab_rails['env'] = {
  "http_proxy" => "http://proxy.domain.com:1234",
  "https_proxy" => "http://proxy.domain.com:1234",
  "no_proxy" => ".domain.com,IP_OF_GITLAB_INSTANCE,127.0.0.1,localhost"
}

proxy.domain.com:1234 是代理实例的域名和端口。 IP_OF_GITLAB_INSTANCE 指向 GitLab 实例的公共 IP 地址。

您可以通过运行 ip a 并检查以下信息之一来获取此信息:

  • 适当网络接口的 IP 地址
  • 您使用的任何负载均衡器的公共 IP 地址

验证 Zoekt 节点连接

要验证您的 Zoekt 节点是否正确配置和连接, 在 Rails console 会话 中:

  • 检查配置的 Zoekt 节点总数:

    Search::Zoekt::Node.count
  • 检查有多少节点在线:

    Search::Zoekt::Node.online.count

或者,您可以使用 gitlab:zoekt:info Rake 任务。

如果在线节点数低于配置的节点数或配置节点数为零时为零, 您可能在 GitLab 和您的 Zoekt 节点之间存在连接问题。