Όταν μια μεταβλητή περιβάλλοντος επιταχύνει τη διαδικασία κατά 40 φορές

Σήμερα θέλουμε να μιλήσουμε για μερικές από τις πιο πρόσφατες ενημερώσεις στο σύστημα Sherlock [αυτό είναι ένα σύμπλεγμα υψηλής απόδοσης στο Πανεπιστήμιο Stanford - περίπου. trans.], που επιταχύνουν σημαντικά την καταχώριση αρχείων σε καταλόγους με μεγάλο αριθμό καταχωρήσεων.

Σε αντίθεση με τα κανονικά άρθρα, αυτή είναι περισσότερο μια αναφορά εμπιστευτικών πληροφοριών σχετικά με τον τρόπο με τον οποίο εργαζόμαστε τακτικά στο Sherlock για να το διατηρήσουμε στην καλύτερη δυνατή λειτουργία για τους χρήστες μας. Ελπίζουμε να δημοσιεύσουμε περισσότερα άρθρα σαν αυτό στο μέλλον.

Η καταχώριση πολλών αρχείων απαιτεί χρόνο

Όλα ξεκίνησαν με μια ερώτηση τεχνικής υποστήριξης από έναν χρήστη. Ανέφερε το πρόβλημα της εκτέλεσης ls διαρκεί λίγα λεπτά σε έναν κατάλογο με περισσότερες από 15 καταχωρήσεις $SCRATCH [κατάλογος για προσωρινά αρχεία - περ. λωρίδα].

Χιλιάδες αρχεία σε έναν κατάλογο συνήθως επιβαρύνουν το σύστημα αρχείων και σίγουρα δεν συνιστάται. Ο χρήστης το γνώριζε αυτό και παραδέχτηκε ότι δεν ήταν καλό, αλλά ανέφερε ότι η καταχώριση ήταν 1000 φορές πιο γρήγορη στον φορητό υπολογιστή του από τον Sherlock. Φυσικά αυτό μας πλήγωσε. Έτσι ψάξαμε πιο βαθιά.

Επειδή φαίνεται ωραίο

Εξετάσαμε τι κάνει στην πραγματικότητα 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} # 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() (που όλα αποτυγχάνουν επειδή το περιβάλλον μας δεν έχει τα χαρακτηριστικά που αναζητά ο ls), 10 κλήσεις capget().

Σίγουρα αυτό μπορεί να βελτιστοποιηθεί.

Χαρακτηριστικό ικανότητας; Όχι

Ακολουθώντας συμβουλές bug πριν από 10 χρόνια, προσπαθήσαμε να απενεργοποιήσουμε τον έλεγχο χαρακτηριστικών δυνατότητες:

$ 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:'

Αυτό σημαίνει: μην χρωματίζετε τα αρχεία κατά χαρακτηριστικό. δυνατότητες, αλλά λίγο-λίγο setuid/setgid, ούτε από σημαία εκτελέσιμοτητας.

Επιταχύνουμε 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 και έγχρωμα εκτελέσιμα αρχεία. Όχι τόσο μεγάλη απώλεια.

Φυσικά, αυτό είναι πλέον ρυθμισμένο στο Sherlock για κάθε χρήστη.

Αλλά αν θέλετε να επιστρέψετε τον χρωματισμό, μπορείτε απλώς να επιστρέψετε στις προεπιλεγμένες ρυθμίσεις:

$ unset LS_COLORS

Ωστόσο, σε καταλόγους με πολλά αρχεία, φροντίστε να παρασκευάζετε καφέ ενώ είναι σε λειτουργία ls.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο