När en miljövariabel påskyndar processen med 40 gånger

Idag vill vi prata om några av de senaste uppdateringarna av Sherlock-systemet [detta är ett högpresterande kluster vid Stanford University - ca. trans.], vilket avsevärt snabbar upp listning av filer i kataloger med ett stort antal poster.

Till skillnad från vanliga artiklar är detta mer en insiderrapport om hur vi regelbundet arbetar med Sherlock för att hålla det igång på bästa sätt för våra användare. Vi hoppas kunna publicera fler liknande artiklar i framtiden.

Att lista många filer tar tid

Allt började med en teknisk supportfråga från en användare. Han rapporterade problemet att avrättningen ls tar några minuter i en katalog med över 15 000 poster i $SCRATCH [katalog för temporära filer - ca. körfält].

Tusentals filer i en katalog utgör vanligtvis en börda för filsystemet och rekommenderas definitivt inte. Användaren visste detta och medgav att det inte var bra, men nämnde att noteringen var 1000 gånger snabbare på hans bärbara dator än Sherlock. Naturligtvis skadade detta oss. Så vi tittade djupare.

För det ser trevligt ut

Vi tittade på vad det faktiskt gör ls när du listar en katalog, och varför processen tar så lång tid. På de flesta moderna distributioner ls som standard körs den som ls --color=auto, eftersom alla gillar färgerna.

Men vackra färger har ett pris: för varje fil ls måste få information om filtypen, dess behörigheter, flaggor, utökade attribut och liknande för att kunna välja lämplig färg.

En enkel lösning på problemet är att inaktivera färg i ls helt och hållet, men föreställ dig upprördheten från användarna. Under inga omständigheter bör du ta bort färgutdata, vi är inga monster.

Så vi tittade djupare. ls färger poster via miljövariabel LS_COLORS, som är inställd dircolors(1) baserat på konfigurationsfilen dir_colors(5). Ja, den körbara filen läser konfigurationsfilen för att skapa en miljövariabel, som sedan används (och om du inte känner till filer Dörren (do), sedan dir_colors det kommer att fungera, Trots allt).

Låt oss ta en närmare titt

För att avgöra vilket färgschema som orsakar nedgången skapade vi en experimentmiljö:

$ 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 sekunder för 10 000 filer, inte särskilt bra.

Förresten, vi behöver en flagga --color=always: fast han vänder sig till ls --color=autoMen ls upptäcker när den inte är ansluten till en terminal (t.ex. via rör eller med utgångsomdirigering) och inaktiverar färgning om den är inställd på auto. Smart kille.

Så vad tar så lång tid? Vi tittade med 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
[...]

Wow: 10 000 samtal lstat(), 10 000 samtal getxattr() (som alla misslyckas eftersom vår miljö inte har de attribut som jag letar efter), 10 000 samtal capget().

Detta kan säkert optimeras.

Egenskaper? Nej

Följer råd bugg från 10 år sedan, försökte vi inaktivera attributkontroll kapacitet:

$ 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

Wow, upp till 8 sekunders acceleration! Vi blev av med alla dyra samtal getxattr()och utmaningar capget() försvann också, jättebra.

Men det finns fortfarande dessa irriterande samtal lstat(), Fastän…

Hur många blommor behöver du?

Därför tog vi en närmare titt LS_COLORS.

Först inaktiverade vi helt enkelt denna variabel:

$ 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

Vad!?! Fortfarande 13 sekunder?

Det visar sig att när miljövariabeln LS_COLORS endast ett av dess element är inte definierat eller saknas <type>=color:, den använder den inbyggda databasen som standard och använder fortfarande färger. Så om du vill inaktivera färgsättning för en viss filtyp måste du åsidosätta den med <type>=: eller <type> 00 i fil DIR_COLORS.

Efter mycket försök och misstag begränsade vi vår sökning till detta:

EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00

som skrivs som

LS_COLORS='ex=00:su=00:sg=00:ca=00:'

Det betyder: färglägg inte filer efter attribut. kapacitet, men bit för bit setuid/setgid, inte heller av körbarhetsflagga.

Vi sätter fart ls

Och om du inte gör någon av dessa kontroller, ring då lstat() försvinna, och nu är det en helt annan sak:

$ 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 sekunder på en lista med 10 000 filer, ett rekord.

Konfigurera Sherlock

Från 13 sekunder med standardinställningar till 0,3 sekunder med mindre justeringar LS_COLORS innebär en 40-faldig acceleration på grund av frånvaron setuid / setgid och färgade körbara filer. Inte så stor förlust.

Naturligtvis är detta nu konfigurerat i Sherlock för varje användare.

Men om du vill returnera färgen kan du helt enkelt återgå till standardinställningarna:

$ unset LS_COLORS

Men då på kataloger med många filer, se till att brygga kaffe medan det körs ls.

Källa: will.com

Lägg en kommentar