در این آموزش کوتاه، می‌خواهم چند ترفند و نکته را با شما در میان بگذارم تا به شما کمک کند با برخی از موقعیت‌های رایج در هنگام کار در خط فرمان لینوکس مقابله کنید.

موارد زیر را پوشش خواهیم داد:

  • پیدا کردن
  • xargs و nproc
  • مجموعه وظایف
  • numactl
  • تماشا کردن
  • inotify-tools

من به شما یک چالش و ابزارهایی را ارائه می کنم که نشان می دهد چگونه هر مشکل را حل کنید.

آنچه شما نیاز دارید:

  • یک توزیع لینوکس
  • کنجکاوی

روش مدیریت دایرکتوری ها با فایل های زیاد

ممکن است قبلاً با این مشکل مواجه شده باشید: سعی کردید یک را انجام دهید ls روی یک دایرکتوری با تعداد بسیار زیادی فایل، اما دستور خطای “لیست آرگومان خیلی طولانی” را نشان داد:

josevnz@orangepi5:/data/test_xargs$ ls *
-bash: /usr/bin/ls: Argument list too long

این به این دلیل است که سیستم‌های سازگار با POSIX برای حداکثر تعداد بایت‌هایی که می‌توانید به عنوان آرگومان ارسال کنید، محدودیت دارند:

[josevnz@dmaf5 Documents]$ getconf ARG_MAX
2097152

2 میلیون بایت ممکن است زیاد به نظر برسد – یا بسته به اندازه کافی کافی نیست روی که از او می پرسی اما همچنین محافظت در برابر حملات یا اشتباهات بی گناه با عواقب بد است.

در هر صورت چگونه می توان از این محدودیت عبور کرد؟ خوب، راه های زیادی برای انجام این کار وجود دارد.

با استفاده از شل داخلی

Bash داخلی محدودیت ARG_MAX را ندارد:

josevnz@orangepi5:/data/test_xargs$ echo *|ls
...
test_file055554  test_file111110  test_file166666  test_file222222  test_file277778  test_file333334  test_file388890  test_file444446
test_file055555  test_file111111  test_file166667  test_file222223  test_file277779  test_file333335  test_file388891  test_file444447
test_file055556  test_file111112  test_file166668  test_file222224  test_file277780  test_file333336  test_file388892  test_file444448

این احتمالا ساده ترین راه حل است، اما اجازه دهید راه دیگری را ببینیم.

استفاده کردن find زمانی که می خواهید گزینه های قالب بندی را داشته باشید

یا می توانید از این شناخته شده استفاده کنید find پرچم:

find /data/test_xargs -type f -ls -printf '%name'

یا با قالب بندی، به تقلید ls:

find /data/test_xargs -type f -printf '%f\n

این سریع و همچنین کامل ترین راه حل است. اما قبل از حرکت روی من راه دیگری را به شما نشان خواهم داد.

استفاده از xargs

آثار زیر:

find /data/test_xargs -type f -print0 | xargs -0 ls

اما ناکارآمد است، زیرا شما در حال انشعاب 3 فرآیند برای نمایش محتویات دایرکتوری هستید. و روی بالاتر از آن، xargs در حال گاز دادن است چند فایل به دستور ls ارسال می شود.

بیا حرکت کنیم روی و یک مشکل متفاوت را بررسی کنید.

چگونه برنامه های بیشتری را بدون خرابی سرور اجرا کنیم

ابتدا راه می روید سپس می دوید: این کار را به صورت سریالی انجام دهید

بنابراین بگویید که می خواهید همه فایل ها را فشرده کنید روی دایرکتوری داده شده از مثال قبلی ما. اولین تلاش به این صورت خواهد بود:

gzip *

که همانطور که gzip طول خواهد کشید process یک فایل در آن زمان

پیشنهاد می‌کنیم بخوانید:  روش نصب استریسک روی CentOS 7

ممکن است فکر کنید برای فشرده سازی فایل ها به صورت موازی کاری شبیه به این انجام دهید:

josevnz@orangepi5:/data/test_xargs$ for file in $(ls data/test_xargs/*); do gzip $file &; done
-bash: /usr/bin/ls: Argument list too long

دوباره، ARG_MAX دوباره ضربه می زند.

ما xargs را می شناسیم یا اکنون پیدا می کنیم، پس اگر این کار را انجام دهیم چه می شود:

for file in $(find $PWD); do echo gzip $file &; done
wait
echo "All files compressed?"

که یا شما را حافظه سرور تمام می شود یا آن را تحت استفاده بسیار سنگین CPU خرد کنید زیرا شما برای هر فایلی که پیدا می شود یک نمونه gzip را فورک می کنید.

اولین تلاش ما برای موازی سازی و خفه کردن (هنر کنترل خود)

آنچه شما نیاز دارید راهی برای رسیدن به آن است دریچه گاز درخواست‌های فشرده‌سازی شما، بنابراین فرآیندهای بیشتری از تعداد CPUSی که دارید راه‌اندازی نمی‌کنید.

بیایید آن را دوباره با find و xargs:

find /data/test_xargs -type f -print0| xargs -0 -P $(($(nproc)-1)) -I % gzip %

اوه به نظر می رسد یک خط فانتزی است. بگذارید توضیح دهم که چگونه کار می کند:

  1. استفاده کنید find برای دریافت همه فایل ها روی دایرکتوری داده شده، از کاراکتر null به عنوان جداکننده استفاده کنید تا بتوانید process نام های عجیب و غریب
  2. nproc به شما می گوید که چند CPUS دارید، سپس با استفاده از محاسبات Bash مانند زیر با استفاده از پوسته های فرعی، 1 را کم کنید: $(($(nproc)-1))
  3. سرانجام، xargs بیش از -P فرآیندها را اجرا نخواهد کرد (در مورد من 8 CPUS – 1 = 7 کار)، جایگزینی ‘%’ با نام فایل برای فشرده سازی

توجه: راه های دیگری برای دریافت شماره CPUS وجود دارد روی ماشین، مانند تجزیه /proc/cpuinfo. فشرده‌سازی کارآمدتر دیگری نیز وجود دارد، اما gzip در دسترس است روی تقریباً هر لینوکس/یونیکس در آنجا وجود دارد.

خوب، وقت آن است که مشکل بعدی خود را ببینیم.

CPU Affinity با مجموعه وظایف برای به حداکثر رساندن زمان اجرا

علیرغم محدود کردن تعداد پردازنده‌ها، برخی از کارهای فشرده می‌توانند فرآیندهای دیگر را کاهش دهند روی هنگام جستجوی منابع، دستگاه شما چند کار وجود دارد که می توانید برای تحت کنترل نگه داشتن عملکرد سرور انجام دهید، مانند استفاده از مجموعه وظایف:

دستور taskset برای تنظیم یا بازیابی CPU affinity استفاده می شود
از یک دویدن process با توجه به pid آن، یا برای راه اندازی یک دستور جدید
با یک میل CPU معین. CPU affinity یک ویژگی زمانبندی است
که “اوراق قرضه” الف process به مجموعه معینی از CPU ها روی سیستم.

به طور کلی، ما همیشه می خواهیم یکی از CPUS را برای وظایف سیستم عامل “رایگان” بگذاریم. هسته معمولاً برای جلوگیری از تغییر متن، فرآیندهای در حال اجرا را به یک CPU خاص چسبانده است، اما اگر می‌خواهید اعمال کنید روی کدام CPUS شما process اجرا خواهد شد شما می توانید استفاده کنید tasket

taskset -c 1,2,3,4,5,6,7 find /data/test_xargs -type f -print0| xargs -0 -P $(($(nproc)-1)) -I % gzip %

taskset تنها بازی در شهر است؟ نه خیلی سریع!

NUMA چیست و چرا باید اهمیت دهید؟

محدودیت‌های فیزیکی برای سخت‌افزار وجود دارد که در صورت نیاز به تعداد زیادی CPU و حافظه زیاد با آن مواجه می‌شویم. محدودیت مهم این است که پهنای باند ارتباطی محدودی بین CPU و حافظه وجود دارد.

یکی از اصلاحات معماری که برای رفع این مشکل معرفی شد، دسترسی به حافظه غیریکنواخت (NUMA) است.

بنابراین اکثر ماشین‌های رومیزی ساده فقط یک NUMA دارند node، مثل مال من:

[josevnz@dmaf5 ~]$ numactl --hardware
available: 1 nodes (0)
node 0 cpus: 0 1 2 3 4 5 6 7
node 0 size: 15679 MB
node 0 free: 5083 MB
node distances:
node   0 
  0:  10
# Or with lscpu
[josevnz@dmaf5 ~]$ lscpu |rg NUMA
NUMA node(s):                    1
NUMA node0 CPU(s):               0-7

اگر بیش از یک NUMA دارید node، ممکن است بخواهید “پین” یا وابستگی برنامه خود را برای استفاده از CPUS و حافظه همان برنامه تنظیم کنید. node.

پیشنهاد می‌کنیم بخوانید:  نحوه استفاده از OpenSea: راه آسان برای تنظیم نمایه شما

مثلا، روی دستگاهی با 16 هسته، 0-7 روی node 0، 8-15 روی node 1، ما می توانیم برنامه فشرده سازی خود را مجبور به اجرا کنیم روی تمام CPUS روی node 1، و از حافظه استفاده کنید node 1 مثل این:

numactl --physcpubind 8-15 --membind=1 find /data/test_xargs -type f -print0| xargs -0 -P $(($(nproc)-1)) -I % gzip %

نگه داشتن چشم روی چیزها

فقط مراقب کارم باش

دستور watch به شما امکان می دهد به صورت دوره ای یک فرمان را اجرا کنید و حتی قبل از تماس تفاوت ها را به شما نشان دهد:

Every 10.0s: ls                                                                                                         orangepi5: Wed May 24 22:46:33 1402

test_file000001.gz
test_file000002.gz
test_file000003.gz
test_file000004.gz
test_file000005.gz
test_file000006.gz
test_file000007.gz
test_file000008.gz
test_file000009.gz
test_file000010.gz
...

خروجی را به من نشان می دهد ls هر 10 ثانیه فرمان دهید. برای تشخیص تغییرات روی یک دایرکتوری ساده است، اما خودکار کردن آن آسان نیست و قطعا کارآمد نیست.

خوب نیست اگر هسته بتواند تغییرات را به من بگوید روی دایرکتوری های من؟

راهی بهتر برای دانستن تغییرات روی سیستم فایل، با ابزارهای inotify

ممکن است لازم باشد این را جداگانه نصب کنید، اما انجام آن باید آسان باشد. در اوبونتو:

sudo apt-get install inotify-tools

در فدورا:

sudo dnf install -y inotify-tools

بنابراین چگونه می توانیم برای رویدادها نظارت کنیم روی یک دایرکتوری داده شده؟

در یک terminal می توانیم inotifywait را اجرا کنیم:

josevnz@orangepi5:/data/test_xargs$ inotifywait --recursive /data/test_xargs/
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

و روی یکی دیگر terminal ما می توانیم برخی از فایل ها را برای شبیه سازی یک رویداد لمس کنیم:

josevnz@orangepi5:/data/test_xargs$ pwd
/data/test_xargs
josevnz@orangepi5:/data/test_xargs$ touch test_file285707.gz test_file357136.gz test_file428565.gz

اصلی terminal اولین رویداد و خروج را دریافت می کند:

Watches established.
/data/test_xargs/ OPEN test_file285707.gz

برای اینکه حتی برای همیشه گوش کند، این کار را انجام می دهیم:

josevnz@orangepi5:/data/test_xargs$ inotifywait --recursive --monitor /data/test_xargs/

اگر دوباره فایل را لمس کنیم روی یک جدا terminal سپس این بار همه وقایع را خواهیم دید:

Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/data/test_xargs/ OPEN test_file285707.gz
/data/test_xargs/ ATTRIB test_file285707.gz
/data/test_xargs/ CLOSE_WRITE,CLOSE test_file285707.gz
/data/test_xargs/ OPEN test_file357136.gz
/data/test_xargs/ ATTRIB test_file357136.gz
/data/test_xargs/ CLOSE_WRITE,CLOSE test_file357136.gz
/data/test_xargs/ OPEN test_file428565.gz
/data/test_xargs/ ATTRIB test_file428565.gz
/data/test_xargs/ CLOSE_WRITE,CLOSE test_file428565.gz

این امر نسبت به درخواست هر بار تغییر دایرکتوری و فیلتر کردن تفاوت‌ها به سیستم عامل کمتر است.

چه خبر بعدی

چیزهای بیشتری برای کشف وجود دارد. نکات بالا شما را با مفاهیم مهم آشنا می کند، پس چرا بیشتر در مورد آنها یاد نگیرید؟

  • انجمن اوبونتو گفتگوی خوبی در مورد آن دارد xargs، پیدا کردن، حد نصاب و چیزهای دیگر. دانش قدرت است.
  • RedHat به عنوان یک خوب است page درباره NUMA، مجموعه وظایف، مدیریت وقفه. اگر در مورد تنظیم دقیق عملکرد فرآیندهای خود جدی هستید، لطفاً آن را بخوانید.
  • شما inotify را دوست داشتید و می خواهید از اسکریپت پایتون خود استفاده کنید. سپس به pynotify نگاهی بیندازید.
  • یافتن ممکن است ترسناک باشد، اما این آموزش درک آن را آسان‌تر می‌کند.
  • Source کد این آموزش را می توانید در اینجا پیدا کنید.