OpenSearch

简介

WARNING

支持的 OpenSearch 版本:3.x

OpenSearch 在各个发行版之间保持 API 一致性,并且与 Elasticsearch 7.10.2 保持兼容。OpenSearch 版本会自动从 root/ping 端点获取。基于该版本,Jaeger 会使用兼容的索引映射和 OpenSearch REST API。也可以通过 version: 配置属性显式提供版本。

除了安装并运行 OpenSearch 之外,OpenSearch 不需要其他初始化。运行起来后,将正确的配置值传递给 Jaeger 即可。

Jaeger 在 OpenSearch 上使用与 Elasticsearch 相同的存储实现。大多数配置选项的行为也相同,因此共享的细节请参考 Elasticsearch 文档。

配置

Jaeger 仓库中提供了一个使用 OpenSearch 后端的 Jaeger 示例配置:config-opensearch.yaml。由于 OpenSearch 共享 Elasticsearch 实现,请参考 config.go 作为可用选项的权威来源。

分片和副本

分片和副本是需要特别注意的配置值,因为它们是在创建索引时决定的。Shards and Replicas 中针对 Elasticsearch 的指导同样适用于 OpenSearch。

查询时间范围

max_span_agemax_trace_duration 的行为与 Elasticsearch 相同,参见 Query Time Range

Alauda Distributed Tracing 在 OpenSearch 上使用基于别名的轮转(rotation.auto_rollover),因此 max_span_age 会被静默替换为 50 年,保留期仅由 ISM policy 决定。只有 max_trace_duration 值值得调优:将其设置为你预期的最长 trace,因为默认值 24h 会将每个查询在两侧各扩展整整一天。

索引管理策略

Jaeger 在 OpenSearch 上提供与 Elasticsearch 相同的三种轮转策略,通过 indices.<type> 下的 rotation 配置选择。比较表和字段参考请参见 Index Management Strategies。唯一与后端相关的差异是生命周期管理由 OpenSearch Index State Management(ISM)插件提供,而不是 Elasticsearch ILM。

Alauda Distributed Tracing 为四种索引类型都配置了 rotation.auto_rollover,并由 ISM policy 驱动轮转和删除。

索引轮转

jaeger-es-rollover init 为 OpenSearch 做的准备与 Elasticsearch 完全相同:它会创建索引模板、每种类型的第一个带编号索引(例如 jaeger-span-000001),以及读写别名。通用说明和轮转触发条件请参见 Index Rollover

该工具会通过 ping 端点检测后端,并切换生命周期相关的部分:

ElasticsearchOpenSearch
生命周期插件ILMISM
Policy API_ilm/policy/<name>_plugins/_ism/policies/<name>
索引模板中的轮转别名index.lifecycle.rollover_aliasindex.plugins.index_state_management.rollover_alias
policy 如何附加到索引index.lifecycle.name,写入索引模板ism_template 模式,声明在 policy 内部

jaeger-es-rollover 镜像地址由 Alauda Build of Jaeger v2 cluster plugin 发布在 jaeger-cluster-plugin-manifest ConfigMap 中,因此它始终与已部署的 Jaeger 版本保持一致:

export JAEGER_ES_ROLLOVER_IMAGE=$(kubectl -ncpaas-system get configmap jaeger-cluster-plugin-manifest -o jsonpath='{.data.jaeger-es-rollover-image}')

ISM 支持

OpenSearch ISM 根据由状态和转换组成的 policy 自动管理索引。它与 Elasticsearch ILM 扮演相同的角色:按时间或大小将写入索引轮转出去,并在索引超过保留期后将其删除。

Jaeger 不会创建生命周期 policy。jaeger-es-rollover init 只会验证 ES_ILM_POLICY_NAME 指定的 policy 是否存在;如果不存在,则会失败并提示 ILM/ISM policy <name> doesn't exist. Please create it and re-run init请在运行初始化之前先创建 ISM policy。

要启用 ISM 支持

  1. 在 OpenSearch 中创建一个 ISM policy,例如命名为 jaeger-ism-policydescription 是必填项,并且 policy 必须包含 ism_template 部分,因为 OpenSearch 是在创建索引时通过匹配索引名称来附加 policy,而不是通过模板设置:

    {
      "policy": {
        "description": "Jaeger index rollover and retention",
        "default_state": "hot",
        "states": [
          {
            "name": "hot",
            "actions": [ { "rollover": { "min_index_age": "1d", "min_primary_shard_size": "50gb" } } ],
            "transitions": [ { "state_name": "delete", "conditions": { "min_index_age": "7d" } } ]
          },
          { "name": "delete", "actions": [ { "delete": {} } ], "transitions": [] }
        ],
        "ism_template": [
          { "index_patterns": ["jaeger-span-0*"], "priority": 100 }
        ]
      }
    }
    WARNING

    ism_template 模式限制为带 -0* 后缀的编号轮转索引。像 jaeger-span-* 这样的模式也会匹配之后创建的日期后缀索引,例如在回滚到 rotation.periodic 之后创建的索引。此时 ISM 会接管这些索引并在其上失败,因为它们没有附加到轮转别名。

    涵盖全部四种索引类型的完整 policy 示例,请参见 Installing Alauda Distributed Tracing with OpenSearch

  2. 使用 ES_USE_ILM=true 和设置为 policy 名称的 ES_ILM_POLICY_NAME 运行初始化程序。这些变量在 OpenSearch 上仍然保留 ES_ 前缀:

    nerdctl run -it --rm --net=host \
      -e ES_USE_ILM=true \
      -e ES_ILM_POLICY_NAME=jaeger-ism-policy \
      -e ADAPTIVE_SAMPLING=true \
      ${JAEGER_ES_ROLLOVER_IMAGE} \
      init https://localhost:9200

    除了 Index Rollover 中描述的模板、种子索引和别名之外,初始化程序还会:

    • 通过 _plugins/_ism/policies/ 端点验证 ISM policy 是否存在。
    • 在索引模板中嵌入 index.plugins.index_state_management.rollover_alias
    • 为写别名设置 is_write_index: true,这是 ISM 执行索引轮转所必需的。

    ADAPTIVE_SAMPLING=true 还会创建 sampling 别名。只要 Jaeger 配置中为 sampling 索引类型声明了轮转策略,就应设置该值;否则对该索引的写入会失败,因为其写别名不存在。

  3. 使用 create_mappings: false 并为每种索引类型设置 auto_rollover 轮转策略部署 Jaeger:

    create_mappings: false
    indices:
      spans:
        rotation:
          auto_rollover: {}
      services:
        rotation:
          auto_rollover: {}
      dependencies:
        rotation:
          auto_rollover: {}
      sampling:
        rotation:
          auto_rollover: {}

    保持 auto_rollover.policy_name 为空。它只会把 policy 名称嵌入 Jaeger 自己创建的模板中,而 OpenSearch 不会读取这些内容。

    WARNING

    此处必须设置 create_mappings: false,而且没有任何配置校验会强制这一点。如果使用默认的 create_mappings: true,Jaeger 会在启动时以相同名称重新创建索引模板,并同时丢失读别名和 ISM 轮转别名。写入仍会继续成功,因此部署看起来是正常的,直到第一次轮转生成一个读别名不覆盖、且 ISM 也无法再轮转的索引:新 trace 会被存储,但永远不会出现在 Jaeger UI 中。修复方法是将 create_mappings: false,重新运行 jaeger-es-rollover init,并手动修复受影响的索引。

一旦由 ISM 管理索引,轮转和保留都会自动执行,不再需要 rolloverlookbackindex-cleaner cron job。

更新 ISM Policy

更改正在运行的部署的保留或轮转条件需要两步。

  1. OpenSearch 会拒绝对现有 policy 执行 PUT,除非请求携带当前序列号,否则会返回 version_conflict_engine_exception。因此需要先读取 policy,再将这些值传回:

    curl -k -sS -u "${OPENSEARCH_USER}:${OPENSEARCH_PASS}" -X PUT \
      "${OPENSEARCH_ENDPOINT}/_plugins/_ism/policies/jaeger-ism-policy?if_seq_no=<seq-no>&if_primary_term=<primary-term>" \
      -H 'Content-Type: application/json' --data-binary @policy.json

    <seq-no><primary-term>GET _plugins/_ism/policies/jaeger-ism-policy 返回的 _seq_no_primary_term 值。

  2. ISM 在接管某个索引时会将 policy 复制到该索引中,因此新的定义只会应用于之后创建的索引。请通过每种索引类型各发起一次请求,将其显式应用到现有索引:

    curl -k -sS -u "${OPENSEARCH_USER}:${OPENSEARCH_PASS}" -X POST \
      "${OPENSEARCH_ENDPOINT}/_plugins/_ism/change_policy/${JAEGER_ES_INDEX_PREFIX}-jaeger-span-0*" \
      -H 'Content-Type: application/json' \
      -d '{"policy_id": "jaeger-ism-policy"}'

    将模式锚定在单一索引类型上。中间包含通配符的模式,例如 -jaeger-*-0*,也会匹配日期后缀索引,并使请求报告失败。

NOTE

_plugins/_ism/explain 是最终一致的:在 policy 变更之后以及索引创建之后,它可能会在几分钟内报告 policy_id: null。发现新索引的后台扫描每 plugins.index_state_management.coordinator.sweep_period 运行一次(默认 10 分钟),随后每个受管理索引还会按 plugins.index_state_management.job_interval(默认 5 分钟)并带抖动进行评估。测试 policy 时应避免按分钟级的条件进行判断。

有关部署步骤,请参见 Installing Alauda Distributed Tracing with OpenSearch