Lambda S3 getObject流到ES摄取管道

时间:2017-04-30 12:09:54

标签: amazon-web-services elasticsearch amazon-s3 aws-lambda elasticsearch-plugin

我使用lambda将上传到S3的PDF文件推送到带有ES摄取附件插件的AWS托管弹性搜索。

有些PDF可能很大 - 超过100mb - 似乎最好以块的形式传输文件,而不是将整个文件缓冲区加载到lambda内存中。 s3-lambda-es示例代码我已经看到了json日志的所有工作都很容易流,但我还没有看到任何人使用二进制文件来获取摄取插件。

注意:我使用带有http-aws-es connectionClass的elasticssearch-js库使其与lambda一起使用。

我当前的代码基本上有效,但它在发送到ES之前加载了整个pdf。 这是getObject回调:

s3.getObject({ Bucket: bucket, Key: key }, function(err, data) {
    if (err) {
      console.log(err, err.stack); // an error occurred
      context.fail();
    } else {
      console.log('data: ', data); // successful response
      var attachment = data.Body.toString('base64');
      elasticsearch.index(
        {
          index: 'attachments2',
          pipeline: 'pdf_attachment2',
          type: 'pdf',
          body: {
            data: attachment
          }
        },
        function(error, resp) {
          if (error) {
            console.trace('index error!', error);
          } else {
            console.log('index response', resp);
            context.succeed();
          }
        }
      );
    }
  });

有没有更好的方法将单个大型文档流式传输到ES?

2 个答案:

答案 0 :(得分:0)

  

有没有更好的方法将单个大型文档流式传输到ES?

简答:不,请使用s3.getObject

答案很长:是的,请参阅下面的

首先,限制是Elasticsearch。它根本不暴露任何流API。如果你尝试search API docs,你甚至都不会发现任何流。

为什么呢?因为Elasticsearch不是为将大文件流式传输而设计的!

请求正文的默认限制为100MB,can be increased to 2GB with tuning。 (相同的链接解释了为什么你不应该索引这样的大文件)。简而言之,你会遇到坏事。不相关的搜索结果,超载ES,吃掉所有RAM等等。

此外,您提到您将使用ingest attachment plugin,如果您继续default configuration,您可能会发现默认值为indexed_chars

enter image description here

这意味着,ES默认阻止您存储大于100KB的字段!

当然,您可以覆盖所有内容,并根据需要调整ES,并将2GB文档存储在1个字段中。但一般不建议这样做。

建议的方法是将较大的pdf拆分为较小的块,并将它们编入具有相同documentId或其他内容的单独文档。然后,您可以使用ES fields collapsing通过共享documentId对文档进行重复数据删除(ES 5.3中的新功能,在旧版本中使用热门命中聚合)。那就是你不会最终在你的Lambda中发送100MB。

总而言之:您无法为1个文档流式传输ES大文本,ES不是为此而设计的。但如果您愿意,可以发送100MB文本。 AWS Lambda应该没问题,内存将在需要时处理。

答案 1 :(得分:-1)

@bscandanavia请分享您用于创建管道的方法和代码。我无法弄清楚如何使用ES摄取附件插件。

很抱歉将其发布为答案,因为我无法添加评论