Синхронизировать две директории без rsync

Вопрос или проблема

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

Настройка:

  1. Сервер-источник имеет папку Upload, содержащую более 140 000 файлов (без подпапок)
  2. Сервер-назначение нуждается в папке Upload, содержащей более 140 000 файлов

Назовем это миграцией только с помощью наклейки Post-It… Теперь, чтобы усложнить задачу, Сервер 1 каждый день получает новые файлы из-за новых загрузок или генерируемых миниатюр, поэтому та идея, которая у вас сейчас в голове “просто скопируйте файл с 1 на 2“, не сработает, так как, как только я закончу с копированием примерно 20+ ГБ, я могу начать снова, так как на сервере-источнике уже появится новый файл…

Моя идея решения

  • Скопировать полную папку с источника на назначение
  • Найти дату создания в сервере-назначении и использовать ее как отправную точку на сервере-источнике
  • Скопировать все файлы с последней даты создания с источника на назначение (дельта)
  • Настроить cron, чтобы делать это как можно чаще.

Моя проблема

find /uploads/* -mtime -1
bash: /bin/find: Слишком длинный аргумент

Теперь, прежде чем я начну писать цикл bash-скрипта, мне интересно, есть ли кто-нибудь, кто мог бы предложить другой способ сделать это без bash-скрипта… добрый старый низкоуровневый CLI.

Мне удалось найти решение, но еще не в одной строке. Я всё еще работаю над этим.

Предполагая, что вы можете доверять дате создания/изменения файловой системы, можно использовать find для генерации списка файлов, вывести это в текстовый файл, а затем с помощью цикла выполнить scp на сервер назначения. Я не могу заставить результат find правильно передавать в scp.

Я использовал вспомогальную программу sshpass, но было бы лучше использовать ключевые файлы, я знаю

Найти файлы на сервере-источнике с сервера-назначения и сохранить результат, ограничив результат только одной директорией и только файлами.

sshpass -p 'MyPassword' ssh [user@server] "find [path/to/look/in] -maxdepth 1 -mtime -1 -type f" > /tmp/last-24-hours-file-list.txt

Цикл по выходному файлу и вызов scp для каждого файла

while read filename; do sshpass -p 'MyPassword' scp -Crpv [user@server]:$filename [path/to/save/to]; done < /tmp/last-24-hours-file-list.txt

Ответ или решение

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

1. Обзор задачи

Вы хотите перенести файлы из одной директории на другой сервер, при этом необходимость в синхронизации возникает из-за постоянного добавления новых файлов. Вам нужно учитывать 140 000+ файлов и избежать проблем, связанных с ошибкой "Argument list too long".

2. Решение

2.1 Копирование файлов в начальном переносе

В первую очередь, вам нужно будет выполнить однократное полное копирование всех файлов из исходной директории на целевой сервер. Это можно сделать с помощью команды scp или sftp. На данном этапе допустимо использовать временный метод, так как он будет только один раз.

scp -r user@source_server:/path/to/uploads/* /path/to/destination/

2.2 Определение последней даты изменения

После первого копирования необходимо определить, когда был сделан последний upload файлов на целевом сервере. Это можно сделать, выполнив команду на целевом сервере:

ls -lt /path/to/uploads/ | head -n 1

2.3 Синхронизация новых файлов

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

  1. Выполните команду find на исходном сервере через SSH, чтобы сохранить список недавно измененных файлов.
ssh user@source_server "find /path/to/uploads -maxdepth 1 -type f -mtime -1" > /tmp/last-24-hours-file-list.txt
  1. Перенесите файлы, указанные в созданном списке. Используем цикл для перебора файлов:
while read filename; do
    scp user@source_server:"$filename" /path/to/destination/
done < /tmp/last-24-hours-file-list.txt

2.4 Настройка автоматизации

Для автоматизации процесса вы можете использовать cron. Добавьте запись в crontab на целевом сервере, чтобы периодически выполнять синхронизацию, например, каждый час:

0 * * * * /path/to/your/script.sh

Где script.sh — это ваш написанный скрипт, содержащий команды из вышеописанного процесса.

3. Заключение

Такой подход обеспечивает эффективную синхронизацию между серверами без использования rsync, но с применением надежных методов, таких как find и scp. Он также подходит для сценариев с большим количеством файлов. Применение автоматизации через cron окончательно решает проблемы, возникающие с новыми файлами, которые появляются в процессе синхронизации.

Это решение эффективно и может быть адаптировано под ваши конкретные нужды, включая использование ключей SSH для безопасного доступа вместо sshpass.

Оцените материал
Добавить комментарий

Капча загружается...