عندما يقوم متغير البيئة بتسريع العملية بمقدار 40 مرة

نريد اليوم أن نتحدث عن بعض آخر التحديثات لنظام Sherlock [هذه مجموعة عالية الأداء في جامعة ستانفورد - تقريبًا. Trans.]، والذي يعمل بشكل كبير على تسريع إدراج الملفات في الدلائل التي تحتوي على عدد كبير من الإدخالات.

على عكس المقالات العادية، يعد هذا تقريرًا من مصادر مطلعة حول كيفية عملنا بانتظام على Sherlock للحفاظ على تشغيله بأفضل حالاته لمستخدمينا. ونأمل أن ننشر المزيد من المقالات مثل هذه في المستقبل.

إدراج العديد من الملفات يستغرق وقتا

بدأ كل شيء بسؤال الدعم الفني من المستخدم. وأبلغ عن مشكلة الإعدام ls يستغرق بضع دقائق في دليل يحتوي على أكثر من 15 إدخال $SCRATCH [دليل الملفات المؤقتة - تقريبًا. خط].

عادةً ما تشكل آلاف الملفات في دليل واحد عبئًا على نظام الملفات ولا يوصى بها بالتأكيد. عرف المستخدم ذلك واعترف بأن الأمر لم يكن جيدًا، لكنه ذكر أن الإدراج كان أسرع بـ 1000 مرة على جهاز الكمبيوتر المحمول الخاص به من شيرلوك. وبطبيعة الحال، هذا يضر بنا. لذلك نظرنا بشكل أعمق.

لأنها تبدو لطيفة

لقد نظرنا إلى ما يفعله بالفعل ls عند إدراج دليل، ولماذا تستغرق العملية وقتًا طويلاً. على معظم التوزيعات الحديثة ls بشكل افتراضي يتم تشغيله كـ ls --color=auto، لأن الجميع يحب الألوان.

لكن الألوان الجميلة لها ثمن: لكل ملف ls يجب أن تحصل على معلومات حول نوع الملف وأذوناته وعلاماته وسماته الموسعة وما شابه ذلك من أجل تحديد اللون المناسب.

أحد الحلول البسيطة لهذه المشكلة هو تعطيل اللون في ls تمامًا، لكن تخيل غضب المستخدمين. لا ينبغي عليك بأي حال من الأحوال إزالة مخرجات اللون، فنحن لسنا وحوش.

لذلك نظرنا بشكل أعمق. ls إدخالات الألوان عبر متغير البيئة LS_COLORS، الذي تم تعيينه dircolors(1) بناء على ملف التكوين dir_colors(5)... نعم، يقرأ الملف القابل للتنفيذ ملف التكوين لإنشاء متغير بيئة، والذي يستخدمه ls بعد ذلك (وإذا كنت لا تعرف عن الملفات باب (افعل)، ثم 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().

بالتأكيد يمكن تحسين هذا.

سمة القدرات؟ لا

بعد النصيحة خطأ من 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

إضافة تعليق