Резюме
Как настроить Linux для чтения с локального диска / файловой системы и одновременной записи в общую сетевую папку, в отличие от чтения, когда данные не передаются по сети, а затем отправки этих данных по сети, когда локальный диск холостой ход?
Гораздо быстрее читать и писать одновременно, вместо того, чтобы выполнять только одну операцию, а затем другую поочередно.
Детали
Я перемещаю большой объем данных с локальных дисков на компьютере с Linux на устройство NAS.
Я использую rsync
в основном скопировать /srv/data
в /mnt/nas
, который является CIFS крепление.
Все началось хорошо: чтение со скоростью 100 МБ / с и запись в NAS со скоростью 100 МБ / с (ограничение гигабитной сети), при этом чтение и запись выполняются одновременно.
Однако теперь, спустя несколько часов, я обнаружил, что он читает с локального диска, затем останавливает чтение, пока записывает в NAS, затем, когда больше нет данных для записи в NAS, он возобновляет чтение с диска. опять таки. Сеть находится в режиме ожидания, пока диск читается, а диск не используется, когда сеть используется.
Излишне говорить, что чтение 200 МБ, а затем запись 200 МБ занимает гораздо больше времени, чем чтение и запись этих 200 МБ одновременно.
Как я могу настроить ядро так, чтобы оно придерживалось более раннего поведения чтения и записи одновременно, а не чередовало чтение и запись, выполняя только одну операцию за раз?
Некоторые наблюдения: Когда локальный диск читает со скоростью 100+ МБ / с, кажется, что все параллельно происходит просто отлично, но как только диск замедляется (кажется, сейчас он работает со скоростью всего 20 МБ / с по какой-то причине), именно тогда происходит чтение / запись. переключение, кажется, происходит.
Я также могу запустить sync
вручную каждые несколько секунд , чтобы получить , что запись происходит параллельно с чтений (хотя , очевидно , при сниженных скоростях) , однако ввод sync
в while
петле так , что она проходит через каждые пять секунд , не кажется правильным решение ...
Кажется, что ядро кеширует около 1 ГБ данных, а затем записывает их по сети настолько быстро, насколько это возможно - и это хорошо - я просто не понимаю, почему медленный диск должен перестать считываться, пока данные отправляются через сеть.
Ответы:
После некоторого дополнительного исследования, похоже, что эта проблема связана не столько с ядром, сколько с
rsync
взаимодействием CIFS.Насколько я могу судить, происходит то, что при
rsync
закрытии файла назначения CIFS (и, возможно, любая сетевая файловая система) гарантирует, что файл полностью сброшен и записан на удаленный диск доclose
возврата системного вызова. Это должно гарантировать любому приложению, что после успешного завершения операции закрытия файл был полностью сохранен, и нет риска дальнейших ошибок, которые могут привести к потере данных.Если это не было сделано, тогда приложение могло бы закрыть файл, не думая, что операция сохранения прошла успешно, а затем (возможно, из-за проблем с сетью) данные не могут быть записаны в конце концов, но к тому времени слишком поздно, чтобы приложение что-либо предприняло, например, попросило пользователя сохранить файл в другом месте.
Это требование означает, что каждый раз, когда
rsync
заканчивается копирование файла, весь дисковый буфер должен очищаться по сети, прежде чемrsync
будет разрешено продолжить чтение следующего файла.Обходной путь - смонтировать общий ресурс CIFS с опцией,
cache=none
которая отключает эту функцию и заставляет все операции ввода-вывода идти прямо на сервер. Это устраняет проблему и позволяет выполнять чтение и запись параллельно, однако недостатком этого решения является то, что производительность несколько ниже. В моем случае скорость передачи по сети падает с 110 МБ / с до 80 МБ / с.Это может означать, что если вы копируете большие файлы, производительность может быть лучше при чередующемся поведении чтения / записи. У многих файлов меньшего размера отключение кеша приведет к уменьшению сброса кеша при каждом закрытии файла, поэтому производительность может увеличиться.
Кажется,
rsync
нужна опция, чтобы закрыть свои файловые дескрипторы в другом потоке, чтобы он мог начать чтение следующего файла, пока последний еще не очищен.РЕДАКТИРОВАТЬ: Я подтвердил, что,
cache=none
безусловно, помогает при передаче большого количества небольших файлов (приносит от 10 МБ / с до 80 МБ / с), но при передаче больших файлов (1 ГБ +)cache=none
снижает скорость передачи со 110 МБ / с до тех же 80 МБ / с. Это говорит о том, что медленная передача из множества маленьких файлов связана не столько с поиском исходного диска, сколько с наличием большого количества очисток кеша от всех маленьких файлов.источник
rsync
действительно читает файл в другом потоке (на самом деле, в другом процессе), потому что он спроектирован так, что одна копияrsync
работает на каждой стороне сети, даже если в вашем случае обе копии находятся на одной стороне (а файловая система скрывает Дело в том, что есть сеть). Я думаю, это не поможет, потому что процесс чтения очень быстро заполняет канал, в то время как процесс записи блокирует наclose()
.rsync
будет работать лучше, если вы используетеrsync
на провод, а не CIFS.rsync
на NAS, - это использовать егоrsync
по сети (напримерrsync -a files localhost:/dest/path
), в то же время искусственно вводя огромный буфер (например, несколько мегабайт, по крайней мере) в сетевые подключения. Не уверен, как будет выглядеть лучший хакер для этого.rsync
на устройстве NAS сама по себе решит эту проблему. Хотя это немного сложнее (странные разрешения NAS, нужно удалить символические ссылки и т. Д.), Но если бы у меня было немного больше данных для копирования, это стоило бы времени, чтобы сделать это, я думаю.dump(8)
на NAS, смонтированный через NFS. В то время я диагностировал проблему как максимальное использование ЦП на NAS из-за совместного действия сервера NFS и брандмауэра, работающего на NAS (коробка не была укоренена, и брандмауэр нельзя было полностью отключить из веб-интерфейс). Проблема ушла, когда мы заменили NAS на старый ПК. FWIW.