Назад | Перейти на главную страницу

Использование rsync для быстрой загрузки файла, похожего на другой файл

Я создаю сценарий развертывания, который обрабатывает каталог моего кода, называет tar-файл после текущей даты и времени, отправляет его на сервер, распаковывает его в каталоге с тем же именем, а затем меняет местами «текущий» "символическая ссылка, указывающая на новый каталог. Это означает, что мои старые развертывания остаются в каталогах с метками времени (по крайней мере, пока я их не удалю).

Размер tar-файла составляет около 5 МБ, и его передача занимает около минуты. Я бы хотел это ускорить.

Я предполагаю, что каждый новый tarball очень похож по структуре на предыдущий tarball (поскольку я часто меняю только несколько строк исходного кода между развертываниями). Есть ли способ воспользоваться этим фактом для ускорения загрузки с помощью rsync?

В идеале я хотел бы сказать: «Привет, rsync, загрузите этот локальный файл с именем 2009-10-28-222403.tar.gz на мой сервер, но он лишь немного отличается от файла 2009-10-27-101155.tar. .gz, который уже существует, так что постарайтесь просто передать различия ". Возможно ли это, или мне стоит поискать еще один инструмент?

Я составляю сценарий развертывания, который обрабатывает каталог моего кода, называет tar-файл после текущей даты и времени, отправляет его на сервер, распаковывает его в каталоге с тем же именем, а затем меняет местами «текущий» "символическая ссылка, указывающая на новый каталог.

Лично я считаю, что вам следует отказаться от использования tar и вместо этого использовать функцию --link-dest или --copy-dest rsync. Функция link-dest довольно крутая, она знает, что нужно посмотреть на предыдущую синхронизацию каталога, и если файлы будут идентичными, она жестко связывает их вместе, пропуская необходимость повторно передавать файл каждый раз.

mkdir -p /srv/codebackup/2009-10-12 \
         /srv/codebackup/2009-10-13

# first backup on 10-12
rsync -a sourcehost:/sourcepath/ \
         /srv/codebackup/2009-10-12/

# second backup made on 10-13
rsync -a --link-dest=/srv/codebackup/2009-10-12/
         sourcehost:/sourcepath/ \
         /srv/codebackup/2009-10-13/

Ваш второй запуск rsync перенесет только измененные файлы. Идентичные файлы будут жестко связаны друг с другом. Вы можете удалить старое дерево, и новая резервная копия все равно будет готова на 100%. Вы сэкономите много места для хранения, так как не будете хранить несколько копий одинаковых файлов.

Я думаю, что использование tar здесь - неправильный ответ. В этом конкретном случае я бы сделал cp -rp ваш «текущий» код на сервере в устаревший каталог. Затем выполните синхронизацию проверки локального кода с "текущим". Итак, в основном это:

  1. ssh user @ host cp -rp / path / to / current / path / to / 2009-10-28 /

  2. rsync / local / copy user @ host: / path / to / current

Это дает вам нужную резервную копию, синхронизирует ваши изменения и будет намного быстрее, чем tar + scp + untar.

Надеюсь, это поможет!

rsync AFAIK не может делать это напрямую, но вы можете структурировать свои архивы, чтобы ускорить их передачу, пользуясь тем фактом, что они похожи.

Проверьте флаг --resyncable в gzip. Из руководства:

Во время сжатия время от времени синхронизируйте вывод на основе ввода. В большинстве случаев это увеличивает размер менее чем на 1 процент, но означает, что программа rsync (1) может гораздо эффективнее синхронизировать файлы, сжатые с этим флагом. gunzip не может отличить сжатый файл, созданный с этим параметром, от файла, созданного без него.

Это сделает ваши похожие архивы более похожими, так что rsync сможет их распознать.

Вам, вероятно, придется немного изменить свои сценарии развертывания, чтобы уменьшить объем передачи, потому что я не думаю, что rsync можно сказать «посмотреть другой файл» ... я бы всегда делал rsync что-то, называемое текущим .tar.gz (сжат с помощью gzip и указанного выше флага), а затем переименуйте его для архивирования на сервере. Это или переименуйте старый тарбол на сервере в имя тарбола, который вот-вот будет загружен, чтобы rsync мог его использовать.

Хорошо, я не пробовал это, но было бы интересно посмотреть, как это работает в вашем случае.

Вы захотите минимизировать изменения при каждом вызове tar. Помогло бы убедиться, что файлы всегда находятся в одном и том же порядке в каждом экземпляре. Затем вы можете сжать --rsyncable вариант.

Можно ли отсортировать файлы по дате последнего изменения? Таким образом, файлы, которые не меняются, всегда находятся в одном и том же порядке и в начале, а файлы, которые меняются, находятся в конце, поэтому при изменении длины они не нарушают алгоритм блокировки.

tar cvf - -T `find . -type f | xargs ls --sort=time -r` | gzip -9 --rsyncable

Еще одна вещь, которую следует учитывать, это то, что tar поддерживает блокировку и дополняет каждый файл нулями до смещения блока. Проверять, выписываться размеры блока. Вы можете установить это на rsync размер блока (ах, это зависит от размера файла, хм, как насчет 8К?). Это поможет алгоритму при изменении порядка одного файла. Теперь поместите gzip на каждом конце (gzip предпоследний на сервере, если вы беспокоитесь о дисковом пространстве), и я думаю, вы можете получить желаемую скорость.

Я не так впечатлен --rsyncable вариант. Я использую его для ежедневных дампов postgres и обнаружил, что, хотя каждый день меняется лишь небольшая часть дампа, rsync использует примерно половину полосы пропускания простого копирования .gz вокруг. Я могу задать вопрос по этому поводу.

Я думаю, вам будет лучше с эффективным rsync отдельных файлов, включенных в другие ответы, а затем сгенерировать .tar.gz из полученного каталога на сервере (или на клиенте, если вы хотите сохранить свой архив именно там). Что не так с вашей системой контроля версий, как с записью того, что вы когда развернули? Вы ведь не развертываете незафиксированный код?

Вы можете изучить нечеткий режим rsync (активируется с помощью --fuzzy переключатель)

Это позволяет rsync выбрать файл в целевой системе, который похож на передаваемый файл, и использовать этот файл в качестве основы для применения своего алгоритма разностной загрузки. Это немного памяти и требует ввода-вывода, особенно если у вас есть большой каталог на стороне назначения, однако он должен дать вам улучшения загрузки, которые вы ищете, без необходимости переделывать свой подход, как предлагали другие ответы.

Что это должен быть за файл tar? Почему бы не выполнить синхронизацию кода с каталогом развертывания и не использовать tar в качестве резервной копии?

Это напрямую не связано, поскольку не касается rsync решение, но это может немного помочь с размером файла: вы пробовали использовать bzip2 сжатие вместо gzip?

Вместо того tar czvf blah.tar.gz files, ты можешь сделать tar cjvf blah.tar.bz2 files и получить лучшее сжатие (если, конечно, у вас установлен bzip2).

Саймон: повторяя тот же вопрос, упомянутый выше ... какая причина, по которой вообще нужно использовать tar?

используйте жесткие ссылки для копирования и переносите только различия; пример: cp -lr old_date_dir / new_date_dir / (это на «сервере») rsync -ax --numeric-ids code server: / path / new_date_dir /

это будет работать, потому что rsync отключается перед передачей различий.

Другие решения игнорируют причину, по которой вы хотели использовать rsync в первую очередь, то есть отправку только тех файлов, которые были изменены. Как насчет того, чтобы подойти к этому несколько иначе, избегая при этом тарболлов, но сохранив преимущества rsync и откатов.

Во-первых, на вашем удаленном хосте создайте недавний каталог для rsync:

mkdir /var/www/recent

Затем создайте символическую ссылку, указывающую на этот каталог:

ln -s /var/www/recent /var/www/active 

Настройте Apache для обслуживания файлов в / var / www / active

Затем выполните синхронизацию вашей локальной папки с удаленным хостом:

rsync -v -r --delete ~/Sites/Foo/ foo.org:/var/www/recent

Затем создайте резервную копию удаленного каталога удаленно:

ssh foo.org cp -R /var/www/current /var/www/`date +%Y%m%d%H%M%S`

Теперь, через некоторое время, ваш удаленный каталог / var / www должен выглядеть примерно так:

/var/www/200909041234
/var/www/200910121712
/var/www/200911030446
/var/www/active
/var/www/recent

Если вам нужно откатиться, вы переключаете символическую ссылку:

ssh foo.org ln -s /var/www/200911030446 /var/www/active

Очень просто!

Для бонусных баллов:

  1. Откройте Automator
  2. Создать новую услугу
  3. Создать новое действие для запуска сценария оболочки
  4. Поместите команду rysnc и команды копирования удаленного каталога в это окно
  5. Сохраните рабочий процесс как «Опубликовать сайт Foo».
  6. Зайдите в Системные настройки
  7. Перейти к настройкам клавиатуры
  8. Перейти к услугам
  9. Найдите службу Publish Foo Site и привяжите ее к сочетанию клавиш

Автоматическая публикация из любого приложения в OS X!