
Комментарии 3
Схема с combine под union мое почтение, сам бы точно сперва наоборот собрал и словил засаду с путями при перезаписи.
Не до конца понял один момент по отказоустойчивости на запись. У вас create_policy = all. Что происходит с PUT-запросом от приложения, когда один из апстримов внезапно ложится или начинает тупить? Прокси ждет --timeout 30s от мертвого облака, потом возвращает 500 приложению (хотя во второе облако файл улетел), или union все-таки умеет молча проглотить ошибку одного бэкенда и отдать 200 OK?
Нет, молча не проглотит. Если упало одно облако — приложение получает ошибку. Перед записью union проверяет объект во всех upstream’ах. Мёртвый ломает весь PUT, и serve s3 отдаёт 500 InternalError. Новый файл при этом успевает лечь во второе облако.
Ждать придётся не ровно 30 секунд. --timeout считает простой соединения, а не длину запроса. Если порт закрыт, ошибка приходит секунд через 25: повторы и проверки складываются. Если облако зависло или пропало из сети, прокси держит запрос дольше минуты, и SDK с таймаутом в 60 с отваливается раньше.
Обнаружилось еще пара проблем:
Удаление при лежащем облаке отвечает 204. Из живого облака объект ушёл, в мёртвом остался. Когда оно вернётся, объект снова начнёт читаться.
Расхождение после аварии само не сходится. Файл, который записался только в живое облако, union потом обновляет только там: перезапись идёт туда, где объект уже лежит. Повторный PUT вернёт 200, а во втором облаке файла так и не будет.
Соответственно, если облако упало — помечаем его :ro или :nc в upstreams и перезапускаем прокси. Запись и удаление сразу идут только в живое облако. Совсем убрать облако из union нельзя, с одним upstream’ом он не стартует. Облако вернулось — догоняем его через rclone sync от живого и снимаем пометку. Это ручной фейловер: union не знает, что такое «облако недоступно», он видит только ошибки.
дел
Переезд S3 без простоя и без привязки к одному облаку: rclone union + serve s3 на практике