معرفی فایل سیستم zfs، قابلیت ها و نقاط ضعف آن

مقدمه

فایل سیستم یکی از مهمترین بخش های هر سیستم استورج محسوب می شود، و zfs یکی از فایل سیستم هایی است که در چند سال اخیر سر و صدای بسیار زیادی کرده است. این فایل سیستم بسیار پیشرفته و شاید فراتر از زمان خود طراحی شده است و دارای قابلیت هایی است که بسیاری از سازندگان استورج گران قیمت مانند EMC و NetApp با لیسانس های گران قیمت به مشتریان خود می فروشند. این فایل سیستم به قدری پیشرفته است که بسیاری از متخصصین در StorageMojo و AnandTech پیش بینی کرده اند که تاثیر زیادی در بازار استورج خواهد داشت.

تاریخچه مختصر zfs

zfs به عنوان بخشی از سیستم عامل sun solaris طراحی شد. کسانی که با عرصه سیستمهای *nix آشنا هستند می داند که سه شاخه اصلی از این سیستم ها وجود دارد. سیستم های اپن سورس مبتنی بر لینوکس، سیستم های اپن سورس مبتنی بر یونیکس، مثل freeBSD, NetBSD و سیستم های یونیکس تجاری، مانند SUN Solaris یا HP AIX.

zfs به عنوان بخشی از سیستم عامل سولاریس در سال 2001 طراحی شد و بعد از اینکه سان تصمیم به سورس باز کردن سولاریس گرفت، zfs هم به عنوان بخشی از آن بصورت سورس باز ارائه شد. بعد از اینکه اوراکل سان را خرید تا مدتی به ارائه سولاریس بصورت سورس باز ادامه داد، ولی از سولاریس 11 اوراکل مجددا لیسانس سولاریس و به تبع آن zfs را بست و انحصاری خودش کرد، اما انشعاب های سورس باز سولاریس، در قالب پروژه illumos به کار خود ادامه دادند.

zfs در ابتدا مخفف زتا بایت فایل سیستم بود و می تواند تا 256 کوادریلیون زتابایت اطلاعات (که هر زتا بایت 2 به توان 70 بایت است) در خود نگهداری کند. مقدار اطلاعاتی که یک فایل سیستم zfs می تواند از نظر تئوری در خود نگهدارد به قدری زیاد است که گفته می شود انرژی لازم برای پر کردن یک فایل سیستم zfs به اندازه انرژی لازم برای تبخیر آب تمام اقیانوس های زمین است! به عبارت دیگر بسیار بعید است که در آینده قابل پیش بینی فایل سیستم zfs به محدودیت های تئوری خود حتی نزدیک شود. پروژه btrfs که یک فایل سیستم 64 بیتی کاملا سورس باز است (zfs فایل سیستم 128 بیتی است) سعی دارد که بسیاری از قابلیت های پیشرفته ای که در zfs وجود دارد شبیه سازی کند، هر چند با فاصله بسیار زیادی از آن عقب است.

zfs دارای قابلیت های پیشرفته بسیار زیادی، مانند snapshot, copy on writes, continous integrity checking, automatic repair, RAID-Z, NFS v4 ACL است که ما بصورت مختصر هر قابلیت را توضیح داده و بعد به کاربرد zfs در کار خود می پردازیم و در ضمن به معایب آن هم اشاره ای خواهیم کرد.

قابلیت های zfs

data integrity

zfs از پایه برای حفظ اطلاعات طراحی شده است. باید توجه کرد که حفظ اطلاعات فقط به معنی ذخیره کردن آنها روی دیسک نیست. در استورج مفهومی به نام silent corruption یا خرابی نامحسوس دیتا وجود دارد که به معنی آن است که دیتایی که شما روی دیسک ذخیره می کند با دیتایی که از روی آن می خوانید متفاوت خواهد بود. عوامل بسیار زیادی در silent corruption دخیل هستند، به عنوان مثال ممکن است بخشی از اطلاعات در رم کامپیوتر تغییر کنند، یا به خاطر نوسان جریان، یا تششعات کیهانی، یا فرم ویر خراب دیسک یا خطاهای DMA تغییر کنند. حتی بسیاری از مواقع عوامل ساده تری مانند یک اتصال لق فیبر یا کابل، یک سوییچ خراب یا باگ های فرم ویر سوییچ می توانند عامل این خرابی باشند.

خرابی نامحسوس امروزه یکی از مشکلات مهم استورج به شمار می رود، چون هیچکدام از کنترلرهای سخت افزاری راید یا فایل سیستم های موجود تدابیر لازم برای مقابله با آن را در خود ندیده اند و به همین خاطر بخش مهمی از این خرابی عملا سنجیده یا ارزیابی نمی شود. حتی هارد دیسک های SAS انترپرایز هم در عمل یک خطای غیر قابل تصحییح در هر 10 به توان 16 بیت از خود نشان می دهند. اندازه گیری ها نشان می دهد که در عمل مقدار خطای نامحسوس خیلی بیشتر از این است و به مرور زمان که ما با حجم بیشتری از دیتا روبرو می شویم مقدار این خطا بیشتر می شود.

این خطا به قدری زیاد است که شرکت GreenPlum Corp که یک شرکت متخصص در زمینه دیتابیس های بزرگ است، گزارش کرده که هر 15 دقیقه یک خطای غیر قابل تصحیح داشته است و به همین خاطر به سراغ zfs رفته است.
برای مقابله با این خطا، zfs برای هر بلوک داده یک چک سام 256 بیتی (با الگوریتم sha256 یا الگوریتم قابل انتخاب دیگر) ذخیره می کند. این چک سام در خود بلوک دیتا ذخیره نمی شود، بلکه در یک پوینتر به آن بلوک دیتا ذخیره می شود و از آنجا که این ذخیره سازی بصورت یک درخت تا بالا ادامه پیدا می کند، در هنگام هر دسترسی به هر قسمت از اطلاعات، تمامی این چک سام ها تا پایین چک می شوند تا اگر خطایی در اطلاعات باشد مشخص شود. از آنجا که در zfs اطلاعات بصورت یک raid داخلی نگهداری می شوند، و حتی اگر راید وجود نداشته باشد می توان دستور داد که روی یک دیسک تکی هم دو یا سه نسخه از اطلاعات نگهداری شود، در صورت مواجه با خطا فایل سیستم می تواند اطلاعات خراب را با اطلاعات درست جایگزین کند.

Software RAID

zfs بصورت داخلی یک راید نرم افزاری دارد که از بسیاری از راید های سخت افزاری بهتر کار می کند. حتی دلایلی برای استفاده از راید نرم افزاری zfs وقتی که راید سخت افزاری هم وجود دارد، ذکر می شود، که یکی از مهمترین آنها، حفظ قابلیت data integrity است. از آنجا که رایدهای سخت افزاری قابلیت data integrity را ندارند، پس از تحویل اطلاعات به کنترلر هارد، تضمینی برای حفظ امنیت اطلاعات نیست، بنابراین توصیه می شود به جای استفاده از راید سخت افزاری، کنترلر بصورت jbod تعریف شده و عملیات راید کردن بصورت نرم افزاری انجام شود. zfs سطوح مختلف راید دارد که راید 1 و راید Z1 تا Z3 از جمله آن هستند. راید Z1 شبیه RAID-5 است

که در آن یک دیسک می تواند fail شود بدون اینکه فایل سیستم از بین برود، Z2 شبیه راید 6 است که در آن دو دیسک می توانند از کار بیافتند بدون اینکه فایل سیستم از بین برود، و در Z3 که می توان آنرا معادل راید 7 دید، تا 3 دیسک می توانند از کار بیافتند بدون اینکه فایل سیستم از بین برود. در ضمن باید توجه داشت که الگوریتم RAID-Z با RAID معمولی متفاوت است و به همین خاطر مشکل write through hole که در راید معمولی باعث از بین رفتن اطلاعات می شود اینجا دیده نمی شود.

scrub به جای fsck

بر خلاف فایل سیستم های معمولی یونیکس و لینوکس که از ابزار fsck استفاده می کنند، zfs از ابزاری به نام scrub برای تشخیص خطاهای فایل سیستم استفاده می کند، که نسبت به fsck دو مزیت زیر را دارد:
fsck نمی تواند روی ولوم های online کار کند، یعنی باید ولوم را offline کرد که به معنی قطع سرویس روی آن ولوم است، اما scrub می تواند روی ولوم های live و در حال سرویس کار کند.

fsck فقط متادیتای فایل را چک می کند، نه دیتای واقعی ذخیره شده در فایل را، به عبارت دیگر ممکن است بعد از پایان fsck هنوز دیتای واقعی خطا داشته باشد، اما اسکراب دیتای واقعی روی دیسک را هم برای وجود خطا چک می کند و اگر خطا داشته باشد، اعلام و اصلاح می کند.
از آنجا که هارددیسک های انترپرایز کمتر دچار خطا می شوند، توصیه می شود که اسکراب روی هارد دیسک های انترپرایز ماهی یکبار و روی هارددیسک های عادی (commodity) حداقل هفته ای یکبار اجرا شود.

storage pools

یکی از مفاهیم جالبی که در طراحی zfs مد نظر قرار گرفته است، مفهوم storage pools است. تمام کسانی که با کامپیوتر آشنا هستند، این را می دانند که هنگامی که به کامپیوتر خود رم اضافه می کنند، نیازی برای اینکه به سیستم عامل بگویند که رم تغییر کرده ندارند و با بوت بعدی کامپیوتر، کامپیوتر از تمام رم موجود (البته به شرط 64 بیتی بودن!) استفاده می کند. بنابراین چرا ما باید در مورد استورج اینهمه سختی به خود بدهیم تا اینکه از قبل تعریف کنیم که چقدر دیسک داریم و آنها کجا قرار دارند؟

این یکی از مفاهیم جالب طراحی در zfs است. در واقع zfs ترکیبی از فایل سیستم و LVM (Logical Volume Manager) است. در zfs هر استورج پول، از ترکیبی از یکسری vdev (virtual device) درست می شود که خود vdev هم از چندین دیسک که به نوعی با هم ترکیب شده اند درست می شود. هر vdev باید redundancy را داخل خود داشته باشد، چون در غیر اینصورت با از کار افتادن آن vdev، کل اطلاعات روی آن هم از دسترس خارج می شود (البته هنوز خود pool در دسترس است، ولی آن بخش از اطلاعات که روی آن vdev بوده است از دسترس خارج می شود). بنابراین خود vdev باید دیسکهای داخلی خود را mirror یا یکی از اقسام raid-z کرده باشد.

دو نکته مهم در اینجا وجود دارد. اول اینکه نمی توان تعداد دیسک های داخل یک vdev را بدون خراب کردن و مجدد ساختن آن تغییر داد. یعنی نمی توان به یک vdev که مثلا 8 دیسک با ترکیب راید z2 دارد، دیسک اضافه کرد. و نکته دوم اینکه همواره هر vdev ظرفیتی برابر مضرب کمترین دیسک داخل آن vdev دارد. یعنی اگر داخل یک vdev هفت تا دیسک یک ترابایت و یک دیسک 500 گیگابایت باشد، مثل این است که داخل آن هشت تا دیسک 500 گیگابایتی باشد! (در مورد بیشتر انواع راید این یک قضیه متداول است). بنابراین باید دیسک های یک vdev را هم ظرفیت انتخاب کرد.
با وجود آنکه می توان به هر zpool هر موقع لازم است vdev های جدید اضافه کرد، معمولا کم کردن vdev به این راحتی نیست.

از دیگر قابلیت های مهم zfs می توان به موارد زیر اشاره کرد:

ARC: که اجازه میدهد کل رم سیستم شبیه یک cache بسیار سریع برای سیستم فایل کار کند.(Adaptive Replacement Cache). این باعث می شود که بخشی از اطلاعات که به مقدار زیاد به آن دسترسی پیدا می شود بسیار سریع سرویس داده شود. بطور طبیعی، خوب کار کردن این قابلیت وابسته به رم سیستم سرور است و اگر به عنوان مثلا سیستم فقط 1 گیگابایت رم داشته باشد، عملا این قابلیت غیر فعال محسوب می شود. در مجموع zfs به شدت به رم وابسته است و در صورت نداشتن رم کافی، پدیده memory starvation یا فقر حافظه در آن دیده می شود و عملکرد سیستم به شدت افت می کند. بصورت عادی توصیه می شود که به ازای هر یک ترابایت فضای zfs، یک گیگابایت رم در نظر گرفته شود. اگر قرار باشد که از قابلیت data deduplication هم استفاده شود به ازای هر ترابایت حداقل 5 گیگابایت باید رم در نظر گرفته شود.

L2ARC: که اجازه می دهد یک مجموعه دیسک SSD بصورت یک کش سطح 2 برای هارد دیسک های عادی کار کند که سرعت را خیلی بالا می برد. (Level 2 ARC). باید توجه داشت که از نظر تئوری، هر چقدر فضای رم سرور بیشتر باشد، سرعت سرویس دهی zfs بالاتر می رود، اما در عمل به علت قیمت بسیار بالای رم و فضای فیزیکی محدود سرور اینکار ممکن نیست، بنابراین گزینه بعدی استفاده از SSD ها است که سرعت کمتر از رم، ولی خیلی بیشتر از هارد دیسک و حجم بیشتر از رم، ولی خیلی کمتر از هارددیسک با قیمت خیلی بالاتر دارند. به همین خاطر از SSD ها به عنوان کش سطح دوم (مثل چیزی که حافظه L2 Cache سی پی یو دارد) استفاده می کنند. علاوه بر این فایل های zil (zfs intent log) باید روی مدیایی نوشته شوند که در عین سرعت بالا، در صورتیکه برق سیستم قطع شد از بین نروند، که در اینجا ssd انتخاب منطقی است.

البته از آنجا که فایل های zil به تناوب بسیار زیادی نوشته و خوانده می شوند، حافظه SSD در این کاربرد به سرعت فرسوده می شود، و انتخاب بهتر، رم دیسک های مجهز به باتری بک آپ (یعنی یک دیسک که در واقع از رم کامپیوتری ساخته شده است، ولی یک باتری بک آپ دارد که اگر برق رفت اطلاعات داخل آن پاک نشود) است.

ZFS قابلیت Data DeDuplication در سطح block دارد. (تشخیص بلاک های مشابه). این باعث می شود که هنگام ذخیره فایل هایی که بخش زیادی از اطلاعات آنها مشابه است، بخش های مشابه ذخیره نشوند و در فضای دیسک صرفه جویی شود. البته در فایل های ویدئویی این قابلیت خیلی کارآیی ندارد.

ZFS قابلیت snapshot دارد. از آنجا که zfs یک فایل سیستم copy on write است، هنگامی که چندین کاربر روی یک فایل کار میکنند، در واقع به ازای هر کدام از آنها یک فایل مجزا تولید نمی شود، بلکه فقط بخش هایی که هر کاربر در حال کار است تغییر می کند. علاوه بر این قابلیت snapshot در zfs بصورت یک ماشین زمان کار می کند. بک آپ گرفتن از کل یک فایل سیستم ممکن است زمان بسیار زیادی ببرد، اما بک آپ گرفتن آن نسبت به تغییرات آن نسبت به قبل می تواند در زمان صفر (یعنی بدون زمان زیاد) و بصورت live انجام شود. در این حالت کاربر می تواند از هر حالت سیستم یک بک آپ بگیرد و فایل سیستم را در زمان به آن حالت برگرداند. snapshot مخصوصا هنگامی که قرار است تغییرات نامعلومی روی فایل سیستم انجام بگیرد که نتیجه آن مشخص نیست مناسب است.

ZFS قابلیت Native Compression مثل Gzip دارد. این باعث می شود در فرمت های فایل که بصورت native کمپرس شده نیستند، هنگام ذخیره شدن روی دیسک صرفه جویی فضایی زیادی انجام شود. البته در فایل های ویدئویی از آنجا که خود فایل قبلا با یک کدک ویدئویی فشرده شده است این مزیت زیادی ایجاد نمی کند.

پیاده سازی های ZFS

همانگونه که در مقدمه گفته شد، zfs ابتدا بصورت بسته در سان سولاریس پیاده سازی شد و بعد از سورس باز شدن سولاریس، zfs هم سورس باز شد. اما بعد از خرید سان توسط اوراکل، اوراکل تا مدتی اقدام به ارائه سولاریس بصورت سورس باز کرد ولی از سولاریس 11 مجدد آنرا بصورت لیسانس بسته و انحصاری در آورد. از اینجا به بعد یک تیم از توسعه دهندگان سورس باز ادامه openSolaris را تحت عنوان پروژه illumos ادامه دادند که پروژه های OpenIndiana و NexentaStor از شاخه های آن هستند.

به همین خاطر، نسخه zfs که در سولاریس 11 به بعد وجود دارد با نسخه zfs سیستم های سورس باز دیگر سازگار نیست. در واقع سولاریس 11.1 از zpool نسخه v34 استفاده می کند، ولی بقیه سورس بازها از نسخه v28 استفاده می کنند و به همین خاطر در صورتی که تصمیم به استفاده از اوراکل سولاریس 11 به بعد گرفته شود باید این نکته را در نظر داشت.

در مورد لینوکس، از آنجا که zfs سورس باز تحت لیسانس CDDL سان است و با لیسانس GPL لینوکس تفاوت زیادی دارد، پیاده سازی zfs در لینوکس به اندازه bsd ها و نسخه های سورس باز سولاریس (منشعب از illomus ) چندان کامل نیست. در حال حاضر یک پیاده سازی از zfs بصورت fuse (یعنی در user space) وجود دارد و کارهایی هم برای پیاده سازی آن بصورت کرنل شروع شده است و در لینوکسی ها بهترین پشتیبانی از zfs را اوبونتو دارد.

در مورد خانواده BSD هم، FreeBSD بهترین پشتیبانی از zfs را دارد که از ورژن 7 آن در آن گنجانده شده است و حتی قابلیت بوت از روی ولوم zfs را هم دارد. اکنون در FreeBSD ورژن 9، نسخه zpool v28 وجود دارد و پروژه های FreeNAS و NAS4Free هم بر پایه همین نسخه FreeBSD هستند.

معایب ZFS

باید در نظر داشت با وجود تمام مزایایی که برای zfs گفته شد، این فایل سیستم خالی از عیب هم نیست، از جمله:
بعد از ساختن یک vdev بصورت راید نمی توان به آن دیسک جدید اضافه کرد، هر چند می توان دیسک های باقی مانده را vdev جدید کرد و جداگانه به zpool اضافه کرد.
بعد از ساخته شدن یا افزایش ظرفیت یک pool، نمی توان vdev های top level آنرا کم کرد، یا اینکه ظرفیت آن pool را کم کرد.
نمی توان چندتا vdev زیر هم داشت.
تغییر تعداد vdev های top level در یک پول ممکن نیتس.

عملیات resilver کردن (یعنی همان repair) کردن بسیار طولانی است، و برای یک مجموعه 5 تا 6 ترابایتی ممکن است چندین روز طول بکشد. علاوه بر این همانند راید 5، فشار مضاعفی که به دیسک ها در طی عملیات rebuild می آید ممکن است باعث از کار افتادن یک دیسک دیگر و از بین رفتن کل آن vdev بشود. به همین خاطر به هیچ عنوان نباید از raid-z1 که معادل راید 5 است استفاده کرد و باید حتما از raid-z2 یا z3 استفاده کرد.

در یک vdev، IOPS مجموع برابر IOPS کمترین دستگاه آن مجموعه است! به همین خاطر هنگام ساختن یک pool نباید یک vdev با مثلا 24 دیسک ساخت، بلکه باید سه تا vdev هشت دیسک ساخت. البته با استفاده از ssd ها می توان این مشکل را بهبود بخشید.
کلا zfs به شدت به رم وابسته است و باید به اندازه کافی رم برای آن در نظر گرفت، در غیر اینصورت performance ممکن است بیش از ده برابر کاهش پیدا کند.

مزایایی که برای ARC و L2ARC توضیح داده شد، بعد از پر شدن کش خودشان را نشان می دهند. به عبارت دیگر بعد از روشن کردن سرور ممکن است یک تا دو روز طول بکشد تا کش سیستم به اندازه کافی پر شود تا قابلیت ARC و L2ARC خودشان را نشان بدهند.

نتیجه گیری

با جمع بندی موارد بالا، باید گفت zfs یک فایل سیستم بسیار مدرن و پیشرفته است، که اگر استفاده کننده بتواند best practice استفاده از آنرا فرابگیرد و پیاده کند، همپای بسیاری از استورج های بسیار گران قیمت تر رقابت کند. zfs می تواند به عنوان یک استورج میانی و با سرعت بالا به عنوان جایگزینی برای دیسک های سن و سرورهای آنها با روش file sharing برای ادیت های غیر خطی کار کند.
البته موارد زیادی در استفاده باقی خواهد ماند، مثلا ما هنوز راه تئوری برای اینکه دو سرور zfs بصورت mirror هم عمل کنند نیافته ایم و مثلا راه حلی که NexentaStor ارائه می دهد نوعی active standby است. در ضمن با وجود اینکه zfs مزایای بسیار زیادی از خود نشان می دهد، اما برای استورج های آرشیوی که حجم بسیاری بالای اطلاعات را باید در خود نگه دارند و برای آنها سرعت در رده دوم اهمیت است چندان مناسب نیست و سیستم های distributed بر مبنای erasure code برای آنها مناسب تر خواهد بود.