ฉันจะคัดลอกไฟล์ขนาดเล็กจำนวนมากไปยัง scp ได้ดีที่สุดอย่างไร


59

ฉันมีไดเรกทอรีที่มีหลายกิกะไบต์และไฟล์ขนาดเล็กหลายพัน ฉันต้องการคัดลอกผ่านเครือข่ายด้วย scp มากกว่าหนึ่งครั้ง เวลาซีพียูในเครื่องต้นทางและปลายทางมีราคาถูก แต่ค่าใช้จ่ายในเครือข่ายที่เพิ่มเข้ามาโดยการคัดลอกแต่ละไฟล์นั้นใหญ่มาก ฉันจะ tar / gzip ขึ้นมาและส่งมันไป แต่เครื่องต้นทางสั้นบนดิสก์

มีวิธีที่ฉันจะท่อส่งออกtar -czf <output> <directory>ไปยัง SCP? ถ้าไม่มีวิธีแก้ปัญหาง่าย ๆ อีกไหม? เครื่องต้นทางของฉันโบราณ (SunOS) ดังนั้นฉันไม่อยากติดตั้งอะไรลงไป

คำตอบ:


104

คุณสามารถไปป์ tar ระหว่างเซสชัน ssh:

$ tar czf - <files> | ssh user@host "cd /wherever && tar xvzf -"

3
+1 tar-pipe solution หากคุณมีแบนด์วิดท์มากขึ้นและ CPU น้อยลงคุณสามารถลบการตั้งค่าการบีบอัด (แม้ว่า gzip จะค่อนข้างเบา)
dietbuddha

2
และคุณสามารถปล่อยแฟลกการบีบอัดและเปิดใช้งาน SSH แทน ( ssh -CหรือCompression yesใน~/.ssh/config)
sam hocevar

3
ไม่เคยคิดว่าจะใช้ tar แบบนี้ นั่นเป็นเหตุผลว่าทำไมฉันมาที่นี่!
Mr. Shickadance

2
คำสั่งนี้สามารถทำให้สั้นลงได้เล็กน้อย:$ tar cz <files> | ssh user@host "cd /wherever; tar xvz"
carlito

2
@Greg the dash เป็นระเบียบปฏิบัติในซอฟต์แวร์ที่รองรับ POSIX เพื่อหมายถึง STDIN หรือ STDOUT ขึ้นอยู่กับบริบท เครื่องหมายขีดแรกคือความหมาย 'อ่านจาก / dev / stdin' และอันที่สอง - ซึ่งถูกเรียกใช้จริงบนรีโมตโฮสต์ - หมายถึง '/ dev / stdin' ไปป์และ ssh เชื่อมต่อทั้งสองกระบวนการ ดูunix.stackexchange.com/questions/16357/…เพื่อเรียนรู้เพิ่มเติม
Richard Metzler

22

Tar ที่มีการบีบอัด bzip2 ควรใช้โหลดมากเท่าที่เครือข่ายและบน cpu

$ tar -C /path/to/src/dir -jcf - ./ | ssh user@server 'tar -C /path/to/dest/dir -jxf -'

ไม่ใช้-vเนื่องจากหน้าจอออกอาจทำให้กระบวนการช้าลง แต่ถ้าคุณต้องการเอาต์พุต verbose ให้ใช้มันที่ด้านโลคัลของ tar ( -jcvf) ไม่ใช่ส่วนรีโมต

หากคุณคัดลอกซ้ำบนเส้นทางปลายทางเดียวกันเช่นอัปเดตสำเนาสำรองตัวเลือกที่ดีที่สุดของคุณคือ rsync พร้อมการบีบอัด

$ rsync -az -e ssh /path/to/src/dir/ user@server:/path/to/dest/dir/

โปรดสังเกตว่าทั้ง src และ dest path ลงท้ายด้วย / อีกครั้งไม่ได้ใช้-vและตั้ง-Pค่าสถานะตามความมุ่งหมายให้เพิ่มหากคุณต้องการเอาต์พุตแบบละเอียด


16

ใช้rsyncมันใช้ SSH

การใช้งาน:

rsync -aPz /source/path destination.server:remote/path

สวิตช์ rsync ใส่ใจกับการบีบอัดและข้อมูล I-Node -Pแสดงความคืบหน้าของทุกไฟล์

คุณสามารถใช้scp -Cซึ่งจะช่วยให้การบีบอัด rsyncแต่ถ้าเป็นไปได้ใช้งาน


น่าเสียดายที่ rsync ไม่สามารถใช้งานได้ในเครื่องต้นทางและไม่มี sshd
nmichaels

1
sshd ไม่จำเป็นสำหรับการดำเนินการเหล่านั้นบนเครื่องไคลเอ็นต์
polemon

3

คุณสามารถวิ่งได้tarทั้งสองด้านโดยใช้ ssh scpเป็นส่วนหนึ่งของsshครอบครัวแห่งความดีดังนั้นคุณอาจมีทั้งสองด้าน

 8:03AM 12 % tar cf - some_directory | ssh dest_host "tar xf -"

อาจมีวิธีการทำงาน gzip หรือ bzip2 ในไพพ์ไลน์เพื่อลดทราฟฟิกเครือข่ายเช่นกัน


3

คำตอบของ @ pdo นั้นดี แต่ก็สามารถเพิ่มความเร็วได้ด้วยบัฟเฟอร์และการบีบอัดที่ดีและเพิ่มแถบความคืบหน้า

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

นอกจากนี้เราสามารถเพิ่มความเร็วได้ด้วยอัลกอริธึมการบีบอัดที่เหมาะสม Gzip (เช่นใช้ด้านบน) เป็นอัลกอริธึมการบีบอัดที่รวดเร็ว แต่โดยทั่วไป zstandard ( zstd) (และสำหรับอัตราส่วนการบีบอัดสูง LZMA / LZMA2 ( xz) จะบีบอัดได้ดีขึ้นและเร็วขึ้นในเวลาเดียวกันใหม่ xz และ zstd มีการสนับสนุนหลายแกน หากต้องการใช้ gzip กับ pigz หลายแกนสามารถใช้ได้

นี่คือตัวอย่างในการส่งข้อมูลที่มีแถบความคืบหน้าการบีบอัดบัฟเฟอร์และการบีบอัดแบบ zstandard ผ่านเครือข่าย:

tar cf - . | pv -perabs $(du -sk . | cut -f 1)K | zstd -14 --long=31 -T0 | pv -qCB 512M | ssh user@host "cd /wherever && pv -qCB 512M | zstd -cd -T0 --long=31 | tar xf -"

สิ่งแรกpvคือการแสดงความคืบหน้า ( p ), เวลาโดยประมาณ ( e ), อัตราการถ่ายโอน ( r ), อัตราเฉลี่ย ( a ), ไบต์ที่ถ่ายโอนทั้งหมด ( b ) ขนาดรวมอยู่ที่ประมาณด้วยduและเพิ่มไปยังตัวเลือกขนาด ( s ) ความคืบหน้าถูกวัดก่อนการบีบอัดและบัฟเฟอร์ดังนั้นจึงไม่แม่นยำมาก แต่ก็ยังมีประโยชน์

zstdจะใช้กับการตั้งค่าการบีบอัดที่14 จำนวนนี้สามารถลดหรือเพิ่มขึ้นอยู่กับเครือข่ายและความเร็วของ CPU ดังนั้น zstd จะเร็วกว่าความเร็วเครือข่ายเล็กน้อย ด้วยสี่คอร์ใน Haswell 3.2 GHz CPU 14ให้ความเร็วประมาณ 120 MB / s ในตัวอย่างโหมดยาว31 (ใช้หน้าต่าง 2 GB ต้องการ RAM จำนวนมาก แต่ดีมากเช่นการบีบอัดฐานข้อมูลทิ้ง) ใช้ T0ตัวเลือกการกำหนดปริมาณของกระทู้ไปยังหมายเลขของแกน สิ่งหนึ่งที่ควรระวังคือเมื่อใช้โหมดความยาวร่วมกับการตั้งค่าเหล่านี้จะใช้หน่วยความจำจำนวนมาก

ปัญหากับ zstd คือระบบปฏิบัติการส่วนใหญ่ไม่ได้จัดส่งมาพร้อมกับรุ่น> = 1.3.4 เวอร์ชั่นนี้จำเป็นสำหรับการรองรับมัลติคอร์และการรองรับที่ยาวนาน หากไม่พร้อมที่จะสามารถรวบรวมและติดตั้งจากhttps://github.com/facebook/zstdmake -j4 && sudo make installมีเพียง แทนที่จะเป็น zstd เราสามารถใช้ xz หรือ pigz ได้ xz ช้า แต่บีบอัดได้ดีมาก (ดีในการเชื่อมต่อที่ช้า) pigz / gzip นั้นเร็ว แต่บีบอัดไม่ค่อยดี pvจะถูกใช้อีกครั้ง แต่สำหรับการบัฟเฟอร์ ( qสำหรับCโหมดเงียบสำหรับโหมดไม่ต่อเนื่อง [ต้องการการบัฟเฟอร์เสมอ] และBเพื่อกำหนดขนาดบัฟเฟอร์)

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


2

หากคุณมี gzip ที่ปลายทั้งสอง: sourcehost$ cd sourcedir && tar cf - . | gzip -c - | ssh user@destinationhost "cd destinationdir && gzip -c -d | tar xf -"

หากคุณไม่มี gzip บนเครื่องต้นทางตรวจสอบให้แน่ใจว่าคุณได้คลายการบีบอัดที่ปลายทาง: sourcehost$ cd sourcedir && tar cf - . | compress | ssh user@destinationhost "cd destdir && uncompress | tar xf -"

นี่จะเร็วกว่าการบีบอัดไฟล์แรกแล้วส่งแล้วคลายซิปและไม่ต้องใช้พื้นที่ดิสก์เพิ่มเติมทั้งสองด้าน ฉันเสียบธงชาติอัด (z) ลงบน tar เพราะคุณอาจไม่มีทางด้านโบราณ


2

หรือคุณสามารถทำมันด้วยวิธีอื่นถ้าคุณต้องการ นั่นคือดึง tarball ผ่านเครือข่ายแทนที่จะผลักมันเหมือนที่ได้รับการแนะนำ สิ่งนี้ไม่ได้แก้ส่วนที่ทำซ้ำของคำถามของคุณและ rsync นั้นดีที่สุดสำหรับสิ่งนั้น แต่อาจมีสวิตช์ tar เพื่อช่วยเหลือ

ดังนั้นในเครื่องท้องถิ่น:

ssh remote 'tar zcf - /etc/resolv.conf' | tar zxf -

ดีที่สุดที่จะอยู่ในไดเรกทอรีที่ถูกต้องก่อนอื่นหรือคุณต้องใช้สวิตช์ -C บนคำสั่งที่ไม่มีการประกาศเมื่อสิ้นสุด

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

HTH



1

ในขณะที่ไม่สวยที่สุดโดยเฉพาะอย่างยิ่งเนื่องจากมันไม่ได้คัดลอกไฟล์ zip หรือ tar เพียงไฟล์เดียวและเพิ่มขึ้นเป็นสองเท่าเพื่อไม่ช่วยลดปัญหาเครือข่าย ovehead ตัวเลือกเดียวของฉันคือscp -r:

-r

      คัดลอกไดเรกทอรีทั้งหมดซ้ำ ๆ โปรดทราบว่าscp ตามลิงก์สัญลักษณ์ที่พบในการแวะผ่านต้นไม้
ที่มา: scp (1)

ฉันพบปัญหาเกี่ยวกับพื้นที่ดิสก์ที่มีไฟล์ tar ซิปขนาด 30 GB ฉันคิดว่า gunzip สามารถทำแบบอินไลน์ได้เช่นลบต้นฉบับเนื่องจากมีการคลายซิป (และฉันอาจพลาดผลการค้นหาของ Google) แต่ฉันไม่พบอะไรเลย

ในที่สุดเนื่องจากฉันเบื่อที่จะลองหลายครั้งเพื่อรอให้ไฟล์ TAR หรือ ZIP ใหม่เสร็จสิ้นการ tar'ing หรือซิปเสร็จฉันก็ทำในที่สุด:

  1. จากเซิร์ฟเวอร์ / พีซี / แล็ปท็อปดั้งเดิมนำทางไปยังไดเรกทอรีที่โฟลเดอร์ของคุณมีไฟล์ / โฟลเดอร์มากมาย
  2. scp -r source_folder_name yourname@yourservername:destination_folder_name

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


ตกลงนี่ใช้เวลาน้อยลงกว่าการพิมพ์scpคำสั่งพันคำสั่ง แต่คำถามถามเกี่ยวกับ“ ค่าใช้จ่ายเครือข่าย” โซลูชันของคุณใช้เครือข่ายน้อยกว่าการคัดลอกแต่ละไฟล์หรือไม่ โซลูชันของคุณเหนือกว่าคู่แข่งทั้งเจ็ดที่เคยโพสต์ไปแล้วหรือไม่?
G-Man

Snap, bad ของฉัน - ฉันพลาดส่วนค่าใช้จ่ายเครือข่ายโดยสิ้นเชิง - ขอบคุณที่ชี้ให้เห็นว่า @G-Man ฉันอัปเดตคำตอบฉันยังคงรู้สึกว่ามันอาจจะมีประโยชน์ถ้าใครบางคนสะดุดกับปัญหาที่คล้ายกันเช่นฉันและเมื่อฉันเจอคำถามนี้
JGlass
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.