Beim Herunterladen einer großen Anzahl von Objekten aus S3 wird die Geschwindigkeit unabhängig von der Objektgröße nicht mäßig angezeigt. Als ich in Python schrieb, gab ich mein Bestes mit ** concurrent.futures **, aber vielleicht kann ich es mit Goroutine tun? Ich dachte, ich gab mein Debüt in Golang.
--Verwenden Sie ListObjectV2, um alle Schlüssel unter dem spezifischen Präfix von S3 abzurufen
Hmm? Gleiche Geschwindigkeit, weil Sie gerade die API gedrückt haben. Wenn ja, bin ich immer noch überzeugt, aber ich mache mir ein wenig Sorgen, dass ** Go langsamer ist als die Skriptsprache **. Ich änderte schnell meinen Zeitplan und versuchte, diese Angelegenheit ein wenig zu überprüfen.
Also hier und [hier](https: // Ich werde es unter Bezugnahme auf docs.aws.amazon.com/sdk-for-go/api/service/s3/#S3.ListObjectsV2) schreiben.
main.go
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"os"
)
func main() {
bucket := os.Getenv("BUCKET")
prefix := os.Getenv("PREFIX")
region := os.Getenv("REGION")
sess := session.Must(session.NewSession())
svc := s3.New(sess, &aws.Config{
Region: ®ion,
})
params := &s3.ListObjectsV2Input{
Bucket: &bucket,
Prefix: &prefix,
}
fmt.Println("Start:")
err := svc.ListObjectsV2Pages(params,
func(p *s3.ListObjectsV2Output, last bool) (shouldContinue bool) {
for _, obj := range p.Contents {
fmt.Println(*obj.Key)
}
return true
})
fmt.Println("End:")
if err != nil {
fmt.Println(err.Error())
return
}
}
Ich werde das auch schreiben. Mit einem Low-Level-Client, der die Bedingungen mit Go erfüllt.
main.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import boto3
bucket = os.environ["BUCKET"]
prefix = os.environ["PREFIX"]
region = os.environ["REGION"]
# r = boto3.resource('s3').Bucket(bucket).objects.filter(Prefix=prefix)
# [print(r.key) for r in r]
#Normalerweise bekomme ich es wie oben, aber ich messe es mit dem folgenden Code, um es an Golang zu senden
s3_client = boto3.client('s3', region)
contents = []
next_token = ''
while True:
if next_token == '':
response = s3_client.list_objects_v2(Bucket=bucket, Prefix=prefix)
else:
response = s3_client.list_objects_v2(Bucket=bucket, Prefix=prefix, ContinuationToken=next_token)
contents.extend(response['Contents'])
if 'NextContinuationToken' in response:
next_token = response['NextContinuationToken']
else:
break
[print(r["Key"]) for r in contents]
――Ich möchte die Umwelt nicht verschmutzen und es ist problematisch, deshalb habe ich alles mit Docker erstellt.
$ docker-compose up -d --build
Dockerfile
FROM golang:1.13.5-stretch as build
RUN go get \
github.com/aws/aws-sdk-go/aws \
github.com/aws/aws-sdk-go/aws/session \
github.com/aws/aws-sdk-go/service/s3
COPY . /work
WORKDIR /work
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go
FROM python:3.7.6-stretch as release
RUN pip install boto3
COPY --from=build /work/main /usr/local/bin/main
COPY --from=build /work/main.py /usr/local/bin/main.py
WORKDIR /usr/local/bin/
docker-compose.yml
version: '3'
services:
app:
build:
context: .
container_name: "app"
tty: True
environment:
BUCKET: <Bucket>
PREFIX: test/
REGION: ap-northeast-1
Erstellen Sie einen Bucket in der Region Tokio und erstellen Sie mit den folgenden Tools etwa 1000.
#/bin/bash
Bucket=<Bucket>
Prefix="test"
#Testdateierstellung
dd if=/dev/zero of=testobj bs=1 count=30
#Kopie der Masterdatei
aws s3 cp testobj s3://${Bucket}/${Prefix}/testobj
#Doppelte Master-Datei
for i in $(seq 0 9); do
for k in $(seq 0 99); do
aws s3 cp s3://${Bucket}/${Prefix}/testobj s3://${Bucket}/${Prefix}/${i}/${k}/${i}_${k}.obj
done
done
$ time docker-compose exec app ./main
~ Abkürzung ~
real 0m21.888s
user 0m0.580s
sys 0m0.107s
$ time docker-compose exec app ./main.py
~ Abkürzung ~
real 0m2.671s
user 0m0.577s
sys 0m0.104s
Go ist zehnmal langsamer als Python. Warum!
#Nur Unterschied
for i in $(seq 0 99); do
for k in $(seq 0 99); do
――Der Upload dauerte übrigens 3-4 Stunden. Ich hätte das Werkzeug richtig machen sollen ...
$ time docker-compose exec app ./main
~ Abkürzung ~
real 0m23.276s
user 0m0.617s
sys 0m0.128s
$ time docker-compose exec app ./main.py
~ Abkürzung ~
real 0m5.973s
user 0m0.576s
sys 0m0.114s
Diesmal beträgt der Unterschied ungefähr das 4-fache. Vielmehr scheint es einen Unterschied von ungefähr 18 Sekunden zu geben, unabhängig von der Anzahl der Objekte. Hmmm.
――Ich habe das Gefühl, dass ich die Sprachspezifikationen aufgrund der Bibliothekseinstellungen nicht verstehe, daher möchte ich weitere Informationen erhalten. ――Wenn die Effizienz der ** parallelen Download-Verarbeitung in Goroutine **, die der ursprüngliche Zweck ist, gut ist, scheint es einen Fehler von etwa 20 Sekunden zu geben, daher werde ich versuchen, den Rest zu implementieren.
Wie im Kommentarbereich empfohlen, habe ich versucht, das SDK zu debuggen Ich habe festgestellt, dass es lange gedauert hat, den IAM-Berechtigungsnachweis zu finden. War der Standardwert des Betriebssystems "-stretch" schlecht? Ich habe es danach mehrmals versucht, aber es ist in dieser Umgebung nicht wieder aufgetaucht, also werde ich es lösen. Es ist launisch, aber ...
@nabeken Danke!