По сути вопрос мало касается самой 1с.
Открываю в конфигураторе 1С 8.3 файл конфигурации (*.cf). Размером он около 200-300 Мб.
Если открывать с локальной фс, то открытие происходит за несколько секунд.
Если открывать с nfs или cifs то открытие занимает минут 10 (sic!).
Моя машина и NAS с файлами находятся в сети 100Mbit/s.
Копирование файла с NFS на локальную фс идёт со скоростью близкой к 80-90Mbit/s.
Далее рассматриваем открытие файла на nfs3:
С помощью strace -cw выясняем что очень долго выполняется read:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
57.41 2007.728556 478600 4195 1538 futex
28.74 1005.053317 434900 2311 epoll_wait
13.04 455.978200 596 764976 25 read
0.41 14.455605 14 1038231 lseek
(Насколько я понял futex и epoll_wait тут вообще не причём, они похоже не связаны с тормозами и время исполнения у них слишком большое)
Если просто сделать strace и посмотреть что делается с нашим файловым дескриптором то можно увидеть что-то такое:
open("/mnt/nas/foo/bar/1Cv8.cf", O_RDONLY) = 83 <0.000631>
fcntl(83, F_GETFD) = 0 <0.000004>
fcntl(83, F_SETFD, FD_CLOEXEC) = 0 <0.000004>
flock(83, LOCK_SH|LOCK_NB) = 0 <0.000007>
open("/mnt/nas/foo/bar/1Cv8.cf", O_RDWR) = 84 <0.000616>
fcntl(84, F_GETFD) = 0 <0.000017>
fcntl(84, F_SETFD, FD_CLOEXEC) = 0 <0.000004>
fcntl(84, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=4294967296, len=1}) = 0 <0.000012>
Целых два дескриптора на один файл.
На кой чёрт открывается второй с O_RDWR я понятия не имею, ибо менять файл 1С-ка всё равно не может.
И потом идёт куча таких вызовов:
lseek(83, 0, SEEK_END) = 211404996 <0.000005>
lseek(83, 16, SEEK_SET) = 16 <0.000004>
read(83, "\r\n00057a80 00057a80 7fffffff \r\n", 31) = 31 <0.000007>
lseek(83, 47, SEEK_SET) = 47 <0.000004>
read(83, "\257z\5\0.{\5\0\377\377\377\177", 12) = 12 <0.000004>
lseek(83, 0, SEEK_END) = 211404996 <0.000004>
lseek(83, 359087, SEEK_SET) = 359087 <0.000003>
read(83, "\r\n00000060 00000060 7fffffff \r\n", 31) = 31 <0.001051>
Т.е. мы постоянно прыгаем в разные места файла и делаем read небольшими порциями (32 байта и меньше).
Таким образом читается весь файл (200-300 мегабайт).
Насколько я понимаю сетевые фс NFS/CIFS на такое не рассчитаны?
Способ обхода
Пока писал пост вроде нашёл решение, хотя хотелось бы попробовать другие и лучше понять почему происходят тормоза.
Чтобы всё работало почти так же быстро как работает локально делаем следующее:
- Настраиваем FS-Cache
- Монтируем NFS со следующими опциями:
vers=4,fsc,ro
fsc - включаем кэширование через FS-Cache
vers=4 - на третьей кэширование с нашим файлом не работает, по-видимому из-за того что 1с открывает дескриптор на чтение/запись; в документации по FS-Cache написано что на NFSv3 кэш на файле отрубается пока открыт R/W дескриптор, а на NFSv4 всё ок.
ro - связано с одним тупым багом, из-за которого нельзя из 1с открывать файлы на NFSv4 если она смонтирована в r/w, к сабжу не относится.
С CIFS я ничего не придумал, хотя мне он особо и не нужен.
С NFSv3 тоже ничего не получается из-за того что файл открывается r/w и кэширование не работает.