S3 객체에 데이터 추가


91

S3 버킷에 저장된 특정 로그 파일에 쓸 수있는 머신이 있다고 가정 해 보겠습니다.

따라서 머신에는 해당 버킷에 대한 쓰기 기능이 있어야하지만 해당 버킷 (내가 쓰려는 파일 포함)에있는 파일을 덮어 쓰거나 삭제할 수있는 기능이 필요하지 않습니다.

따라서 기본적으로 내 컴퓨터가 데이터를 재정의하거나 다운로드하지 않고 해당 로그 파일에만 데이터를 추가 할 수 있기를 바랍니다.

S3가 그렇게 작동하도록 구성하는 방법이 있습니까? 내가 원하는대로 작동하도록 연결할 수있는 IAM 정책이있을 수 있습니까?


S3에서는 객체를 수정할 수 없습니다. 새 로그 파일을 추가 할 수 있습니까? 그것은 더 나은 모델이 될 것이고 여러 동시 클라이언트를 지원할 것입니다.
jarmod

@jarmod 예, 생각해 보았습니다.하지만 문제는 공격자가 내 서버에 액세스하는 데 성공하면 S3 버킷으로 전송되기 전에 서버에 저장된 로컬 파일을 삭제할 수 있다는 것입니다 (예 : 하루가 끝날 때 발생).
Theodore

CloudWatch 로그를 살펴볼 수도 있습니다. 로그 수집 및 저장의 복잡성을 관리하고, 검색 기능, 보존 정책을 제공하고, 로그에 대해 사용자 지정할 수있는 지표를 기반으로 경고를 생성 할 수 있도록합니다.
jarmod

1
Google BigQuery를 살펴볼 수도 있습니다. 문제를 해결하는 데 사용할 수 있습니다.
Daniel777

답변:


133

불행히도 할 수 없습니다.

S3에는 "추가"작업이 없습니다. * 객체가 업로드되면 제자리에서 수정할 수 없습니다. 유일한 옵션은 요구 사항을 충족하지 않는 새 개체를 업로드하여 대체하는 것입니다.

* : 예,이 게시물이 몇 년 전이라는 것을 알고 있습니다. 그래도 여전히 정확합니다.


멀티 파트 업로드를 사용하면이 작업을 수행 할 수 있습니다.
Anjali

1
멀티 파트 업로드를 사용하면 원본 객체를 다운로드하지 않고 S3로 데이터를 가져올 수 있지만 원본 객체를 직접 덮어 쓸 수는 없습니다. 예를 들어 docs.aws.amazon.com/AmazonS3/latest/API/…를 참조하십시오. 그런 다음 이전 객체를 삭제하거나 새 객체의 이름을 바꿀 수 있습니다. 그러나 이것은 질문이 요구하는 것이 아닙니다.
MikeGM 2018 년

Multipart Upload를 사용하면 실제로 작동 할 수 있다고 생각합니다. 모든 부품은 동일한 파일의 순차적 세그먼트입니다. 파트 업로드에 성공하면 결국 파일을 읽을 수 있도록 업로드를 커밋 할 수 있습니다. 따라서 파일의 내용을 읽을 필요가없는 한 동일한 멀티 파트 업로드를 사용하여 추가 할 수 있습니다.
cerebrotecnologico

@cerebrotecnologico 여전히 OP의 요구 사항을 충족하지 않는다고 생각합니다. S3 사용자가 객체에 추가되는 멀티 파트 업로드를 수행하도록 제한하는 방법은 없습니다. 멀티 파트 업로드를 수행 할 수 있다면 원하는 콘텐츠를 업로드 할 수 있습니다.
duskwuff -inactive-

16

받아 들여진 대답에 따르면 할 수 없습니다. 내가 아는 가장 좋은 해결책은 다음을 사용하는 것입니다.

AWS Kinesis Firehose

https://aws.amazon.com/kinesis/firehose/

그들의 코드 샘플 은 복잡해 보이지만 당신은 정말 간단 할 수 있습니다. 애플리케이션의 Kinesis Firehose 전송 스트림에 대해 계속 PUT (또는 BATCH PUT) 작업을 수행하고 (AWS SDK 사용), 스트리밍 데이터를 선택한 AWS S3 버킷으로 전송하도록 Kinesis Firehose 전송 스트림을 구성합니다 ( AWS Kinesis Firehose 콘솔).

여기에 이미지 설명 입력

>>S3에서 파일을 생성 한 후에는 새 파일을 다시 다운로드, 추가 및 업로드해야하지만 한 줄에 한 번만 수행하면되므로 여전히 Linux 명령 줄에서 만큼 편리하지 않습니다. 추가 작업의 양으로 인해 막대한 비용이 발생하는 것에 대해 걱정할 필요가 없습니다. 아마도 할 수 있지만 콘솔에서 어떻게하는지 볼 수 없습니다.


8
최대 시간 (파일 생성 이후 900초) 또는이 일의 최대 크기 (128 메가 바이트 파일 크기) 중 하나가 있습니다 - 그것은 하나 그 한계에 도달 할 때까지 의미는, 운동성은 파이어 호스 같은 S3 파일에 추가합니다 : docs.aws를 .amazon.com / 파이어 호스 / 최신 / dev에 / 생성 - configure.html
Yaron Budowski

Firehose에서 단일 S3 파일을 출력으로 사용할 수 있습니까? S3 버킷에서 여러 파일을 병합해야하는 것은 약간 지저분하게 들립니다.
Jón Trausti Arason 2019

1
불행하게도. 나도 더 나은 해결책이 있었으면 좋겠다.
Sridhar Sarnobat 19

네, 불행합니다. 단일 S3 객체에 레코드를 수동으로 다운로드하고 추가하는 경우 주로 경합 상태에 대해 걱정합니다. SQS에 레코드를 추가 한 다음 SNS + Lambda와 함께 일부 로직을 사용하여 SQS를 폴링 한 다음 S3 객체에 새 항목을 작성하는 방법을 생각했습니다.
Jón Trausti Arason

6

S3의 객체는 추가 할 수 없습니다. 이 경우 두 가지 솔루션이 있습니다.

  1. 모든 S3 데이터를 새 객체에 복사하고 새 콘텐츠를 추가 한 다음 S3에 다시 씁니다.
function writeToS3(input) {
    var content;
    var getParams = {
        Bucket: 'myBucket', 
        Key: "myKey"
    };

    s3.getObject(getParams, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
            content = new Buffer(data.Body).toString("utf8");
            content = content + '\n' + new Date() + '\t' + input;
            var putParams = {
                Body: content,
                Bucket: 'myBucket', 
                Key: "myKey",
                ACL: "public-read"
             };

            s3.putObject(putParams, function(err, data) {
                if (err) console.log(err, err.stack); // an error occurred
                else     {
                    console.log(data);           // successful response
                }
             });
        }
    });  
}
  1. 두 번째 옵션은 Kinesis Firehose를 사용하는 것입니다. 이것은 매우 간단합니다. firehose 전송 스트림을 생성하고 대상을 S3 버킷에 연결해야합니다. 그게 다야!
function writeToS3(input) {
    var content = "\n" + new Date() + "\t" + input;
    var params = {
      DeliveryStreamName: 'myDeliveryStream', /* required */
      Record: { /* required */
        Data: new Buffer(content) || 'STRING_VALUE' /* Strings will be Base-64 encoded on your behalf */ /* required */
      }
    };

    firehose.putRecord(params, function(err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else     console.log(data);           // successful response
    }); 
}

단일 S3 파일을 출력으로 사용할 수 있습니까?
Jón Trausti Arason 2019

1

다른 사람들이 이전에 언급했듯이 S3 객체는 추가 할 수 없습니다.
그러나 또 다른 해결책은 CloudWatch 로그에 기록한 다음 원하는 로그를 S3내보내는 것 입니다. 또한 Lambda에는 S3 권한이 필요하지 않기 때문에 서버에 액세스하는 공격자가 S3 버킷에서 삭제하는 것을 방지 할 수 있습니다.


1

S3와 유사한 서비스를 사용하여 객체에 데이터를 추가하려는 경우 Alibaba Cloud OSS (Object Storage Service) 가이를 기본적으로 지원합니다 .

OSS는 AppendObject API를 통해 추가 업로드를 제공하므로 개체 끝에 콘텐츠를 직접 추가 할 수 있습니다. 이 메서드를 사용하여 업로드 한 개체는 추가 가능한 개체이고 다른 방법을 사용하여 업로드 한 개체는 일반 개체입니다. 추가 된 데이터는 즉시 읽을 수 있습니다.


-1

나는 비슷한 문제가 있었고 이것이 내가 요청한 것입니다.

AWS Lambda를 사용하여 파일에 데이터를 추가하는 방법

위의 문제를 해결하기 위해 내가 생각 해낸 것은 다음과 같습니다.

getObject를 사용하여 기존 파일에서 검색

   s3.getObject(getParams, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else{
       console.log(data);           // successful response
       var s3Projects = JSON.parse(data.Body);
       console.log('s3 data==>', s3Projects);
       if(s3Projects.length > 0) {
           projects = s3Projects;
       }   
   }
   projects.push(event);
   writeToS3(); // Calling function to append the data
});

파일에 추가 할 쓰기 기능

   function writeToS3() {
    var putParams = {
      Body: JSON.stringify(projects),
      Bucket: bucketPath, 
      Key: "projects.json",
      ACL: "public-read"
     };

    s3.putObject(putParams, function(err, data) {
       if (err) console.log(err, err.stack); // an error occurred
       else     console.log(data);           // successful response
        callback(null, 'Hello from Lambda');
     });
}

이 도움을 바랍니다 !!


13
귀하의 writeToS3기능은에 추가되지 않은 파일을 덮어 쓰게됩니다.
duskwuff -inactive- 2015 년

@ duskwuff-inactive- 동의했으며 두 가지 방법이 동일한 객체에서 작동하려고하면 경합 상태가 발생하지만 이는 변경 불가능한 문자열 또는 유형이있는 언어와 실제로 다르지 않습니다. 새로운 개체.
fatal_error
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.