Днес искаме да ви разкажем за някои от последните ъпдейти на системата Sherlock [това е високопроизводителен клъстер на Станфордския университет — бел. ред.], които значително ускоряват изброяването на файлове в каталози с голям брой записи.
В контекста на обикновените статии, това е по-скоро инсайдерски доклад за редовната работа по Sherlock, за да го поддържаме в оптимално състояние за нашите потребители. Надяваме се в бъдеще да публикуваме повече такива статии.
Изброяването на много файлове отнема време.
Всичко започна с въпрос до техническата поддръжка от потребител. Той съобщи за проблема, че изпълнението ls отнема няколко минути в каталог с повече от 15 000 записа в $SCRATCH [каталог за временни файлове — бел. ред.].
Хилядите файлове в един каталог обикновено създават затруднения за файловата система и определено не се препоръчва. Потребителят беше наясно с това и призна, че не е добре, но спомена, че на лаптопа му изброяването се извършва 1000 пъти по-бързо, отколкото в Sherlock. Разбира се, ни засегна. Затова копнахме по-дълбоко.
Защото ls изглежда красиво.
Ние разгледахме какво всъщност прави ls при изброяването на каталог и защо процесът отнема толкова много време. В повечето съвременни дистрибуции ls по подразбиране се изпълнява като ls --color=auto, защото всички харесват цветове.
Но красивите цветове имат своя цена: за всеки файл ls т трябва да получи информация за типа на файла, неговите разрешения, флаговете, разширените атрибути и т.н., за да избере подходящия цвят.
Едно от простите решения на проблема е изобщо да се изключи цветът в ls, но представете си недоволството на потребителите. Никак не е позволено да се взема цветния изход, не сме чудовища.
Затова копнахме по-дълбоко. ls раскрашва записките чрез променлива на средата LS_COLORS, която се задава от dircolors(1) на база на конфигурационния файл dir_colors(5).Да, (а ако не знаете за файловете (do), то dir_colors , независимо от всичко).
Нека разгледаме по-подробно
За да определим коя от схемите за оцветяване причинява забавяне, създадохме експериментална среда:
$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # не опитвайте това вкъщи!
$ time ls --color=always $SCRATCH/dont | wc -l
10000
real 0m12.758s
user 0m0.104s
sys 0m0.699s12.7 секунди за 10 000 файла, не е много добре.
Между другото, нужен е флаг
--color=always: макар и той да се преобразува вls --color=auto, ноlsразпознава, когато не е свързан с терминала (например, по канал или с пренасочване на изхода) и отключва оцветяването, ако е зададена стойностauto. Умен човек.
Какво тогава отнема толкова време? Разгледахме с помощта на strace:
$ strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% време секунди микросекунди/извикване извиквания грешки системен повик
------ ----------- ----------- --------- --------- ----------------
44.21 0.186617 19 10000 lstat
42.60 0.179807 18 10000 10000 getxattr
12.19 0.051438 5 10000 capget
0.71 0.003002 38 80 getdents
0.07 0.000305 10 30 mmap
0.05 0.000217 12 18 mprotect
0.03 0.000135 14 10 read
0.03 0.000123 11 11 open
0.02 0.000082 6 14 close
[...] Невероятно: 10 000 извиквания lstat(), 10 000 извиквания getxattr() (които всички се провалят, защото в нашата среда няма атрибути, които tърси ls), 10 000 извиквания capget().
Сигурно може да се оптимизира.
Атрибут capabilities? Не.
Следвайки съветите на , опитахме да деактивираме проверката на атрибута :
$ eval $(dircolors -b | sed s/ca=[^:]*:/ca=:)
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% време секунди микросекунди/извикване извиквания грешки системен повик
------ ----------- ----------- --------- --------- ----------------
98.95 0.423443 42 10000 lstat
0.78 0.003353 42 80 getdents
0.04 0.000188 10 18 mprotect
0.04 0.000181 6 30 mmap
0.02 0.000085 9 10 read
0.02 0.000084 28 3 mremap
0.02 0.000077 7 11 open
0.02 0.000066 5 14 close
[...]
------ ----------- ----------- --------- --------- ----------------
100.00 0.427920 10221 6 общо
реално 0m8.160s
потребител 0m0.115s
система 0m0.961s Уау, ускорение до 8 секунди! Премахнахме всички тези скъпи извиквания getxattr(), и извикванията capget() също изчезнаха, чудесно.
Но все пак останаха тези досадни извиквания lstat(), макар и…
Колко цвята са нужни?
Затова разгледахме по-подробно LS_COLORS.
Първо просто деактивирахме тази променлива:
$ echo $LS_COLORS rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00: $ unset LS_COLORS $ echo $LS_COLORS $ time ls --color=always $SCRATCH/dont | wc -l 10000 real 0m13.037s user 0m0.077s sys 0m1.092s
Какво!?! Все още 13 секунди?
Оказва се, че когато променливата на средата LS_COLORS не е определена или липсва само един от елементите й =color:, по подразбиране използва вградена база данни и все пак използва цветове. Затова, ако искате да изключите оцветяването за определен тип файл, трябва да я преопределите с =: или 00 в файла DIR_COLORS.
След множество проби и грешки стеснихме търсенето до следното:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00което се записва като
LS_COLORS='ex=00:su=00:sg=00:ca=00:' Това означава: не оцветявай файловете нито по атрибута , нито по битовете , нито по .
Ускоряване ls
И ако не се извършват нито едни от тези проверки, повикванията lstat() изчезват, и сега става съвсем различно:
$ export LS_COLORS='ex=00:su=00:sg=00:ca=00:'
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
63.02 0.002865 36 80 getdents
8.10 0.000368 12 30 mmap
5.72 0.000260 14 18 mprotect
3.72 0.000169 15 11 open
2.79 0.000127 13 10 read
[...]
------ ----------- ----------- --------- --------- ----------------
100.00 0.004546 221 6 total
real 0m0.337s
user 0m0.032s
sys 0m0.029s0,3 секунди за списък от 10 000 файла, рекорд.
Настройваме Шерлок
От 13 секунди с настройки по подразбиране до 0,3 секунди с малка настройка LS_COLORS означава 40-кратно ускорение за сметка на отсъствието на setuid / setgid и оцветени изпълними файлове. Не толкова голяма загуба.
Разбира се, сега това е настроено в Sherlock за всеки потребител.
Но ако искате да възвърнете оцветяването, можете просто да се върнете към настройките по подразбиране:
$ unset LS_COLORS Но тогава, когато имате директории с голям брой файлове, не забравяйте да си направите кафе, докато работи. ls.
Източник: habr.com
