Hängen Sie Daten an ein S3-Objekt an

89

Angenommen, ich habe einen Computer, den ich in eine bestimmte Protokolldatei schreiben möchte, die in einem S3-Bucket gespeichert ist.

Der Computer muss also über Schreibfähigkeiten für diesen Bucket verfügen, aber ich möchte nicht, dass er Dateien in diesem Bucket überschreiben oder löschen kann (einschließlich der Dateien, in die er schreiben soll).

Grundsätzlich möchte ich, dass mein Computer nur Daten an diese Protokolldatei anhängen kann, ohne sie zu überschreiben oder herunterzuladen.

Gibt es eine Möglichkeit, meinen S3 so zu konfigurieren? Vielleicht gibt es eine IAM-Richtlinie, die ich anhängen kann, damit sie wie gewünscht funktioniert?

Theodor
quelle
Sie können Objekte in S3 nicht ändern. Könnten Sie einfach eine neue Protokolldatei anhängen? Das wäre ein besseres Modell und würde mehrere gleichzeitige Clients unterstützen.
Jarmod
@jarmod Ja, ich habe darüber nachgedacht, aber das Problem ist, dass ein Angreifer, wenn er erfolgreich auf meinen Server zugreifen kann, die darauf gespeicherte lokale Datei löschen kann, bevor sie an den S3-Bucket gesendet wurde (sagen wir mal) passiert am Ende des Tages).
Theodore
Vielleicht möchten Sie auch einen Blick auf CloudWatch-Protokolle werfen. Lassen Sie es die Komplexität des Sammelns und Speicherns Ihrer Protokolle verwalten, Suchfunktionen und Aufbewahrungsrichtlinien bereitstellen und Warnungen basierend auf Metriken generieren, die Sie für Ihre Protokolle anpassen können.
Jarmod
1
Sie können sich auch Google BigQuery ansehen. Sie können es verwenden, um Ihr Problem zu lösen.
Daniel777

Antworten:

130

Das kannst du leider nicht.

S3 hat keine "Anhängen" -Operation. * Sobald ein Objekt hochgeladen wurde, kann es nicht mehr geändert werden. Sie können nur ein neues Objekt hochladen, um es zu ersetzen, das Ihren Anforderungen nicht entspricht.

*: Ja, ich weiß, dass dieser Beitrag ein paar Jahre alt ist. Es ist jedoch immer noch genau.

Dämmerung -inaktiv-
quelle
Darf ich wissen, können wir dies mit Multipart Upload erreichen?
Anjali
1
Mit dem mehrteiligen Hochladen können Sie die Daten in S3 übertragen, ohne das ursprüngliche Objekt herunterladen zu müssen. Sie können das ursprüngliche Objekt jedoch nicht direkt überschreiben. Siehe z. B. docs.aws.amazon.com/AmazonS3/latest/API/…. Sie können dann das alte Objekt löschen / das neue umbenennen. Dies ist jedoch nicht das, was die Frage stellt.
MikeGM
Ich denke, dass die Verwendung von Multipart Upload tatsächlich funktionieren kann. Alle Ihre Teile sind aufeinanderfolgende Segmente derselben Datei. Wenn das Hochladen des Teils erfolgreich ist, können Sie den Upload eventuell festschreiben, um die Datei lesen zu können. Solange Sie den Inhalt der Datei nicht lesen müssen, können Sie an die Verwendung des gleichen mehrteiligen Uploads anhängen.
cerebrotecnologico
@cerebrotecnologico Ich glaube immer noch nicht, dass es die Anforderungen des OP erfüllt. Mir ist nicht bekannt, dass ich einen S3-Benutzer darauf beschränken kann, mehrteilige Uploads durchzuführen, die an ein Objekt angehängt werden. Wenn er einen mehrteiligen Upload durchführen kann, kann er jeden gewünschten Inhalt hochladen.
Abenddämmerung -inaktiv-
16

Wie die akzeptierte Antwort besagt, können Sie nicht. Die beste Lösung, die mir bekannt ist, ist:

AWS Kinesis Firehose

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

Ihr Codebeispiel sieht kompliziert aus, aber Ihr Codebeispiel kann sehr einfach sein. Sie führen weiterhin PUT- (oder BATCH PUT-) Vorgänge für einen Kinesis Firehose-Übermittlungsdatenstrom in Ihrer Anwendung aus (mithilfe des AWS SDK) und konfigurieren den Kinesis Firehose-Übermittlungsdatenstrom so, dass Ihre gestreamten Daten an einen AWS S3-Bucket Ihrer Wahl gesendet werden (im AWS Kinesis Firehose-Konsole).

Geben Sie hier die Bildbeschreibung ein

Es ist immer noch nicht so praktisch wie >>über die Linux-Befehlszeile, da Sie nach dem Erstellen einer Datei in S3 erneut das Herunterladen, Anhängen und Hochladen der neuen Datei durchführen müssen, dies jedoch nur einmal pro Zeilenstapel als für jede Datenzeile, sodass Sie sich aufgrund des Umfangs der Anhängevorgänge keine Gedanken über hohe Gebühren machen müssen. Vielleicht kann es gemacht werden, aber ich kann nicht sehen, wie es von der Konsole aus gemacht wird.

Sridhar Sarnobat
quelle
8
Beachten Sie, dass dies entweder eine maximale Zeit (900 Sekunden seit der Dateierstellung) oder eine maximale Größe (128 MB Dateigröße) ist. Dies bedeutet, dass Kinesis firehose an dieselbe S3-Datei angehängt wird, bis eine der folgenden Grenzen erreicht ist: docs.aws .amazon.com / firehose / latest / dev / create-configure.html
Yaron Budowski
Können Sie eine einzelne S3-Datei als Ausgabe auf dem Firehose verwenden? Es klingt etwas chaotisch, mehrere Dateien in einem S3-Bucket zusammenführen zu müssen.
RaRaRa
1
Unglücklicherweise nicht. Ich wünschte auch, es gäbe eine bessere Lösung.
Sridhar Sarnobat
Ja, das ist unglücklich. Ich mache mir hauptsächlich Sorgen um die Rennbedingungen, wenn ich Datensätze manuell herunterlade und an ein einzelnes S3-Objekt anhänge. Ich habe darüber nachgedacht, die Datensätze zu SQS hinzuzufügen und dann eine Logik mit SNS + Lambda zu verwenden, um das SQS abzufragen und dann die neuen Einträge in das S3-Objekt zu schreiben.
RaRaRa
6

Objekte in S3 können nicht angehängt werden. In diesem Fall haben Sie 2 Lösungen:

  1. Kopieren Sie alle S3-Daten in ein neues Objekt, hängen Sie den neuen Inhalt an und schreiben Sie zurück in 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. Die zweite Option ist die Verwendung von Kinesis Firehose. Das ist ziemlich einfach. Sie müssen Ihren Firehose-Lieferstrom erstellen und das Ziel mit dem S3-Bucket verknüpfen. Das ist es!
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
    }); 
}
Bharthan
quelle
Können Sie eine einzelne S3-Datei als Ausgabe verwenden?
RaRaRa
1

Wie bereits erwähnt, können S3-Objekte nicht angehängt werden.
Eine andere Lösung wäre jedoch, in CloudWatch-Protokolle zu schreiben und dann die gewünschten Protokolle in S3 zu exportieren . Dies würde auch verhindern, dass Angreifer, die auf Ihren Server zugreifen, aus Ihrem S3-Bucket gelöscht werden, da Lambda keine S3-Berechtigungen benötigt.

Leo Glowacki
quelle
0

Falls jemand Daten an ein Objekt mit einem S3-ähnlichen Dienst anhängen möchte, unterstützt dies der Alibaba Cloud OSS (Objektspeicherdienst) nativ .

OSS bietet einen Append-Upload (über die AppendObject-API), mit dem Sie Inhalte direkt an das Ende eines Objekts anhängen können. Mit dieser Methode hochgeladene Objekte sind anhängbare Objekte, während mit anderen Methoden hochgeladene Objekte normale Objekte sind. Die angehängten Daten sind sofort lesbar.

wanghq
quelle
-1

Ich hatte ein ähnliches Problem und das hatte ich gefragt

So hängen Sie Daten mit AWS Lambda an eine Datei an

Folgendes habe ich mir ausgedacht, um das oben genannte Problem zu lösen:

Verwenden Sie getObject, um von der vorhandenen Datei abzurufen

   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
});

Schreibfunktion zum Anhängen in die Datei

   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');
     });
}

Ich hoffe das hilft!!

Neeraj Kumar
quelle
13
Ihre writeToS3Funktion überschreibt eine Datei und hängt sie nicht an.
Abenddämmerung -inaktiv-
@ duskwuff-inactive- vereinbart, und es leidet auch unter Rennbedingungen, wenn zwei Methoden versuchen, an demselben Objekt zu arbeiten, aber dies unterscheidet sich nicht wirklich von Sprachen mit unveränderlichen Zeichenfolgen oder Typen - Sie simulieren ein Anhängen, indem Sie mit / zurückgeben / überschreiben ein neues Objekt.
fatal_error