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

`find / nfs / server / mount / data [12] -name data _ *. gz> / dev / null` Во второй раз он выполняется в 4 раза медленнее - почему?

Сервер NFS (это что-то вроде устройства NAS, я не знаю, какой марки и ничего о том, как он настроен) имеет одну файловую систему, экспортированную и смонтированную на клиенте Linux. Сервер и клиент находятся в одной локальной сети. Удаленная файловая система устроена так:

/nfs/server/mount/data1/
                        client_uuid_1/
                                      data_20170101.gz
                                      data_20170102.gz
                                      ...
                        client_uuid_2/
                                      data_20170101.gz
                                      data_20170102.gz
                                      ...
                        ...
                  data2/
                        client_uuid_3/
                                      data_20170101.gz
                                      data_20170102.gz
                                      ...
                        ...

Всего существует порядка 40 000 каталогов client_uuid_N и порядка 300 000 файлов данных. Я заметил, что скрипт, который должен сканировать все каталоги на предмет новых файлов данных, работал очень медленно, просто чтобы выполнить глобальную операцию, поэтому я продолжил исследование и обнаружил это странное явление:

В первый раз бегу find /nfs/server/mount/data[12] -name data_*.gz > /dev/null после повторного монтирования файловой системы это занимает примерно пять минут. Это уже мучительно медленно и предполагает какую-то проблему, но становится еще более странным.

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

Почему это могло происходить?

В find Команда сканирует каталог на наличие записей, а также получает атрибут файлов, чтобы обнаруживать подкаталоги и периодически их сканировать. Когда ты бежишь find первый раз клиент nfs выполнит операции READDIR, которые помимо получения списка каталогов также запрашивают атрибуты файлов. Это довольно эффективно, так как по сети проходит всего несколько запросов nfs. При втором запуске, поскольку каталог не изменяется, используется кешированный листинг. Однако клиент проверяет наличие изменений атрибутов файла для каждого файла, что увеличивает общее время выполнения. Технически тип объекта файловой системы не может быть изменен (файл никогда не станет каталогом), но клиент nfs не знает, какие атрибуты действительно необходимы приложению, поскольку stat звонок, используемый find командные запросы для всех атрибутов файла.

Это звучит контр-интуитивно понятно, но если вы сбросите кеш файловой системы (echo 3 > /proc/sys/vm/drop_cache на linux), тогда вы получите лучшую производительность и при втором запуске.

Был обсуждение об этом в списке рассылки linux nfs, если вы хотите глубже погрузиться в технические детали реализации Linux.