Oggi vogliamo raccontare alcune delle ultime aggiornamenti del sistema Sherlock [è un cluster ad alte prestazioni dell'Università di Stanford - ndr], che accelerano notevolmente il listing dei file in directory con un gran numero di record.
A differenza degli articoli normali, questo è più un rapporto interno su come avviene il lavoro regolare su Sherlock per mantenerlo nelle migliori condizioni per i nostri utenti. Speriamo in futuro di pubblicare più articoli di questo tipo.
Elencare molti file richiede tempo
Tutto è iniziato con una domanda al supporto tecnico da parte di un utente. Ha segnalato un problema, che l'esecuzione ls richiede diversi minuti in una directory con oltre 15.000 record in $SCRATCH [directory per file temporanei - ndr].
Migliaia di file in una sola directory creano generalmente difficoltà per il sistema dei file e questo non è certamente raccomandato. L'utente lo sapeva e ha riconosciuto che non era una cosa buona, ma ha menzionato che sul suo portatile il listing viene eseguito 1000 volte più velocemente che su Sherlock. Certo, ci ha colpito. Così, abbiamo approfondito.
Perché ls appare bello
Abbiamo esaminato cosa fa realmente ls quando elenca una directory, e perché il processo richiede così tanto tempo. Nella maggior parte delle moderne distribuzioni ls viene eseguito per impostazione predefinita come ls --color=auto, perché a tutti piace il colore.
Ma i colori belli hanno un prezzo: per ogni file ls deve ottenere informazioni sul tipo di file, sui permessi, sui flag, sugli attributi estesi e così via, per scegliere il colore appropriato.
Una delle soluzioni semplici al problema è disabilitare completamente il colore in ls, ma immaginate l'indignazione degli utenti. Non possiamo assolutamente togliere l'output colorato, non siamo mostri.
Quindi, abbiamo approfondito. ls colorizza le voci attraverso la variabile ambiente LS_COLORS, che è impostata da dircolors(1) basandosi sul file di configurazione dir_colors(5). Sì, (e se non sai dei file (do), allora dir_colors , a prescindere da tutto).
Esploriamo più nel dettaglio
Per determinare quale schema di colorazione sta causando il rallentamento, abbiamo creato un ambiente sperimentale:
$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # non provate a farlo a casa!
$ time ls --color=always $SCRATCH/dont | wc -l
10000
real 0m12.758s
user 0m0.104s
sys 0m0.699s12,7 secondi per 10.000 file, non è molto buono.
A proposito, ci vuole un flag
--color=always: anche se si trasforma inls --color=auto, malsrileva quando non è collegato al terminale (ad esempio, tramite pipe o con redirezione dell'output) e disattiva i colori se impostato suauto. Bravo ragazzo.
Cosa ci sta quindi mettendo tanto tempo? Abbiamo guardato usando 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
[...] Cavolo: 10.000 chiamate lstat(), 10.000 chiamate getxattr() (tutte falliscono perché nel nostro ambiente non ci sono attributi che cerca ls), 10.000 chiamate capget().
Sicuramente si può ottimizzare.
Attributo capabilities? No.
Seguendo i consigli , abbiamo provato a disabilitare il controllo dell'attributo :
$ 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 totale
real 0m8.160s
user 0m0.115s
sys 0m0.961s Wow, accelerazione a 8 secondi! Abbiamo eliminato tutte quelle costose chiamate getxattr(), e le chiamate capget() sono sparite anche, ottimo.
Ma ci sono ancora queste fastidiose chiamate lstat(), anche se…
Quanti colori ci vogliono?
Quindi abbiamo esaminato più dettagliatamente LS_COLORS.
Inizialmente abbiamo semplicemente disabilitato questa variabile:
$ 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
Cosa!?! Ancora 13 secondi?
A quanto pare, quando la variabile ambiente LS_COLORS non è definita o manca solo uno dei suoi elementi =color:, essa utilizza automaticamente il database integrato e continua a utilizzare i colori. Pertanto, se desideri disattivare la colorazione per un certo tipo di file, devi sovrascriverla con =: o 00 nel file DIR_COLORS.
Dopo molte prove ed errori, abbiamo ristretto la ricerca a questo:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00che viene registrato come
LS_COLORS='ex=00:su=00:sg=00:ca=00:' Questo significa: non colorare i file né in base all'attributo , né in base ai bit , né in base al .
Acceleriamo ls
E se non esegui nessuna di queste verifiche, le chiamate lstat() scompaiono, e ora è tutta un'altra storia:
$ 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 totale
real 0m0.337s
user 0m0.032s
sys 0m0.029s0,3 secondi per un elenco di 10 000 file, un record.
Configuriamo Sherlock
Da 13 secondi con le impostazioni predefinite a 0,3 secondi con una piccola configurazione LS_COLORS significa un'accelerazione di 40 volte grazie all'assenza di setuid / setgid e file eseguibili colorati. Non è una grande perdita.
Certo, ora è impostato in Sherlock per ogni utente.
Ma se desideri ripristinare la colorazione, puoi semplicemente tornare alle impostazioni predefinite:
$ unset LS_COLORS Ma allora su directory con un gran numero di file non dimenticare di preparare un caffè mentre è in esecuzione. ls.
Fonte: habr.com
