در دنیای پرمخاطره DevOps و مدیریت زیرساخت، تأخیر برنامه اغلب تنها یک علامت است. بیماری معمولاً عمیقتر، در تعامل هسته لینوکس با منابع سختافزاری نهفته است. برای توسعهدهندگان متوسط تا پیشرفته، درک نحوه بهینهسازی محیط لینوکس نه تنها یک تکنیک بهینهسازی است، بلکه ضروری است تا مقیاسپذیری، پایداری و کارایی هزینه را تضمین کند.
بهینهسازی عملکرد یک راهحل یکاندازه برای همه نیست. یک سرور پایگاه داده نیازمندیهای کاملاً متفاوتی نسبت به یک پیشنمایش وب یا یک نود معاملاتی با فرکانس بالا دارد. با این حال، اصول اصلی مدیریت منابع ثابت باقی میمانند. این راهنما لایههای حیاتی بهینهسازی عملکرد لینوکس را بررسی میکند و از مدیریت حافظه تا استراتژیهای ورودی/خروجی و بهینهسازیهای لایه شبکه حرکت میکند.
مدیریت حافظه و رفتار جابجایی (Swapping)
فشار حافظه یکی از رایجترین گلوگاهها در محیطهای تولید است. بهطور پیشفرض، لینوکس تمایل دارد صفحات غیرفعال را برای آزاد کردن RAM جهت کش کردن، به دیسک جابجا کند. اگرچه این رفتار بهطور کلی خوب است، در برنامههای با تراکم بالا، جابجایی میتواند باعث ایجاد جهشهای تأخیر فاجعهبار شود.
یکی از اولین تنظیماتی که باید انجام شود، پارامتر vm.swappiness است. این مقدار، که بین 0 تا 100 متغیر است، به هسته میگوید که چگونه تهاجمی عمل کند. برای برنامههای حساس به تأخیر، معمولاً میخواهید جابجایی را به حداقل برسانید.
# کاهش swappiness به 10 برای ترجیح دادن نگهداری دادهها در RAM
sudo sysctl -w vm.swappiness=10
# پایدارسازی آن در طول راهاندازی مجدد
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
علاوه بر این، در نظر بگیرید که vm.vfs_cache_pressure را تنظیم کنید. این مورد تعادل بین بازیابی حافظه استفاده شده برای کش کردن دایرکتوریها و اینودها (inodes) در مقابل کش صفحه را کنترل میکند. کاهش این مقدار هسته را تشویق میکند تا کشهای دایرکتوری و اینود را برای مدت طولانیتری حفظ کند که برای بارهای کاری فشرده فایلسیستم مفید است.
# کاهش فشار کش برای نگهداری کشهای دایرکتوری/اینود در حافظه برای مدت طولانیتر
sudo sysctl -w vm.vfs_cache_pressure=50
بهینهسازی زمانبندهای ورودی/خروجی (I/O Schedulers)
زمانبند I/O بین برنامه و زیرسیستم ذخیرهسازی قرار دارد و ترتیب پردازش درخواستهای I/O را تعیین میکند. زمانبند پیشفرض بسته به توزیع متفاوت است اما اغلب mq-deadline برای درایوهای NVMe مدرن یا bfq برای دیسکهای چرخشی است. با این حال، بارهای کاری خاص ممکن است از زمانبندهای متفاوتی بهره ببرند.
برای SSDها و درایوهای NVMe، زمانبندهای none یا mq-deadline اغلب بهینه هستند زیرا سختافزار صفبندی را کارآمدتر از لایه نرمافزاری هسته مدیریت میکند. میتوانید زمانبند فعلی خود را با دستور زیر بررسی کنید:
cat /sys/block/sda/queue/scheduler
برای تغییر زمانبند برای یک دستگاه بلوکی، میتوانید مستقیماً به رابط sysfs بنویسید. توجه داشته باشید که این تغییر موقتی است و باید برای پایدارسازی از طریق قوانین udev اسکریپتنویسی شود.
# تغییر به زمانبند 'none' برای درایو NVMe sda
echo "none" | sudo tee /sys/block/sda/queue/scheduler
بهینهسازی لایه شبکه برای همزمانی بالا
هنگام ارائه هزاران اتصال همزمان، تنظیمات پیشفرض لایه TCP اغلب به یک گلوگاه تبدیل میشوند. دو پارامتر حیاتی net.core.somaxconn و net.ipv4.tcp_tw_reuse هستند.
تنظیم somaxconn حداکثر طول صف اتصال سوکت را تعریف میکند. اگر برنامه شما یک سرور وب مانند Nginx یا Apache است و با وجود استفاده کم از CPU، خطاهای "Connection refused" را مشاهده میکنید، احتمالاً صف پشتبند (backlog queue) شما پر شده است.
# افزایش حداکثر طول صف اتصال سوکت به 65535
sudo sysctl -w net.core.somaxconn=65535
علاوه بر این، tcp_tw_reuse امکان استفاده مجدد از سوکتهای TIME-WAIT برای اتصالات خروجی جدید را فراهم میکند. این برای برنامههایی که اتصالات خروجی زیادی ایجاد میکنند، مانند دروازههای API یا تعادلکنندههای بار، حیاتی است.
# فعالسازی استفاده مجدد از سوکتهای TIME-WAIT TCP
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
پایش و تکرار
بهینهسازی بدون اندازهگیری، حدس و گمان است. از ابزارهایی مانند vmstat، iostat و pidstat برای ایجاد یک خط پایه استفاده کنید. به دنبال wa (انتظار I/O) بالا در vmstat، استفاده زیاد از دیسک در iostat یا جهشهای تعویض زمینه در pidstat باشید. هر بار یک پارامتر را تنظیم کنید، تأثیر آن را اندازهگیری کنید و تکرار نمایید.
نتیجهگیری
بهینهسازی عملکرد لینوکس یک رشته ظریف است که نیازمند درک عمیقی از نحوه مدیریت سیستمعامل منابع سختافزاری است. با تنظیم دقیق پارامترهای هسته مرتبط با حافظه، I/O و شبکه، میتوانید سودهای عملکرد قابل توجهی از زیرساخت خود استخراج کنید. با این حال، همیشه به یاد داشته باشید که این بهینهسازیها باید با ویژگیهای بار کاری برنامه خاص شما همسو باشند. با یک پایه پایش محکم شروع کنید، تغییرات تدریجی ایجاد کنید و بگذارید دادهها تصمیمات بهینهسازی شما را هدایت کنند.