วิธีที่ดีที่สุดในการย้ายไฟล์ระหว่างบัคเก็ต S3?


91

ฉันต้องการคัดลอกไฟล์บางไฟล์จากที่เก็บข้อมูลการผลิตไปยังที่เก็บข้อมูลการพัฒนาทุกวัน

ตัวอย่างเช่นคัดลอก productionbucket / feed / feedname / date ไปยัง developmentbucket / feed / feedname / date

เนื่องจากไฟล์ที่ฉันต้องการอยู่ลึกมากในโครงสร้างโฟลเดอร์การไปที่แต่ละโฟลเดอร์และคัดลอก / วางจึงใช้เวลานานเกินไป

ฉันได้เล่นกับการติดตั้งไดรฟ์ไปยังแต่ละที่เก็บข้อมูลและเขียนสคริปต์แบตช์ Windows แต่มันช้ามากและดาวน์โหลดไฟล์ / โฟลเดอร์ทั้งหมดไปยังเซิร์ฟเวอร์ภายในเครื่องโดยไม่จำเป็นและสำรองข้อมูลอีกครั้ง

คำตอบ:


111

อัปเดต

ตามที่ระบุไว้โดย alberge (+1) ในปัจจุบันAWS Command Line Interface ที่ยอดเยี่ยมมอบแนวทางที่หลากหลายที่สุดสำหรับการโต้ตอบกับ AWS (เกือบ) ทุกอย่างในขณะเดียวกันก็ครอบคลุม API ของบริการส่วนใหญ่และยังมีคำสั่ง S3 ระดับที่สูงขึ้นสำหรับจัดการกับของคุณ กรณีใช้งานโดยเฉพาะดูการอ้างอิง AWS CLI สำหรับ S3 :

  • ซิงค์ - ซิงค์ไดเรกทอรีและคำนำหน้า S3 กรณีการใช้งานของคุณจะถูกปกคลุมด้วยตัวอย่างที่ 2 (ละเอียดมากขึ้นเม็ดเล็กใช้งานด้วย--exclude, --includeและการจัดการคำนำหน้า ฯลฯ นอกจากนี้ยังมี):

    คำสั่ง sync ต่อไปนี้จะซิงค์ออบเจ็กต์ภายใต้คำนำหน้าและที่เก็บข้อมูลที่ระบุกับอ็อบเจ็กต์ภายใต้คำนำหน้าและที่เก็บข้อมูลอื่นที่ระบุโดยการคัดลอกอ็อบเจ็กต์ s3 [... ]

    aws s3 sync s3://from_my_bucket s3://to_my_other_bucket
    

เพื่อความสมบูรณ์ฉันจะพูดถึงว่าคำสั่ง S3 ระดับล่างยังสามารถใช้ได้ผ่านคำสั่งย่อยs3apiซึ่งจะอนุญาตให้แปลโซลูชันที่ใช้ SDK ไปยัง AWS CLI โดยตรงก่อนที่จะใช้ฟังก์ชันระดับที่สูงขึ้นในที่สุด


คำตอบเริ่มต้น

การย้ายไฟล์ระหว่างบัคเก็ต S3 สามารถทำได้โดยใช้PUT Object - Copy API (ตามด้วยDELETE Object ):

การใช้การดำเนินการ PUT นี้จะสร้างสำเนาของวัตถุที่เก็บไว้แล้วใน Amazon S3 การดำเนินการ PUT copy จะเหมือนกับการดำเนินการ GET และ PUT การเพิ่มส่วนหัวของคำขอ x-amz-copy-source ทำให้การดำเนินการ PUT คัดลอกออบเจ็กต์ต้นทางลงในที่เก็บข้อมูลปลายทาง ที่มา

มีตัวอย่างที่เกี่ยวข้องมีการทั้งหมดที่มีอยู่ AWS SDK ของที่มีอยู่ให้ดูที่การคัดลอกวัตถุในการทำงานครั้งเดียว ตามปกติแล้วโซลูชันที่ใช้สคริปต์จะเป็นตัวเลือกแรกที่ชัดเจนที่นี่ดังนั้นการคัดลอกวัตถุโดยใช้ AWS SDK สำหรับ Rubyอาจเป็นจุดเริ่มต้นที่ดี ถ้าคุณชอบงูใหญ่แทนเดียวกันสามารถทำได้ผ่านทางBotoเช่นกันแน่นอนดูวิธีการcopy_key()ภายใน Boto ของเอกสาร API S3

PUT Objectคัดลอกไฟล์เท่านั้นดังนั้นคุณจะต้องลบไฟล์อย่างชัดเจนผ่านทางDELETE Objectภาพนิ่งหลังจากดำเนินการคัดลอกสำเร็จ แต่จะเป็นเพียงไม่กี่บรรทัดเมื่อสคริปต์โดยรวมที่จัดการถังและชื่อไฟล์อยู่ในตำแหน่ง (มีตัวอย่างตามลำดับเช่นกัน ดูเช่นการลบหนึ่งออบเจ็กต์ต่อคำขอ )


ฉันลงเอยด้วยการเขียนสคริปต์การดำเนินการด้วย AWS SDK ใน. NET
Matt Dell

1
@MattDell คุณสามารถเพิ่มคำตอบ. NET สำหรับคำถามนี้ได้หรือไม่?
balexandre

1
สิ่งที่แย่เกี่ยวกับเรื่องนี้คือ Amazon ไม่ชัดเจนมากนักว่าคำสั่งคัดลอกสำเร็จหรือไม่ดังนั้นการลบหลังจากการดำเนินการจึงดูเป็นอันตราย
James McMahon

เพื่อความชัดเจนฉันหมายถึง Java API โดยเฉพาะ ฉันได้เปิดคำถามแยกต่างหากstackoverflow.com/questions/17581582
James McMahon

เรายังต้องการวิธีง่ายๆในการสร้าง id เดียวและคีย์ที่สามารถอ่านจากที่เก็บข้อมูลหนึ่งและเขียนไปยังที่เก็บข้อมูลอื่นได้ โดยเฉพาะอย่างยิ่งถ้าที่เก็บข้อมูลอยู่ข้ามบัญชี
CMCDragonkai

66

AWS CLIใหม่อย่างเป็นทางการรองรับฟังก์ชันการทำงานส่วนใหญ่ของs3cmd. ก่อนหน้านี้ฉันใช้s3cmdหรือ Ruby AWS SDK เพื่อทำสิ่งนี้ แต่ CLI อย่างเป็นทางการใช้งานได้ดีสำหรับสิ่งนี้

http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html

aws s3 sync s3://oldbucket s3://newbucket

4
สิ่งนี้ควรได้รับการโหวตให้อยู่ในอันดับต้น ๆ ของรายการ เป็นวิธีที่เหมาะสมในการซิงค์ที่เก็บข้อมูลและเป็นข้อมูลล่าสุดในคำตอบทั้งหมดนี้
dft

หากคุณมีปัญหาเกี่ยวกับข้อผิดพลาดที่ปฏิเสธการเข้าถึง 403 โปรดดูบล็อกโพสต์นี้ มันช่วยได้ alfielapeter.com/posts/…
crlane

3
สำเนาข้ามภูมิภาคaws s3 sync s3://my-bucket-in-eu-west1 s3://my-bucket-in-eu-central1 --source-region=eu-west-1 --region=eu-central-1
เทียบเท่า

หากคุณต้องการเรียกใช้ ower night บนเซิร์ฟเวอร์ให้ใช้nohup aws s3 sync s3://my-bucket-in-eu-west1 s3://my-bucket-in-eu-central1 --source-region=eu-west-1 --region=eu-central-1 & thegeekstuff.com/2010/12/5-ways-to-execute-linux-command
equivalent8

@alberge มีวิธีใดในการระบุคีย์การเข้าถึงและความลับโดยใช้อาร์กิวเมนต์บรรทัดคำสั่งหรือไม่
EmptyData

30

ผมใช้เวลาหลายวันในการเขียนเครื่องมือกำหนดเองของฉันจะคู่ขนานสำเนาที่จำเป็นสำหรับการนี้ แต่แล้วผมวิ่งข้ามเอกสารเกี่ยวกับวิธีการที่จะได้รับ AWS S3 CLI ซิงค์คำสั่งเพื่อประสานกับบุ้งกี๋ขนานใหญ่ คำสั่งต่อไปนี้จะบอก AWS CLI ให้ใช้ 1,000 เธรดเพื่อดำเนินการงาน (แต่ละไฟล์ขนาดเล็กหรือส่วนหนึ่งของสำเนาหลายส่วน) และมองไปข้างหน้า 100,000 งาน:

aws configure set default.s3.max_concurrent_requests 1000
aws configure set default.s3.max_queue_size 100000

หลังจากเรียกใช้สิ่งเหล่านี้คุณสามารถใช้คำสั่งซิงค์แบบง่ายดังนี้:

aws s3 sync s3://source-bucket/source-path s3://destination-bucket/destination-path

บนเครื่อง m4.xlarge (ใน AWS - 4 คอร์, RAM 16GB) สำหรับเคสของฉัน (ไฟล์ 3-50GB) ความเร็วในการซิงค์ / คัดลอกเปลี่ยนจากประมาณ 9.5MiB / s เป็น 700 + MiB / s ความเร็วเพิ่มขึ้น 70x เหนือการกำหนดค่าเริ่มต้น

อัปเดต: โปรดทราบว่า S3CMD ได้รับการอัปเดตในช่วงหลายปีที่ผ่านมาและการเปลี่ยนแปลงเหล่านี้จะมีผลเฉพาะเมื่อคุณทำงานกับไฟล์ขนาดเล็กจำนวนมาก โปรดทราบว่า S3CMD บน Windows (เฉพาะใน Windows) มีข้อ จำกัด อย่างมากในปริมาณงานโดยรวมและสามารถบรรลุได้ประมาณ 3Gbps ต่อกระบวนการเท่านั้นไม่ว่าคุณจะใช้ขนาดอินสแตนซ์หรือการตั้งค่าใด ระบบอื่น ๆ เช่น S5CMD ก็มีปัญหาเช่นเดียวกัน ฉันได้พูดคุยกับทีม S3 เกี่ยวกับเรื่องนี้แล้วและพวกเขากำลังตรวจสอบอยู่


ขอบคุณที่จัดการเพื่อรับมากกว่า 900 + MiB / s ด้วยการกำหนดค่าของคุณความเร็วสูงกว่าค่าเริ่มต้น
kozyr

@ เจมส์: API จำกัด เราในการถ่ายโอนข้อมูลความเร็วสูงหรือไม่? ฉันใช้ Transferermanager API ที่ AWS Java SDK เทียบกับ CLI จากเครื่อง T2 EC2 เพื่อถ่ายโอนไฟล์ 2 GB ความแตกต่างของเวลาประมาณ 5.5 เท่า (CLI - 14 วินาที) เทียบกับ (SDK - 80 วินาที) นอกจากนี้ฉันไม่เห็นตัวเลือกใด ๆ สำหรับ s3.max_queue_size ใน SDK มีคำแนะนำอะไรมั้ย?
Dwarrior

@Dwarrior การตั้งค่าทั้งสองนี้มีไว้สำหรับ CLI เมื่อใช้ SDK คุณต้องจัดการคำขอทั้งหมดที่เข้าคิวด้วยตัวเอง ฝ่ายสนับสนุนของ AWS อ้างว่ามีปริมาณงานถึง 80% ของปริมาณงานสูงสุดที่เป็นไปได้ระหว่าง EC2 และ S3 โดยใช้ Linux (เช่นปริมาณงานเครือข่ายอินสแตนซ์ EC2 ที่โฆษณา) Windows เป็นพลเมืองชั้นสองบน AWS และไม่สามารถทำได้ถึงครึ่งหนึ่งด้วยเครื่องมือที่ Amazon จัดหาให้และดูเหมือนว่าพวกเขาไม่ได้วางแผนที่จะแก้ไขปัญหานั้น :-( ด้วยเครื่อง T2 AWS ไม่ได้ระบุจำนวนแบนด์วิดท์ที่คุณได้รับแม้ว่าสิ่งต่างๆจะดีขึ้นบ้างหากคุณตั้งค่าปลายทาง S3 VPC
James

@ เจมส์ฉันไปจนถึงขอบเขตของการขนานรายการไฟล์ของฉันบนคลัสเตอร์ในจุดประกายรวมกับการขนานภายในแต่ละพาร์ติชันแล้วใช้โอนย้ายสำหรับการอัปโหลดแบบขนานสำหรับไฟล์ใดก็ได้ ฉันเห็นการปรับปรุงจาก 80 เป็น 45 วินาทีหลังจากทำเช่นนั้น แต่ก็ยังขาดหายไปในวิธีที่ CLI จัดการจาก EC2 ขอบคุณสำหรับการตั้งค่านี้ ปรับปรุงประสิทธิภาพบน windows อย่างมากเช่นกัน ใน SDK เราสามารถตั้งค่าการเชื่อมต่อสูงสุดได้ แต่ไม่ใช่ขนาดคิวดังนั้นฉันคิดว่าเราอาจต้องทิ้งไว้ :) คำแนะนำใด ๆ เกี่ยวกับวิธีจัดการการจัดคิวโค้ดตัวอย่างใด ๆ ที่ฉันสามารถใช้เป็นพื้นฐานได้
Dwarrior

2
S5Cmd ( github.com/peakgames/s5cmd ) เป็นยูทิลิตี้ที่ AWS รองรับผู้ที่ใช้สำหรับปริมาณงานสูงสุด ขนาดอินสแตนซ์สร้างความแตกต่างอย่างมาก ซีรีส์ c5n ใหม่คุ้มค่ามากสำหรับระบบเครือข่ายและไปได้ถึง 100Gbps ที่น่าทึ่ง
James

29

ในการย้าย / คัดลอกจากที่เก็บข้อมูลหนึ่งไปยังอีกที่หนึ่งหรือที่เก็บข้อมูลเดียวกันฉันใช้เครื่องมือ s3cmd และทำงานได้ดี ตัวอย่างเช่น:

s3cmd cp --recursive s3://bucket1/directory1 s3://bucket2/directory1
s3cmd mv --recursive s3://bucket1/directory1 s3://bucket2/directory1

14

.NET ตัวอย่างตามที่ร้องขอ:

using (client)
{
    var existingObject = client.ListObjects(requestForExisingFile).S3Objects; 
    if (existingObject.Count == 1)
    {
        var requestCopyObject = new CopyObjectRequest()
        {
            SourceBucket = BucketNameProd,
            SourceKey = objectToMerge.Key,
            DestinationBucket = BucketNameDev,
            DestinationKey = newKey
        };
        client.CopyObject(requestCopyObject);
    }
}

กับลูกค้าเป็นสิ่งที่ชอบ

var config = new AmazonS3Config { CommunicationProtocol = Protocol.HTTP, ServiceURL = "s3-eu-west-1.amazonaws.com" };
var client = AWSClientFactory.CreateAmazonS3Client(AWSAccessKey, AWSSecretAccessKey, config);

อาจมีวิธีที่ดีกว่านี้ แต่เป็นเพียงรหัสด่วนที่ฉันเขียนเพื่อรับโอนไฟล์บางไฟล์


1
ดูเหมือนจะเป็นทางออกที่ดี แต่จะเกิดอะไรขึ้นหากคุณมีข้อมูลประจำตัวที่แตกต่างกันสำหรับ 2 ที่เก็บข้อมูล
Roee Gavirel

2
หนังสือรับรองมีไว้สำหรับการดำเนินการของคำสั่งคัดลอก ข้อมูลรับรองเดียวเหล่านี้ต้องการสิทธิ์ในการอ่าน / เขียนที่เหมาะสมในที่เก็บข้อมูลต้นทาง / เป้าหมาย หากต้องการคัดลอกระหว่างบัญชีคุณต้องใช้นโยบายที่เก็บข้อมูลเพื่ออนุญาตให้เข้าถึงที่เก็บข้อมูลจากข้อมูลรับรองของบัญชีอื่น
Matt Houser

9

หากคุณมีโฮสต์ unix ภายใน AWS ให้ใช้ s3cmd จาก s3tools.org ตั้งค่าการอนุญาตเพื่อให้คีย์ของคุณเป็นแบบอ่านเข้าถึงที่เก็บข้อมูลการพัฒนาของคุณ จากนั้นเรียกใช้:

s3cmd cp -r s3://productionbucket/feed/feedname/date s3://developmentbucket/feed/feedname

ฝั่งเซิร์ฟเวอร์? ไม่มีฝั่งเซิร์ฟเวอร์สำหรับ s3 คำสั่งทั้งหมดดำเนินการจากไคลเอนต์ระยะไกล
dk.

คำสั่งนี้ดูเหมือนจะใช้งานได้ดีผ่านทางอินเทอร์เน็ต!
Gabe Kopley

3
คำถาม "ฝั่งเซิร์ฟเวอร์" ถูกต้อง s3cmd ถ่ายโอนข้อมูลทั้งหมดไปยังไคลเอนต์หรือเป็นการถ่ายโอน S3 ไปยัง S3 โดยตรงหรือไม่ หากเป็นแบบเดิมควรเรียกใช้สิ่งนี้ใน AWS cloud เพื่อหลีกเลี่ยงการถ่ายโอน WAN ภายนอก
Bruce Edge

1
การคัดลอกเกิดขึ้นจากระยะไกลบน S3
dk.

โปรดทราบว่าหากคุณขัดจังหวะกระบวนการนี้โดยs3cmd cpไม่ได้ตั้งใจจะไม่ยอมรับ--skip-existingตัวเลือกอย่างไรก็ตามคุณสามารถดำเนินการs3cmd syncแทนได้โดยข้ามที่มีอยู่
ianstarz

9

สำหรับฉันคำสั่งต่อไปนี้ใช้งานได้:

aws s3 mv s3://bucket/data s3://bucket/old_data --recursive

2
วิธีแก้ปัญหาที่ง่ายและตรงไปตรงมา ... ทำไมต้องใช้เครื่องมือของบุคคลที่สามหรือวิธีแก้ปัญหาสำหรับงานง่ายๆเช่นนี้ในเมื่อสามารถทำได้ด้วย aws cli!
Fr0zenFyr

7

นี่คือคลาสทับทิมสำหรับการแสดงสิ่งนี้: https://gist.github.com/4080793

ตัวอย่างการใช้งาน:

$ gem install aws-sdk
$ irb -r ./bucket_sync_service.rb
> from_creds = {aws_access_key_id:"XXX",
                aws_secret_access_key:"YYY",
                bucket:"first-bucket"}
> to_creds = {aws_access_key_id:"ZZZ",
              aws_secret_access_key:"AAA",
              bucket:"first-bucket"}
> syncer = BucketSyncService.new(from_creds, to_creds)
> syncer.debug = true # log each object
> syncer.perform

6

จริงๆแล้วเมื่อเร็ว ๆ นี้ฉันเพิ่งใช้การคัดลอก + วางในอินเทอร์เฟซ AWS s3 เพียงไปที่ไฟล์ที่คุณต้องการคัดลอกคลิก "การดำเนินการ" -> "คัดลอก" จากนั้นไปที่ที่เก็บข้อมูลปลายทางและ "การดำเนินการ" -> "วาง"

มันถ่ายโอนไฟล์ได้ค่อนข้างรวดเร็วและดูเหมือนว่าจะเป็นวิธีแก้ปัญหาที่ซับซ้อนน้อยกว่าซึ่งไม่จำเป็นต้องมีการเขียนโปรแกรมใด ๆ หรือมากกว่าโซลูชันชั้นนำเช่นนั้น


ใช่. ฉันได้ค้นพบสิ่งเดียวกันนี้เมื่อหลายนาทีก่อน ฉันโหวตแล้วคนจะได้ประหยัดเวลามากขึ้น :)
JCarlosR

ฉันลองทำในถังเพื่อเก็บสำเนาที่มีวัตถุ 134,364 ชิ้นอยู่ในนั้น ใช้เวลาหลายชั่วโมง และปลายทางลงเอยด้วยไฟล์เพียง 134,333 ไฟล์ - สำเนาบอกว่า "สำเร็จ" แต่ไม่มีคำอธิบายสำหรับไฟล์ที่หายไป
ผึ้ง

การใช้คำสั่งประเภท "aws s3 sync" ที่อธิบายไว้ในโพสต์อื่น ๆ ที่นี่อ็อบเจ็กต์ทั้งหมด 134,364 รายการถูกคัดลอกในเวลาประมาณ 20 นาที
ผึ้ง

4

เรามีปัญหาตรงนี้กับงาน ETL ของเราที่Snowplowดังนั้นเราจึงแยกโค้ดสำเนาไฟล์แบบขนาน (Ruby ที่สร้างขึ้นบนFog ) เป็นอัญมณี Ruby ของตัวเองที่เรียกว่า Sluice:

https://github.com/snowplow/sluice

Sluice ยังจัดการลบไฟล์ S3 ย้ายและดาวน์โหลด ขนานทั้งหมดและลองใหม่โดยอัตโนมัติหากการดำเนินการล้มเหลว (ซึ่งบ่อยครั้งที่น่าแปลกใจ) ฉันหวังว่ามันจะมีประโยชน์!


1

ฉันรู้ว่านี่เป็นกระทู้เก่า แต่สำหรับคนอื่น ๆ ที่ไปถึงที่นั่นคำแนะนำของฉันคือสร้างงานตามกำหนดการเพื่อคัดลอกเนื้อหาจากที่เก็บข้อมูลการผลิตไปยังการพัฒนา

คุณสามารถใช้ If you use .NET บทความนี้อาจช่วยคุณได้

https://edunyte.com/2015/03/aws-s3-copy-object-from-one-bucket-or/


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.