Данас желимо да разговарамо о неким од најновијих ажурирања система Схерлоцк [ово је кластер високих перформанси на Универзитету Станфорд – прибл. транс.], што значајно убрзава листање датотека у директоријумима са великим бројем уноса.
За разлику од редовних чланака, ово је више инсајдерски извештај о томе како редовно радимо на Схерлоцк-у како бисмо га одржали на најбољи могући начин за наше кориснике. Надамо се да ћемо у будућности објављивати још оваквих чланака.
Навођење многих датотека захтева време
Све је почело питањем техничке подршке од стране корисника. Он је пријавио проблем који је извршење ls
траје неколико минута у директоријуму са преко 15 уноса $SCRATCH
[директориј за привремене датотеке - прибл. трака].
Хиљаде датотека у једном директоријуму обично представљају оптерећење за систем датотека и дефинитивно се не препоручује. Корисник је то знао и признао да то није добро, али је споменуо да је листање била 1000 пута бржа на његовом лаптопу од Шерлока. Наравно, ово нас је повредило. Па смо погледали дубље.
Јер изгледа лепо
Погледали смо шта заправо ради ls
када наводите директоријум и зашто процес траје толико дуго. На већини савремених дистрибуција ls
подразумевано ради као ls --color=auto
, јер сви воле боје.
Али лепе боје имају своју цену: за сваку датотеку ls
мора да добије информације о типу датотеке, његовим дозволама, заставицама, проширеним атрибутима и слично како би изабрао одговарајућу боју.
Једно једноставно решење проблема је да се потпуно онемогући боја у лс-у, али замислите бес корисника. Ни у ком случају не би требало да одузимате излаз у боји, ми нисмо чудовишта.
Па смо погледали дубље. ls
уносе боја преко променљиве окружења LS_COLORS
, који је постављен dircolors(1)
на основу конфигурационог фајла dir_colors(5)
... Да,
Хајде да погледамо изблиза
Да бисмо утврдили која шема боја узрокује успоравање, направили смо експериментално окружење:
$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # don't try this at home!
$ time ls --color=always $SCRATCH/dont | wc -l
10000
real 0m12.758s
user 0m0.104s
sys 0m0.699s
12,7 секунди за 10 фајлова, не баш добро.
Узгред, треба нам застава
--color=always
: иако се окреће каls --color=auto
Алиls
детектује када није повезан са терминалом (нпр. путем цеви или са преусмеравањем излаза) и онемогућава бојење ако је подешено наauto
. Паметан момак.
Па шта толико траје? Гледали смо са strace
:
$ strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
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 позива lstat()
, 10 позива getxattr()
(што сви не успевају јер наше окружење нема атрибуте које тражи лс), 10 позива capget()
.
Ово се сигурно може оптимизовати.
Атрибут способности? Јок
Следећи савет
$ eval $(dircolors -b | sed s/ca=[^:]*:/ca=:/)
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
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 total
real 0m8.160s
user 0m0.115s
sys 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;36: $ 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
само један његов елемент није дефинисан или недостаје <type>=color:
, подразумевано користи уграђену базу података и још увек користи боје. Дакле, ако желите да онемогућите колоризацију за одређени тип датотеке, морате га заменити са <type>=:
или <type> 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.029s
0,3 секунде на листи од 10 фајлова, рекорд.
Постављање Шерлока
Од 13 секунди са подразумеваним подешавањима до 0,3 секунде са мањим подешавањима LS_COLORS
значи 40-струко убрзање због одсуства setuid
/ setgid
и обојене извршне датотеке. Није тако велики губитак.
Наравно, ово је сада конфигурисано у Схерлоцк-у за сваког корисника.
Али ако желите да вратите боју, једноставно се можете вратити на подразумевана подешавања:
$ unset LS_COLORS
Али онда у директоријумима са пуно датотека, обавезно скувајте кафу док је у току ls
.
Извор: ввв.хабр.цом