วิธีที่เร็วที่สุดในการย้ายรูปภาพนับล้านรูปจากไดเรกทอรีหนึ่งไปยังอีกไดเรกทอรีหนึ่งใน Linux คืออะไร


14

ฉันมีหนึ่งล้านภาพที่ใช้พื้นที่ดิสก์ 30GB ซึ่งจำเป็นต้องย้ายจากไดเรกทอรีภายในเครื่องหนึ่งไปยังไดเรกทอรีภายในเครื่องอื่น

อะไรจะเป็นวิธีที่มีประสิทธิภาพมากที่สุดในการทำเช่นนี้? ใช้งานmvหรือ? ใช้งานcpหรือ? ใช้งานrsyncหรือ? อื่น ๆ อีก?

ฉันต้องการสิ่งเหล่านี้:

/path/to/old-img-dir/*
                     00000000.jpg
                     --------.jpg  ## nearly 1M of them! ##
                     ZZZZZZZZ.jpg

และย้ายพวกเขาที่นี่:

/path/to/new/img/dir/

5
ฉันไม่คิดว่าคุณจะสามารถเอาชนะmvประสิทธิภาพได้ถ้าทั้งไดเรกทอรีต้นทางและเป้าหมายอยู่ในระบบไฟล์เดียวกัน
Frédéric Hamidi

คำตอบ:


26

rsync จะเป็นตัวเลือกที่ไม่ดีเพราะมันมีพื้นหลังไคลเอนต์ / เซิร์ฟเวอร์จำนวนมากซึ่งทำงานในระบบทั้งในและนอกสถานที่

mvน่าจะเป็นทางเลือกที่ดีที่สุด ถ้าเป็นไปได้คุณควรพยายามมากกว่าmv directory_old directory_new mv directory_old/* directory_new/ด้วยวิธีนี้คุณย้ายสิ่งหนึ่งแทนที่จะเป็นล้านสิ่ง


6
+1 สำหรับคำแนะนำในการย้ายไดเรกทอรีแทนไฟล์
อดีต Umbris

4
นอกจากนี้การขยายตัวไวด์การ์ดอาจทำลายข้อโต้แย้งสูงสุดที่สนับสนุนโดยmvหากเรากำลังพูดถึงคนนับล้าน
slhck

6
rsync จัดการการถ่ายโอนบนสื่อเก็บข้อมูลภายในได้ดี มันบังคับให้สิ่งต่าง ๆ เช่น - ทั้งไฟล์ (ลบการใช้อัลกอริทึมของเดลต้าเอ็กซ์เฟอร์) และป้องกันสิ่งอื่น ๆ เช่น - การบีบอัดข้อมูลซึ่งไม่มีจุดประสงค์ในการถ่ายโอนในท้องถิ่น หากไดเรกทอรีอยู่ในระบบไฟล์ที่แตกต่างกัน 'mv' จะไม่ให้ประสิทธิภาพใด ๆ หากพวกเขาอาศัยอยู่ในระบบไฟล์เดียวกันก็แค่ 'mv' ไดเรกทอรีเช่นคนเหล่านี้กล่าวว่า
UtahJarhead

หากมีภาพจำนวนมากการใช้ wildcard ของเชลล์แบบง่ายจะทำให้ล้นบรรทัดคำสั่งสูงสุด
Raúl Salinas-Monteagudo

1
การย้ายระหว่างดิสก์จะยังคงย้ายข้อมูลทั้งหมด บนดิสก์เดียวกันmvเพียงอัปเดตข้อมูล inode เพื่อให้mv directory_old directory_newทำงานได้เร็วกว่าmv directory_old/* directory_new
Anshul

14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • การทำเช่นนี้จะไม่เป็นการขยายข้อโต้แย้งมากเกินไป
  • คุณสามารถระบุนามสกุลไฟล์ได้หากต้องการ (-name ... )
  • find -print0ด้วยxargs -0อนุญาตให้คุณใช้ช่องว่างในชื่อ
  • xargs -rจะไม่ทำงานmvจนกว่าจะมีสิ่งที่จะย้าย ( mvจะบ่นหากไม่ได้รับไฟล์ต้นฉบับ)
  • ไวยากรณ์ช่วยให้คุณระบุแรกปลายทางและไฟล์ที่มาแล้วจำเป็นโดยmv -txargs
  • แน่นอนว่าการย้ายไดเรกทอรีทั้งหมดนั้นเร็วกว่ามากเนื่องจากจะเกิดขึ้นในเวลาคงที่โดยไม่คำนึงถึงจำนวนไฟล์ที่อยู่ในนั้น แต่:
    • ไดเรกทอรีต้นทางจะหายไปสักครู่และอาจทำให้คุณเกิดปัญหา
    • หากกระบวนการใช้ไดเรกทอรีปัจจุบันเป็นไดเรกทอรีผลลัพธ์ (ตรงกันข้ามกับการอ้างอิงถึงเส้นทางแบบเต็มจากตำแหน่งที่ไม่ย้าย) คุณจะต้องเปิดใช้งานอีกครั้ง (เหมือนที่คุณทำกับการหมุนบันทึก )

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


สิ่งนี้ทำงานได้ดีพอสำหรับการย้ายไฟล์ข้ามระบบไฟล์บนเซิร์ฟเวอร์เดียวกัน ดีพอที่ฉันไม่ได้มองหาวิธีแก้ปัญหาใน rsync แน่นอนว่าใช้เวลาหนึ่งหรือสองชั่วโมง แต่ก็ใช้งานได้ สิ่งหนึ่งที่ควรทราบถ้าคุณให้ค้นหาชื่อไดเรกทอรีแทน "." - ต้องแน่ใจว่าใช้เครื่องหมายสแลชต่อท้ายในคำสั่ง find มิฉะนั้นไดเร็กทอรีจะถูกสร้างขึ้นใหม่ในปลายทางของคำสั่ง mv
Speeddymon

7

หากทั้งสองไดเร็กทอรีอยู่ในระบบไฟล์เดียวกันให้ใช้mvบน DIRECTORY ไม่ใช่เนื้อหาของไดเร็กทอรี

หากพวกเขาอยู่ในระบบไฟล์ที่แตกต่างกันสองระบบให้ใช้ rsync:

rsync -av /source/directory/ /destination

สังเกตเห็นการลาก/บนแหล่งที่มา ซึ่งหมายความว่ามันจะคัดลอกเนื้อหาของไดเรกทอรีและไม่ใช่ไดเรกทอรีเอง หากคุณปล่อยให้/ออกก็จะยังคงคัดลอกไฟล์ /destination/directoryแต่พวกเขาจะนั่งอยู่ในไดเรกทอรีชื่อ ด้วย / ไฟล์จะอยู่ใน/destination

rsyncจะรักษาความเป็นเจ้าของไฟล์หากคุณเรียกใช้ในฐานะรูทหรือหากคุณเป็นเจ้าของไฟล์ นอกจากนี้ยังจะดูแลmtimeไฟล์แต่ละไฟล์


2
สำหรับการคัดลอกโฟลเดอร์ที่มีขนาดใหญ่จากฮาร์ดไดรฟ์หนึ่งไปยังฮาร์ดไดรฟ์ที่แตกต่างกันดูเหมือนว่าจะทำงานวงกลมรอบrsync mvขอบคุณสำหรับทิป!
leo-the-manic

2
tar cf - dir1 | (cd dir2; tar xf -)

tar cf - dir1 | ssh remote_host "( cd /path/to/dir2; tar xf - )"

เมื่อคุณใช้ 'cp' แต่ละไฟล์จะเป็นการเปิดอ่าน - ปิด - เปิด - เขียน - ปิด Tar ใช้กระบวนการที่แตกต่างกันสำหรับการอ่านและการเขียนรวมถึงดอกยางหลายอันเพื่อใช้งานกับไฟล์หลายไฟล์พร้อมกัน แม้ในแอพพลิเคชั่นแบบมัลติเธรดแบบหลายช่องกล่อง CPU ก็เร็วขึ้น


2
แม้ว่าสิ่งนี้อาจตอบคำถามได้ แต่มันจะเป็นคำตอบที่ดีกว่าถ้าคุณสามารถให้คำอธิบายได้ว่าทำไมถึงเป็นเช่นนั้น
DavidPostill

1
หากพวกเขาอยู่ในเครื่องท้องถิ่นโอกาสที่พวกเขาจะอยู่ในระบบไฟล์เดียวกัน โดยการใช้งานtar c | tar xคุณจะได้รับค่าใช้จ่าย O (total_size) แทน O (file_count)
Raúl Salinas-Monteagudo

1

เนื่องจากทั้ง directory_old และ directory_new อยู่ในระบบไฟล์เดียวกันคุณสามารถใช้cp -lแทนmvตัวเลือกได้ cp -lจะสร้างฮาร์ดลิงก์ไปยังไฟล์ต้นฉบับ เมื่อคุณทำ 'ย้าย' และคุณพอใจกับผลแล้วคุณสามารถลบไฟล์เหล่านี้ออกจาก directory_old ในแง่ของความเร็วมันจะเหมือนกับ 'mv' เป็นครั้งแรกที่คุณสร้างลิงค์จากนั้นคุณลบลิงค์เดิม แต่วิธีการนี้ช่วยให้คุณเริ่มจากจุดเริ่มต้นหากวิธีนี้เหมาะสม


0

มันขึ้นอยู่กับ (tm) หากระบบไฟล์ของคุณเป็น copy-on-write ดังนั้นการคัดลอก ( cpหรือrsyncตัวอย่าง) ควรเทียบเคียงกับการย้าย แต่สำหรับกรณีทั่วไปส่วนใหญ่ move ( mv) จะเร็วที่สุดเนื่องจากสามารถสลับไปมารอบ ๆ ชิ้นส่วนของข้อมูลที่อธิบายตำแหน่งที่วางไฟล์ได้ (หมายเหตุ: สิ่งนี้ง่ายเกินไป)

mvดังนั้นในการติดตั้งลินุกซ์ของคุณโดยเฉลี่ยแล้วฉันไป

แก้ไข: @ Frédéric Hamidi มีจุดดีในความคิดเห็น: นี้จะใช้ได้เฉพาะถ้าพวกเขาทั้งสองอยู่ในระบบไฟล์และดิสก์เดียวกัน มิฉะนั้นข้อมูลจะถูกคัดลอกต่อไป


0

หากต้องการคัดลอกไฟล์อย่างน้อย ~ 10k (ไม่มีไดเรกทอรี) ให้ cp ร้องเรียนด้วย:

ไม่สามารถดำเนินการ / bin / cp: รายการอาร์กิวเมนต์ยาวเกินไป

ตัวเลือกที่ดีที่สุดคือ Rsync:

เป้าหมายต้นทาง rsync

และมันก็เสร็จเร็วมาก!


0

หากคุณมีพื้นที่ว่างให้เก็บถาวรไว้ในไฟล์. tar ไฟล์เดียว (โดยไม่มีการบีบอัดใด ๆ ที่เร็วกว่า) จากนั้นย้ายไฟล์นั้นไปแล้วยกเลิกการเก็บถาวร


0

ลักษณะของปลายทางจะเป็นตัวกำหนดวิธีที่มีประสิทธิภาพที่สุดในการทำงานนี้ สมมติว่าคุณอยู่ในระบบท้องถิ่นคุณPWDอยู่/ในขณะนี้ และ/aมีรูปภาพนับล้าน หน้าที่ของเราคือการย้ายภาพทั้งหมดไป/bยังในขณะที่ยังคงโครงสร้างไดเรกทอรีย่อยทั้งหมด ให้ถือว่า/aและ/bเป็นจุดเชื่อมต่อสำหรับสองพาร์ติชันที่ต่างกันโดยแต่ละอันบนดิสก์ที่เชื่อมต่อแบบโลคัล เราต้องการที่จะทำงานนี้ด้วยผ้าใบกันน้ำ ซึ่งอาจใช้เวลาสักครู่เพื่อให้แน่ใจว่าคุณกำลังใช้screen, tmuxหรือคุณดำเนินการนี้เป็นกระบวนการพื้นหลัง

tar -C /a -cf . | tar -C /b -xf -

นั่นจะเป็นการคัดลอกไฟล์และไดเรกทอรีทั้งหมด/aไปยัง/bดังนั้นตอนนี้คุณจะต้องล้างข้อมูล/aเมื่อคุณยืนยันว่าเสร็จสิ้นโดยไม่มีข้อผิดพลาด

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