Elastic Search 6.3 备份数据到阿里云

Elastic Search 使用 snapshot 备份数据。但是备份的存储不支持阿里云 oss。想要支持阿里云 oss,需要自己实现插件。幸好,开源社区已经有了实现 elasticsearch-repository-oss,不用自己造轮子了。
然而这个插件只支持到 6.1.3。想要在高版本 Elastic Search 上使用,需要稍稍调整一下。
我使用的容器部署的 Elastic Search。镜像版本为( docker.elastic.co/elasticsearch/elasticsearch:6.3.2)
首先,参考OSS 快照迁移,下载压缩包,解压到 plugin 文件夹。修改配置。这里修改 plugin-descriptor.properties 中的 version 为对应 elastic search 对应版本,我这里改为 6.3.2。另外,将配置中的 jvm 和 isolated 都 注释掉。因为高版本的 elastic search 已经移除了这两个属性。

如果,你使用的环境不是我这样的容器,或者 java 8。那么本文看到这里就可以结束了。因为容器使用的是 java 10,所以我还遇到了两个兼容的问题。

缺少依赖

从 java 9 引入了模块的概念。把 java ee 相关的包从标准 java api 中分离出来了。如果遇到缺少 javax 包,十有八九就是这个原因引起的。具体解决方案,可以参考这篇博文。我下载了文中提到的 4 个 jar 包,放入 plugin 对应目录中。问题解决。

阿里云 oss sdk client 提示 NoSuchKey

到真正创建 snapshot 的时候,会报错。查看日志,提示

[ErrorCode]: InvalidResponse
[RequestId]: 5BED337CEA872636F81B8746
[HostId]: null
[ResponseError]:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>InvalidBucketName</Code>
  <Message>The specified bucket is not valid.</Message>
  <RequestId>5BED337CEA872636F81B8746</RequestId>
  <HostId>test-es.oss-cn-beijing.aliyuncs.com</HostId>
  <BucketName>test-es</BucketName>
</Error>

如果遇到类似的问题,先查看一下请求的参数里,key,secret 以及 BucketName 是否正确。我验证之后,发现参数都是对的,然而依旧无法成功。这就比较坑了。
查看源码之后,发现问题出在

 @Override  public  boolean  doesObjectExist(String  bucketName,  String  key) |
   throws  OSSException,  ClientException  { 
   return  this.client.doesObjectExist(bucketName,  key); |
   }

这个插件的作者是希望,当 key 不存在的时候,阿里云 client 返回 false 的,但是阿里云的 client 竟然坑爹的抛了异常。完全不按套路出牌。

由于我以前也使用过 oss 的 client。就在我本机上试了一下。我本机用的 client 是 aliyun-sdk-oss-2.2.3.jar。写了个 demo 调用这个 api 时,竟然没有报错,正确的返回了 false。初步怀疑也是 java 10 的兼容问题。

所以解决方案是,替换 plugin oss 插件目录下的 sdk-oss-2.8.1.jar 为 sdk-oss-2.2.3.jar , 然后重启 Elastic Search。成功创建 snapshot。