教程:基于单向跨集群复制的灾难恢复

编辑

教程:基于单向跨集群复制的灾难恢复编辑

了解如何基于单向跨集群复制在两个集群之间进行故障转移和故障恢复。您还可以访问 双向灾难恢复,以设置自动故障转移和故障恢复的数据流复制。

  • 设置从 clusterAclusterB 的单向跨集群复制。
  • 故障转移 - 如果 clusterA 离线,clusterB 需要将 follower 索引“提升”为常规索引,以允许写入操作。所有摄取都需要重定向到 clusterB,这由客户端(Logstash、Beats、Elastic Agents 等)控制。
  • 故障恢复 - 当 clusterA 恢复在线时,它将承担 follower 的角色,并从 clusterB 复制 leader 索引。
Uni-directional cross cluster replication failover and failback

跨集群复制提供功能来仅复制用户生成的索引。跨集群复制并非设计用于复制系统生成的索引或快照设置,并且无法跨集群复制 ILM 或 SLM 策略。在跨集群复制 限制 中了解更多信息。

先决条件编辑

在完成本教程之前,设置跨集群复制 以连接两个集群并配置 follower 索引。

在本教程中,kibana_sample_data_ecommerceclusterA 复制到 clusterB

response = client.cluster.put_settings(
  body: {
    persistent: {
      cluster: {
        remote: {
          "clusterA": {
            mode: 'proxy',
            skip_unavailable: 'true',
            server_name: 'clustera.es.region-a.gcp.elastic-cloud.com',
            proxy_socket_connections: '18',
            proxy_address: 'clustera.es.region-a.gcp.elastic-cloud.com:9400'
          }
        }
      }
    }
  }
)
puts response
### On clusterB ###
PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "clusterA": {
          "mode": "proxy",
          "skip_unavailable": "true",
          "server_name": "clustera.es.region-a.gcp.elastic-cloud.com",
          "proxy_socket_connections": "18",
          "proxy_address": "clustera.es.region-a.gcp.elastic-cloud.com:9400"
        }
      }
    }
  }
}
### On clusterB ###
PUT /kibana_sample_data_ecommerce2/_ccr/follow?wait_for_active_shards=1
{
  "remote_cluster": "clusterA",
  "leader_index": "kibana_sample_data_ecommerce"
}

写入(例如摄取或更新)应仅发生在 leader 索引上。follower 索引是只读的,将拒绝任何写入。

clusterA 停机时的故障转移编辑

  1. clusterB 中的 follower 索引提升为常规索引,以便它们接受写入。这可以通过以下方式实现

    • 首先,暂停 follower 索引的索引跟踪。
    • 接下来,关闭 follower 索引。
    • 取消跟踪 leader 索引。
    • 最后,打开 follower 索引(此时它是一个常规索引)。
    response = client.ccr.pause_follow(
      index: 'kibana_sample_data_ecommerce2'
    )
    puts response
    
    response = client.indices.close(
      index: 'kibana_sample_data_ecommerce2'
    )
    puts response
    
    response = client.ccr.unfollow(
      index: 'kibana_sample_data_ecommerce2'
    )
    puts response
    
    response = client.indices.open(
      index: 'kibana_sample_data_ecommerce2'
    )
    puts response
    ### On clusterB ###
    POST /kibana_sample_data_ecommerce2/_ccr/pause_follow
    POST /kibana_sample_data_ecommerce2/_close
    POST /kibana_sample_data_ecommerce2/_ccr/unfollow
    POST /kibana_sample_data_ecommerce2/_open
  2. 在客户端(Logstash、Beats、Elastic Agent)上,手动重新启用 kibana_sample_data_ecommerce2 的摄取,并将流量重定向到 clusterB。在此期间,您还应将所有搜索流量重定向到 clusterB 集群。您可以通过将文档摄取到此索引来模拟这种情况。您应该注意到此索引现在是可写的。

    response = client.index(
      index: 'kibana_sample_data_ecommerce2',
      body: {
        user: 'kimchy'
      }
    )
    puts response
    ### On clusterB ###
    POST kibana_sample_data_ecommerce2/_doc/
    {
      "user": "kimchy"
    }

clusterA 恢复时的故障恢复编辑

clusterA 恢复时,clusterB 成为新的 leader,而 clusterA 成为 follower。

  1. clusterA 上设置远程集群 clusterB

    response = client.cluster.put_settings(
      body: {
        persistent: {
          cluster: {
            remote: {
              "clusterB": {
                mode: 'proxy',
                skip_unavailable: 'true',
                server_name: 'clusterb.es.region-b.gcp.elastic-cloud.com',
                proxy_socket_connections: '18',
                proxy_address: 'clusterb.es.region-b.gcp.elastic-cloud.com:9400'
              }
            }
          }
        }
      }
    )
    puts response
    ### On clusterA ###
    PUT _cluster/settings
    {
      "persistent": {
        "cluster": {
          "remote": {
            "clusterB": {
              "mode": "proxy",
              "skip_unavailable": "true",
              "server_name": "clusterb.es.region-b.gcp.elastic-cloud.com",
              "proxy_socket_connections": "18",
              "proxy_address": "clusterb.es.region-b.gcp.elastic-cloud.com:9400"
            }
          }
        }
      }
    }
  2. 在将任何索引转换为 follower 之前,需要丢弃现有数据。确保在删除 clusterA 上的任何索引之前,clusterB 上有最新的数据可用。

    response = client.indices.delete(
      index: 'kibana_sample_data_ecommerce'
    )
    puts response
    ### On clusterA ###
    DELETE kibana_sample_data_ecommerce
  3. clusterA 上创建一个 follower 索引,现在跟踪 clusterB 中的 leader 索引。

    ### On clusterA ###
    PUT /kibana_sample_data_ecommerce/_ccr/follow?wait_for_active_shards=1
    {
      "remote_cluster": "clusterB",
      "leader_index": "kibana_sample_data_ecommerce2"
    }
  4. follower 集群上的索引现在包含更新的文档。

    response = client.search(
      index: 'kibana_sample_data_ecommerce',
      q: 'kimchy'
    )
    puts response
    ### On clusterA ###
    GET kibana_sample_data_ecommerce/_search?q=kimchy

    如果软删除在复制到 follower 之前被合并,则以下过程将因 leader 上的历史记录不完整而失败,请参阅 index.soft_deletes.retention_lease.period 以了解更多详细信息。