创建和恢复 OpenSearch 快照

快照并非瞬间完成。它需要时间,也不能提供集群在某个时刻的完美视图。创建快照期间,仍然可以索引文档并向集群发送其他请求,但新文档及对已有文档的更新通常不会包含在快照中。快照包含 OpenSearch 开始创建快照时的主分片状态。根据快照线程池的大小,不同分片被纳入快照的时间可能略有差异。

OpenSearch 快照是增量的,也就是说,只存储自上次成功创建快照以来发生变化的数据。频繁创建快照与较少创建快照之间的磁盘占用差异通常很小。

换句话说,连续一周每小时创建一次快照,总计 168 个快照,其占用的磁盘空间可能不会比一周末创建单个快照多很多。此外,创建快照越频繁,每次完成所需的时间越短。一些 OpenSearch 用户每 30 分钟就创建一次快照。

需要删除快照时,务必使用 OpenSearch API,而不是直接进入存储位置删除文件。一个集群的增量快照通常共享大量数据;使用 API 时,OpenSearch 只会删除其他快照不再使用的数据。


Table of contents

注册仓库

创建快照前,必须先“注册”快照仓库。快照仓库只是一个存储位置,可以是共享文件系统、Amazon Simple Storage Service(Amazon S3)、Hadoop 分布式文件系统(HDFS)或 Azure Storage。

节点级仓库设置

以下节点级设置针对各自类型的所有仓库,全局控制仓库行为。这些设置在 opensearch.yml 中配置,修改后需要重启集群。

文件系统仓库设置

  • repositories.fs.chunk_size(静态,字节单位):设置文件系统仓库存储大型二进制对象时的默认分块大小,决定如何把大型对象文件拆成较小块存储。较大的块可提高顺序访问性能,但也可能增加内存占用和网络传输开销。当仓库设置没有明确指定块大小时,此设置作为回退值。默认无限制,即不分块;最小值为 5 字节。

URL 仓库设置

  • repositories.url.allowed_urls(静态,列表):指定允许 URL 仓库访问的 URL 模式列表。该安全设置限制创建 URL 仓库时可使用的 URL,防止访问未经授权的资源或内部网络资源。URL 模式支持通配符,例如 http://snapshot.example.com/*。为空(默认)时,除非配置了 path.repo,否则不允许使用 URL 仓库。此设置有助于防止服务器端请求伪造(SSRF)攻击。默认值为 [],即空列表。

  • repositories.url.supported_protocols(静态,列表):定义 URL 仓库支持的 URL 协议,控制访问 URL 仓库时允许使用的协议方案,例如 HTTP、HTTPS 或 FTP。限制协议有助于避免通过不安全或非预期协议访问资源,提高安全性。默认值为 [“http”, “https”, “ftp”, “file”, “jar”]。

共享文件系统

  1. 要使用共享文件系统作为快照仓库,请将其添加到 opensearch.yml:

    path.repo: ["/mnt/snapshots"]
    

    对于 RPM 和 Debian 安装,随后可以挂载该文件系统。如果使用 Docker 安装,在启动集群之前,将该文件系统添加到 docker-compose.yml 中的每个节点:

    volumes:
      - /Users/jdoe/snapshots:/mnt/snapshots
    
  2. 然后通过 REST API 注册仓库:

    PUT /_snapshot/my-fs-repository
    {
      "type": "fs",
      "settings": {
        "location": "/mnt/snapshots"
      }
    }
    

通常只需要指定 location 参数。有关允许的请求参数,请参阅“注册或更新快照仓库 API”。 [1]

Amazon S3

  1. 要使用 Amazon S3 存储桶作为快照仓库,请在所有节点上安装 repository-s3 插件:

    sudo ./bin/opensearch-plugin install repository-s3
    

    如果使用 Docker 安装,请参阅“使用插件”。Dockerfile 应类似如下: [2]

    FROM opensearchproject/opensearch:3.9.0
    
    ENV AWS_ACCESS_KEY_ID <access-key>
    ENV AWS_SECRET_ACCESS_KEY <secret-key>
    
    # Optional
    ENV AWS_SESSION_TOKEN <optional-session-token>
    
    RUN /usr/share/opensearch/bin/opensearch-plugin install --batch repository-s3
    RUN /usr/share/opensearch/bin/opensearch-keystore create
    
    RUN echo $AWS_ACCESS_KEY_ID | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.access_key
    RUN echo $AWS_SECRET_ACCESS_KEY | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.secret_key
    
    # Optional
    RUN echo $AWS_SESSION_TOKEN | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.session_token
    

    Docker 集群启动后,跳到第 7 步。

    如果使用 AWS IAM 实例配置文件,让 AWS EC2 实例上的 OpenSearch 节点在授予 S3 存储桶访问权限时继承策略角色,跳到第 8 步。 [3]

  2. 将 AWS 访问密钥和私有密钥添加到 OpenSearch 密钥库:

    sudo ./bin/opensearch-keystore add s3.client.default.access_key
    sudo ./bin/opensearch-keystore add s3.client.default.secret_key
    
  3. 可选:如果使用自定义 S3 端点,例如 MinIO,请禁用 Amazon EC2 元数据连接:

    export AWS_EC2_METADATA_DISABLED=true
    

    如果通过 Helm 安装 OpenSearch,请在 values 文件中更新以下设置:

    extraEnvs:
      - name: AWS_EC2_METADATA_DISABLED
        value: "true"
    
  4. 可选:如果使用临时凭证,请添加会话令牌:

    sudo ./bin/opensearch-keystore add s3.client.default.session_token
    
  5. 可选:如果通过代理连接互联网,请添加相应凭证:

    sudo ./bin/opensearch-keystore add s3.client.default.proxy.username
    sudo ./bin/opensearch-keystore add s3.client.default.proxy.password
    
  6. 可选:将其他设置添加到 opensearch.yml:

    s3.client.default.endpoint: s3.amazonaws.com # S3 has alternate endpoints, but you probably don't need to change this value.
    s3.client.default.max_retries: 3 # number of retries if a request fails
    s3.client.default.path_style_access: false # whether to use the deprecated path-style bucket URLs.
    # You probably don't need to change this value, but for more information, see https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html#path-style-access.
    s3.client.default.protocol: https # http or https
    s3.client.default.proxy.host: my-proxy-host # the hostname for your proxy server
    s3.client.default.proxy.port: 8080 # port for your proxy server
    s3.client.default.read_timeout: 50s # the S3 connection timeout
    s3.client.default.use_throttle_retries: true # whether the client should wait a progressively longer amount of time (exponential backoff) between each successive retry
    s3.client.default.region: us-east-2 # AWS region to use. For non-AWS S3 storage, this value is required but has no effect.
    
  7. 可选:如果不想使用 AWS 访问密钥和私有密钥,可以配置 S3 插件,使用面向服务账户的 AWS Identity and Access Management(IAM)角色:

    sudo ./bin/opensearch-keystore add s3.client.default.role_arn
    sudo ./bin/opensearch-keystore add s3.client.default.role_session_name
    

    如果不想配置 AWS 访问密钥和私有密钥,请修改以下 opensearch.yml 设置,并确保 repository-s3 插件可以访问该文件:

    s3.client.default.identity_token_file: /usr/share/opensearch/plugins/repository-s3/token
    

    如果不能复制文件,可以在 ${OPENSEARCH_PATH_CONFIG} 文件夹中创建指向网页身份令牌文件的符号链接:

    ln -s $AWS_WEB_IDENTITY_TOKEN_FILE "${OPENSEARCH_PATH_CONFIG}/aws-web-identity-token-file"
    

    在以下 opensearch.yml 设置中,可以通过指定相对于 ${OPENSEARCH_PATH_CONFIG} 解析的路径,引用网页身份令牌文件:

    s3.client.default.identity_token_file: aws-web-identity-token-file
    

    IAM 角色至少需要上述设置中的一项。其他设置将从环境变量(如果存在)中读取:AWS_ROLE_ARN、AWS_WEB_IDENTITY_TOKEN_FILE、AWS_ROLE_SESSION_NAME。

  8. 如果修改了 opensearch.yml,必须重启集群中的每个节点。否则,只需重新加载集群的安全设置:

    POST /_nodes/reload_secure_settings
    
  9. 如果还没有 S3 存储桶,请先创建一个。创建快照需要存储桶访问权限。以下 IAM 策略是这些权限的示例:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": [
            "s3:GetBucketLocation",
            "s3:ListBucket",
            "s3:ListBucketMultipartUploads",
            "s3:ListBucketVersions"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::your-bucket"
          ]
        },
        {
          "Action": [
            "s3:AbortMultipartUpload",
            "s3:DeleteObject",
            "s3:GetObject",
            "s3:ListMultipartUploadParts",
            "s3:PutObject"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::your-bucket/*"
          ]
        }
      ]
    }
    
  10. 通过 REST API 注册仓库:

    PUT /_snapshot/my-s3-repository
    {
      "type": "s3",
      "settings": {
        "bucket": "my-s3-bucket",
        "base_path": "my/snapshot/directory"
      }
    }
    

通常只需要指定 bucket 和 base_path 参数。有关允许的请求参数,请参阅“注册或更新快照仓库 API”。 [4]

HDFS

要使用 Hadoop 分布式文件系统(HDFS)作为快照仓库,请执行以下步骤:

  1. 为快照创建一个 HDFS 目录,例如 /opensearch/repositories/searchable_snapshots,并确保 OpenSearch 用户对该目录具有读写权限。

  2. 在所有节点上安装 repository-hdfs 插件:

    sudo ./bin/opensearch-plugin install repository-hdfs
    

    如果使用 Docker 安装,请参阅“使用插件”。Dockerfile 应类似如下: [5]

    FROM opensearchproject/opensearch:3.9.0
    
    RUN /usr/share/opensearch/bin/opensearch-plugin install --batch repository-hdfs
    
  3. 可选:如果 HDFS 集群使用 Kerberos,可能需要将 keytab 文件分发到所有节点,并确保 OpenSearch 用户具有读取权限。

  4. 重启 OpenSearch 集群中的所有节点。

  5. 使用 OpenSearch Snapshot API 注册仓库:

    不使用 HDFS 身份验证:

     PUT _snapshot/searchable_snapshots
     {
       "type": "hdfs",
       "settings": {
         "uri": "hdfs://namenode:8020/",
         "path": "/opensearch/repositories/searchable_snapshots",
         "conf.<key>": "<value>"
       }
     }
    

    使用 HDFS 身份验证:

     PUT _snapshot/searchable_snapshots
     {
       "type": "hdfs",
       "settings": {
         "uri": "hdfs://namenode:8020/",
         "path": "/opensearch/repositories/searchable_snapshots",
         "security.principal": "opensearch@YOURREALM",
         "conf.<key>": "<value>"
       }
     }
    

使用 Helm 注册 Microsoft Azure 存储账户

对于通过 Helm 部署的 OpenSearch 集群,使用以下步骤注册以 Azure 存储账户为后端的快照仓库。

  1. 创建 Azure 存储账户,然后在其中创建一个容器。详情请参阅“Azure Storage 简介”。 [6]

  2. 使用 bash 脚本创建 OpenSearch 密钥库文件。将以下示例复制到名为 create-keystore.sh 的文件中,以创建脚本:

    #!/bin/bash
    
    /usr/share/opensearch/bin/opensearch-keystore create
    echo $AZURE_SNAPSHOT_STORAGE_ACCOUNT | /usr/share/opensearch/bin/opensearch-keystore add --stdin azure.client.default.account
    echo $AZURE_SNAPSHOT_STORAGE_ACCOUNT_KEY | /usr/share/opensearch/bin/opensearch-keystore add --stdin azure.client.default.key
    cp /usr/share/opensearch/config/opensearch.keystore /tmp/keystore/opensearch.keystore
    
  3. 创建 Docker 文件,其中包含密钥库、OpenSearch 实例和 Azure 仓库的详细信息。将以下示例复制并保存为 Dockerfile:

    FROM opensearchproject/opensearch:3.9.0
    
    RUN /usr/share/opensearch/bin/opensearch-plugin install --batch repository-azure
    COPY --chmod=0775 create-keystore.sh create-keystore.sh
    
  4. 使用以下 docker build 命令,根据 Dockerfile 构建 OpenSearch 镜像:

    docker build -t opensearch-custom:3.9.0 -f Dockerfile .
    
  5. 使用以下清单和命令创建一个包含 Azure 存储账户密钥的 Kubernetes Secret:

    apiVersion: v1
    kind: Secret
    metadata:
      name: opensearch
    data:
      azure-snapshot-storage-account-key: ### Insert base64 encoded key
    
  6. 通过 Helm 部署 OpenSearch,并使用以下附加值。在 AZURE_SNAPSHOT_STORAGE_ACCOUNT 环境变量中指定存储账户的值: [7]

    extraInitContainers:
    - name: keystore-generator
      image: opensearch-custom:3.9.0
      command: ["/bin/bash", "-c"]
      args: ["bash create-keystore.sh"]
      env:
      - name: AZURE_SNAPSHOT_STORAGE_ACCOUNT
        value: ### Insert storage account name
      - name: AZURE_SNAPSHOT_STORAGE_ACCOUNT_KEY
        valueFrom:
          secretKeyRef:
            name: opensearch
            key: azure-snapshot-storage-account-key
      volumeMounts:
      - name: keystore
        mountPath: /tmp/keystore
    
    extraVolumeMounts:
    - name: keystore
      mountPath: /usr/share/opensearch/config/opensearch.keystore
      subPath: opensearch.keystore
      
    extraVolumes:
    - name: keystore
      emptyDir: {}
    
    image:
      repository: "opensearch-custom"
      tag: 3.9.0
    
  7. 使用 Snapshot API 注册仓库。在以下命令中,将 snapshot_container 替换为第 1 步指定的名称:

    PUT /_snapshot/my-azure-snapshot
    {
      "type": "azure",
      "settings": {
        "client": "default",
        "container": "snapshot_container"
      }
    }
    

设置 Microsoft Azure Blob Storage

要使用 Azure Blob Storage 作为快照仓库,请执行以下步骤:

  1. 在所有节点上运行以下命令,安装 repository-azure 插件:

    ./bin/opensearch-plugin install repository-azure
    
  2. 安装 repository-azure 插件后,在初始化节点之前定义 Azure Blob Storage 设置。首先通过以下安全设置定义 Azure Storage 账户名:

    ./bin/opensearch-keystore add azure.client.default.account
    

选择以下一种方式配置 Azure Blob Storage 的身份验证凭证。

使用 Azure Blob Storage 账户密钥

使用以下设置指定 Azure Storage 账户密钥:

./bin/opensearch-keystore add azure.client.default.key

共享访问签名

使用共享访问签名(SAS)访问 Azure 时,使用以下设置:

./bin/opensearch-keystore add azure.client.default.sas_token      

Azure 令牌凭证

从 OpenSearch 2.15 开始,可以在 opensearch.yml 中配置令牌凭证身份验证流程。这种方式不同于需要 SAS 或账户密钥的连接字符串身份验证。

如果使用令牌凭证身份验证,需要选择令牌凭证类型。尽管 Azure 提供多种类型,截至 OpenSearch 2.15,只支持托管标识。 [8]

要使用托管标识,在 opensearch.yml 中添加令牌凭证类型,值设为 managed 或 managed_identity,表示使用托管标识进行令牌凭证身份验证:

azure.client.default.token_credential_type: "managed_identity"

使用 Azure 令牌凭证时,请注意:

  • opensearch.yml 中默认禁用令牌凭证支持。
  • 配置多个选项时,令牌凭证的优先级高于 Azure Storage 账户密钥或 SAS。

创建快照

创建快照时,需要指定两项信息:

  • 快照仓库名称。
  • 快照名称。

以下快照包含所有索引和集群状态:

PUT /_snapshot/my-repository/snapshot-1

也可以添加请求正文,包含或排除特定索引,或指定其他设置:

PUT /_snapshot/my-repository/snapshot-2
{
  "indices": "opensearch_dashboards*,my-index*,-my-index-2016",
  "ignore_unavailable": true,
  "include_global_state": false,
  "partial": false
}

详情请参阅“创建快照 API”。 [9]

创建后立即查询快照,可能看到类似以下结果:

GET /_snapshot/my-repository/snapshot-2
{
  "snapshots": [{
    "snapshot": "snapshot-2",
    "version": "6.5.4",
    "indices": [
      "opensearch_dashboards_sample_data_ecommerce",
      "my-index",
      "opensearch_dashboards_sample_data_logs",
      "opensearch_dashboards_sample_data_flights"
    ],
    "include_global_state": false,
    "state": "IN_PROGRESS",
    ...
  }]
}

详情请参阅“获取快照 API”。 [10]

注意,快照仍在进行中。如果要等快照完成后再继续,在请求中添加 wait_for_completion 参数。快照可能需要一段时间才能完成,因此请考虑这个选项是否适合你的使用场景:

PUT _snapshot/my-repository/snapshot-3?wait_for_completion=true

快照具有以下状态:

状态 说明
SUCCESS 快照已成功存储所有分片。
IN_PROGRESS 快照正在进行中。
PARTIAL 至少一个分片未能成功存储。只有在创建快照时将 partial 设为 true,才可能出现该状态。
FAILED 快照遇到错误,没有存储任何数据。
INCOMPATIBLE 快照与该集群运行的 OpenSearch 版本不兼容。请参阅“冲突和兼容性”。 [11]

已有快照正在进行时,不能创建另一个快照。使用以下请求检查状态:

GET /_snapshot/_status

恢复快照

恢复快照的第一步是获取已有快照。要查看所有快照仓库:

GET /_snapshot/_all

要查看某个仓库中的所有快照:

GET /_snapshot/my-repository/_all

然后恢复快照:

POST /_snapshot/my-repository/snapshot-2/_restore

与创建快照一样,可以添加请求正文以包含或排除特定索引,或指定其他设置:

POST /_snapshot/my-repository/snapshot-2/_restore
{
  "indices": "opensearch_dashboards*,my-index*",
  "ignore_unavailable": true,
  "include_global_state": false,
  "include_aliases": false,
  "partial": false,
  "rename_pattern": "opensearch_dashboards(.+)",
  "rename_replacement": "restored_opensearch_dashboards$1",
  "index_settings": {
    "index.blocks.read_only": false
  },
  "ignore_index_settings": [
    "index.refresh_interval"
  ]
}

详情请参阅“恢复快照 API”。 [12]

在使用远程存储的集群之间恢复快照

使用远程存储时,OpenSearch 自动将索引段和 translog 备份到远程仓库,通常为 Amazon S3。如果在两个都使用远程存储、但使用不同远程存储仓库的集群之间恢复快照,必须指定源集群的远程存储仓库。

此流程仅适用于启用了远程存储的集群。对于没有远程存储的标准 OpenSearch 集群,使用标准快照恢复过程,不需要这些附加参数。

以下流程将快照从集群 A 恢复到集群 B;两个集群都使用远程存储,但各自使用不同的 Amazon S3 仓库。

前提条件

开始前,请确保满足以下条件:

  • 两个集群运行相同的 OpenSearch 版本。
  • 已从源集群的远程存储配置中取得 Amazon S3 存储桶名称、基础路径、AWS Key Management Service(KMS)密钥的 Amazon Resource Name(ARN)以及域 ARN。

步骤

要将源集群的快照恢复到目标集群,请执行以下步骤:

  1. 在目标集群中,将源集群的快照仓库注册为只读:

    PUT /_snapshot/source-cluster-snapshots
    {
      "type": "s3",
      "settings": {
        "bucket": "source-snapshot-bucket",
        "base_path": "snapshots",
        "region": "us-east-1",
        "readonly": true
      }
    }
    
  2. 在目标集群中,将源集群的远程索引段仓库注册为只读:

    PUT /_snapshot/source-remote-segment-repo
    {
      "type": "s3",
      "settings": {
        "bucket": "source-segment-bucket",
        "base_path": "remote-store/segments",
        "region": "us-east-1",
        "amazon_es_kms_enc_ctx": "domainARN=arn:aws:es:us-east-1:123456789012:domain/source-cluster",
        "amazon_es_kms_key_arn": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-56ef-78gh-90ij-klmnopqrstuv",
        "amazon_es_encryption": "true",
        "remote_store_index_shallow_copy": "true",
        "readonly": true
      }
    }
    
  3. 在目标集群中,将源集群的远程 translog 仓库注册为只读:

    PUT /_snapshot/source-remote-translog-repo
    {
      "type": "s3",
      "settings": {
        "bucket": "source-translog-bucket",
        "base_path": "remote-store/translogs",
        "region": "us-east-1",
        "amazon_es_kms_enc_ctx": "domainARN=arn:aws:es:us-east-1:123456789012:domain/source-cluster",
        "amazon_es_kms_key_arn": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-56ef-78gh-90ij-klmnopqrstuv",
        "amazon_es_encryption": "true",
        "remote_store_index_shallow_copy": "true",
        "readonly": true
      }
    }
    
  4. 确认能够列出源快照仓库中的快照:

    GET /_snapshot/source-cluster-snapshots/_all
    
  5. 恢复快照,同时指定源索引段和 translog 仓库:

    POST /_snapshot/source-cluster-snapshots/snapshot-1/_restore
    {
      "indices": "my-index",
      "source_remote_store_repository": "source-remote-segment-repo",
      "source_remote_translog_repository": "source-remote-translog-repo"
    }
    

目标集群将从快照仓库恢复索引,并将恢复后的索引配置为从源集群的远程存储仓库读取远程索引段和 translog。

如果恢复时出现索引名称冲突,可以使用 rename_pattern 和 rename_replacement 参数重命名索引,也可以在恢复前删除存在冲突的索引。

冲突和兼容性

恢复索引时,避免名称冲突的一种方式是使用 rename_pattern 和 rename_replacement 选项。必要时,随后可以使用 _reindex API 合并两者。不过,在从快照恢复之前删除造成冲突的索引,可能更简单。

同样,恢复带有别名的索引时,可以使用 rename_alias_pattern 和 rename_alias_replacement 选项,避免别名冲突。

在从快照恢复之前,可以使用 _close API 关闭已有索引,但快照中的索引必须与已有索引具有相同的分片数。

建议在从快照恢复之前停止向集群发送写入请求,以避免出现以下情况:

  1. 删除索引时,同时删除了它的别名。
  2. 对已删除别名的写入请求,创建了一个与该别名同名的新索引。
  3. 快照中的别名因与新索引名称冲突,无法恢复。

快照只能向前兼容一个主版本。较早 OpenSearch 版本创建的快照,在版本升级后,仍可由最初创建它的 OpenSearch 版本恢复。例如,OpenSearch 2.11 或更早版本创建的快照,在升级到 2.12 之后,仍可以由 2.11 集群恢复。

如果旧快照来自更早的 OpenSearch 主版本,可以先把它恢复到比快照版本高一个主版本的中间集群,对所有索引重新建立索引,然后创建新快照,反复执行,直到达到目标主版本。但你也可能发现,在新集群中手动索引数据更简单。

安全注意事项

如果使用 Security 插件,快照还受到以下限制:

  • 执行快照和恢复操作的用户,必须具有内置 manage_snapshots 角色。
  • 不能恢复包含全局状态或 .opendistro_security 索引的快照。

如果快照包含全局状态,恢复时必须将其排除。如果快照还包含 .opendistro_security 索引,应将其排除,或列出所有希望包含的其他索引:

POST /_snapshot/my-repository/snapshot-3/_restore
{
  "indices": "-.opendistro_security",
  "include_global_state": false
}

.opendistro_security 索引包含敏感数据,因此建议在创建快照时排除它。如果确实需要从快照恢复该索引,请求中必须包含管理员证书:

curl -k --cert ./kirk.pem --key ./kirk-key.pem -XPOST 'https://localhost:9200/_snapshot/my-repository/snapshot-3/_restore?pretty'

强烈建议不要使用管理员证书恢复 .opendistro_security,因为这样可能改变整个集群的安全状态。有关备份和恢复 Security 插件配置的推荐流程,请参阅“注意事项”。 [13]

索引编解码器注意事项

有关索引编解码器的注意事项,请参阅“索引编解码器”。 [14]

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容