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 chart (作为独立 chart 或 GitLab Helm chart 的子 chart)
- GitLab Operator (使用
gitlab-zoekt.install=true)
以下安装方法仅用于测试,不适用于生产环境:
启用精确代码搜索
先决条件:
- 您必须拥有该实例的管理员权限。
- 您必须安装 Zoekt。
要在 GitLab 中启用精确代码搜索:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 选中 Enable indexing 和 Enable searching 复选框。
- 选择 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暂停索引
先决条件:
- 您必须拥有该实例的管理员权限。
要暂停精确代码搜索的索引:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 选中 Pause indexing 复选框。
- 选择 Save changes。
当您暂停精确代码搜索的索引时,您仓库中的所有更改都会被排队。 要恢复索引,请清除 Pause indexing for exact code search 复选框。
自动索引根命名空间
先决条件:
- 您必须拥有该实例的管理员权限。
您可以自动索引现有的和新创建的根命名空间。 要自动索引所有根命名空间:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 选中 Index root namespaces automatically 复选框。
- 选择 Save changes。
当您启用此设置时,GitLab 会为以下所有项目创建索引任务:
- 所有组和子组
- 任何新的根命名空间
项目被索引后,GitLab 只会在检测到仓库更改时创建增量索引。
当您禁用此设置时:
- 现有的根命名空间保持索引状态。
- 新的根命名空间不再被索引。
缓存搜索结果
先决条件:
- 您必须拥有该实例的管理员权限。
您可以缓存搜索结果以获得更好的性能。 此功能默认启用,缓存结果时间为五分钟。
要缓存搜索结果:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 选中 Cache search results for five minutes 复选框。
- 选择 Save changes。
设置并发索引任务数
先决条件:
- 您必须拥有该实例的管理员权限。
您可以设置 Zoekt 节点的并发索引任务数,相对于其 CPU 容量。
更高的乘数意味着可以同时运行更多任务,这会
提高索引吞吐量,但会增加 CPU 使用量。
默认值为 1.0(每个 CPU 核心一个任务)。
您可以根据节点的性能和工作负载调整此值。 要设置并发索引任务数:
-
在左侧边栏底部,选择 Admin。
-
选择 Settings > Search。
-
展开 Exact code search configuration。
-
在 Indexing CPU to tasks multiplier 文本框中,输入一个值。
例如,如果 Zoekt 节点有
4个 CPU 核心,乘数为1.5, 则该节点的并发任务数为6。 -
选择 Save changes。
设置每个索引任务的并行进程数
先决条件:
- 您必须拥有该实例的管理员权限。
您可以设置每个索引任务的并行进程数。
更高的数字会减少索引时间,但会增加 CPU 和内存使用量。
默认值为 1(每个索引任务一个进程)。
您可以根据节点的性能和工作负载调整此值。 要设置每个索引任务的并行进程数:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 在 Number of parallel processes per indexing task 文本框中,输入一个值。
- 选择 Save changes。
设置每次索引部署的命名空间数量
先决条件:
- 您必须拥有该实例的管理员权限。
您可以设置每次 RolloutWorker 作业的初始索引命名空间数量。
默认值为 32。
您可以根据节点的性能和工作负载调整此值。
要设置每次索引部署的命名空间数量:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 在 Number of namespaces per indexing rollout 文本框中, 输入一个大于零的数字。
- 选择 Save changes。
定义离线节点的自动删除时间
先决条件:
- 您必须拥有该实例的管理员权限。
您可以在特定时间段后自动删除离线的 Zoekt 节点,
以及它们相关的索引、仓库和任务。
默认值为 12h(12 小时)。
使用此设置来管理您的 Zoekt 基础设施,防止出现孤立资源。 要定义离线节点的自动删除时间:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 在 Offline nodes automatically deleted after 文本框中,输入一个值
(例如,
30m(30 分钟)、2h(2 小时)或1d(1 天))。 要禁用自动删除,设置为0。 - 选择 Save changes。
定义项目的索引超时时间
先决条件:
- 您必须拥有该实例的管理员权限。
您可以定义项目的索引超时时间。
默认值为 30m(30 分钟)。
要定义项目的索引超时时间:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 在 Indexing timeout per project 文本框中,输入一个值
(例如,
30m(30 分钟)、2h(2 小时)或1d(1 天))。 - 选择 Save changes。
设置项目中可被索引的最大文件数
先决条件:
- 您必须拥有该实例的管理员权限。
您可以设置项目中可被索引的最大文件数。 默认分支中文件数超过此限制的项目不会被索引。
默认值为 500,000。
您可以根据节点的性能和工作负载调整此值。 要设置项目中可被索引的最大文件数:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 在 Maximum number of files per project to be indexed 文本框中,输入一个大于零的数字。
- 选择 Save changes。
定义失败命名空间的重试间隔
先决条件:
- 您必须拥有该实例的管理员权限。
您可以定义之前失败的命名空间的重试间隔。
默认值为 1d(1 天)。
值为 0 表示失败的命名空间永不重试。
要定义失败命名空间的重试间隔:
- 在左侧边栏底部,选择 Admin。
- 选择 Settings > Search。
- 展开 Exact code search configuration。
- 在 Retry interval for failed namespaces 文本框中,输入一个值
(例如,
30m(30 分钟)、2h(2 小时)或1d(1 天))。 - 选择 Save changes。
在独立服务器上运行 Zoekt
先决条件:
- 您必须拥有该实例的管理员权限。
要在与 GitLab 不同的服务器上运行 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 节点之间存在连接问题。