• Elasticsearch8.2 使用snapshot备份能力


    背景

    1.有个向量搜索相关需求,选择使用ES8版本,并且在k8s环境中容器化部署;

    2.考虑核心程度以及成本问题,不需要准备多数据中心的备份集群,为了保证数据可靠性,预期使用snapshot备份能力;

    选型

    ES支持将snapshot存储到各种存储产品,例如 fs(本地)、S3(或者ceph)、hdfs等。

    1.OSS,考虑到已经和阿里云OSS有合作,且支持S3接口 -----> 测试

    2.ceph,私有云部署,不好控制容量,成本偏高 --------> 暂不考虑

    3.hdfs,私有云部署,不好控制容量,成本偏高,需要安装插件 -----> 暂不考虑

    4.fs,本地,由于团队还在做juicefs产品,可以juicefs挂载到本地目录,ES snapshot 存到本地目录即可完成上传到公有云OSS ------> 测试

    snapshot直接从ES传到OSS

    1.创建账号、bucket,获取ak/sk;

    2.ES容器实例如何加载密钥库

    通过官方文档可知需要执行如下命令:将密钥设置到ES密钥库

    S3 repository | Elasticsearch Guide [8.2] | Elastic

    1. bin/elasticsearch-keystore add s3.client.default.access_key
    2. bin/elasticsearch-keystore add s3.client.default.secret_key

    考虑到容器环境不允许直接进入pod执行命令,secret也不允许直接写死到镜像中,则需要在entrypoint.sh中设置完成该命令。

    最终方案如下:

    1.在k8s环境中创建secret,记录ak/sk信息

    2.pod创建时候mount到指定目录

    3.container(ES)启动的时候读取指定目录信息,并执行elasticsearch-keystore命令

    3.具体操作

    0.安装 repository-s3 插件

    略(ES8版本内置了该插件,无需安装)

    1.创建secret

    kubectl apply -f secret.yml
    
    # cat secret.yml
    apiVersion: v1
    kind: Secret
    metadata:
      namespace: uat-es
      name: es-snapshot-oss-secret
    type: Opaque
    data:
      access_key: xxx(注意base64编码)
      secret_key: xxx(注意base64编码)

    2.修改crd的yaml,将该secret mount到指定目录

    # 定义secret
      volumes:  
      - name: "oss-secret"
        secret: 
          secretName: "es-snapshot-oss-secret"
          
    # 指定容器挂载选项
    containers:
        ...
      volumeMounts:
      - mountPath: "/mnt/secret/oss"
        name: "oss-secret"
        readOnly: true

    3.镜像修改

    注:Dockerfile中最后是通过docker-entrypoint.sh完成ES实例的启动

    ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]

    # docker-entrypoint.sh 增加如下内容
    
    /usr/share/elasticsearch/bin/elasticsearch-keystore create
    chown root:root /usr/share/elasticsearch/config/elasticsearch.keystore
    echo "$(</mnt/secret/oss/access_key)" | /usr/share/elasticsearch/bin/elasticsearch-keystore add --stdin s3.client.default.access_key
    echo "$(</mnt/secret/oss/secret_key)" | /usr/share/elasticsearch/bin/elasticsearch-keystore add --stdin s3.client.default.secret_key
    chown elasticsearch:elasticsearch /usr/share/elasticsearch/config/elasticsearch.keystore

    1.可以看到先执行了 bin/elasticsearch-keystore create 命令,因为发行版的ES中config目录并没有elasticsearch.keystore文件,需要通过 bin/elasticsearch-keystore create 命令生成密钥库(即 config/elasticsearch.keystore 文件);

    注:如果不create,可以发现pod中最后也会生成密钥库,并且含有一个 seed 的密钥信息。该部分是ES启动时创建的,所以在启动之前必须create,否则执行bin/elasticsearch-keystore add 会触发一个密钥库不存在的异常;

    2.可以看到先通过 chown root:root xxx 命令将config/elasticsearch.keystore文件的用户和group都设置成了root,执行完成命令后将其改回elasticsearch,因为bin/elasticsearch-keystore命令执行时对密钥库的权限有要求,pod启动是root用户,所以必须将该文件改成root权限,后续改成elasticsearch用户是为了保证container(ES)启动时的权限,ES的启动是使用elasticsearch用户;

    注:该方式是在ES启动之前先将密钥加载到密钥库,ES提供另一个方式,允许在ES启动后执行 elasticsearch-keystore add 命令后再 reload,也能生效,这里不讨论。

    4.测试创建repository、snapshot命令

    # 创建repository
    # 注:对象存储OSS不允许出现对象name中带 “/” ,所以 base_path 中 “-” 表示层级
    PUT _snapshot/zmc_test_oss_repository
    {
      "type": "s3",
      "settings": {
        "bucket": "es-snapshot",
        "endpoint": "http://dataplatform.xxxx.com",
        "base_path":"user-elasticsearch-uat-1067"
      }
    }
    # 创建snapshot
    PUT /_snapshot/zmc_test_oss_repository/snapshot_1?wait_for_completion=true
    {
      "indices": "zmc",
      "ignore_unavailable": true,
      "include_global_state": false,
      "metadata": {
        "taken_by": "zmc",
        "taken_because": "backup test"
      }
    }
    
    # 该命令异常:
    amazon_s3_exception: Aws MultiChunkedEncoding is not supported. (Service: Amazon S3; Status Code: 400; Error Code: NotImplemented; Request ID: xxxxx; S3 Extended Request ID: es-snapshot.dataplatform.xxx.com

    5.测试结果

    很不幸,OSS暂时不支持MultiChunkedEncoding;(和OSS同学沟通后发现是 主集群暂时不支持,海外小集群已经支持该接口,后续会推到主集群)

    这条路无法走通,继续测试其他方案;

    snapshot存本地后通过juicefs上传OSS

    juicefs是一个分布式文件系统,简言之就是通过juicefs程序可以将远程对象存储与本地目录关联,将文件写入本地即可上传到对象存储。该产品对ES而言比较适合作为snapshot的存储以及ES冷热分离架构中的冷数据存储。

    juicefs有一定的维护成本,这里仅提供一种snapshot备份设计的新思路。对ES8而言更简要的方案可以考虑hdfs、ceph以及亚马逊的s3对象存储,弊端主要在成本和容量规划,体量较小或者公司支持较好则可以忽略。

    预期架构如下:

    可以看到从使用层面看ES只需将snapshot存在本地目录即可完成上公有云操作;

    juicefs部分只需从运维层面考虑,将进程打到镜像中、或者通过CSI、静态PVC的方式均可实现。图中元数据引擎是juicefs架构中的一环,从ES使用的角度看可以忽略;

    此处juicefs可以替换成任何分布式共享存储。

    ----------------------------end---------------------------------

  • 相关阅读:
    SpringBoot集成MyBatis
    一文读懂野指针
    Apache DolphinScheduler PMC:开源不一定也要九死一生
    分销模式为用户解决哪些痛点?
    微信小程序云开发教程——墨刀原型工具入门(素材面板)
    安达发|APS排单软件中甘特图的应用
    解决 VMware Network Adapter VMnet1 IP 地址冲突导致无法打开路由器管理页面
    如何向客户推广 API 商品数据接口,如何跟进项目和程序员对接?
    Git 开发必备.gitignore详解
    铱钌合金/氧化铱仿生纳米酶|钯纳米酶|GMP-Pd纳米酶|金钯复合纳米酶|三元金属Pd-M-Ir纳米酶|中空金铂合金纳米笼核-多空二氧化硅壳纳米酶
  • 原文地址:https://blog.csdn.net/qq_33999844/article/details/125457244