Làm cách nào tôi có thể sao chép tốt nhất số lượng lớn các tệp nhỏ qua scp?


59

Tôi có một thư mục có vài gigabyte và vài nghìn tệp nhỏ. Tôi muốn sao chép nó qua mạng với scp nhiều lần. Thời gian CPU trên các máy nguồn và đích là rẻ, nhưng chi phí mạng được thêm bằng cách sao chép từng tệp riêng lẻ là rất lớn. Tôi sẽ tar / gzip nó lên và gửi nó đi, nhưng máy nguồn bị thiếu trên đĩa.

Có cách nào để tôi dẫn đầu ra của tar -czf <output> <directory>scp không? Nếu không, có một giải pháp dễ dàng khác? Máy nguồn của tôi là cổ (SunOS) vì vậy tôi không muốn cài đặt mọi thứ trên đó.

Câu trả lời:


104

Bạn có thể dẫn tar qua một phiên ssh:

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

3
Giải pháp ống nhựa +1. Nếu bạn có nhiều băng thông hơn và ít CPU hơn, bạn có thể xóa cờ nén (mặc dù gzip khá nhẹ).
Dietbuddha

2
Và bạn có thể thả cờ nén và thay vào đó kích hoạt nó trong SSH ( ssh -Choặc Compression yestrong ~/.ssh/config).
sam hocevar

3
Chưa bao giờ nghĩ đến việc sử dụng tar như thế này. Vâng, đó là lý do tại sao tôi đến đây!
Ông Shickadance

2
Lệnh này có thể được thực hiện ngắn hơn một chút:$ tar cz <files> | ssh user@host "cd /wherever; tar xvz"
carlito

2
@Greg dash là một quy ước trong phần mềm tương thích POSIX có nghĩa là STDIN hoặc STDOUT tùy thuộc vào ngữ cảnh. Dấu gạch đầu tiên có nghĩa là 'đọc từ / dev / stdin' và dấu thứ hai - thực sự được thực thi trên máy chủ từ xa - có nghĩa là '/ dev / stdin'. Các đường ống và ssh kết nối cả hai quá trình. Xem unix.stackexchange.com/questions/16357/ Google để tìm hiểu thêm.
Richard Metzler

22

Tar với nén bzip2 sẽ tải càng nhiều mạng và trên cpu.

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

Không sử dụng -vvì đầu ra màn hình có thể làm chậm quá trình. Nhưng nếu bạn muốn một đầu ra dài dòng, hãy sử dụng nó ở phía cục bộ của tar ( -jcvf), chứ không phải ở phần từ xa.

Nếu bạn liên tục sao chép trên cùng một đường dẫn đích, như cập nhật một bản sao lưu, lựa chọn tốt nhất của bạn là rsync với nén.

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

Lưu ý rằng cả hai đường dẫn src và Dest đều kết thúc bằng a /. Một lần nữa, không sử dụng -vvà gắn -Pcờ vào mục đích, thêm chúng nếu bạn cần đầu ra dài dòng.


16

sử dụng rsync, nó sử dụng SSH.

Sử dụng:

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

Các công tắc rsync quan tâm đến thông tin nén và I-Node. -Phiển thị tiến trình của mọi tập tin.

Bạn có thể sử dụng scp -C, cho phép nén, nhưng nếu có thể, hãy sử dụng rsync.


Thật không may, rsync không khả dụng trên máy nguồn và sshd cũng không.
nmichaels

1
sshd không cần thiết cho các hoạt động trên máy khách.
Polemon

3

Bạn có thể chạy tartrên cả hai đầu bằng ssh. scplà một phần của sshgia đình tốt, vì vậy bạn có thể có nó ở cả hai đầu.

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

Có thể có một cách để làm việc gzip hoặc bzip2 vào đường ống để giảm lưu lượng mạng.


3

Câu trả lời của @ pdo là tốt, nhưng người ta có thể tăng tốc độ với bộ đệm và nén tốt và thêm thanh tiến trình.

Thông thường mạng là nút cổ chai và tốc độ thay đổi theo thời gian. Do đó, nó giúp đệm dữ liệu trước khi gửi chúng qua mạng. Điều này có thể được thực hiện với pv.

Ngoài ra, người ta thường có thể tăng tốc độ bằng thuật toán nén phù hợp. Gzip (như được sử dụng ở trên) là một thuật toán nén nhanh, nhưng nói chung zst Chuẩn ( zstd) (và đối với tỷ lệ nén cao, LZMA / LZMA2 ( xz) sẽ nén tốt hơn và đồng thời nhanh hơn. Xz và zstd mới đã hỗ trợ đa lõi Để sử dụng gzip với nhiều lõi pigz có thể được sử dụng.

Dưới đây là một ví dụ để gửi dữ liệu với thanh tiến trình, bộ đệm và nén theo tiêu chuẩn z qua mạng:

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 -"

Đầu tiên pvlà hiển thị tiến trình ( p ), thời gian ước tính ( e ), tốc độ truyền ( r ), tốc độ trung bình ( a ), tổng số byte được truyền ( b ). Tổng kích thước được ước tính duvà thêm vào ( các ) tùy chọn kích thước . Tiến trình được đo trước khi nén và đệm, do đó nó không chính xác lắm, nhưng vẫn hữu ích.

zstdđược sử dụng với cài đặt nén 14 . Con số này có thể giảm hoặc tăng tùy thuộc vào mạng và tốc độ CPU, vì vậy zstd nhanh hơn một chút so với tốc độ mạng. Với bốn lõi trên Haswell 3.2 CPU GHz 14 đưa ra một tốc độ khoảng 120 MB / s. Trong ví dụ, chế độ dài 31 (sử dụng cửa sổ 2 GB, cần rất nhiều RAM, nhưng rất tốt, ví dụ như để nén các cơ sở dữ liệu) được sử dụng. Các tùy chọn T0 đặt số lượng luồng cho số lượng lõi. Mọi người nên biết rằng cùng với chế độ dài, các cài đặt này sử dụng rất nhiều bộ nhớ.

Một vấn đề với zstd là hầu hết các hệ điều hành không xuất xưởng với phiên bản> = 1.3.4. Phiên bản này là cần thiết cho đa lõi thích hợp và hỗ trợ lâu dài. Nếu không có sẵn, nó có thể được biên dịch và cài đặt từ https://github.com/facebook/zstd chỉ với make -j4 && sudo make install. Thay vì zstd, người ta cũng có thể sử dụng xz hoặc pigz. xz chậm nhưng nén rất tốt (tốt trên các kết nối chậm), pigz / gzip nhanh nhưng nén không tốt lắm. pvsau đó được sử dụng lại, nhưng để đệm ( qđối với Cchế độ yên tĩnh, đối với chế độ không có mối nối [luôn luôn cần thiết cho bộ đệm] và Bđể đặt kích thước bộ đệm).

Trong ví dụ, một bộ đệm cũng được sử dụng ở phía bên nhận. Điều này thường không cần thiết (vì giải nén và tốc độ ghi đĩa cứng cao nhất thời gian so với tốc độ mạng), nhưng thường cũng không gây hại.


2

Nếu bạn có gzip ở cả hai đầu: sourcehost$ cd sourcedir && tar cf - . | gzip -c - | ssh user@destinationhost "cd destinationdir && gzip -c -d | tar xf -"

Nếu bạn không có gzip trên máy nguồn, hãy đảm bảo rằng bạn đã giải nén ở đích: sourcehost$ cd sourcedir && tar cf - . | compress | ssh user@destinationhost "cd destdir && uncompress | tar xf -"

Điều này sẽ nhanh hơn so với lần đầu tiên nén nó, sau đó gửi, sau đó giải nén và nó không yêu cầu thêm không gian đĩa ở hai bên. Tôi đã gắn cờ nén (z) trên tar, vì có lẽ bạn không có nó ở phía cổ.


2

Hoặc bạn có thể làm theo cách khác nếu bạn cần. Đó là kéo tarball qua mạng thay vì đẩy nó như đã được đề xuất. Điều này không giải quyết được phần lặp lại của câu hỏi của bạn và rsync là tốt nhất cho điều đó nhưng có lẽ có các công tắc tar để trợ giúp.

Vì vậy, trên máy cục bộ:

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

Tốt nhất là ở trong thư mục bên phải trước hoặc bạn phải sử dụng công tắc -C trên lệnh chưa xử lý ở cuối.

Chỉ cần đề cập đến điều này trong trường hợp này là cần thiết. Đó là đối với tôi vì trong tình huống của tôi, máy chủ cục bộ của tôi đứng sau nat, vì vậy sẽ mất một số mạng tương lai để có thể làm điều đó theo cách mà trước đây đã được đề cập.

HTH


1

Hoặc gắn kết hệ thống tập tin từ xa thông qua sshfs

sshfs user@remotehost:/path/on/remote /path/on/local

1

Mặc dù không thanh lịch nhất, đặc biệt là vì nó không sao chép một tệp zip hoặc tar duy nhất và đôi khi vì vậy nó không giúp giảm bớt tình trạng mạng, lựa chọn duy nhất của tôi là sử dụng scp -r:

-r

      Đệ quy sao chép toàn bộ thư mục. Lưu ý rằng scp sau các liên kết tượng trưng gặp phải trong giao dịch cây.
Nguồn: scp (1)

Tôi đã gặp vấn đề với việc hết dung lượng đĩa với tệp tar được nén 30 GB. Tôi nghĩ gunzip có thể thực hiện nội tuyến, tức là xóa bản gốc vì nó đã được giải nén (và tôi có thể đã bỏ lỡ một kết quả của Google) nhưng tôi không thể tìm thấy bất cứ điều gì.

Cuối cùng, vì tôi đã mệt mỏi vì đã cố gắng nhiều lần chờ đợi một tệp TAR hoặc ZIP mới được hoàn thành tar'ing hoặc nén, cuối cùng tôi cũng đã làm:

  1. Từ máy chủ / PC / máy tính xách tay ban đầu, điều hướng đến thư mục chứa thư mục của bạn với nhiều tệp / thư mục.
  2. scp -r source_folder_name yourname@yourservername:destination_folder_name

Sau đó chỉ cần lấy một ít bia, cà phê hoặc bỏng ngô và chờ đợi. Điều tốt là, scp sẽ thử lại nếu kết nối mạng "gian hàng". Chỉ hy vọng nó không đi xuống hoàn toàn.


OK, điều này rõ ràng tốn ít thời gian của bạn hơn là gõ một nghìn scplệnh. Nhưng câu hỏi đặt ra về mạng trên mạng. Giải pháp của bạn có sử dụng mạng ít hơn là sao chép từng tệp riêng lẻ không? Là giải pháp của bạn vượt trội trong bất kỳ cách nào trong bảy đã được đăng?
G-Man nói 'Phục hồi Monica'

Snap, xấu của tôi - Tôi hoàn toàn bỏ lỡ phần trên mạng - cảm ơn vì đã chỉ ra @ G-Man. Tôi đã cập nhật câu trả lời, tôi vẫn cảm thấy nó có thể hữu ích nếu ai đó tình cờ gặp phải một vấn đề tương tự như tôi và khi tôi vấp phải câu hỏi này.
JGlass
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.