копирование большого дерева каталогов локально? cp или rsync?

<p>я должен скопировать большое дерево каталогов, около 1,8 тб. это все локально. по привычке я бы использовал <code>rsync</code>, однако мне интересно, есть ли смысл, и лучше ли использовать <code>cp</code>.</p><p>я беспокоюсь о разрешениях и uid/gid, так как они должны быть сохранены в копии (я знаю, что rsync делает это). а также такие вещи, как символические ссылки.</p><p>место назначения пустое, поэтому мне не нужно беспокоиться об условном обновлении некоторых файлов. это все локальный диск, поэтому мне не нужно беспокоиться о ssh или сети.</p><p>причина, по которой я бы соблазнился от rsync, заключается в том, что rsync может делать больше, чем мне нужно. rsync контрольные суммы файлов. мне это не нужно, и я обеспокоен тем, что это может занять больше времени, чем cp.</p><p>итак, что вы считаете, <code>rsync</code> или <code>cp</code>?</p>

<p>я бы использовал rsync, так как это означает, что если он прерван по какой-либо причине, вы можете легко перезапустить его с минимальными затратами. и будучи rsync, он может даже частично перезапустить большой файл. как упоминают другие, он может легко исключать файлы. самый простой способ сохранить большинство вещей - использовать <code>-a</code> флаг - ‘архив.’ итак:</p><pre><code>rsync -a source dest </code></pre><p>хотя uid/gid и символические ссылки сохраняются <code>-a</code> (видеть <code>-lpgo</code>), ваш вопрос подразумевает, что вам может потребоваться <em>полная</em> копия информации о файловой системе; а также <code>-a</code> не включает жесткие ссылки, расширенные атрибуты или acl (в linux) или выше <em>ни</em> ветвления ресурсов (в os x). таким образом, для надежной копии файловой системы вы ' вам нужно будет включить эти флаги:</p><pre><code>rsync -ahax source dest # linux rsync -ahe source dest # os x </code></pre><p>cp по умолчанию начнется снова, хотя <code>-u</code> flag будет <em>"копировать только в том случае, если файл source новее, чем целевой файл или отсутствует целевой файл"</em>. и <code>-a</code> (архив) будет рекурсивным, а не будет переписывать файлы, если вам нужно перезапустить и сохранить права доступа. так:</p><pre><code>cp -au source dest </code></pre>

<p>при копировании в локальную файловую систему я склонен использовать rsync со следующими параметрами:</p><pre><code># rsync -avhw --no-compress --progress /src/ /dst/ </code></pre><p>вот мои рассуждения:</p><pre><code>-a is for archive, which preserves ownership, permissions etc. -v is for verbose, so i can see what's happening (optional) -h is for human-readable, so the transfer rate and file sizes are easier to read (optional) -w is for copying whole files only, without delta-xfer algorithm which should reduce cpu load --no-compress as there's no lack of bandwidth between local devices --progress so i can see the progress of large files (optional) </code></pre><p>я видел на 17% более быстрые передачи с использованием вышеуказанных настроек rsync по сравнению со следующей командой tar, как было предложено в другом ответе:</p><pre><code># (cd /src; tar cf - .) | (cd /dst; tar xpf -) </code></pre>

<p>когда мне приходится копировать большой объем данных, я обычно использую комбинацию tar и rsync. первый проход - смолить что-то вроде этого:</p><pre><code># (cd /src; tar cf - .) | (cd /dst; tar xpf -) </code></pre><p>обычно с большим количеством файлов будут некоторые, которые tar не сможет обработать по какой-либо причине. или, возможно, процесс будет прерван, или, если это миграция файловой системы, вы можете сделать первоначальную копию до фактического шага миграции. в любом случае, после первоначальной копии я делаю шаг rsync, чтобы синхронизировать все это:</p><pre><code># cd /dst; rsync -avphsx --delete /src/ . </code></pre><p>обратите внимание, что косая черта на <code>/src/</code> является важным.</p>

<h2>rsync</h2><p>вот rsync, который я использую, я предпочитаю cp для простых команд, а не это.</p><pre><code>$ rsync -ahsd --ignore-errors --force --delete --stats $src/ $dir/ cpioвот способ, который еще безопаснее, cpio. это примерно так же быстро, как смола, может быть, немного быстрее.$ cd $src && find . -mount -depth -print0 2>/dev/null | cpio -0admp $dest &>/dev/null </code></pre><h2>tar</h2><p>это тоже хорошо, и продолжается при сбое чтения.</p><pre><code>$ tar --ignore-failed-read -c $src -cf - . | tar --ignore-failed-read -c $dest -xf - </code></pre><p>обратите внимание, что все это только для локальных копий.</p>

<p>что вы предпочитаете. только не забудь <code>-a</code> переключайтесь, когда вы решите использовать <code>cp</code>.</p><p>если вам действительно нужен ответ: я бы использовал rsync, потому что он гораздо более гибкий. необходимо завершить работу до завершения копирования? просто ctrl-c и возобновить, как только вы вернулись. нужно исключить некоторые файлы? просто используйте <code>--exclude-from</code>. нужно изменить владельца или разрешения? rsync сделает это за вас.</p>

<p>команда <code>rsync</code> всегда вычисляет контрольные суммы для каждого передаваемого байта.</p><p>параметр командной строки <code>--checksum</code> относится только к тому, используются ли контрольные суммы файлов для определения, какие файлы передавать или нет, т.е.</p><blockquote> <p><code>-c, --checksum</code> пропустить на основе контрольной суммы, а не времени и размера мода "</p> </blockquote><p>manpage также говорит это:</p><blockquote> <p>обратите внимание, что rsync всегда проверяет, что каждый переданный файл был правильно восстановлен на принимающей стороне, проверяя контрольную сумму всего файла, но что автоматическая проверка после передачи не имеет ничего общего с опцией перед передачей "нужен ли этот файл быть обновленным?" чек об оплате.</p> </blockquote><p>так что <code>rsync</code> также всегда вычисляет контрольную сумму всего файла на принимающей стороне, даже когда <code>-c/ --checksum</code> опция выключена.</p>

<p><code>rsync -aphw --protocol=28</code> помогает ускорить эти большие копии с rsync. я всегда rsync, потому что мысль о том, чтобы быть на полпути через 90gib, и это ломает меня пугает от cp</p>

<p>эта ветка была очень полезна, и поскольку было так много вариантов для достижения результата, я решил сравнить несколько из них. я полагаю, что мои результаты могут быть полезны для других, которые чувствуют, что работает быстрее.</p><p>чтобы переместить <strong> 532 гб </strong> данных, распределенных среди <strong> 1 753 200 файлов </strong>, у нас было то время:</p><ul> <li><code>rsync</code> заняло 232 минуты</li> <li><code>tar</code> заняло 206 минут</li> <li><code>cpio</code> заняло 225 минут</li> <li><code>rsync + parallel</code> заняло 209 минут</li> </ul><p>в моем случае я предпочел использовать <code>rsync + parallel</code>. я надеюсь, что эта информация поможет большему количеству людей выбирать среди этих альтернатив.</p><p>полный тест опубликован <a href="http://arjon.es/2017/05/11/which-is-the-best-tool-for-copying-a-large-directory-tree-locally/">здесь</a> </p>

<p>rsync великолепен, но имеет проблемы с действительно большими деревьями каталогов, потому что он хранит деревья в памяти. я просто искал, решат ли они эту проблему, когда я нашел эту ветку.</p><p>я также нашел:</p><p> <a href="http://matthew.mceachen.us/geek/gigasync/">http://matthew.mceachen.us/geek/gigasync/</a> </p><p>вы также можете вручную разбить дерево и запустить несколько rsyncs.</p>

<p>при локальном копировании локального каталога мой опыт показывает, что cp -van src dest на 20% быстрее, чем rsync. что касается перезапуска, это то, что делает "-n". вам просто нужно восстановить частично скопированный файл. не больно, если это не iso или что-то подобное.</p>

<p>arj is so старая школа !! я действительно сомневаюсь, что arj и/или rsync дадут производительность.</p><p>определенно, я всегда использую cpio:</p><pre><code>find . -print | cpio -pdm /target/folder </code></pre><p>это почти быстро, чем cp, определенно быстрее, чем tar, и ничего не передает.</p>

<p>вы определенно хотите попробовать <a href="https://rclone.org/">rclone</a> . эта вещь сумасшедшая быстро:</p><pre><code>sudo rclone sync /usr /home/fred/temp -p -l --transfers 64 transferred: 17.929g / 17.929 gbytes, 100%, 165.692 mbytes/s, eta 0s errors: 75 (retrying may help) checks: 691078 / 691078, 100% transferred: 345539 / 345539, 100% elapsed time: 1m50.8s </code></pre><p>это локальная копия с и на liteonit lcs-256 (256gb) ssd.</p><p>можете добавить <code>--ignore-checksum</code> при первом запуске, чтобы сделать его еще быстрее.</p>

<p>оба будут работать нормально.</p>

<p>есть несколько ускорений, которые можно применить к <code>rsync</code>:</p><h3>избегайте</h3><ul> <li><code>-z</code>/<code>--compress</code>: сжатие будет загружать только процессор, так как передача происходит не по сети, а по озу.</li> <li><code>--append-verify</code>: возобновить прерванную передачу. это звучит как хорошая идея, но имеет опасный случай сбоя: любой файл назначения того же размера (или больше), что и источник, будет игнорироваться. кроме того, он проверяет суммы всего файла в конце, что означает отсутствие значительного ускорения за <code>--no-whole-file</code> при добавлении опасного случая сбоя.</li> </ul><h3>использование</h3><ul> <li><code>-s</code>/<code>--sparse</code>: превратить последовательности нулей в разреженные блоки</li> <li><code>--partial</code> или <code>-p</code> который <code>--partial --progress</code>: сохранить частично переданные файлы для последующего возобновления. примечание: файлы не будут иметь временного имени, поэтому убедитесь, что больше никто не ожидает использовать место назначения, пока не будет завершена полная копия.</li> <li><code>--no-whole-file</code> так что все, что нужно отправить, использует дельта-передачу. чтение половины частично переданного файла часто происходит намного быстрее, чем повторная запись.</li> <li><code>--inplace</code>, чтобы избежать копирования файла (но только если ничто не читает место назначения, пока не завершится вся передача)</li> </ul>

<p><code>tar</code> также выполнит эту работу, но не прекратит прерывание, как это делает rsync.</p>

<p>что делать, если вы используете arj?</p><pre><code>arj a -jm -m1 -r -je filepack /source </code></pre><p>где <code>-jm -m1</code> - уровни сжатия и <code>-je</code> делает его исполняемым. теперь у вас есть инкапсулированный пакет файлов.</p><p>затем для извлечения на целевую карту</p><pre><code>filepack -y </code></pre><p>где будет составлена исходная карта (где <code>-y</code> всегда принимайте, перезаписывайте, пропускайте и т. д.)</p><p>затем можно скопировать ftp файл-пакета в целевую область и выполнить его, если это возможно.</p>