پیوست ه
پاسخ پرسشهای مرور
پاسخهای زیر کوتاه و راهنما هستند؛ برای توضیح کامل به بخش «تکمیلی و بهروز» همان فصل برگردید.
فصل ۱: Ceph: آغاز دورانی تازه — معماری، برنامهریزی و نخستین کلاستر#
- ۱. سه محدودیت بنیادی آرایههای ذخیرهسازی سنتی که ذخیرهسازی نرمافزارمحور برطرف میکند کداماند؟
مقیاس عمودی محدود به جفت کنترلر، وابستگی به سختافزار و نرمافزار یک فروشنده، و جزیرههای داده (محصول جدا برای بلوک، فایل و شیء). Ceph با مقیاس افقی روی سرورهای معمولی و ارائهی هر سه رابط روی یک RADOS مشترک آنها را برطرف میکند. - ۲. چرا زمان بازسازی RAID با بزرگتر شدن دیسکها بدتر میشود، اما زمان بازیابی Ceph با بزرگتر شدن کلاستر بهتر میشود؟
بازسازی RAID به سرعت نوشتن یک دیسک یدک محدود است و با بزرگ شدن دیسکها زمانش خطی زیاد میشود. در Ceph دادهی OSD خراب در صدها PG پخش است و همهی OSDهای سالم موازی میخوانند و مینویسند؛ هرچه OSD بیشتری باشد، سهم هر کدام کمتر و ترمیم سریعتر است. - ۳. نقش MON و OSD را در مسیر نوشتن یک شیء مقایسه کنید. آیا داده از MON عبور میکند؟
MON فقط نقشهی کلاستر را به کلاینت میدهد و در اجماع دربارهی تغییر نقشه شرکت میکند. داده از MON عبور نمیکند؛ کلاینت مستقیم به OSD اصلی مینویسد و OSD اصلی تکثیر به ثانویهها را هماهنگ میکند. - ۴. لایهی PG چه مشکلی را حل میکند و اگر وجود نداشت چه میشد؟
PG میلیاردها شیء را در چند هزار گروه تجمیع میکند تا همتاسازی، بازیابی و scrub در سطح گروه انجام شود. بدون آن، OSDها باید وضعیت هر شیء را جداگانه ردیابی میکردند و سربار حافظه و پیامرسانی غیرقابلتحمل میشد. - ۵. چرا تعداد MONها فرد انتخاب میشود؟ چهار MON چند خرابی را تحمل میکنند؟
برای تصمیمگیری اکثریت (quorum) لازم است؛ با عدد فرد، بیشترین تحمل خرابی به ازای کمترین عضو به دست میآید. چهار MON به اکثریت سه نیاز دارند و فقط یک خرابی را تحمل میکنند، یعنی همان سه MON. - ۶. تفاوت
size و min_size چیست و چرا min_size=1 خطرناک است؟
size تعداد نسخههای مطلوب است و min_size کمترین تعداد نسخهی در دسترس برای پذیرش I/O. با min_size=1 ممکن است نوشتنی فقط روی یک OSD تأیید شود و با خرابی همان OSD، دادهی تأییدشده از دست برود. - ۷. چه زمانی شبکهی کلاستر جداگانه مفید است و چه خطری دارد؟
وقتی ترافیک تکثیر و بازیابی آنقدر زیاد است که با ترافیک کلاینت رقابت میکند، جداسازی مفید است. خطرش این است که اگر شبکهی کلاستر جزئی خراب شود، OSDها همدیگر را down گزارش میکنند در حالی که از دید MON زندهاند و flapping رخ میدهد. - ۸. چرا SSD بدون PLP برای Ceph نامناسب است؟
Ceph برای هر نوشتن پایدار flush میکند؛ SSD بدون PLP باید cache را واقعاً روی flash بنویسد و بسیار کند میشود، و در قطع برق ممکن است دادهی تأییدشده را از دست بدهد. - ۹. cephadm در bootstrap چه فایلهایی در
/etc/ceph میسازد و کدامیک حساسترین است؟
ceph.conf حداقلی، ceph.client.admin.keyring و ceph.pub. حساسترین فایل keyring مدیر است که دسترسی کامل به کلاستر میدهد. - ۱۰. دو تغییر پیشفرض Umbrella که میتواند پس از ارتقا رفتار کلاستر را عوض کند کداماند؟
افزایش mon_target_pg_per_osd از ۱۰۰ به ۲۰۰ و mon_max_pg_per_osd از ۲۵۰ به ۵۰۰، که میتواند باعث افزایش PGهای poolها پس از ارتقا شود. (تغییر تنظیمات shard در زمانبند mClock برای HDD هم نمونهی دیگری است.)
فصل ۲: کار با Ceph Block Device (RBD)#
- ۱. یک image صد گیگابایتی تازهساختهشده که هنوز در آن نوشته نشده، چند شیء در RADOS دارد؟ چرا؟
تقریباً هیچ شیء دادهای؛ فقط اشیای فراداده (header، id و ورودی در directory و در صورت فعال بودن object map). RBD thin است و شیء داده فقط پس از نخستین نوشتن در بازهی متناظرش ساخته میشود. - ۲. تفاوت krbd، librbd و rbd-nbd چیست و هر کدام کجا مناسب است؟
krbd راهانداز هسته است و دستگاه /dev/rbdX میسازد؛ سریع و مناسب میزبانهای فیزیکی و Kubernetes، اما ویژگیهایش وابسته به نسخهی هسته است. librbd کتابخانهی کامل فضای کاربر است که QEMU و OpenStack از آن استفاده میکنند. rbd-nbd دستگاه بلوکی هسته را روی librbd میسازد؛ وقتی به ویژگیای نیاز دارید که krbd ندارد. - ۳. چرا ویژگی object-map به exclusive-lock وابسته است؟
object-map وضعیت وجود اشیاء را در حافظهی کلاینت نگه میدارد و فقط وقتی معتبر است که یک کلاینت تنها نویسنده باشد؛ exclusive-lock همین انحصار را تضمین میکند. - ۴. snapshot crash-consistent با application-consistent چه فرقی دارد و چطور دومی را به دست میآوریم؟
crash-consistent مثل قطع برق است: هر چه روی دیسک بود ثبت شده، اما buffer و تراکنشهای نیمهکاره نه. application-consistent با منجمد کردن فایلسیستم (fsfreeze یا guest agent) یا سازوکار خود برنامه (حالت backup پایگاه داده) پیش از snapshot به دست میآید. - ۵. در قالب clone نسخهی ۲ چه چیزی نسبت به نسخهی ۱ عوض شده است؟
در نسخهی ۲ نیازی به snap protect نیست و snapshot والد دارای فرزند را میتوان «حذف» کرد؛ snapshot به trash منتقل میشود تا آخرین فرزند flatten یا حذف شود. نیازمند حداقل کلاینت سازگار Mimic است. - ۶. حالتهای journal و snapshot در mirroring را از نظر RPO، سربار و سازگاری با krbd مقایسه کنید.
journal: RPO چندثانیهای، تقریباً دو برابر نوشتن، فقط librbd. snapshot: RPO برابر فاصلهی زمانبندی، سربار کم، با krbd هم کار میکند. - ۷. تفاوت
--direction rx-only و rx-tx در bootstrap import چیست؟
rx-only یعنی کلاستر محلی فقط دریافتکننده است (یکطرفه). rx-tx یعنی هر دو کلاستر میتوانند مبدأ و مقصد باشند (دوطرفه) و پس از failover نیاز به پیکربندی دوباره نیست. - ۸. چرا promote اجباری بدون fencing خطرناک است؟
اگر سایت اصلی هنوز زنده باشد و کلاینتهایش بنویسند، دو primary با تاریخچهی متفاوت به وجود میآید (split-brain) و یکی از دو مجموعهی تغییرات باید دور ریخته شود. - ۹. گامهای failback پس از بازگشت سایت اصلی کداماند؟
demote image در سایت اصلی، resync آن از primary فعلی، صبر تا وضعیت up+replaying، سپس demote در سایت پشتیبان و promote در سایت اصلی. - ۱۰. برای میزبان VMware که کلاینت Ceph ندارد، امروز کدام راه برای استفاده از RBD توصیه میشود؟
دروازهی NVMe-oF روی TCP با دستکم دو دروازه در یک gateway group برای HA؛ iSCSI در حالت نگهداری است.
فصل ۳: Ceph و OpenStack#
- ۱. سه دلیل اصلی که Ceph را به پشتوانهی محبوب OpenStack تبدیل کرده کداماند؟
یک پشتوانهی واحد برای همهی سرویسها (بلوک، image، backup، فایل و شیء)، copy-on-write سرتاسری که ساخت VM را آنی میکند، و ذخیرهسازی مشترک که live migration و evacuate را بدون انتقال دیسک ممکن میکند؛ بهعلاوهی مقیاس افقی و متنباز بودن. - ۲. چرا
client.cinder روی pool images فقط مجوز خواندن دارد؟
Cinder و Nova فقط باید از snapshot imageها clone بسازند؛ نوشتن یا حذف image وظیفهی Glance است. اصل کمترین دسترسی از imageها در برابر خطا یا نفوذ در cinder محافظت میکند. - ۳. چه دو شرطی برای copy-on-write بین Glance و Cinder لازم است؟
image در Glance با قالب raw ذخیره شده باشد و show_image_direct_url = True باشد تا Cinder نشانی RBD را ببیند؛ و طبعاً هر دو سرویس به همان کلاستر Ceph متصل باشند. - ۴. secret در libvirt چه نقشی دارد و چرا UUID آن باید روی همهی computeها یکسان باشد؟
QEMU کلید Ceph را از libvirt میگیرد و XML دامنه فقط به UUID secret ارجاع میدهد. در live migration همان XML به میزبان مقصد میرود، پس secret با همان UUID باید آنجا هم وجود داشته باشد. - ۵. گزینهی
images_type = rbd در Nova چه چیزی را عوض میکند و چه مزیتی برای evacuate دارد؟
دیسک ریشهی VM بهجای فایل روی دیسک محلی، یک image در pool vms میشود. اگر compute خراب شود، میتوان VM را روی compute دیگری evacuate کرد چون دیسکش روی Ceph سالم است. - ۶.
rbd_flatten_volume_from_snapshot و rbd_max_clone_depth چه مصالحهای را کنترل میکنند؟
سرعت ساخت volume (بدون flatten و با clone عمیق) در برابر وابستگیهای زنجیره و کارایی خواندن. flatten زنجیره را قطع میکند اما زمان و فضای بیشتری میگیرد. - ۷. چرا backup روی همان کلاستر Ceph کافی نیست؟
چون در برابر خرابی یا خطای همان کلاستر (حذف اشتباه، باگ، دسترسی مهاجم به کلید مدیر) محافظتی ندارد. backup باید در کلاستر یا سایت دیگری باشد. - ۸. دو درایور Manila برای CephFS چه تفاوتی دارند؟
درایور بومی کلاینت CephFS را مستقیم در مهمان استفاده میکند (سریع اما نیازمند دسترسی شبکهای مهمان به Ceph)، درایور NFS اشتراکها را از طریق NFS-Ganesha صادر میکند (جداسازی بهتر، یک لایهی اضافه). - ۹.
disk_cachemodes = "network=writeback" چرا امن است؟
چون librbd flushهای مهمان را رعایت میکند و با rbd cache writethrough until flush تا وقتی مهمان flush نفرستاده، cache در حالت writethrough میماند. - ۱۰. چرا بهتر است Ceph را مستقل از ابزار استقرار OpenStack مدیریت کنیم؟
تا چرخهی عمر و ارتقای دو سیستم مستقل باشد، مشکل یکی به دیگری سرایت نکند، و Ceph بتواند همزمان به مصرفکنندگان دیگر (Kubernetes، S3) هم سرویس دهد.
فصل ۴: ذخیرهسازی شیء با RADOS Gateway#
- ۱. چرا RGW را «بدون حالت» مینامیم و این چه اثری بر طراحی دسترسپذیری بالا دارد؟
چون هیچ داده یا وضعیت پایداری در خود فرایند radosgw نگه داشته نمیشود و همهچیز در RADOS است. پس هر تعداد نمونه را میتوان پشت load balancer قرار داد و خرابی یک نمونه فقط درخواستهای در جریانش را تحت تأثیر قرار میدهد. - ۲. یک شیء S3 بیستمگابایتی در RADOS به چه اشیایی تبدیل میشود؟
یک head object (حدود ۴ مگابایت نخست داده بههمراه فراداده و manifest)، چند tail object برای بقیهی داده، و یک ورودی omap در یکی از shardهای index bucket. - ۳. چرا pool index نباید EC یا روی HDD باشد؟
index در omap نگه داشته میشود که EC از آن پشتیبانی نمیکند؛ و هر PUT و DELETE یک بهروزرسانی index است، پس تأخیر HDD مستقیماً تأخیر همهی عملیات میشود. - ۴. resharding پویا چه مشکلی را حل میکند و آستانهی پیشفرض آن چیست؟
از بزرگ شدن بیش از حد shardهای index (اشیای omap غولپیکر) جلوگیری میکند؛ با رسیدن تعداد اشیاء هر shard به rgw_max_objs_per_shard (پیشفرض ۱۰۰٬۰۰۰) shardها خودکار افزایش مییابند. - ۵. تفاوت tenant و account چیست؟
tenant یک فضای نام برای bucketها و کاربران است؛ account (از Squid) یک واحد مالکیت به سبک AWS است که کاربر ریشهاش کاربران، گروهها، نقشها و سیاستها را با API IAM خودش مدیریت میکند. - ۶. برای دسترسی virtual-hosted-style چه پیکربندیهایی لازم است؟
رکورد DNS wildcard برای دامنه، تنظیم rgw_dns_name (یا hostnames در zonegroup) و گواهی TLS wildcard. - ۷. دو حالت GOVERNANCE و COMPLIANCE در object lock چه فرقی دارند؟
در GOVERNANCE کاربر دارای مجوز bypass میتواند قفل را دور بزند؛ در COMPLIANCE هیچ کاربر S3ای تا پایان مهلت نمیتواند نسخه را حذف یا مدت را کوتاه کند. - ۸. چرا پس از حذف انبوه اشیاء، فضای کلاستر فوراً آزاد نمیشود؟
فقط head object فوراً حذف میشود؛ tailها به garbage collector سپرده میشوند و پس از rgw_gc_obj_min_wait پاک میشوند. - ۹. گزینهی
rgw_s3_auth_use_keystone چه امکانی فراهم میکند؟
اجازه میدهد کلاینت S3 با اعتبارنامههای EC2 که در Keystone ساخته شدهاند احراز هویت شود و RGW آنها را نزد Keystone اعتبارسنجی کند. - ۱۰. چرا S3A committers برای Spark روی RGW مهماند؟
چون commit سنتی Hadoop با rename کار میکند که در S3 یعنی کپی و حذف همهی اشیاء؛ committerهای S3A با multipart upload که فقط در commit نهایی تکمیل میشود، این هزینه را حذف میکنند و خروجی را امن و سریع مینویسند.
فصل ۵: ذخیرهسازی شیء چندسایتی با RGW Multi-Site#
- ۱. تفاوت نقش zonegroup و realm در تکثیر داده و فراداده چیست؟
zonegroup مرز تکثیر داده است: دادهی bucketها فقط بین zoneهای یک zonegroup تکثیر میشود. realm مرز فضای نام و فراداده است: کاربران و bucketها در کل realm یکتا و همگاماند. - ۲. period چیست و چرا پس از تغییرات ساختاری باید commit شود؟
period نسخهی نامدار و epochدار پیکربندی realm است. commit آن، پیکربندی جدید را به همهی zoneها منتشر میکند تا همه دربارهی ساختار و master توافق داشته باشند. - ۳. سه تفاوت اصلی multisite نسخهی ۲ با پیکربندی federated در Hammer کداماند؟
همگامسازی درون radosgw بهجای radosgw-agent بیرونی؛ active-active بهجای slave فقطخواندنی؛ و مفهوم realm و period برای پیکربندی نسخهدار و failover. - ۴. چرا ساخت bucket در zone غیر master هنگام از دست رفتن master شکست میخورد اما نوشتن شیء نه؟
ساخت bucket عملیات فرادادهای است که باید در master zone ثبت شود و درخواست به master forward میشود؛ نوشتن شیء در bucket موجود محلی است و بعداً همگام میشود. - ۵. کاربر system چه نقشی دارد و چرا باید بهشدت حفاظت شود؟
zoneها با کلید آن لاگها و اشیای همدیگر را میخوانند؛ دسترسی کامل به داده و فرادادهی realm دارد، پس افشای آن یعنی افشای کل داده. - ۶. در خروجی
sync status عبارت «oldest incremental change not applied» چه اطلاعاتی میدهد؟
زمان قدیمیترین تغییری که هنوز در این zone اعمال نشده؛ تفاوت آن با زمان فعلی برآورد RPO واقعی است. - ۷. گامهای failover و بازگرداندن master قدیمی را بنویسید.
failover: در zone سالم zone modify --master --default، period update --commit و راهاندازی دوبارهی RGW، سپس تغییر DNS. بازگشت: در zone قدیمی realm pull و period pull، بررسی caught up بودن، و در صورت تمایل master کردن دوبارهی آن با commit period. - ۸. تفاوت وضعیتهای enabled، allowed و forbidden در sync policy چیست؟
enabled یعنی همگامسازی انجام میشود؛ allowed یعنی مجاز است اما سطح پایینتر باید فعالش کند؛ forbidden یعنی ممنوع است و سطح پایینتر هم نمیتواند فعالش کند. - ۹. archive zone چه مشکلی را حل میکند؟
حفاظت در برابر حذف یا بازنویسی تصادفی و مخرب با نگهداری همهی نسخهها در یک zone جداگانه، بدون نیاز به versioning در zoneهای کاربر. - ۱۰. چرا resharding پیش از Reef در multisite مشکلساز بود و امروز چطور حل شده است؟
reshard تعداد و چیدمان shardهای index را عوض میکرد و همگامسازی که بر پایهی bilog هر shard است مختل میشد؛ از Reef با zone feature به نام resharding هر zone مستقل reshard میکند بدون قطع تکثیر.
فصل ۶: سامانهی فایل Ceph (CephFS)#
- ۱. چرا MDS در مسیر دادهی فایلها قرار ندارد و این چه مزیتی دارد؟
MDS فقط فراداده را مدیریت میکند و پس از دادن capability، کلاینت داده را مستقیم با OSDها رد و بدل میکند؛ بنابراین پهنای باند داده با تعداد OSDها مقیاس میپذیرد و MDS گلوگاه نمیشود. - ۲. capability چیست و چه زمانی MDS یک کلاینت را evict میکند؟
capability مجوزی است که MDS روی هر inode به کلاینت میدهد (خواندن، نوشتن، cache، buffer) و در صورت نیاز پس میگیرد. اگر کلاینت در مهلت مقرر پاسخ ندهد یا session آن منقضی شود، MDS آن را evict و در blocklist میگذارد. - ۳. تفاوت standby و standby-replay چیست؟
standby بیکار است و هنگام جایگزینی باید کل journal را بازپخش کند؛ standby-replay journal یک rank مشخص را دائماً دنبال میکند و cache گرم دارد، پس failover سریعتر است. - ۴. چرا pool دادهی پیشفرض CephFS نباید EC باشد؟
چون فرادادهی backtrace همهی فایلها در pool دادهی پیشفرض نوشته میشود و این عملیات کوچک روی EC ناکارآمد است؛ pool EC را بهعنوان pool دوم اضافه و با layout استفاده کنید. - ۵. چه زمانی چند MDS فعال لازم است و چرا pinning صریح توصیه میشود؟
وقتی بار فراداده (تعداد فایل، کلاینت یا عملیات در ثانیه) از توان یک MDS بیشتر شود. balancer خودکار سابقهی جابهجاییهای ناپایدار دارد و pinning صریح رفتار قابل پیشبینی میدهد. - ۶. کلاینت هسته و ceph-fuse را از نظر کارایی و بهروز بودن مقایسه کنید.
کلاینت هسته سریعتر است ولی به نسخهی هسته وابسته است؛ ceph-fuse کندتر ولی همنسخه با Ceph، سادهتر برای اشکالزدایی و با خطای محدود به یک فرایند. - ۷. چرا NFS-Ganesha پیکربندی exportها را در RADOS نگه میدارد؟
تا همهی daemonهای Ganesha پیکربندی یکسان و متمرکز داشته باشند و افزودن یا جابهجایی daemon نیاز به همگامسازی فایل نداشته باشد. - ۸. چرا quota در CephFS «همکارانه» نامیده میشود؟
چون خود کلاینت مصرف را دنبال و نوشتن را متوقف میکند؛ ممکن است با تأخیر کمی بیش از سقف بنویسد و کلاینت مخرب میتواند آن را نادیده بگیرد. - ۹. چرا تغییر layout یک پوشه فایلهای موجود را جابهجا نمیکند؟
layout هنگام ساخت فایل روی آن ثبت میشود و جای اشیای موجود را تغییر نمیدهد؛ rename هم فقط فراداده را عوض میکند. برای انتقال باید فایل را کپی کرد. - ۱۰. امروز جایگزین معمول «Hadoop روی CephFS» چیست؟
اجرای Spark، Trino یا Hive روی RGW از طریق رابط S3A؛ برای بارهای POSIX، mount مستقیم CephFS.
فصل ۷: راهبری و مدیریت کلاستر Ceph#
- ۱. چرا توقف daemon با systemctl در cephadm توصیه نمیشود؟
چون orchestrator از توقف خبر ندارد و ممکن است daemon را دوباره راه بیندازد یا گزارش خطا بدهد؛ برای کارهای برنامهریزیشده باید از ceph orch یا حالت نگهداری استفاده کرد. - ۲. ترتیب اولویت منابع پیکربندی چیست و مقدار مؤثر را چطور میبینید؟
از کم به زیاد: پیشفرض کامپایلشده، پایگاه پیکربندی MON، ceph.conf محلی، آرگومان خط فرمان و تغییر زمان اجرا. مقدار مؤثر با ceph config show <daemon> دیده میشود. - ۳. تفاوت
ceph tell و ceph daemon چیست؟
ceph tell از طریق شبکه و MON/مسیر پیامرسانی به daemon میرسد؛ ceph daemon از admin socket محلی و فقط روی میزبان همان daemon استفاده میکند. - ۴. مزایا و معایب scale-up و scale-out را از نظر دامنهی خرابی مقایسه کنید.
scale-up هزینهی هر ترابایت را کم میکند اما دامنهی خرابی و حجم بازیابی بزرگتری دارد؛ scale-out دامنهی خرابی کوچکتر و کارایی خطیتر دارد اما فضای رک و شبکهی بیشتری میخواهد. - ۵. چرا هنگام افزودن تعداد زیادی OSD، پرچمهای norebalance و nobackfill مفیدند؟
تا PGها یک بار و پس از ساخته شدن همهی OSDها جابهجا شوند، نه پس از هر OSD. - ۶. تفاوت
ok-to-stop و safe-to-destroy چیست؟
ok-to-stop میپرسد آیا توقف موقت باعث از دسترس رفتن PG میشود؛ safe-to-destroy میپرسد آیا حذف دائمی بدون از دست رفتن داده ممکن است. - ۷. گزینهی
--replace در حذف OSD چه مزیتی دارد؟
id و جایگاه OSD در CRUSH حفظ میشود و OSD تازه با همان id ساخته میشود؛ تغییر نقشه و جابهجایی داده کمتر است. - ۸. حالت نگهداری cephadm چه کاری انجام میدهد؟
همهی daemonهای میزبان را متوقف میکند و noout را برای همان میزبان تنظیم میکند تا بازیابی بیمورد شروع نشود. - ۹. چرا در mClock تنظیم مستقیم
osd_max_backfills اثر ندارد و راه درست چیست؟
چون mClock این تنظیمات را خودش مدیریت میکند؛ راه درست تغییر osd_mclock_profile است، یا در صورت نیاز فعال کردن osd_mclock_override_recovery_settings. - ۱۰. ارتقای OSD به ترتیب bucketهای CRUSH در Umbrella چه ریسکی را کاهش میدهد؟
ارتقای همزمان OSDهایی را که نسخههای یک PG را نگه میدارند محدود میکند و با ok-to-upgrade مطمئن میشود دسترسپذیری داده حفظ میشود.
فصل ۸: Ceph از درون: CRUSH، نقشهها، احراز هویت و PGها#
- ۱. دو مرحلهی نگاشت شیء به OSD کداماند و چرا PG لازم است؟
شیء با hash نامش به یک PG نگاشت میشود و CRUSH آن PG را به مجموعهای از OSDها نگاشت میکند. PG لازم است چون پیگیری وضعیت تکثیر، بازیابی و scrub برای هر شیء جداگانه در مقیاس میلیاردی ممکن نیست. - ۲. تفاوت up set و acting set چیست؟
up set خروجی خالص CRUSH است؛ acting set مجموعهای است که واقعاً I/O را سرویس میدهد و ممکن است به دلیل pg_temp یا upmap با up set فرق کند. - ۳. مزیت straw2 نسبت به الگوریتمهای قبلی چیست؟
با تغییر وزن یک آیتم، داده فقط بین همان آیتم و بقیه جابهجا میشود و جابهجاییهای بیمورد بین آیتمهای دیگر رخ نمیدهد. - ۴. چرا تغییر tunableها باعث جابهجایی داده میشود و پیش از آن چه چیزی را باید بررسی کرد؟
چون نتیجهی محاسبهی CRUSH برای بسیاری از PGها تغییر میکند. پیش از آن باید سازگاری همهی کلاینتها (ceph features) و ظرفیت کلاستر برای جابهجایی را بررسی کرد. - ۵. چرا چهار MON از سه MON تحمل خرابی بیشتری ندارد؟
چون اکثریت چهار MON سه است و فقط یک خرابی تحمل میشود، همانند سه MON. - ۶. OSDها نقشهی جدید را از کجا دریافت میکنند؟
از MON یا از همتایانشان (OSDها و کلاینتها) که در پیامها epoch جدیدتر را منتشر میکنند. - ۷. چرا cephx از ticket استفاده میکند؟
تا OSDها بدون مراجعه به MON برای هر درخواست، اعتبار کلاینت را بررسی کنند و MON گلوگاه نشود؛ کلید مخفی هم روی شبکه ارسال نمیشود. - ۸. چرا تأخیر نوشتن به کندترین OSD acting set بستگی دارد؟
چون primary فقط پس از commit همهی نسخهها ack میدهد. - ۹. حالتهای incomplete و inconsistent چه تفاوتی دارند؟
incomplete یعنی نسخهی معتبر کافی برای فعال شدن PG نیست و I/O متوقف است؛ inconsistent یعنی PG فعال است اما scrub بین نسخهها ناسازگاری پیدا کرده است. - ۱۰. راه توصیهشده برای قرار دادن یک pool روی OSDهای خاص چیست؟
تعریف کلاس دستگاه (پیشفرض یا دلخواه)، ساختن قانون CRUSH با آن کلاس و اختصاص قانون به pool.
فصل ۹: از VSM تا Ceph Dashboard: مدیریت گرافیکی کلاستر#
- ۱. چرا VSM امروز گزینهی مناسبی نیست؟
مخزن آن آرشیو شده، آخرین نسخهاش ۲۰۱۶ است، فقط با نسخههای قدیمی Ceph کار میکرد و هیچ نگهداری یا بهروزرسانی امنیتی ندارد. - ۲. کدام ایدههای VSM در Ceph امروزی ادامه یافتهاند و به چه شکلی؟
گروههای ذخیرهسازی به کلاس دستگاه و قانونهای CRUSH، manifest سختافزار به specهای cephadm و رابط وب به Ceph Dashboard تبدیل شدند. - ۳. چرا Dashboard فقط روی MGR فعال سرویس میدهد و این چه پیامدی دارد؟
چون یک ماژول MGR است و فقط ماژولهای MGR فعال اجرا میشوند؛ با جابهجایی MGR آدرس تغییر میکند، مگر اینکه از redirect، load balancer یا mgmt-gateway استفاده شود. - ۴. نقش orchestrator در Dashboard چیست؟
Dashboard عملیات استقرار (میزبان، OSD، سرویس) را از طریق orchestrator (cephadm یا Rook) انجام میدهد؛ بدون آن این بخشها فقطخواندنیاند. - ۵. چرا رمز عبور را با
-i از فایل میخوانیم؟
تا رمز در تاریخچهی shell و فهرست فرایندها دیده نشود. - ۶. تفاوت نقش و scope در RBAC Dashboard چیست؟
scope حوزهای از منابع (مثل pool یا rbd-image) است و نقش مجموعهای از مجوزها (read، create، update، delete) روی چند scope. - ۷. چرا SSO به تنهایی برای دسترسی کافی نیست؟
چون SSO فقط هویت را تأیید میکند؛ کاربر باید در Dashboard تعریف شده باشد تا نقش و مجوزش مشخص شود. - ۸. mgmt-gateway چه مشکلی را حل میکند؟
نقطهی ورود واحد با TLS برای Dashboard و ابزارهای پایش فراهم میکند و وابستگی آدرس به MGR فعال را حذف میکند؛ با oauth2-proxy احراز هویت متمرکز هم ممکن میشود. - ۹. پس از حذف ماژول restful، چه جایگزینی برای خودکارسازی وجود دارد؟
REST API نسخهدار Dashboard برای عملیات، و Prometheus برای متریکها. - ۱۰. چرا نباید پایش اصلی کلاستر فقط به Dashboard وابسته باشد؟
چون Dashboard به MGR و MONها وابسته است و در بحرانهای جدی اولین چیزی است که از دسترس خارج میشود؛ پایش و هشدار باید مسیر مستقل داشته باشند.
فصل ۱۰: سنجش کارایی و ابزارهای کارشناسی Ceph#
- ۱. چرا سنجش کارایی باید لایهبهلایه انجام شود؟
چون بدون دانستن سقف لایههای پایین (دیسک و شبکه) نمیتوان فهمید کمبود کارایی در کدام لایه ایجاد شده است. - ۲. چرا fio برای سنجش دیسک بر dd ترجیح دارد؟
fio عمق صف، الگوی تصادفی/ترتیبی، direct I/O و sync را کنترل میکند و صدکهای تأخیر را گزارش میدهد؛ dd فقط یک الگوی ترتیبی ساده را میسنجد. - ۳. چرا آزمایش نوشتن sync با عمق صف ۱ برای انتخاب SSD مهم است؟
چون WAL و DB در BlueStore با نوشتنهای کوچک sync کار میکنند و SSDهای بدون حفاظت در برابر قطع برق در این الگو بسیار کندند. - ۴. MTU ناهماهنگ چه علائمی در Ceph ایجاد میکند؟
heartbeatهای کوچک رد میشوند و OSDها up به نظر میرسند، ولی پیامهای بزرگ گم میشوند و عملیات کند یا معلق میشوند. - ۵. در مثال سقف نظری، چرا شبکه گلوگاه شد؟
چون هر بایت ورودی باید دو بار دیگر روی شبکه به OSDهای ثانویه برود و پهنای باند شبکهی هر گره از توان مجموع دیسکهایش بسیار کمتر بود. - ۶. تفاوت
ceph tell osd.N bench و rados bench چیست؟
ceph tell osd.N bench فقط BlueStore یک OSD را بدون شبکه و تکثیر میسنجد؛ rados bench مسیر کامل RADOS شامل شبکه و تکثیر را روی یک pool میسنجد. - ۷. چرا باید image RBD را پیش از سنجش نوشتن تصادفی پر کرد؟
چون اولین نوشتن روی هر بخش، شیء RADOS تازه میسازد و کندتر از بازنویسی است؛ بدون پر کردن، نتیجه ترکیبی و گمراهکننده است. - ۸. تفاوت admin socket و
ceph tell چیست و هر کدام چه زمانی مفیدترند؟
admin socket محلی است و بدون شبکه یا MON کار میکند (مفید وقتی daemon به پیامهای شبکه پاسخ نمیدهد)؛ ceph tell از هر جای کلاستر در دسترس است. - ۹. در خروجی
heap stats، حافظهی freelist چه معنایی دارد؟
حافظهای است که برنامه آزاد کرده اما tcmalloc هنوز به سیستمعامل برنگردانده؛ heap release آن را برمیگرداند. - ۱۰. پیش از استفاده از
ceph-objectstore-tool چه اقدامهایی لازم است؟
توقف OSD، گرفتن export پشتیبان از PG، استفاده از dry-run در صورت امکان و اطمینان از شکست روالهای عادی بازیابی.
فصل ۱۱: استقرار Ceph: آزمایشگاه، cephadm، Ansible و Rook#
- ۱. چرا ceph-deploy دیگر گزینهی مناسبی نیست؟
مخزن آن آرشیو شده و با نسخههای جدید Ceph و مدل کانتینری کار نمیکند. - ۲. تفاوت فلسفی ceph-ansible و cephadm چیست؟
ceph-ansible دستوری است و فقط هنگام اجرای playbook وضعیت را اصلاح میکند؛ cephadm اعلانی و پیوسته است و وضعیت مطلوب را درون کلاستر نگه میدارد و مدام با وضعیت واقعی تطبیق میدهد. - ۳. چرا برای آزمایشگاه Umbrella باید مدل CPU مجازی را بررسی کرد؟
چون imageهای Umbrella به CPU با سطح x86-64-v3 نیاز دارند و مدلهای CPU مجازی عمومی ممکن است آن را اعلام نکنند. - ۴. گزینهی
--single-host-defaults چه کاری میکند و محدودیت کلاستر تکگره چیست؟
تنظیماتی مناسب یک میزبان (مثلاً دامنهی خرابی OSD) اعمال میکند؛ کلاستر تکگره در برابر خرابی میزبان هیچ حفاظتی ندارد و برای تمرین خرابی مناسب نیست. - ۵. چرا
--dry-run پیش از اعمال spec OSD مهم است؟
چون نشان میدهد کدام OSDها روی کدام دیسکها ساخته میشوند و از OSD شدن ناخواستهی دیسکها جلوگیری میکند. - ۶. چرا فیلتر
rotational در محیط مجازی ممکن است گمراهکننده باشد؟
چون دیسکهای مجازی ممکن است خود را چرخان یا غیرچرخان معرفی کنند بیارتباط با سختافزار واقعی. - ۷. تقسیم کار پیشنهادی بین Ansible و cephadm چیست؟
Ansible برای سیستمعامل، بستهها، شبکه، زمان و کلیدها؛ cephadm برای همهی daemonها، specها و ارتقای Ceph. - ۸. مسیر مهاجرت از ceph-ansible به cephadm چیست؟
استفاده از cephadm adopt (یا playbook cephadm-adopt.yml) برای تحویل گرفتن daemonها یکییکی، پس از تمرین در آزمایشگاه و با کلاستر سالم. - ۹. ریسک اجرای Ceph درون همان کلاستر Kubernetes برنامهها چیست و راه کاهش آن کدام است؟
وابستگی چرخهای بین Kubernetes و ذخیرهسازی؛ با جدا کردن گرههای ذخیرهسازی یا استقرار Ceph بیرون از Kubernetes و حالت external cluster کاهش مییابد. - ۱۰. تشخیص drift چه فایدهای دارد؟
تغییرات دستی یا خودکار ثبتنشده را آشکار میکند تا یا به Git برگردند یا اصلاح شوند.
فصل ۱۲: BlueStore: موتور ذخیرهسازی OSD#
- ۱. سه محدودیت اصلی FileStore کدام بودند؟
نوشتن دوباره به دلیل journal جدا، لایههای اضافهی فایلسیستم POSIX با رفتار غیرقابل پیشبینی، و نبود checksum سرتاسری (بهعلاوهی فهرستگیری کند). - ۲. چرا BlueStore برای نوشتنهای بزرگ نیازی به journal جدا ندارد؟
چون داده را در فضای تازه مینویسد و فقط پس از commit فراداده در RocksDB به آن اشاره میکند؛ نسخهی قبلی تا آن لحظه دستنخورده است. - ۳. BlueFS چیست و چرا Ceph از XFS برای RocksDB استفاده نمیکند؟
یک فایلسیستم کوچک مخصوص فایلهای RocksDB که روی دستگاه خام کار میکند و سربار و پیچیدگی یک فایلسیستم عمومی را ندارد. - ۴. سرریز BlueFS چیست و چه اثری دارد؟
وقتی block.db پر شود، فایلهای RocksDB روی دستگاه کند block نوشته میشوند و کارایی فراداده افت میکند؛ هشدار BLUEFS_SPILLOVER. - ۵. شرط deferred شدن یک نوشتن در
_defer_or_allocate چیست؟
اندازهی لازم از فضای آزادشده توسط همان نوشتن بیشتر نباشد و این فضا از prefer_deferred_size کوچکتر باشد. - ۶. چرا ack به کلاینت پس از KV_DONE ایمن است؟
چون دادهی deferred همراه رکورد L در WAL RocksDB پایدار شده و هنگام mount با _deferred_replay دوباره اعمال میشود. - ۷. سه نسل omap در فضای کلید BlueStore کداماند و چرا per-PG بهتر است؟
M (مشترک)، m (per-pool) و p (per-PG)؛ per-PG حذف و انتقال PG را با بازهی پیوستهی کلیدها ممکن و آمار را دقیق میکند. - ۸. چرا min_alloc_size از ۶۴ کیلوبایت به ۴ کیلوبایت کاهش یافت؟
برای کاهش هدررفت فضا با اشیای کوچک، بهویژه در RGW. - ۹. HybridAllocator چه مصالحهای بین AVL و bitmap برقرار میکند؟
AVL جستوجوی سریع بازههای آزاد دارد اما حافظهاش با تکهتکگی رشد میکند؛ پس از سقف حافظه، بازهها به bitmap با حافظهی ثابت سرریز میشوند. - ۱۰. خرابی یک NVMe پشتیبان db چه اثری بر کلاستر دارد؟
همهی OSDهایی که db آنها روی آن NVMe است همزمان از دست میروند و بازیابی گسترده آغاز میشود.
فصل ۱۳: کدگذاری پاکشونده (Erasure Coding) برای بهرهوری ذخیرهسازی#
- ۱. سربار و تحمل خرابی EC 8+3 در مقایسه با تکثیر سهتایی چیست؟
سربار ۱.۳۷۵ برابر در برابر ۳ برابر، با تحمل سه خرابی در برابر دو خرابی؛ اما دستکم یازده دامنهی خرابی لازم است. - ۲. چرا هر زیرماتریس k×k ماتریس مولد باید وارونپذیر باشد؟
چون هر k shard در دسترس باید برای بازسازی کافی باشد و این فقط وقتی ممکن است که زیرماتریس متناظر معکوس داشته باشد. - ۳. تفاوت shard در EC و نسخه در تکثیر چیست؟
هر shard فقط قطعهی i از هر stripe را نگه میدارد و جایگاهش معنا دارد؛ در تکثیر هر نسخه کل شیء را دارد و قابل جابهجایی است. - ۴. چرا نوشتن کوچک در EC قدیمی پرهزینه بود؟
چون بازنویسی بخشی از stripe نیازمند خواندن بقیهی stripe، encode دوباره و نوشتن همهی shardها بود. - ۵. parity delta بر چه ویژگی ریاضی تکیه دارد؟
خطی بودن کد روی میدان گالوا: parity جدید برابر parity قدیم بهعلاوهی ضریب ضربدر تفاوت دادهی قدیم و جدید است. - ۶. محدودیتهای فعالسازی FastEC کداماند؟
همهی MON و OSDها Tentacle+، فقط ISA-L یا Jerasure reed_sol_van، stripe_unit مضرب ۴K، و غیرقابل خاموش شدن پس از فعالسازی. - ۷. چرا پرچم allow_ec_optimizations برگشتپذیر نیست؟
چون قالب ذخیرهی دادهی جدید را تغییر میدهد و پیادهسازی قدیمی (ECBackendL) نمیتواند آن را بخواند. - ۸. CLAY و LRC چطور ترافیک بازیابی را کاهش میدهند؟
LRC با parity محلی، بازسازی را به گروه کوچکی محدود میکند؛ CLAY با sub-chunkها فقط بخشی از دادهی کمککنندهها را میخواند. - ۹. عدد ۲۱۴۷۴۸۳۶۴۷ در نگاشت PG چه معنایی دارد و علتهای رایج آن کداماند؟
همان CRUSH_ITEM_NONE است: CRUSH برای آن جایگاه shard OSD پیدا نکرده؛ علتها: دامنهی خرابی ناکافی، OSDهای out، قانون نادرست یا تلاش ناکافی CRUSH. - ۱۰. چرا در pool بهینه، primary همیشه shard 0 نیست؟
چون در نوشتن جزئی برخی shardهای داده بهروز نمیشوند و نمیتوانند log کامل PG را داشته باشند؛ pgtemp_primaryfirst shardهای مجاز را جلو میآورد.
فصل ۱۴: برنامهنویسی با librados#
- ۱. سه بخش مستقل یک شیء RADOS کداماند؟
داده (بایتها با offset)، xattrها و omap (کلید-مقدار مرتب). - ۲. namespace چه فرقی با pool دارد و چه زمانی مفید است؟
namespace زیرفضای نام درون یک pool است و قانون CRUSH و PG جدا ندارد؛ برای جداسازی مستأجران بدون ساختن pool جدید و با capability محدود به namespace مفید است. - ۳. چرا omap در pool EC پشتیبانی نمیشود و چه پیامدی برای طراحی دارد؟
چون پیادهسازی EC روی shardها برای داده طراحی شده و omap کلید-مقدار را پوشش نمیدهد؛ فراداده و شاخصها باید در pool تکثیری باشند. - ۴. عملیات مرکب چه تضمینی میدهد و چه تضمینی نمیدهد؟
اجرای اتمی همهی عملیات روی یک شیء (همه یا هیچ)؛ تراکنش بین چند شیء را تضمین نمیکند. - ۵. assert_version در چه حالتهایی ERANGE و EOVERFLOW برمیگرداند؟
ERANGE وقتی نسخهی دادهشده کمتر از نسخهی فعلی شیء است (کهنه)؛ EOVERFLOW وقتی بیشتر است. - ۶. چرا قفل مشورتی به تنهایی برای ایمنی کافی نیست؟
چون فقط کلاینتهای همکار آن را رعایت میکنند و کلاینت کند ممکن است بیخبر از انقضای قفل ادامه دهد؛ باید با guard یا blocklist ترکیب شود. - ۷. watch در Objecter چگونه پس از تغییر نقشه حفظ میشود؟
بهصورت عملیات linger که Objecter با هر نقشهی جدید یا قطع اتصال، هدفش را دوباره محاسبه و به primary جدید ارسال میکند. - ۸. چرا بازارسال Op پس از تغییر نقشه ایمن است؟
چون هر Op شناسهی یکتا دارد و OSD درخواستهای تکراری را از روی log PG تشخیص میدهد و دوباره اجرا نمیکند. - ۹. چه زمانی باید rados_osd_op_timeout را تنظیم کرد؟
وقتی برنامه باید در زمان محدود پاسخ یا خطا بدهد، چون پیشفرض بدون timeout است و Op تا active شدن PG منتظر میماند. - ۱۰. برای ذخیرهی دادهی چندگیگابایتی روی RADOS چه الگویی مناسب است؟
شکستن داده به اشیای چندمگابایتی (striping)، مثلاً با libradosstriper، همانند RBD و CephFS.
فصل ۱۵: کلاسهای RADOS: محاسبه در کنار داده#
- ۱. سه مزیت اصلی اجرای منطق در کلاس به جای کلاینت چیست؟
کاهش رفتوبرگشت شبکه، اجرای اتمی درون تراکنش PG، و کاهش انتقال داده با پردازش کنار داده. - ۲. چرا متد کلاس نمیتواند شیء دیگری را تغییر دهد؟
چون شیء دیگر ممکن است در PG و OSD دیگری باشد و متد فقط در بافت تراکنش همان شیء اجرا میشود. - ۳. تفاوت osd_class_load_list و osd_class_default_list چیست؟
load_list تعیین میکند کدام کلاسها اصلاً بارگذاری شوند؛ default_list تعیین میکند کدامها با capهای عمومی (x، class-read، class-write) مجازند. - ۴. اگر متدی بدون پرچم WR بنویسد چه رخ میدهد و چرا؟
OSD پس از اجرا شمارندهی num_write را بررسی میکند و -EIO برمیگرداند، چون عملیات نوشتنی باید بهعنوان نوشتن پردازش، ثبت و تکثیر شود. - ۵. cap «allow class numops add» دقیقاً چه چیزی را مجاز میکند؟
فقط فراخوانی متد add از کلاس numops (با محدودهی match مشخصشده، مثلاً pool). - ۶. چرا cls_lua بهصورت پیشفرض بارگذاری نمیشود؟
چون اجرای کد دلخواه درون OSD را ممکن میکند و بدون sandbox یا timeout میتواند PG را مسدود کند. - ۷. در cephadm چگونه کلاس سفارشی را مستقر میکنید؟
با ساخت image سفارشی بر پایهی image رسمی همنسخه که libcls_*.so را در osd_class_dir دارد، و ارتقا یا تنظیم container_image به آن، سپس افزودن کلاس به فهرستها. - ۸. چه تغییری در رابط ثبت متدها در Umbrella رخ داد؟
ثبت از cls_register_cxx_method با پرچم صریح به ClassRegistrar و ClsMethod نوعدار با Tagهای RD/WR/PROMOTE تغییر کرد. - ۹. متد کند چه اثری بر سایر عملیات PG دارد؟
چون زیر قفل PG در thread پردازش اجرا میشود، سایر عملیات همان PG منتظر میمانند و slow ops ایجاد میشود. - ۱۰. librbd و RGW از کدام کلاسها استفاده میکنند؟
librbd از cls_rbd (و cls_lock، cls_journal)؛ RGW از cls_rgw، cls_rgw_gc، cls_2pc_queue، cls_fifo، cls_version، cls_refcount و cls_log.
فصل ۱۶: لایهبندی ذخیرهسازی: از Cache Tiering تا Device Class و Storage Class#
- ۱. وضعیت رسمی cache tiering در نسخههای جاری چیست؟
از Reef منسوخ شده، نگهدارنده ندارد و ممکن است بدون اطلاع حذف شود؛ نباید tier جدید ساخت و موارد موجود باید مهاجرت کنند. - ۲. overlay چگونه درخواست کلاینت را به pool کش میبرد؟
set-overlay فیلدهای read_tier و write_tier pool پایه را در OSDMap به pool کش اشاره میدهد و Objecter درخواست را به آن pool میفرستد. - ۳. HitSet نوع bloom چه مزیتی دارد و min_read_recency_for_promote چه میکند؟
حافظهی کم با خطای مثبت کنترلشده؛ min_read_recency_for_promote تعداد HitSetهای اخیری است که شیء باید در آنها دیده شده باشد تا روی خواندن promote شود (۰ یعنی همیشه). - ۴. چرا cache tiering برای بیشتر بارهای RBD کارایی را کاهش میداد؟
چون دسترسیها پراکندهاند و هر promote و evict هزینهی خواندن و نوشتن اضافه دارد؛ کش گرم نمیشود و I/O بیشتر میشود. - ۵. عامل کش چگونه هدف کل pool را به سهم هر PG تبدیل میکند؟
با تقسیم هدف بر get_pg_num_divisor که تعداد PGها را با در نظر گرفتن تقسیم ناتمام برمیگرداند. - ۶. نقش osd_agent_slop چیست؟
هیسترزیس: آستانهی ورود به حالت بالاتر و آستانهی خروج پایینتر از هدف تا از نوسان بین حالتها جلوگیری شود (پیشفرض ۰.۰۲). - ۷. evict در حالت SOME چگونه قربانی را انتخاب میکند؟
دمای شیء از HitSetهای وزندار تخمین زده و در هیستوگرام قرار میگیرد؛ اگر جایگاهش در بخش داغتر از evict_effort باشد نگه داشته میشود، وگرنه evict. - ۸. مراحل حذف یک cache tier writeback را بنویسید.
cache-mode proxy، rados cache-flush-evict-all تا خالی شدن، tier remove-overlay روی pool پایه، tier remove. - ۹. چه چیزی دلیل تاریخی cache tier جلوی pool EC را از بین برد؟
پشتیبانی از overwrite در pool EC (allow_ec_overwrites از Luminous) و بهینهسازیهای FastEC در Tentacle. - ۱۰. برای دادهی شیء با عمر مشخص چه جایگزینی پیشنهاد میشود؟
storage class و قانون lifecycle در RGW (و cloud transition برای بایگانی بیرونی).
فصل ۱۷: عیبیابی Ceph: از HEALTH_WARN تا ماشین حالت Peering#
- ۱. نخستین دو فرمان در هر حادثه کداماند و چرا؟
ceph -s برای نمای کلی و ceph health detail برای کد دقیق هر هشدار؛ این دو لایهی درگیر را نشان میدهند. - ۲. تفاوت degraded، undersized و remapped چیست؟
degraded: برخی اشیا نسخهی کافی ندارند؛ undersized: تعداد OSDهای acting کمتر از size است؛ remapped: acting با up متفاوت است (به دلیل pg_temp یا backfill). - ۳. حالت WaitUpThru چه مشکلی را حل میکند؟
تضمین میکند MON ثبت کرده که OSD تا این epoch زنده بوده؛ پس در peeringهای بعدی میتوان فهمید آیا آن interval ممکن بوده نوشتن بپذیرد. - ۴. چرا PG به حالت down میرود و فیلد down_osds_we_would_probe چه میگوید؟
چون intervalی وجود دارد که ممکن است در آن نوشتن رخ داده باشد و هیچ OSD آن در دسترس نیست؛ فیلد، OSDهایی را نشان میدهد که بازگشتشان peering را ممکن میکند. - ۵. find_best_info در pool تکثیری و EC چه تفاوتی دارد و چرا؟
در تکثیری بیشترین last_update مرجع است؛ در EC کمترین last_update که همهی shardها بتوانند به آن rollback کنند، چون نوشتن ناقص EC قابل بازسازی نیست. - ۶. آخرین رویداد sub_op_sent در یک slow op چه معنایی دارد؟
عملیات به replicaها ارسال شده ولی ack همه نرسیده؛ OSD replica یا شبکهی آن کند است. - ۷. scrub چگونه با نوشتنهای در جریان هماهنگ میشود؟
scrub تکهبهتکه پیش میرود و برای هر بازه تا پایان نوشتنهای در جریان و همگام شدن last_update منتظر میماند (RangeBlocked، WaitPushes، WaitLastUpdate). - ۸. پیش از ceph pg repair چه چیزی را باید بررسی کنید؟
خروجی rados list-inconsistent-obj برای اینکه بدانید خطا روی کدام shard یا OSD است و نسخهی معتبر روشن است؛ و سلامت دیسک مقصر. - ۹. ceph osd lost چه خطری دارد؟
نوشتنهای تأییدشدهای که فقط روی آن OSD بودهاند برای همیشه از دست میروند. - ۱۰. چرا nodown و noout باید موقت باشند؟
nodown روی OSD مرده کلاینتها را منتظر نگه میدارد و noout مانع بازیابی خودکار میشود؛ هر دو کلاستر را از رفتار ترمیمی خود محروم میکنند.
فصل ۱۸: بازیابی از فاجعه: rbd-mirror، stretch mode و نجات کلاستر#
- ۱. چرا تکثیر جایگزین پشتیبان نیست؟
چون حذف اشتباه، باجافزار و خرابی منطقی هم تکثیر میشوند؛ پشتیبان باید از دسترس همان اعتبارنامهها و عملیات خارج باشد. - ۲. تفاوت mirroring مبتنی بر journal و snapshot در سربار و RPO چیست؟
journal هر نوشتن را دو بار انجام میدهد و RPO چندثانیهای دارد؛ snapshot سربار کمی دارد و RPO آن برابر بازهی زمانبندی است. - ۳. فیلد complete در MirrorSnapshotNamespace چه نقشی دارد؟
نشان میدهد کپی تفاوت برای آن snapshot مقصد تمام شده است؛ snapshot ناقص یعنی تصویر ممکن است ناسازگار باشد و آخرین نقطهی سازگار snapshot کامل قبلی است. - ۴. rbd-mirror در کدام کلاستر اجرا میشود و چرا pull میکند؟
در کلاستر مقصد؛ از مبدأ میکشد تا مبدأ نیازی به دانستن یا دسترسی به مقصد نداشته باشد و daemon کنار نسخهای که مینویسد اجرا شود. - ۵. پس از promote --force و بازگشت سایت قبلی چه باید کرد؟
تصویر سایت قبلی را demote و سپس resync کنید تا از primary فعلی دوباره همگام شود؛ نوشتنهای پس از قطع روی آن سایت از دست میروند. - ۶. نقش MON داور در stretch mode چیست؟
MON بدون داده در سایت سوم که هنگام قطع ارتباط دو سایت با quorum تعیین میکند کدام سایت فعال بماند. - ۷. stretch mode چه اثری بر تأخیر نوشتن دارد؟
تأخیر هر نوشتن به اندازهی رفتوبرگشت بین دو سایت افزایش مییابد، چون نوشتن پیش از ack باید در هر دو سایت ثبت شود. - ۸. چه اطلاعاتی در بازسازی MON از OSDها از دست میرود؟
keyringهای MDS و بیشتر keyringهای دیگر، وضعیت poolهای در حال ساخت، و برخی تنظیمات صرفاً MON. - ۹. Umbrella چه ابزاری برای پشتیبان MON افزوده است؟
پشتیبان دورهای RocksDB مانیتور (mon_backup_interval)، فرمان ceph tell mon.* backup و بازیابی با ceph-mon --restore-backup. - ۱۰. ceph-objectstore-tool در DR چه کاربردی دارد و پیششرطش چیست؟
صدور PG از OSD مردهی خوانا و ورود آن به OSD دیگر برای نجات PG incomplete یا down؛ پیششرط: OSDهای مبدأ و مقصد متوقف باشند.
فصل ۱۹: راهبری و نگهداری روزمره: ارتقا، جایگزینی دیسک، autoscaler و balancer#
- ۱. ترتیب ارتقای daemonها در cephadm چیست و چرا mgr اول است؟
mgr، سپس mon یکییکی، سپس OSDها و در پایان سایر سرویسها؛ mgr اول است چون ماژول cephadm که ارتقا را هدایت میکند در mgr اجرا میشود و باید نسخهی جدید باشد. - ۲. ارتقای OSD بر اساس bucket CRUSH چه مزیتی دارد؟
همهی OSDهای یک دامنهی خرابی با هم و با تأیید ok-to-upgrade ارتقا مییابند؛ زمان ارتقای کلاستر بزرگ بسیار کم میشود بدون نقض در دسترس بودن. - ۳. چرا
--replace جابهجایی داده را کم میکند؟
OSD در وضعیت destroyed با همان شناسه و جایگاه CRUSH میماند؛ پس فقط PGهای همان OSD دوباره پر میشوند و بازتوزیع کلی رخ نمیدهد. - ۴. maintenance enter چه کاری با پرچم noout انجام میدهد؟
با osd set-group، noout را برای زیردرخت CRUSH میزبان تنظیم و در خروج برمیدارد. - ۵. فرمول پایهی pg_target در autoscaler چیست؟
pg_target = نسبت ظرفیت pool × (تعداد OSDهای ریشه × mon_target_pg_per_osd) × bias / size، سپس گرد کردن به توان ۲. - ۶. آستانهی autoscaler چه مشکلی را حل میکند و آستانهی پویا چه زمانی اعمال میشود؟
از تغییرات کوچک و پرتکرار pg_num جلوگیری میکند (تغییر فقط با اختلاف سهبرابری)؛ آستانهی پویا در افزایش به ۵۱۲ و ۱۰۲۴ (آستانه ۱) و ۲۰۴۸ (آستانه ۲) اعمال میشود. - ۷. تغییر پیشفرض mon_target_pg_per_osd در Umbrella چه پیامدی دارد؟
مقدار از ۱۰۰ به ۲۰۰ رسیده؛ پس از ارتقا autoscaler ممکن است PGها را تقسیم کند و داده جابهجا شود. - ۸. upmap balancer چگونه PGی را برای جابهجایی انتخاب میکند؟
OSDهایی با انحراف بیش از max_deviation از سهم وزندار را مییابد و PGی از OSD پر را به OSD کمبار منتقل میکند بهشرطی که قانون CRUSH نقض نشود. - ۹. چرا upmap ایمنتر از تغییر دستی وزنهاست؟
روی خروجی CRUSH اعمال میشود و اگر قانون را نقض کند نادیده گرفته و پاک میشود؛ تغییر وزن کل نگاشت را تغییر میدهد و پیشبینیپذیر نیست. - ۱۰. تفاوت ceph config set و injectargs چیست؟
ceph config set در پایگاه دادهی MON ماندگار و قابل بازگشت است؛ injectargs فقط مقدار در حافظهی daemon را موقتاً تغییر میدهد.
فصل ۲۰: پایش Ceph: Prometheus، ceph-exporter، هشدارها و مشاهدهپذیری#
- ۱. چرا perf counters از ماژول prometheus به ceph-exporter منتقل شدند؟
جمعآوری همهی شمارندههای همهی daemonها از یک mgr در کلاسترهای بزرگ کارایی mgr را کاهش میداد؛ ceph-exporter روی هر میزبان فقط daemonهای محلی را از admin socket میخواند. - ۲. چرا باید همهی mgrها یا service discovery را برای scrape تعریف کرد؟
فقط mgr فعال متریکهای کلاستر را منتشر میکند؛ پس از failover، هدف ثابت به mgr قبلی نقطهی کور میسازد. - ۳. اولویت شمارنده و exporter_prio_limit چه رابطهای دارند؟
ceph-exporter فقط شمارندههایی با اولویت دستکم exporter_prio_limit (پیشفرض ۵) را منتشر میکند. - ۴. میانگین تأخیر یک بازه از شمارندهی time_avg چگونه محاسبه میشود؟
نسبت افزایش sum به افزایش avgcount در آن بازه؛ در PromQL نسبت rate دو سری _sum و _count. - ۵. متریک ceph_health_detail چه کاربردی دارد؟
یک سری برای هر کد سلامت فعال با برچسب name؛ امکان هشدار دقیق بر اساس کدهایی مانند SLOW_OPS یا MON_DOWN. - ۶. نقش for در قاعدهی هشدار چیست؟
شرط باید در تمام مدت for برقرار بماند تا هشدار فعال شود؛ از هشدار برای پدیدههای گذرا جلوگیری میکند. - ۷. inhibit در Alertmanager چه مشکلی را حل میکند؟
وقتی هشدار ریشه (مثلاً میزبان down) فعال است، هشدارهای فرعی ناشی از آن (OSDهای down همان میزبان) را خاموش میکند. - ۸. mgmt-gateway چه مزایایی دارد؟
یک نقطهی ورود با TLS و نشانی مجازی برای همهی رابطها، امکان احراز هویت متمرکز با oauth2-proxy و امن شدن endpointهای پایش. - ۹. چرا Prometheus نباید مستقیماً در معرض کاربران باشد؟
مدل امنیتی Prometheus فرض میکند دادهها برای هر دارندهی دسترسی آشکار است؛ API آن همهی (فرا)دادههای جمعآوریشده را نشان میدهد. - ۱۰. چند SLI مناسب برای سرویس RBD نام ببرید.
درصد زمان فعال بودن همهی PGهای pool، صدک ۹۹ تأخیر نوشتن، و برای تصاویر mirror شده RPO (اختلاف timestamp).
فصل ۲۱: تنظیم کارایی Ceph: از mClock تا هسته و شبکه#
- ۱. چرا تنظیم کارایی باید با خط پایه و یک تغییر در هر زمان انجام شود؟
چون بدون خط پایه نمیتوان اثر را سنجید و با چند تغییر همزمان نمیتوان فهمید کدام مؤثر بوده یا آسیب زده است. - ۲. شارد هر PG چگونه تعیین میشود و چرا همهی عملیات یک PG در یک شارد است؟
با pgid.hash_to_shard(num_shards)؛ تا ترتیب عملیات یک PG حفظ شود و نیاز به هماهنگی بین شاردها نباشد. - ۳. Squid 19.2.1 چه تغییری در پیشفرض شاردهای HDD داد و چرا معقول است؟
از ۵ شارد با ۱ thread به ۱ شارد با ۵ thread؛ با یک شارد، mClock دید کامل از همهی درخواستهای OSD دارد و سهمها را دقیقتر اعمال میکند. - ۴. سه پارامتر mClock را تعریف کنید.
reservation حداقل سهم تضمینشده، weight سهم نسبی از ظرفیت اضافه، limit سقف سهم. - ۵. برچسب R در dmclock چگونه محاسبه میشود و max(now, ...) چه نقشی دارد؟
R = max(now, R_prev + increment × (δ + cost)) با increment = ۱/reservation؛ max(now, ...) مانع انباشت اعتبار برای کلاس بیکار میشود. - ۶. پروفایل high_client_ops چه تفاوتی با balanced دارد؟
رزرو کلاینت ۶۰٪ با وزن ۲ در برابر ۵۰٪ با وزن ۱، رزرو بازیابی ۴۰٪، و سقف best-effort ۷۰٪ به جای ۹۰٪. - ۷. چرا تغییر osd_max_backfills در پروفایلهای داخلی اثری ندارد؟
چون پروفایلهای داخلی mClock این مقادیر را مدیریت میکنند و فقط با osd_mclock_override_recovery_settings=true میتوان آنها را تغییر داد. - ۸. OSD ظرفیت IOPS خود را چگونه تعیین میکند و چه زمانی نتیجه را کنار میگذارد؟
هنگام شروع، اگر مقدار ظرفیت پیشفرض باشد و سنجش رد نشده باشد، یک سنجش داخلی اجرا میکند؛ اگر نتیجه بیرون از بازهی آستانههای پایین و بالا باشد، مقدار پیشفرض را به کار میبرد. - ۹. سه تنظیم سیستمعامل یا شبکه که بیشترین اثر را دارند نام ببرید.
پروفایل CPU (tuned و C-state)، MTU یکسان و شبکهی cluster کافی، و زمانبند I/O مناسب (none برای NVMe). - ۱۰. چرا باید صدکها را به جای میانگین گزارش کرد؟
چون میانگین دم توزیع را پنهان میکند؛ تجربهی کاربر و SLOها را صدکهای بالا تعیین میکنند.
فصل ۲۲: معماری کد Ceph و مسیر درخواستها از درون#
- ۱. چرا OSD مستقیم روی دیسک نمینویسد و از ObjectStore::Transaction استفاده میکند؟
چون Transaction اتمیک است: دادهی شیء، xattr، omap و ورودی pg log با هم پایدار میشوند یا هیچکدام. همچنین backend (BlueStore، MemStore، SeaStore) قابل تعویض میماند. - ۲.
_calc_target در Objecter چه ورودیهایی دارد و چه زمانی op دوباره ارسال میشود؟
ورودیها نام شیء، pool، namespace، snap و OSDMap جاری هستند و خروجی pg، acting و primary است. اگر با نقشهی جدید primary یا acting تغییر کند، op به OSD درست دوباره ارسال میشود. - ۳. چرا op هر PG همیشه به یک OSDShard میرود؟
چون شارد از hash شناسهی PG به دست میآید. این کار ترتیب opهای یک PG را بدون هماهنگی بین شاردها حفظ میکند. - ۴. نقش
ms_fast_dispatch چیست و چه کاری نباید در آن انجام شود؟
تحویل سریع پیام در همان thread شبکه و صف کردن آن در شارد. هیچ کار مسدودکننده یا قفل طولانی نباید در آن انجام شود. - ۵.
ENCODE_START(v, compat, bl) چگونه ارتقای غلتان را ممکن میکند؟
v نسخهی فعلی و compat کمترین نسخهی decoder سازگار است. طول بلوک ذخیره میشود تا decoder قدیمی فیلدهای جدید را رد کند. - ۶. تفاوت مسیر مستقیم و deferred در BlueStore چیست و چرا پیشفرض SSD صفر است؟
در مسیر مستقیم داده با aio در فضای تازه نوشته میشود. در deferred، دادهی کوچک ابتدا در WAL RocksDB ثبت و بعداً نوشته میشود. روی SSD، seek گران نیست و دوبار نوشتن فقط write amplification اضافه میکند. - ۷. primary در replication چه زمانی به کلاینت پاسخ میدهد؟
وقتی همهی اعضای acting (و خود primary) تراکنش را commit کرده باشند؛ eval_repop این را بررسی میکند. - ۸. در RGW، کدام تابع ورودی index را از pending به complete میبرد؟
متد cls به نام bucket_complete_op که از طریق UpdateIndex::complete فراخوانی میشود. - ۹. در CephFS، چرا MDS در مسیر داده نیست و نبودِ cap Fb چه اثری دارد؟
چون کلاینت با Striper و Objecter مستقیم به OSD مینویسد. بدون Fb، کلاینت نمیتواند بافر کند و هر نوشتن همگام به OSD میرود. - ۱۰. برای یافتن پیشفرض واقعی یک گزینه در یک نسخهی مشخص، به کجا مراجعه میکنید؟
فایل src/common/options/*.yaml.in در tag همان نسخه (مثلاً v20.2.0) در مخزن ceph/ceph.
فصل ۲۳: لایههای پایینی (۱): دستگاه بلوکی، bufferlist، mempool و crc32c#
- ۱. چرا KernelDevice برای هر write hint یک fd جدا باز میکند؟
تا روی هستههایی که F_SET_FILE_RW_HINT را پشتیبانی میکنند، hint طول عمر داده (برای SSDهای دارای streams) روی هر fd ثابت تنظیم شود و هر نوشتن بسته به hint از fd مناسب برود. - ۲. همترازی O_DIRECT چه محدودیتی بر کوچکترین نوشتن BlueStore میگذارد؟
offset، طول و آدرس بافر باید با بلوک (۴K) همتراز باشند. بنابراین کوچکترین نوشتن ۴K است و نوشتنهای کوچکتر یا RMW میشوند یا deferred. - ۳. نقش
bdev_aio_max_queue_depth و bdev_aio_reap_max چیست؟
اولی حداکثر تعداد I/O در حال اجرا در صف را تعیین میکند و دومی حداکثر تعداد تکمیلی را که در هر دور برداشته میشود. - ۴. چه زمانی BlueStore flush جداگانهی دستگاه داده را اجباری میکند؟
وقتی داده و DB روی دستگاههای جدا باشند، یا چیزی برای commit در RocksDB نباشد؛ در این حالت flush لاگ BlueFS دستگاه داده را پوشش نمیدهد. - ۵. چرا discard بهطور پیشفرض خاموش است؟
چون TRIM روی بسیاری از دستگاهها همگام و کند است و تأخیر را بالا میبرد؛ دستگاههای امروزی NVMe بدون آن هم خوب کار میکنند. - ۶. تفاوت
buffer::ptr و buffer::raw چیست؟
raw مالک حافظه است و شمارندهی ارجاع دارد؛ ptr فقط پنجرهای (offset و طول) روی یک raw است. - ۷. چرا
bufferlist::c_str() میتواند گران باشد؟
چون اگر لیست چندتکه باشد، rebuild همهی داده را در یک حافظهی پیوستهی جدید کپی میکند. - ۸. mempool چگونه به autotune حافظه کمک میکند؟
مصرف هر بخش را دقیق و شاردشده ثبت میکند و autotune با مقایسهی آن با osd_memory_target، سهم کشها را تنظیم میکند. - ۹. چرا crc32c مقدار
"123456789" در Ceph با مقدار مرجع استاندارد فرق دارد؟
چون ceph_crc32c XOR نهایی را انجام نمیدهد؛ ۰x1CF96D7C پس از XOR با ۰xFFFFFFFF برابر ۰xE3069283 میشود. - ۱۰. سربار checksum با chunk ۴K چقدر است و بزرگ کردن chunk چه بدهبستانی دارد؟
حدود ۰.۱٪ (۴ بایت برای هر ۴۰۹۶ بایت). chunk بزرگتر سربار را کم میکند ولی خواندن کوچک را مجبور به خواندن کل chunk میکند.
فصل ۲۴: لایههای پایینی (۲): قالب رویدیسک BlueStore و BlueFS#
- ۱. ۶۰ بایت اول label شامل چیست و چرا decoder از آن میپرد؟
رشتهی «bluestore block device\n»، uuid مربوط به OSD به شکل متن و یک \n؛ این بخش فقط برای خوانایی انسان است و دادهی کدگذاریشده پس از آن آغاز میشود. - ۲. چرا superblock مربوط به BlueFS همیشه در offset 4096 است؟
چون بلوک اول به label اختصاص دارد و BlueFS آگاهانه همین فرض (بلوک دوم) را دارد؛ این در bluestore_common.h ثابت شده است. - ۳.
denc_lba برای offset همتراز با ۴K چند بایت مصرف میکند و چرا؟
معمولاً ۴ بایت؛ ۱۲ بیت صفر انتهایی با یک بیت نوع حذف میشود و ۳۰ بیت داده تا حدود ۴ ترابایت آدرسدهی را پوشش میدهد. - ۴. چه شرطی فشردهسازی لاگ BlueFS را آغاز میکند؟
اندازهی لاگ حداقل bluefs_log_compact_min_size (۱۶M) باشد و نسبت آن به اندازهی تخمینی حداقل bluefs_log_compact_min_ratio (۵) باشد. - ۵. چرا hash در کلید onode بیتمعکوس است؟
تا اشیای یک PG که بیتهای پایینی hash مشترک دارند، یک بازهی پیوسته در فضای کلید بسازند و list و scrub با range scan انجام شود. - ۶. پرچمهای BLOBID در extent map چه صرفهجوییای ایجاد میکنند؟
logical_offset، blob_offset یا length تکراری نوشته نمیشوند؛ یک lextent معمولی ۱ تا ۲ بایت میشود. - ۷. چرا checksum بزرگترین بخش یک blob کدگذاریشده است؟
با crc32c و chunk ۴K، هر blob ۶۴K برابر ۶۴ بایت checksum دارد، در حالی که pextentها چند بایتاند. - ۸. hybrid allocator چگونه مصرف حافظه را محدود میکند؟
با سقف bluestore_hybrid_alloc_mem_cap (۶۴M) برای AVL؛ قطعههای اضافی به Bitmap با حافظهی ثابت سرریز میکنند. - ۹. چرا freelist از merge با XOR استفاده میکند؟
چون XOR جابهجاپذیر و خودمعکوس است؛ تخصیص و آزادسازی بدون خواندن مقدار قبلی به یک merge تبدیل میشوند. - ۱۰. الگوریتم ۲Q چه مشکلی از LRU را حل میکند؟
یک اسکن ترتیبی یکباره کش دادههای پرکاربرد را خالی نمیکند، چون داده فقط با دیده شدن دوباره به hot میرود.
فصل ۲۵: لایههای پایینی (۳): RocksDB درون BlueStore#
- ۱. group commit در
_kv_sync_thread چگونه تعداد fsyncها را کم میکند؟
چند تراکنش آماده در یک WriteBatch پشت سر هم ثبت میشوند و فقط آخرین آنها sync است؛ یک fsync روی WAL همه را پایدار میکند. - ۲. سرآیند رکورد WAL چند بایت است و چه فیلدهایی دارد؟
۷ بایت: crc32c ماسکشده (۴)، طول (۲) و نوع (۱)؛ در حالت recyclable ۴ بایت شمارهی لاگ هم اضافه میشود. - ۳. چرا
min_write_buffer_number_to_merge=6 برای Ceph مهم است؟
چون کلیدهای کوتاهعمر (deferred و pg log) در ادغام memtableها حذف میشوند و هرگز به SST نمیرسند، که write amplification را بسیار کم میکند. - ۴. چرا برای CFهای
L و P این عدد ۳۲ است؟
چون عمر کلیدهای deferred (L) و pgmeta (P) بسیار کوتاه است و ادغام بیشتر یعنی حذف بیشتر پیش از flush. - ۵. بلوک filter در SST چه نقشی در مسیر خواندن دارد؟
بدون خواندن بلوک داده تعیین میکند کلید احتمالاً در این فایل نیست و بیشتر خواندنهای بیفایدهی L0 تا Ln را حذف میکند. - ۶. با پیشفرضها اندازهی L3 چقدر است؟
حدود ۶۴G (۱G × ۸ × ۸). - ۷.
use_some_extra چه تفاوتی با rocksdb_original دارد؟
rocksdb_original فقط سطوح کامل را روی DB میگذارد؛ use_some_extra فضای اضافه را برای بخشی از سطح بعدی استفاده میکند. - ۸. چگونه CF یک کلید omap per-pg انتخاب میشود؟
بایتهای ۰ تا ۱۲ کلید با ceph_str_hash_rjenkins هش میشوند و باقیمانده بر ۳ شمارهی CF را میدهد. - ۹. چرا omap یک PG باید در یک shard بماند؟
تا پیمایش omap یک شیء یا PG در یک CF و یک range scan انجام شود. - ۱۰. چرا تغییر کل رشتهی
bluestore_rocksdb_options خطرناک است و جایگزین آن چیست؟
چون پیشفرضهای مهم (مثل ادغام memtable و LZ4) ناخواسته حذف میشوند؛ bluestore_rocksdb_options_annex فقط کلیدهای تغییرکرده را اضافه میکند.
فصل ۲۶: لایههای پایینی (۴): msgr2 در سطح بایت، AsyncConnection و EventCenter#
- ۱. ساختار banner در msgr2 چیست و ویژگیهای فعلی کداماند؟
«ceph v2\n»، طول u16 (۱۶) و دو u64 برای ویژگیهای supported و required؛ ویژگیهای فعلی REVISION_1 و COMPRESSION هستند. - ۲. چرا preamble دقیقاً ۳۲ بایت است؟
تا مضرب بلوک AES (۱۶) باشد و در حالت secure بدون padding اضافه رمز شود. - ۳. crc مربوط به preamble و crc مربوط به segment با چه seedهایی محاسبه میشوند؟
preamble با seed صفر روی ۲۸ بایت اول؛ segmentها با seed برابر ۰xFFFFFFFF (−۱). - ۴. چرا segment داده همترازی ۴۰۹۶ دارد؟
تا گیرنده بافر همتراز با صفحه تخصیص دهد و داده را بدون کپی به O_DIRECT برساند. - ۵. inline کردن ۴۸ بایت در حالت secure چه سودی دارد؟
header پیام و frameهای کنترلی کوچک با یک رمزگشایی و یک tag خوانده میشوند و طول بقیهی frame بلافاصله معلوم میشود. - ۶. AUTH_SIGNATURE از چه حملهای جلوگیری میکند؟
از حملهی downgrade یا دستکاری بایتهای رمزنشدهی پیش از auth، مثل تغییر preferred_modes. - ۷. SESSION_RESET و SESSION_RETRY_GLOBAL چه زمانی ارسال میشوند؟
RESET وقتی cookie جلسه برای سرور ناشناخته است (مثلاً پس از restart)؛ RETRY_GLOBAL وقتی global_seq کلاینت از آنچه سرور دیده قدیمیتر است. - ۸. سه throttler در دریافت پیام کداماند و چگونه backpressure ایجاد میکنند؟
تعداد پیام، بایتهای policy و صف dispatch؛ با پر شدن هرکدام خواندن از سوکت متوقف میشود و پنجرهی TCP فرستنده را کند میکند. - ۹. چرا handlerها در EventCenter باید تا EAGAIN بخوانند؟
چون epoll در حالت edge-triggered است و دادهی خواندهنشده رویداد جدیدی ایجاد نمیکند. - ۱۰. thread دیگری چگونه یک worker را برای ارسال پیام بیدار میکند؟
رویداد را در external_events صف میکند و با نوشتن در eventfd (یا pipe)، epoll_wait آن worker را بیدار میکند.
فصل ۲۷: لایههای پایینی (۵): ریاضیات erasure coding، از GF(۲⁸) تا FastEC#
- ۱. چرا جمع و تفریق در هر دو XOR هستند؟
چون ضرایب در GF(۲) هستند و ۱ + ۱ = ۰؛ پس جمع بیتبهبیت همان XOR است و هر عنصر قرینهی خودش است. - ۲. ۰x56 × ۰x04 در با ۰x11D چگونه محاسبه میشود؟
۰x56 دو بار شیفت میشود و ۰x158 به دست میآید؛ چون بیت ۸ روشن است، ۰x58 ⊕ ۰x1D = ۰x45. - ۳. کد MDS چیست و چرا Vandermonde سادهی ISA-L همیشه MDS نیست؟
کدی که هر k chunk از k+m برای بازسازی کافی باشد؛ در Vandermonde ساده برخی زیرماتریسهای k×k در معکوسپذیر نیستند. - ۴. Ceph در چه شرایطی خودکار به cauchy تغییر میدهد؟
وقتی m > ۴ باشد، یا m = ۴ و k > ۲۱. - ۵. در مثال این فصل، P0 و P1 چگونه به دست آمدند؟
P0 برابر XOR چهار بایت (۰x08) است و P1 برابر ۱۲ ⊕ ۲·۳۴ ⊕ ۴·۵۶ ⊕ ۸·۷۸ = ۰xD8. - ۶. چرا ضرایب decode کش میشوند؟
چون معکوس کردن ماتریس برای هر الگوی خرابی گران است و همان الگو بارها در recovery تکرار میشود. - ۷. PSHUFB چگونه ضرب در ثابت را سریع میکند؟
ضرب به دو جستوجوی ۱۶ خانهای برای nibbleها تبدیل میشود و PSHUFB دهها جستوجو را در یک دستور انجام میدهد. - ۸. parity delta چیست و چرا درست است؟
بهروزرسانی parity با ؛ چون کد خطی است، تغییر یک chunk داده اثر خطی جداگانهای بر هر parity دارد. - ۹. stripe_unit پیشفرض در pool بهینه چقدر است و چرا؟
۱۶K؛ چون با نوشتن جزئی بهینه، stripe بزرگتر هزینهی RMW ندارد و خواندن ترتیبی و فراداده کاراتر میشوند. - ۱۰. پهنای باند ترمیم CLAY با k=8، m=4 و d=11 چقدر است و هزینهی آن چیست؟
۲.۷۵S در برابر ۸S؛ هزینهی آن ۶۴ sub-chunk در هر chunk و خواندنهای ریز و پراکنده است.
فصل ۲۸: لایههای پایینی (۶): CRUSH در سطح بیت، از rjenkins تا upmap#
- ۱. ceph_stable_mod چگونه حرکت داده را هنگام افزایش pg_num محدود میکند؟
فقط PGهایی که بیت جدید mask را دارند و شمارهشان از pg_num کمتر میشود جابهجا (split) میشوند؛ بقیه همان شماره را نگه میدارند. - ۲. چرا HASHPSPOOL لازم است؟
تا PGهای همشماره در poolهای مختلف به یک x نرسند و روی همان OSDها انباشته نشوند. - ۳. چرا CRUSH فقط از عملیات صحیح استفاده میکند؟
تا نتیجه روی همهی معماریها و در هسته و فضای کاربر بیتبهبیت یکسان باشد. - ۴. در straw2، draw چگونه محاسبه میشود و چرا بیشترین draw برنده است؟
draw = ؛ چون ln منفی است، وزن بیشتر draw بزرگتر (کممنفیتر) میدهد. این معادل کمینهی متغیرهای نمایی است. - ۵. crush_ln چه چیزی را با چه دقتی برمیگرداند؟
را با دو جدول و عملیات صحیح، با دقت کافی برای توزیع ۱۶ بیتی، برمیگرداند. - ۶. چرا straw2 حرکت حداقلی دارد و straw قدیمی نداشت؟
چون draw هر آیتم فقط به وزن خودش بستگی دارد؛ در straw طول نیها نسبی و وابسته به همهی وزنها بود. - ۷. تصادم در firstn چگونه حل میشود و سقف آن چیست؟
ftotal افزایش و r = rep + ftotal میشود؛ تا choose_total_tries=50. - ۸. تفاوت firstn و indep برای EC چیست؟
در firstn موقعیتها جابهجا میشوند؛ در indep جایگاه هر shard ثابت است و فقط shard گمشده دوباره انتخاب میشود. - ۹. weight-set در choose_args چه مشکلی را حل میکند؟
انحراف توزیع replicaهای دوم و سوم از وزنها را با وزن جداگانه برای هر position اصلاح میکند، بدون تغییر وزنهای اصلی. - ۱۰. ترتیب اعمال upmapها چیست و mon با upmap نامعتبر چه میکند؟
pg_upmap، سپس pg_upmap_items و سپس pg_upmap_primary؛ mon upmapهایی را که قاعده را نقض کنند حذف میکند.
فصل ۲۹: لایههای پایینی (۷): کلاینتهای هستهی لینوکس، libceph، krbd و ceph.ko#
- ۱. libceph از چه بخشهایی تشکیل شده است و چرا CRUSH در هسته هم هست؟
messenger، mon_client، osd_client، osdmap و CRUSH، cephx و striper؛ CRUSH در هسته هست تا کلاینت خودش PG→OSD را بدون واسطه حساب کند. - ۲. یک request در blk-mq چگونه به obj_requestها تقسیم میشود؟
img_request بازهی بایت را با striper و اندازهی شیء به بازههای هر شیء میشکند و برای هرکدام یک obj_request میسازد. - ۳. چه زمانی krbd بهجای WRITE از WRITEFULL، ZERO، TRUNCATE یا DELETE استفاده میکند؟
WRITEFULL برای پوشش کامل شیء؛ ZERO برای صفر کردن میانه؛ TRUNCATE برای صفر کردن انتها؛ DELETE برای discard کل شیء بدون parent. - ۴. copyup در krbd چه زمانی رخ میدهد؟
وقتی در یک clone روی شیئی نوشته میشود که هنوز وجود ندارد و parent در آن بازه داده دارد. - ۵. چرا کلاینت هسته در برابر pool پر گیر میکند و چگونه میتوان آن را محدود کرد؟
چون درخواستها با PAUSEWR یا pool_full نگه داشته میشوند تا نقشهی بعدی؛ با osd_request_timeout محدود میشود. - ۶. مقادیر io_opt و io_min در krbd از کجا میآیند؟
io_opt از object_size × stripe_count و io_min از alloc_size (پیشفرض ۶۴K). - ۷. رشتهی caps به شکل
pAsLsXsFrwcb را تفسیر کنید.
pin؛ Auth shared؛ Link shared؛ Xattr shared؛ File read، write، cache و buffer. - ۸. چرا خوانندهی دوم یک فایل در حال نوشتن، Fc نمیگیرد؟
چون با وجود نویسندهی همزمان، دادهی کششده ممکن است کهنه باشد؛ MDS فقط Fr میدهد و خواندن مستقیم از OSD انجام میشود. - ۹. هشدار MDS_HEALTH_CLIENT_LATE_RELEASE چه معنایی دارد؟
یک کلاینت به درخواست revoke caps پاسخ نداده است و کلاینتهای دیگر منتظرند. - ۱۰. دو مزیت و دو عیب krbd نسبت به librbd را بگویید.
مزایا: سربار کم و عدم نیاز به فرایند کاربر؛ معایب: ویژگیهای محدود (بدون journaling) و نیاز به هستهی جدید برای ارتقا.
فصل ۳۰: لایههای پایینی (۸): Crimson و Seastar، OSD تکهستهای و SeaStore#
- ۱. چرا مدل thread pool در OSD کلاسیک روی NVMe هزینهبر است؟
هر درخواست چند بار بین threadها و قفلها جابهجا میشود و هزینهی context switch و cache miss با تأخیر چند ده میکروثانیهای NVMe قابل مقایسه است. - ۲. future و continuation در Seastar چگونه جایگزین بلوکه شدن میشوند؟
تابع ناهمگام بیدرنگ future برمیگرداند؛ ادامه با then وصل میشود و پس از set_value در صف همان reactor اجرا میشود. - ۳. crimson_reactor_task_quota_ms چه چیزی را محدود میکند و یک continuation طولانی چه اثری دارد؟
بیشینهی زمانی که reactor پیش از poll دوباره taskها را اجرا میکند؛ continuation طولانی همهی PGهای آن هسته را متوقف میکند (stall). - ۴. PG تازه چگونه به یک هسته نسبت داده میشود و این روش چه ضعفی دارد؟
هستهی ۰ کمبارترین هسته از نظر تعداد PG را با min_element انتخاب میکند؛ بار PGها در نظر گرفته نمیشود و work-stealing ندارد. - ۵. تفاوت phaseهای exclusive و concurrent را با مثال WaitRepop توضیح دهید.
exclusive یک عملیات در لحظه و ترتیب ورود؛ concurrent چند عملیات همزمان با خروج به ترتیب؛ WaitRepop اجازه میدهد چند نوشتن همزمان منتظر replicaها باشند. - ۶. AlienStore چرا لازم است و چه هزینهای دارد؟
برای اجرای BlueStore و MemStore کلاسیک خارج از reactor؛ هزینهی دو گذر از مرز reactor/thread و رقابت CPU. - ۷. laddr و paddr در SeaStore چه تفاوتی دارند و چرا این جداسازی هزینهی GC را کم میکند؟
laddr منطقی و پایدار است و paddr فیزیکی؛ با جابهجایی بلوک فقط LBA tree بهروز میشود. - ۸. ساختار ۶۴ بیتی paddr_t را برای segment و RBM شرح دهید.
۸ بیت device_id؛ segment: ۲۴ بیت شمارهی segment و ۳۲ بیت آفست؛ RBM: ۵۶ بیت آفست مطلق. - ۹. فرمول cost-benefit را بنویسید و autotune را با مثال توضیح دهید.
؛ اگر سهم آزاد greedy دستکم ratio برابر سهم آزاد انتخاب فرمول باشد، انتخاب greedy جایگزین میشود. - ۱۰. سه پرچمی که برای فعال کردن Crimson لازماند کداماند؟
ویژگی آزمایشی crimson، پرچم allow_crimson در OSDMap (set-allow-crimson) و osd_pool_default_crimson برای poolها.
فصل ۳۱: لایههای پایینی (۹): SPDK و NVMe، از صفهای سختافزاری تا درگاه NVMe-oF#
- ۱. SQ و CQ کجا قرار دارند و چه کسی در هرکدام مینویسد؟
هر دو در حافظهی میزباناند؛ میزبان در SQ فرمان مینویسد و کنترلر در CQ نتیجه. - ۲. Phase Tag چگونه بدون خواندن ثبات دستگاه، CQE تازه را مشخص میکند؟
کنترلر در هر دور صف مقدار P را وارونه مینویسد؛ میزبان ورودیای را تازه میداند که P آن با cq_phase فعلی برابر باشد. - ۳. چرا هسته نوشتن doorbell را تا پایان دسته به تعویق میاندازد؟
هر doorbell یک نوشتن MMIO گران از راه PCIe است؛ یک نوشتن برای کل دسته کافی است. - ۴. فیلد length در فرمان Read چرا صفرمبناست و برای ۸ بلوک چه مقداری دارد؟
چون صفر بلوک بیمعناست و بیشینهی ۶۵۵۳۶ بلوک در ۱۶ بیت جا میگیرد؛ برای ۸ بلوک مقدار ۷. - ۵. چرا NVMEDevice داده را در بافرهای DMA کپی میکند؟
کنترلر حافظهی pinned با IOVA معلوم (hugepage مربوط به DPDK) لازم دارد و bufferlist چنین نیست. - ۶. thread_local SharedDriverQueueData چه سودی و چه هزینهای دارد؟
سود: qpair و مخزن بافر بدون قفل؛ هزینه: هر thread تازه ۸ MiB بافر DMA و یک qpair مصرف میکند. - ۷. aio_submit در NVMEDevice از نظر بلوکه شدن با KernelDevice چه تفاوتی دارد؟
NVMEDevice تا تکمیل همهی I/Oهای IOContext در همان thread poll میکند؛ KernelDevice فقط ارسال میکند. - ۸. مسیر یک نوشتن از nvme_tcp میزبان تا OSD را با نام توابع bdev_rbd شرح دهید.
Command Capsule ⇒ nvmf_tgt ⇒ bdev_rbd ⇒ rbd_aio_writev ⇒ librbd/Objecter ⇒ bdev_rbd_finish_aiocb ⇒ spdk_thread_send_msg به submit_td ⇒ Response Capsule. - ۹. چرا درگاه جایگزین پیش از ACTIVE شدن باید منتظر blocklist باشد؟
تا درگاه قبلی، اگر هنوز زنده است، نتواند بنویسد و دو نویسندهی همزمان روی یک namespace پدید نیاید (fencing). - ۱۰. الگوریتم انتخاب درگاه جایگزین چه زمانی -EBUSY و چه زمانی -ENOENT برمیگرداند؟
-EBUSY اگر نامزدی نباشد ولی دستکم یک درگاه در حال گذار باشد؛ -ENOENT اگر هیچ درگاه در دسترسی در محدوده نباشد.
فصل ۳۲: لایههای پایینی (۱۰): scrub، recovery، backfill و repair در سطح کد#
- ۱. زمان scrub بعدی shallow و deep با پیشفرضها در چه بازهای است و چرا توزیع deep در لبهها قله دارد؟
shallow یکنواخت در [۲۴، ۳۶) ساعت؛ deep نرمال با میانگین ۷ روز و انحراف ۱.۴ روز که به [۴.۲، ۹.۸] روز بریده میشود. بریدن احتمال دنبالهها را روی لبهها جمع میکند. - ۲. هشدار PG_NOT_DEEP_SCRUBBED دقیقاً پس از چه مدتی داده میشود؟
وقتی از آخرین deep scrub بیش از deep_interval × (۱ + ۰.۷۵) یعنی ۱۲.۲۵ روز گذشته باشد. - ۳. چرا chunk scrub نباید head را از cloneهایش جدا کند؟
clone تازه همیشه درست کنار head ساخته میشود و ممکن است میان دو chunk دیده نشود. - ۴. پس از سه preemption در deep scrub، بیشینهی اندازهی chunk چقدر است؟
divisor برابر ۸ است و ۱۵/۸=۱، اما حداقل ۵ است، پس ۵. - ۵. در select_auth_object، اگر نسخهها برابر باشند، چه معیاری برنده را تعیین میکند؟
شمار digestهای ثبتشده (dcount) و در تساوی کامل، ترتیب نامزدها که با primary شروع میشود. - ۶. اولویت backfill یک PG undersized با size=3 و دو عضو acting چقدر است؟
۱۴۰ + ۱ + ۱۰ = ۱۵۱. - ۷. چرا حتی با recovery_priority=0 اولویت ۱۰ واحد بالا میرود؟
clamp_recovery_priority بازهی −۱۰ تا +۱۰ را به ۰ تا ۲۰ منتقل میکند. - ۸. AsyncReserver در چه شرطی یک رزرو در جریان را پس میگیرد؟
وقتی خانهها پرند و درخواست صفشده اولویتی بیشتر از کماولویتترین رزرو قابلpreempt دارد، یا min_priority بالا رفته یا max پایین آمده است. - ۹. async recovery چه هدفی را از acting بیرون میگذارد و چه شرطی آن را محدود میکند؟
عضوی با هزینهی (فاصلهی نسخه + اشیای گمشده) بیش از ۱۰۰، به شرط آنکه acting باقیمانده هنوز قابل نوشتن باشد. - ۱۰. چرا repair همان محدودیتهای recovery را دارد؟
چون repair فقط shardهای خراب را missing علامت میزند و کپی را به recovery عادی میسپارد.
فصل ۳۳: لایههای پایینی (۱۱): حافظه و CPU درون OSD، از mempool تا NUMA و پروفایلگیری#
- ۱. چرا mempool بهجای یک شمارندهی atomic مشترک از shard استفاده میکند و shard چگونه انتخاب میشود؟
تا cache line شمارنده میان هستهها رفت و برگشت نکند؛ با sched_getcpu() & (num_shards−۱)، یا round-robin ثابت برای هر thread. - ۲. اندازهی shard_t چرا مضرب ۱۲۸ است؟
aligned(۱۲۸) تا دو shard هرگز یک cache line مشترک نداشته باشند. - ۳. دو عددی را که از osd_memory_target بهعنوان max و min بودجهی cache به دست میآیند با پیشفرضها محاسبه کنید.
max = ۰.۸۵ × ۴۰۹۶ − ۷۶۸ = ۲۷۱۳.۶ MiB و min = osd_memory_cache_min = ۱۲۸ MiB. - ۴. tune_memory در افزایش و کاهش چه رفتار متفاوتی دارد؟
افزایش متناسب با (۱ − mapped/target) × فاصله تا max، و کاهش متناسب با (۱ − target/mapped) × فاصله تا min. - ۵. چرا osd_memory_target سقف سخت نیست؟
چون فقط اندازهی cacheها را کم میکند؛ حافظهی حسابنشده میتواند خودش از هدف بگذرد. - ۶. در balance، cacheی که کمتر از سهمش میخواهد چه میشود و باقیمانده به چه کسی میرسد؟
همان مقدار را میگیرد و از دورهای بعد خارج میشود؛ باقیمانده بر پایهی نسبت میان cacheهای ناراضی تقسیم میشود. - ۷. get_chunk برای tuned_mem برابر ۱۶۷۲ MiB چه مقداری دارد؟
chunk = ۸ MiB؛ get_chunk(۱) = ۷۲ MiB. - ۸. چرا افزایش threads_per_shard برای یک PG داغ کمکی نمیکند؟
چون قفل PG اجرای موازی opهای یک PG را محدود میکند و همهی opهای آن PG به یک shard میروند. - ۹. OSD در چه شرطی خودکار وابستگی NUMA تنظیم میکند؟
وقتی گره دستگاه ذخیرهسازی و گره رابطهای public و cluster یکی باشد و osd_numa_auto_affinity=true؛ یا با osd_numa_node صریح. - ۱۰. «بودجهی CPU برای هر op» را چگونه حساب میکنید و از آن چه نتیجهای میگیرید؟
هستههای مصرفشده تقسیم بر op در ثانیه؛ سپس سهم هر لایه از flame graph را در آن ضرب کنید تا سقف صرفهجویی هر تنظیم معلوم شود.
فصل ۳۴: بخش تخصصی (۱): RADOS — هویت شیء، فراداده و مسیر op درون OSD#
- ۱. hobject_t به چه ترتیبی مقایسه میشود؟
max، pool، کلید بیتی (hash برعکسشده)، nspace، key مؤثر (اگر یکی از دو key خالی نباشد)، oid و در پایان snap. - ۲. چرا کلید بیتی hash را برعکس میکند؟
تا بیتهای پایین hash که PG را تعیین میکنند به بالای کلید بروند و همهی اشیای یک PG یک بازهی پیوسته در ترتیب مرتبسازی بسازند. - ۳. پس از دوبرابر شدن pg_num، بازهی کلید بیتی PG
0x1f چگونه تقسیم میشود؟
به دو نیمهی پیوسته: PG ۰x1f بازهی [۰xf8000000, 0xfbffffff] و PG تازهی ۰x3f بازهی [۰xfc000000, 0xffffffff]. - ۴. xattrهای
_ و snapset چه چیزی نگه میدارند؟
_ همان object_info_t (نسخه، اندازه، پرچمها، digestها، watcherها) و snapset همان SnapSet شیء head است. - ۵. shard یک op چگونه انتخاب میشود و پیشفرضها روی SSD چیست؟
shard = ps % num_shards؛ روی SSD پیشفرض ۸ shard و ۲ thread در هر shard است. - ۶. اگر شیء روی primary missing باشد، op در کدام صف میماند؟
waiting_for_unreadable_object با متن «waiting for missing object». - ۷. درخواست تکراری چگونه تشخیص داده میشود و dups چه نقشی دارند؟
با جستوجوی reqid در caller_ops و extra_caller_ops و dup_index؛ dups نتیجهی درخواستهایی را نگه میدارند که ورودی log آنها trim شده است. - ۸. user_version چگونه محاسبه میشود و چرا ممکن است برای یک شیء پیوسته نباشد؟
max(last_user_version مربوط به PG, user_version شیء) + ۱ (و حداقل به اندازهی at_version.version)؛ چون شمارنده در سطح PG افزایش مییابد، نه در سطح شیء. - ۹. پاسخ نوشتن replicated چه زمانی به کلاینت فرستاده میشود؟
وقتی همهی اعضای acting (از جمله خود primary) commit را گزارش کرده باشند. - ۱۰. کلید یک ورودی pg log چه قالبی دارد و چرا طول آن ثابت است؟
%۰۱۰u.%۰۲۰llu از epoch و version (و برای dup پیشوند dup_)؛ طول ثابت باعث میشود ترتیب رشتهای با ترتیب عددی یکی باشد.
فصل ۳۵: بخش تخصصی (۲): RADOS — pg log، intervalها، missing و سازوکار recovery و backfill#
- ۱. چه تغییرهایی در OSDMap یک interval تازه میسازند؟ سه مورد غیر از up و acting نام ببرید.
افزون بر up و acting و primaryها: تغییر size یا min_size، split یا merge، sort_bitwise، recovery_deletes، پارامترهای stretch در CRUSH و روشن شدن بهینهسازیهای EC. - ۲.
maybe_went_rw در چه شرایطی true است؟
وقتی acting قابل نوشتن بوده (دستکم min_size) و یا up_thru primary آغاز interval را پوشانده یا last_epoch_clean درون آن interval بوده است. - ۳. چرا up_thru برای ایمنی peering لازم است؟
چون primary فقط پس از ثبت up_thru در mon active میشود؛ پس intervalی که up_thru در آن ثبت نشده نوشتنی نداشته و لازم نیست منتظر اعضایش ماند. - ۴. چه زمانی PG down میشود و
blocked_by چه کسی را نشان میدهد؟
وقتی برای intervalی با maybe_went_rw اعضای up یا lost کافی نباشند (replicated: هیچ، EC: کمتر از k) و دستکم یک عضو آن down باشد؛ blocked_by همان OSDهای down است. - ۵. merge_log وقتی log معتبر جلوتر است چه کار میکند؟
ورودیهای بعد از lower_bound را اضافه میکند، missing را برای هر کدام بهروز میکند، ورودیهای محلی بعد از lower_bound را divergent میشمارد و last_update را برابر سر log معتبر میکند. - ۶. ورودی divergent چیست و چرا برگرداندن آن ایمن است؟
ورودیای که در log معتبر نیست؛ چون پاسخ کلاینت فقط پس از commit همهی acting داده میشود، کلاینت آن نوشتن را موفق ندیده است. - ۷. حالتهای ۴ و ۵ رسیدگی به divergent چه فرقی دارند؟
در ۴ همهی ورودیها rollback دارند و شیء محلی برگردانده میشود؛ در ۵ شیء حذف و با need=prior در missing گذاشته میشود تا از عضو دیگری بازیابی شود. - ۸. هدف طول log برای OSDی با ۶۰۰ PG با پیشفرضها چقدر است؟
۳۰۰۰۰۰/۶۰۰ = ۵۰۰، که بین ۲۵۰ و ۱۰۰۰۰ است؛ پس ۵۰۰. - ۹. چه شرطی تعیین میکند یک عضو backfill شود؟
اگر log_tail ما از last_update آن عضو جلوتر باشد یا last_backfill آن خالی باشد (عضو تازه). - ۱۰. backfill چگونه تشخیص میدهد شیئی باید از هدف حذف شود؟
شیئی که در بازهی هدف هست ولی کوچکتر از کوچکترین شیء باقیماندهی بازهی primary است، یعنی در primary وجود ندارد.
فصل ۳۶: بخش تخصصی (۳): RADOS — snapshot و clone، watch/notify و cls در سمت OSD، و مرجع rados و pool#
- ۱. چرا یک pool نمیتواند هم pool snapshot و هم self-managed snapshot داشته باشد؟
چون هر دو از یک snap_seq شماره میگیرند و SnapContext در یکی را OSD و در دیگری کلاینت تعیین میکند؛ ترکیب آنها مالکیت شمارهها را مبهم میکند و mon آن را رد میکند. - ۲. SnapContext چه فیلدهایی دارد و در RBD چه کسی آن را میفرستد؟
seq و فهرست نزولی snaps؛ librbd آن را از header تصویر میخواند و در هر نوشتن روی اشیای داده میفرستد. - ۳. شرط ساختن clone در make_writeable چیست؟
head وجود داشته باشد و whiteout نباشد، SnapContext دستکم یک snap داشته باشد و snaps[0] از snapset.seq بزرگتر باشد. - ۴. clone با چه شمارهای نامگذاری میشود؟
با snapc.seq، یعنی بزرگترین snap تازهای که clone نمایندهی آن است. - ۵. در مثال فصل، خواندن در snap 5 و snap 3 به چه نتیجهای میرسد؟
snap 5 به clone @۶ میرسد چون ۵ در clone_snaps[6] است؛ snap 3 به @۴ میرسد ولی ۳ در [۴] نیست، پس ENOENT. - ۶. whiteout چیست و چه زمانی حذف میشود؟
head حذفشدهای که برای نگه داشتن SnapSet باقی میماند؛ وقتی snaptrim آخرین clone را حذف کند، whiteout هم حذف میشود. - ۷. کلید
SNA_ در SnapMapper چه ساختاری دارد و چرا به این شکل است؟
SNA_<pool>_<snap به hex شانزدهرقمی>_ سپس پیشوند shard و hobject.to_str()؛ تا همهی cloneهای یک snap با یک اسکن بازهای پیدا شوند. - ۸. وقتی clone دیگر هیچ snapی ندارد، با clone_overlap چه میشود؟
اگر clone قدیمیتری باشد، overlap آن با overlap clone حذفشده اشتراک گرفته میشود؛ سپس ورودیهای clone از clones و clone_overlap و clone_size و clone_snaps پاک میشوند. - ۹. watch منقضیشده چگونه حذف میشود و چرا ممکن است تا مدتی بماند؟
پس از osd_client_watch_timeout بدون ping، با یک نوشتن روی شیء از object_info_t حذف میشود؛ اگر PG نوشتن نپذیرد، تا بازگشت آن میماند. - ۱۰. چرا فراخوانی cls با بقیهی opهای یک پیام اتمی است؟
چون متد روی همان OpContext اجرا میشود و همهی cls_cxx_*ها به همان تراکنش و همان ورودی log اضافه میشوند.
فصل ۳۷: بخش تخصصی (۴): RBD — چیدمان روی RADOS، striping، object map و fast-diff، و مرجع rbd#
- ۱. کدام کلیدهای header برای ساختن نام اشیای داده لازماند؟
object_prefix و order (و در صورت striping سفارشی، stripe_unit و stripe_count)؛ نام هر شیء object_prefix بههمراه شمارهی شیء به hex شانزدهرقمی است. - ۲. با data pool جدا، نام اشیای داده چه تغییری میکند و چرا؟
پیشوند به rbd_data.<شناسهی pool فراداده>.<id> تبدیل میشود تا اشیای imageهای چند pool که یک data pool مشترک دارند با هم برخورد نکنند. - ۳.
rbd_directory چه دو نوع کلیدی دارد؟
name_<name> که به id اشاره میکند و id_<id> که به نام اشاره میکند. - ۴. در مثال striping، بایت آفست ۱۱۰۰۰۰۰ در کدام شیء و کدام آفست است؟
block 16، stripe 4، stripepos 0؛ پس شیء ۰ در آفست ۳۱۳۵۶۸. - ۵. object map هر شیء را با چند بیت نگه میدارد و شیء ۰ در کدام بیتهای بایت اول است؟
دو بیت؛ شیء ۰ در دو بیت بالای بایت اول است (shift = ۶). - ۶. چرا footer object map برای هر بلوک ۴ KiB یک crc جدا دارد؟
تا بهروزرسانی یک شیء فقط همان بلوک ۴ KiB و crc آن را بازنویسی کند و کل نقشه لازم نباشد. - ۷. EXISTS_CLEAN چه زمانی تنظیم و چه زمانی پاک میشود؟
هنگام گرفتن snapshot همهی EXISTSهای head به EXISTS_CLEAN تبدیل میشوند؛ نخستین نوشتن بعدی روی آن شیء آن را به EXISTS برمیگرداند. - ۸. در fast-diff اگر شیء در from_snap DATA و در head EXISTS باشد، نتیجه چیست؟
DATA_UPDATED، چون حالت EXISTS (نه EXISTS_CLEAN) یعنی شیء پس از snapshot نوشته شده است. - ۹. چرا object map به exclusive-lock وابسته است؟
چون فقط یک نویسنده باید نقشه را تغییر دهد تا حالت حافظه و RADOS سازگار بمانند؛ مالک قفل همان نویسنده است. - ۱۰. namespace در RBD چگونه پیاده شده و چه مزیتی دارد؟
همان namespace در RADOS است و همهی اشیای فهرست (rbd_directory و دیگران) در هر namespace جدا ساخته میشوند؛ میتوان با cap یک کلاینت را به یک namespace محدود کرد بیآنکه pool جدا ساخت.
فصل ۳۸: بخش تخصصی (۵): RBD — مسیر I/O در librbd، layering و copyup، exclusive-lock، cache و QoS#
- ۱. لایهی EXCLUSIVE_LOCK پیش از کدام لایهها اجرا میشود و چرا؟
پیش از REFRESH، MIGRATION، JOURNAL، WRITE_BLOCK، WRITEBACK_CACHE و CORE؛ چون journal، object map و cache فقط برای مالک قفل معتبرند و نوشتن باید پیش از رسیدن به آنها منتظر قفل بماند. - ۲. چه زمانی copyup بدون فرستادن نخستین نوشتن انجام میشود؟
وقتی object map میگوید شیء در clone وجود ندارد و extent در overlap والد است؛ librbd مستقیم copyup میکند و نوشتن را به همان op میچسباند. - ۳. چرا متد cls
copyup اگر شیء وجود داشته باشد کاری نمیکند؟
چون اگر کلاینت دیگری زودتر copyup کرده باشد، دادهی والد نباید روی نوشتنهای تازهتر کلاینت دیگر بازنویسی شود؛ نوشتن همراه در همان op بههرحال اعمال میشود. - ۴. deep-flatten چه چیزی را اضافه میکند؟
copyup به snapshotهای clone هم میرسد (copyup جدا با SnapContext خالی و بهروزرسانی object map snapshotها)، پس snapshotهای clone هم از والد مستقل میشوند. - ۵. cookie قفل
rbd_lock چه ساختاری دارد و به چه کاری میآید؟
«auto <watch handle>» با tag internal؛ با مقایسهی آدرس و handle با list_watchers میتوان فهمید مالک قفل هنوز watch زنده دارد. - ۶. چرا شکستن قفل بدون blocklist خطرناک است؟
چون مالک قدیمی ممکن است فقط از شبکه جدا شده باشد و نوشتنهای در مسیرش بعداً روی دادهی مالک جدید فرود آیند. - ۷. writearound چه زمانی نوشتن را بلافاصله تأیید نمیکند؟
وقتی max_dirty صفر باشد یا پرچم FUA داده شود، وقتی extent با نوشتن در جریان همپوشانی داشته باشد، یا وقتی بایتهای در جریان به rbd_cache_max_dirty رسیده باشند. - ۸.
rbd_cache_writethrough_until_flush از چه چیزی محافظت میکند؟
از مهمانی که هرگز flush نمیفرستد؛ تا نخستین flush همهی نوشتنها همگاماند. - ۹. با
rbd_qos_iops_limit = 1000 و tick ۵۰ ms، در هر tick چند توکن اضافه میشود؟
۱۰۰۰ × ۰.۰۵ = ۵۰ توکن. - ۱۰. دو دلیل برای استفاده از rbd-nbd بهجای krbd نام ببرید.
نیاز به ویژگیهایی که krbd ندارد (journaling، cache یا QoS در librbd، LUKS در librbd) و هستهی قدیمی که ویژگیهای image را پشتیبانی نمیکند.
فصل ۳۹: بخش تخصصی (۶): RBD — درون rbd-mirror: journal در برابر snapshot#
- ۱. نام اشیای header و دادهی journal چیست؟
header در journal.<image-id> و داده در journal_data.<pool-id>.<image-id>.<n>. - ۲. رویداد با entry_tid ۱۲۳۴ در journal با splay_width ۴ و active_set ۹ در کدام شیء نوشته میشود؟
splay_offset = ۱۲۳۴ % ۴ = ۲؛ شیء ۹ × ۴ + ۲ = ۳۸، یعنی journal_data.<pool>.<id>.38. - ۳. سربار ثابت هر رویداد journal چند بایت است و از چه فیلدهایی تشکیل میشود؟
۳۳ بایت: preamble ۸، version ۱، entry tid ۸، tag tid ۸، طول داده ۴ و crc32c ۴. - ۴. چرا نوشتن داده باید منتظر SAFE شدن رویداد بماند؟
تا اگر کلاینت پس از نوشتن داده و پیش از ثبت رویداد از کار بیفتد، مقصد (و replay محلی) تغییری را ببیند که در journal نیست؛ ترتیب «اول رویداد» تضمین میکند هر تغییر داده در journal هست. - ۵. چه چیزی جلوی trim شدن journal را میگیرد؟
commit position کندترین client ثبتشده؛ setهای پیش از کمترین commit set حذف نمیشوند. - ۶. چرا مقصد در حالت journal همیشه crash-consistent است؟
چون رویدادها با همان ترتیب و نقاط flush مبدأ replay میشوند، پس مقصد همیشه حالت مبدأ در یک لحظهی گذشته را دارد. - ۷. چهار حالت snapshot mirror کداماند؟
PRIMARY، PRIMARY_DEMOTED، NON_PRIMARY و NON_PRIMARY_DEMOTED. - ۸. rbd-mirror در حالت snapshot چگونه اشیای تغییرکرده را پیدا میکند؟
با object map diff (fast-diff) میان دو snapshot mirror متوالی در مبدأ و کپی فقط اشیای DATA_UPDATED یا HOLE_UPDATED. - ۹. چه زمانی حالت snapshot پهنای باند بیشتری از حالت journal مصرف میکند؟
وقتی نوشتنها کوچک و پراکنده روی اشیای زیاد باشند؛ هر شیء تغییرکرده کامل (تا ۴ MiB) منتقل میشود. - ۱۰. leader در rbd-mirror چگونه انتخاب میشود و پس از چه مدتی جایگزین میشود؟
با قفل cls_lock انحصاری روی rbd_mirror_leader و heartbeat هر ۵ ثانیه؛ پس از دو heartbeat از دست رفته، دیگران قفل را میشکنند و leader تازه انتخاب میشود.
فصل ۴۰: بخش تخصصی (۷): RGW — مدل داده روی RADOS: فراداده، bucket index، نسخهبندی، manifest و multipart#
- ۱. entrypoint و instance یک bucket چه فرقی دارند و reshard کدام را عوض میکند؟
entrypoint با نام bucket فقط به instance فعلی اشاره میکند؛ instance (.bucket.meta.<bucket>:<id>) همهی ویژگیها و layout ایندکس را دارد. reshard یک instance تازه با bucket_id جدید میسازد و entrypoint را به آن میبرد؛ marker ثابت میماند. - ۲. کلید ورودی bilog در omap ایندکس چه ساختاری دارد؟
در حالت InIndex: بایت ۰x80، پیشوند 0_، سپس index_ver با قالب %011llu، نقطه، نسخهی OSD و نقطه و شمارهی subop. - ۳. چرا کلیدهای ویژه با بایت ۰x80 شروع میشوند؟
تا از نامهای معمولی جدا شوند: در UTF-8 هیچ نامی با ۰x80 شروع نمیشود، پس بایت اول نوع کلید را معلوم میکند. فهرستگیری باید بازهی ۰x80 را رد کند چون نامهای غیر ASCII پس از آن مرتب میشوند. - ۴.
size و accounted_size در ورودی ایندکس چه فرقی دارند؟
size حجم واقعی ذخیرهشده (پس از فشردهسازی یا رمزنگاری) است و accounted_size حجمی که کاربر فرستاده و دیده؛ سهمیه و آمار بر پایهی دومی است. - ۵. اگر RGW پس از prepare و نوشتن داده ولی پیش از complete از کار بیفتد، ورودی چگونه ترمیم میشود؟
برچسب در pending_map میماند. فهرستگیری بعدی وقتی برچسب از rgw_pending_bucket_index_op_expiration (۱۲۰ ثانیه) قدیمیتر باشد، head را با check_disk_state میخواند و با dir_suggest_changes ورودی را بهروز یا حذف میکند. bucket check --fix هم همین کار را برای همه انجام میدهد. - ۶. OLH چیست و در کجا ذخیره میشود؟
object logical head؛ نشانگر نسخهی جاری. یک ورودی 1001_<name> در ایندکس (با log تغییرات) و یک شیء head بیداده با نام اصلی که xattrهای user.rgw.olh.* دارد. - ۷. حذف بدون versionId در bucket نسخهدار چه میکند؟
یک instance تازه از نوع delete marker میسازد و با link_olh آن را نسخهی جاری میکند؛ هیچ دادهای پاک نمیشود و GET بدون versionId ۴۰۴ میدهد. - ۸. head یک شیء COLD در کدام pool است و چه دارد؟
در pool STANDARD placement bucket؛ بدون داده، فقط manifest و xattrها. همهی داده در tailهای pool COLD است. - ۹. ETag آپلود سهبخشی چگونه ساخته میشود؟
md5 الحاق ETagهای دودویی بخشها به ترتیب، بهصورت hex، بهاضافهی - و تعداد بخشها. - ۱۰. پیشوند
2~ در upload_id چه چیزی را نشان میدهد؟
upload با قالب جدید (v2) ساخته شده و کلیدهای omap بخشها part.%08d و در نتیجه بهترتیب عددی مرتباند.
فصل ۴۱: بخش تخصصی (۸): RGW — مسیر درخواست، SigV4، سهمیه، محدودیت نرخ، gc و lifecycle#
- ۱. مراحل اصلی
rgw_process_authenticated به ترتیب کداماند؟
init permissions و خواندن مجوزها، init op، بررسی op mask، بررسی CORS، بررسی مجوز op، بررسی پارامترها، pre-exec، بررسی محدودیت نرخ، execute و complete. - ۲. RGW اختلاف زمان مجاز درخواست SigV4 را چقدر میگیرد و چه خطایی میدهد؟
RGW_AUTH_GRACE یعنی ۱۵ دقیقه؛ بیش از آن با RequestTimeTooSkewed رد میشود. - ۳. کلید امضای SigV4 چگونه از کلید محرمانه مشتق میشود؟
چهار HMAC-SHA256 زنجیرهای: کلید اول «AWS4» بهاضافهی secret روی تاریخ، سپس region، سپس نام سرویس s3 و در پایان رشتهی aws4_request. - ۴. چه چیزی توان یک جریان PUT را محدود میکند و کدام گزینه آن را تنظیم میکند؟
حجم دادهی در پرواز تقسیم بر تأخیر نوشتن RADOS؛ با rgw_put_obj_min_window_size (۱۶ MiB) تنظیم میشود (برای GET rgw_get_obj_window_size). - ۵. در حالت پیشفرض، سهمیهی حجم شیء ۱۰۰ بایتی را چقدر حساب میکند؟
۴۰۹۶ بایت، چون DefApplier اندازه را تا مضرب ۴ KiB گرد میکند (مگر check_on_raw روشن باشد). - ۶. چرا سهمیه در RGW «نرم» است؟
هر RGW آمار را از cache خود میخواند و cache پس از rgw_bucket_quota_ttl تازه میشود؛ چند RGW همزمان میتوانند کمی از سقف عبور کنند. - ۷. محدودیت نرخ ۶۰۰ read op در دقیقه پشت سه RGW در عمل چقدر است؟
تا حدود ۱۸۰۰ در دقیقه، چون هر RGW سطل توکن مستقل دارد. - ۸. shard gc یک زنجیره چگونه انتخاب میشود و چرا tail فوراً حذف نمیشود؟
XXH64 برچسب با seed ثابت به پیمانهی rgw_gc_max_objs (۳۲). tail دستکم rgw_gc_obj_min_wait (۲ ساعت) نگه داشته میشود تا GETهای در جریان که manifest قدیمی را دارند ناقص نمانند. - ۹. lifecycle چگونه bucket را به shard میبرد و در چه بازهای کار میکند؟
کلید «tenant:bucket:marker» با ceph_str_hash_linux به پیمانهی ۷۸۷۷ و سپس rgw_lc_max_objs به یک شیء lc.N میرود؛ کارگرها فقط در rgw_lifecycle_work_time (۰۰:۰۰ تا ۰۶:۰۰) کار میکنند. - ۱۰. چرا bucket_lc_process مقدار marker را بررسی میکند؟
اگر bucket حذف و با همان نام دوباره ساخته شده باشد، marker فرق دارد و ورودی کهنه نباید روی bucket جدید اجرا شود.
فصل ۴۲: بخش تخصصی (۹): RGW — درون multisite: period، قالب لاگها، نسلهای bucket و موتور همگامسازی#
- ۱. commit یک period چه سه شرطی را پیش از هر چیز بررسی میکند؟
commit فقط روی master zone انجام میشود، predecessor_uuid باید برابر period جاری باشد و realm_epoch باید دقیقاً یکی بیشتر از period جاری باشد. - ۲. چه زمانی commit شناسهی period را عوض میکند و پیامدش برای mdlog چیست؟
وقتی master zone تغییر کند؛ period جدید با epoch اول ساخته میشود و mdlog با پیشوند تازهی meta.log.<period>. شروع میشود، پس zoneها باید لاگ period قدیمی را تا انتها بخوانند و سپس سراغ لاگ جدید بروند. - ۳. zones_trace در bilog چه مشکلی را حل میکند؟
از رفتوبرگشت بیپایان تغییرها در active-active جلوگیری میکند: zoneهایی که تغییر از آنها گذشته ثبت میشوند و دوباره برایشان فرستاده نمیشود. - ۴. کلید یک ورودی datalog چه چیزی را مشخص میکند؟
یک bucket shard (bucket:instance:shard) و در صورت نیاز نسل آن؛ یعنی «در این shard چیزی تغییر کرده، bilog آن را بخوان». - ۵. وضعیت همگامسازی یک bucket shard در کدام شیء و کدام pool است؟
در bucket.sync-status.<src-zone>:<bucket>:<shard> (با پسوند نسل در صورت وجود) در pool لاگ zone مقصد. - ۶. چرا marker shard datalog با وجود شکست یک bucket جلو میرود و شکست کجا ثبت میشود؟
تا یک bucket خراب کل shard را متوقف نکند. کلید شکستخورده در error repo یعنی omap شیء datalog.sync-status.shard.<zone>.<N>.retry ثبت و جداگانه تکرار میشود. - ۷. lease و bid در همگامسازی چه نقشی دارند؟
تضمین میکنند هر shard در هر لحظه فقط یک پردازشگر داشته باشد (lease با rgw_sync_lease_period) و bid shardها را میان RGWها پخش میکند. - ۸. پس از reshard در zone مبدأ، zone مقصد چگونه بدون full sync ادامه میدهد؟
مبدأ bilogهای نسل قبلی را نگه میدارد؛ مقصد همهی shardهای نسل قدیم را تمام میکند (shards_done_with_gen)، سپس incremental_gen را به نسل جدید با تعداد shard تازه میبرد. - ۹. تعارض نوشتن همزمان با چه ترتیبی از معیارها حل میشود؟
mtime (با دقت ثانیه مگر high precision)، سپس zone_short_id و در پایان pg_ver. - ۱۰. چرا ساختن bucket در zone غیر master به در دسترس بودن master وابسته است؟
فراداده (کاربر، bucket) فقط در master نوشته میشود؛ zoneهای دیگر درخواست را به master میفرستند و آن را با metadata sync دریافت میکنند.