Я пытаюсь синхронизировать контент между двумя серверами. Серверы имеют идентичные сборки (Ubuntu 12.04LTS) и имеют это задание cron, запущенное для синхронизации контента:
rsync -arzc --update --delete /htdocs/testing/www/cms_uploads/* [email protected]:/htdocs/testing/www/cms_uploads/
но я получаю некоторые странные результаты, когда тестирую процесс, описанный ниже.
Первый тест
- Загрузил aaaa.jpg на Node2
- синхронизируется с Node1
- Удалить из Node1
- Появляется снова на узле Node1
- Удалить из Node2
- Удалено из Node1
Второй тест
- Загружено bbbb.png на Node1
- Синхронизируется с Node2
- Удалить из Node2
- Появляется снова на Node2
- Удалить из узла 1
- Появляется снова на узле Node1
Все, что я пытаюсь сделать, это убедиться, что один и тот же контент всегда одинаков на обоих серверах. Что я делаю не так?
решение1
rsync
не настроен на двустороннюю синхронизацию. Без специальной помощи (например, синхронизации с машины, которая была изменена) и большой удачи он не может этого сделать.
Удача нужна, чтобы изменения были редкими и далеко друг от друга. Если и Node1, и Node2 будут изменены до начала следующей синхронизации (с любой машины), некоторые изменения будут потеряны при синхронизации.
Смотрите такжеэтот
решение2
Что-то фундаментально сломалось в вашем определении проблемы. Предположим, что ваши серверы синхронизированы, а затем вы создаете файл aaaa.jpg
на узле 2. Должна ли следующая синхронизация удалить этот поддельный файл с узла 2 (поскольку его нет на узле 1, он должен быть удален) или она должна скопировать файл на узел 1 (поскольку его нет на узле 1, он должен быть создан заново)?
Порядок, в котором вы запускаете синхронизации, определит, что произойдет в каждом случае. Это практически гарантированно не даст желаемого результата во многих случаях. Хуже того, если синхронизации выполняются параллельно (так что один из хостов обновляется своим собственным заданием синхронизации и в то же время проходится заданием синхронизации, запущенным на другом хосте), результат будет выглядеть довольно случайным.
Rsync изначально разработан для односторонней синхронизации. Вы не можете просто запустить два задания rsync и надеяться на двустороннюю синхронизацию.
Унисон— это синхронизатор файлов, предназначенный для двусторонней синхронизации. Это наиболее близкий к нужному инструменту для вашей задачи. Настройте его и запустите unison -auto remote.example.com://path/to/directory /path/to/directory
на одном из хостов.
Независимо от того, какой инструмент вы используете, существует вероятность конфликтов, например, если один и тот же файл заменяется двумя разными версиями на двух разных машинах. Хорошего автоматизированного способа разрешения таких конфликтов не существует, поэтому потребуется ручное вмешательство.
В большинстве настроек правильным решением будет назначить один сервер местом для загрузки и синхронизировать все остальные серверы с этого главного сервера. Если кто-то загружает файл на подчиненный сервер, заставьте его ретранслировать загрузку на главный сервер; не меняйте ничего локально. Всякий раз, когда файл изменяется на главном сервере, отправляйте его на подчиненный сервер(ы).
решение3
У rsync есть опция -u, которая делает следующее:
«Это заставляет rsync пропускать все файлы, которые существуют в месте назначения и имеют время изменения, которое новее, чем у исходного файла. (Если существующий файл назначения имеет время изменения, равное времени изменения исходного файла, он будет обновлен, если размеры отличаются.)»
Таким образом, скрипт оболочки, который содержит
1) указанную вами команду плюс опция -u и минус опция -c и
2) ту же команду, но с обратным направлением,
может как бы выполнить двунаправленную синхронизацию, но с двумя проблемами:
1) файлы, удаленные (или переименованные) на удаленном сервере, будут скопированы с локального, потому что rsync будет думать, что нашел новый файл на локальном, и
2) если один файл изменяется в обоих местах между синхронизациями, будут сохранены только самые последние изменения.