
اگر درباره اجرای فایلسیستم ZFS از کسی بپرسید، با همان هشدار همیشگی روبهرو میشوید: ZFS نیمی از رم شما را میخورد. این هشدار زمانی در لینوکس درست بود؛ به همین دلیل بسیاری از کاربرانی که با TrueNAS Scale یک NAS شخصی میسازند، وارد داشبورد میشوند، دیوار بزرگی از حافظه را در وضعیت «استفادهشده» میبینند و گمان میکنند نشتی حافظه وجود دارد. اما دیگر خبری از «نیمه» نیست؛ در نسخههای کنونی TrueNAS، فایلسیستم ZFS با خیال راحت تقریباً تمام رم شما را پر میکند و این دقیقاً همان رفتاری است که باید انتظارش را داشته باشید.
عدد «نیمه» هرگز یک قاعده کارایی نبود؛ یک حاشیه امن برای یک رفتار خاص در مدیریت حافظه لینوکس بود. وقتی دلیل وجود آن را بدانید، نمودار حافظهای که کاملاً پر به نظر میرسد دیگر ترسناک نخواهد بود. با این حال، چند سناریو وجود دارد که میتواند دردسر واقعی ایجاد کند و پیش از هر تغییری باید آنها را شناخت.
کش ARC چیست و چرا رم شما را طلب میکند؟
ZFS یک کش خواندنی در حافظه رم نگه میدارد که «کش جایگزینی تطبیقی» (Adaptive Replacement Cache) یا به اختصار ARC نامیده میشود. این کش دادهها و فرادادههایی (Metadata) را در خود نگه میدارد که بهتازگی خواندهاید، بههمراه دادههایی که مرتب میخوانید، و بهصورت پویا میان این دو فهرست تعادل برقرار میکند. رم در مقیاس نانوثانیه پاسخ میدهد، در حالی که حتی سریعترین درایوهای SSD در مقیاس میکروثانیه و هارددیسکها در مقیاس میلیثانیه عمل میکنند؛ بنابراین هر خواندنی که از ARC پاسخ بگیرد، خواندنی است که دیسکهای شما هرگز مجبور به پردازش آن نشدهاند. همین موضوع توضیح میدهد چرا افزودن رم میتواند برای یک NAS مفیدتر از افزودن یک کش SSD باشد.
از دید ZFS، رم خالی، رم هدررفته است. اگر چیز دیگری به آن حافظه نیاز نداشته باشد، ARC در آن رشد میکند، چون کش بزرگتر یعنی نرخ برخورد (Cache Hit) بالاتر. این همان ایدهای است که سالها در قالب کش صفحهای لینوکس (Page Cache) توضیح داده شده، با این تفاوت که ARC روش هوشمندانهتری برای تصمیمگیری درباره اینکه چه چیزی را نگه دارد، در اختیار دارد.
در یک آزمون عملی روی یک ماشین مجازی TrueNAS 25.10.7 با ۱۶ گیگابایت رم، یک فایل ۱۲ گیگابایتی روی یک استخر آینهای (Mirror Pool) کوچک نوشته و دو بار خوانده شد. هر دو بار در کمتر از یک ثانیه و با سرعت حدود ۱۳.۵ گیگابایت بر ثانیه به پایان رسید و دیسکهای استخر حتی یک بایت از این خواندنها را پردازش نکردند؛ این سرعت رم است، نه سرعت دیسک.
پس از آن، ابزار arc_summary نشان داد که ARC حدود ۱۳.۱ گیگابایت از ۱۵.۶ گیگابایت حافظه قابلاستفاده ماشین مجازی را در اختیار گرفته و ZFS تنها ۲۱ مگابایت حافظه آزاد گزارش میکند. با هر معیار سنجش حافظه آزاد، این ماشین مجازی در آستانه فروپاشی به نظر میرسید؛ اما هیچ محدودیت (Throttle) و هیچ بازیابی حافظهای (Reclaim) در گزارشها ثبت نشده بود، چون هیچ برنامه دیگری خواهان آن رم نبود.
نکته کلیدی این است که ARC حافظه را انبار نمیکند. وقتی هسته سیستمعامل (Kernel) سیگنال کمبود حافظه بدهد، ZFS حجم ARC را کوچک میکند و آن رم را به هر برنامهای که درخواست کرده باشد تحویل میدهد. به همین دلیل یک NAS با نمودار حافظه «پر» همچنان میتواند یک کانتینر یا ماشین مجازی را بدون مشکل اجرا کند. تنها نکته این است که کوچکسازی زمان میبرد و همین تأخیر، محل بروز مشکلات واقعی است.
چرا ZFS پیشتر در نیمی از رم متوقف میشد؟
ZFS ابتدا روی سولاریس (Solaris) متولد شد و روی FreeBSD رشد کرد؛ جایی که ARC میتوانست تقریباً تمام حافظه سیستم را در اختیار بگیرد. با انتقال آن به لینوکس، این رفتار تغییر کرد و دلیلش به یک درخواست ادغام کد (Pull Request) در پروژه ZFS on Linux در سال ۲۰۱۲ بازمیگردد. مشکل، تکهتکه شدن (Fragmentation) در تخصیصدهنده اسلب (Slab Allocator) هسته لینوکس بود. محدودیتهای ZFS فرض میکردند هر بایت کش دقیقاً یک بایت رم هزینه دارد، اما توسعهدهندگان دریافتند که تکهتکه شدن میتواند مصرف واقعی را تا حدود دو برابر اندازه گزارششده ARC بالا ببرد. بدون محدودیت، از نظر تئوری ممکن بود کش از حافظه فیزیکی دستگاه فراتر برود.
به همین دلیل ZFS on Linux بهصورت پیشفرض روی نیمی از رم متوقف میشد تا در بدترین حالت تکهتکه شدن، همچنان در محدوده حافظه فیزیکی باقی بماند. در مقابل، TrueNAS CORE که روی FreeBSD اجرا میشد هرگز چنین محدودیتی نداشت؛ به همین دلیل کاربرانی که از CORE به SCALE مهاجرت میکردند، از کوچک به نظر رسیدن کش خود شکایت داشتند.
حذف محدودیت توسط TrueNAS و OpenZFS
شرکت iXsystems این وضعیت را با TrueNAS SCALE 24.04 با نام رمزی Dragonfish تغییر داد و تخصیص حافظه ARC را با TrueNAS CORE یکسان کرد. همین تغییر به پروژه بالادستی OpenZFS نیز راه یافت. یکی از مهندسان iXsystems نویسنده کامیت (Commit) مربوطه در OpenZFS بود و استدلال کرد که محدودیت نیمی از حافظه فیزیکی برای سیستمهای مدرن با رم فراوان بیش از حد سختگیرانه است؛ این تغییر در OpenZFS 2.3.0 منتشر شد. مقدار پیشفرض جدید، بزرگترین مقدار میان «کل رم منهای یک گیگابایت» و «پنجهشتم کل رم» است.
- TrueNAS 24.04 با OpenZFS 2.2 و تغییر iX: سقف ARC برابر رم منهای یک گیگابایت یا پنجهشتم رم
- TrueNAS 24.10 و 25.04 با OpenZFS 2.3: رم منهای یک گیگابایت یا پنجهشتم رم
- TrueNAS 25.10 با OpenZFS 2.3.9: رم منهای یک گیگابایت یا پنجهشتم رم
- اوبونتو 26.04 LTS با OpenZFS 2.4.1: رم منهای یک گیگابایت یا پنجهشتم رم
- اوبونتو 24.04 LTS با OpenZFS 2.2.2: ۵۰ درصد رم
- Proxmox VE 8.1 و بالاتر: متغیر، ۱۰ درصد رم با سقف ۱۶ گیگابایت
این فرمول تقریباً معادل ۹۴ درصد رم در یک سیستم ۱۶ گیگابایتی و ۹۷ درصد در یک سیستم ۳۲ گیگابایتی است و ماشین مجازی آزمایشی نیز دقیقاً با همین فرمول، سقف ARC خود را ۱۴.۶ گیگابایت گزارش کرد. بنابراین در یک NAS مدرن، عدد «نیمه» یک بازمانده تاریخی است.
چرا NAS شما در ظاهر با کمبود حافظه روبهروست؟
بخش گیجکننده ماجرا اینجاست: ZFS کار اشتباهی انجام نمیدهد، اما لینوکس آن را به شکلی گزارش میکند که هشدارآمیز به نظر میرسد. اگر ترمینال را باز کنید و دستور free را اجرا کنید، تقریباً هیچ حافظه آزادی نخواهید دید، حتی وقتی سیستم کاملاً سالم است.
کش صفحهای معمول لینوکس زیر ستون buff/cache نمایش داده میشود؛ همان حافظهای که همه میدانند در صورت نیاز بازگردانده میشود. اما ARC در کش صفحهای قرار نمیگیرد و لینوکس آن را بهعنوان حافظه استفادهشده خالص گزارش میکند. همچنین این حافظه در شاخص حافظه قابلاستفاده هسته نیز محاسبه نمیشود و همین موضوع میتواند ابزارهایی مانند earlyoom و systemd-oomd را فریب دهد تا تصور کنند سیستم با کمبود رم مواجه است.
این یک مشکل گزارشدهی است، نه یک مشکل حافظه. کش همچنان قابل بازپسگیری است؛ فقط لینوکس آن را با این برچسب نمایش نمیدهد.
داشبورد TrueNAS واقعاً چه چیزی نشان میدهد؟
TrueNAS در این زمینه عملکرد بهتری دارد، چون داشبورد آن حافظه را به سه بخش Free، ZFS Cache و Services تقسیم میکند و در یک نگاه مشخص میشود که بیشتر رم شما کش است، نه برنامهها. با این حال، این تفکیک جلوی پرسشها را نمیگیرد؛ یکی از کاربران انجمن TrueNAS پرسیده بود چرا پس از ارتقا به نسخه 25.10 حدود ۱۰۱.۷ گیگابایت از ۱۲۵ گیگابایت رم او در بخش ZFS Cache قرار گرفته و پاسخ ساده این بود که ZFS در حال انجام وظیفه خود است.
چه زمانی اشتهای ZFS واقعاً مشکلساز میشود؟
هیچکدام از این توضیحات به معنای بیخطر بودن همیشگی مصرف حافظه ZFS نیست. کش حافظه را بازمیگرداند، اما نه بهصورت آنی، و تعامل آن با سایر بخشهای مدیریت حافظه لینوکس دردسرهای واقعی ایجاد کرده است. اگر روی NAS خود بیش از اشتراک فایل اجرا میکنید، این موارد را در نظر بگیرید.
راهاندازی یک ماشین مجازی نیازمند یک بلوک بزرگ حافظه بهصورت یکجا است. اگر ARC پر باشد، ZFS باید آن را کوچک کند تا حافظه آزاد شود و ماشین مجازی در این فاصله منتظر میماند. روی دستگاهی که عمدتاً فایل سرو میکند، این موضوع بهندرت اهمیت دارد؛ اما روی دستگاهی که ماشینهای مجازی مرتب راهاندازی و خاموش میشوند، میتواند به کندی راهاندازی یا شکست در تخصیص حافظه منجر شود. به همین دلیل هایپروایزرها (Hypervisor) رفتار کاملاً متفاوتی با ARC دارند.
چرا Proxmox سقف ۱۰ درصد را اعمال میکند؟
Proxmox VE نیز روی ZFS اجرا میشود، اما دقیقاً برعکس عمل میکند. نصبهای جدید از نسخه 8.1 به بعد سقف ARC را ۱۰ درصد رم (حداکثر ۱۶ گیگابایت) تعیین میکنند و قاعده سرانگشتی Proxmox، دو گیگابایت بهعلاوه یک گیگابایت به ازای هر ترابایت فضای ذخیرهسازی است. رم یک هایپروایزر متعلق به ماشینهای مهمان آن است و قرار گرفتن کش در مسیر راهاندازی ماشین مجازی، همان مشکلی است که پیشتر اشاره شد. فایلسیستم یکسان، کاربرد متفاوت و پیشفرض متفاوت.
آیا باید ARC را محدود کرد؟
برای بیشتر کاربرانی که یک NAS اختصاصی دارند، پاسخ منفی است. کش پر میشود چون رم آزاد است و همان رم را زمانی که برنامهای به آن نیاز داشته باشد بازمیگرداند. اعمال محدودیت تنها به این معناست که خواندنهای بیشتری به دیسکها مراجعه کنند.
با این حال، در چند حالت اعمال محدودیت منطقی است:
- دستگاه TrueNAS شما تعداد زیادی ماشین مجازی اجرا میکند، بهویژه ماشینهایی که مرتب روشن و خاموش میشوند.
- ZFS را روی یک هایپروایزر مانند Proxmox اجرا میکنید که در آن ماشینهای مهمان به حافظه در لحظه نیاز دارند.
- ZFS را روی یک رایانه رومیزی یا لپتاپ نصب کردهاید که در آن برنامهها و بازیها بر سر رم رقابت میکنند.
این محدودیت از طریق یک پارامتر قابل تنظیم (Tunable) به نام zfs_arc_max اعمال میشود و هم روی TrueNAS و هم روی Ubuntu Server کار میکند. تنظیم آن یک دقیقه زمان میبرد، اما پیش از هر تغییری نرخ برخورد ARC خود را بررسی کنید تا بدانید چه چیزی را از دست میدهید.
پر بودن رم هدف است، نه مشکل
هشدار قدیمی اشتباه نبود؛ فقط منقضی شده است. ZFS on Linux بیش از یک دهه در نیمی از رم متوقف میشد تا در برابر یک رفتار خاص تخصیصدهنده حافظه محافظت کند و اکنون TrueNAS و OpenZFS تصمیم گرفتهاند که سیستمهای مدرن به آن حاشیه امن نیازی ندارند. نموداری که پر از ZFS Cache است یعنی NAS شما خواندنها را از رم و نه از دیسک پاسخ میدهد و این دقیقاً همان دلیلی است که ARC برای آن ساخته شده است.
اگر کنجکاو هستید که آیا این کش ارزش نگهداشتن دارد، پیش از هر تغییری نرخ برخورد ARC را در مسیر Reporting و سپس ZFS در TrueNAS بررسی کنید. نرخ برخورد بالا یعنی کش در حال انجام وظیفه خود است و این دلیل بهتری برای دستنزدن به تنظیمات است تا هر عددی که روی داشبورد میبینید.