راهنمای جامع Ceph
Englishشروع کنید
در این صفحه
پیوست ه

پاسخ پرسش‌های مرور

۱ ساعت و ۵۶ دقیقه مطالعه

پاسخ‌های زیر کوتاه و راهنما هستند؛ برای توضیح کامل به بخش «تکمیلی و به‌روز» همان فصل برگردید.

فصل ۱: ‏Ceph‏: آغاز دورانی تازه — معماری، برنامه‌ریزی و نخستین کلاستر#

  1. ۱. سه محدودیت بنیادی آرایه‌های ذخیره‌سازی سنتی که ذخیره‌سازی نرم‌افزارمحور برطرف می‌کند کدام‌اند؟
    مقیاس عمودی محدود به جفت کنترلر، وابستگی به سخت‌افزار و نرم‌افزار یک فروشنده، و جزیره‌های داده (محصول جدا برای بلوک، فایل و شیء). ‏Ceph‏ با مقیاس افقی روی سرورهای معمولی و ارائه‌ی هر سه رابط روی یک ‏RADOS‏ مشترک آن‌ها را برطرف می‌کند.
  2. ۲. چرا زمان بازسازی ‏RAID‏ با بزرگ‌تر شدن دیسک‌ها بدتر می‌شود، اما زمان بازیابی ‏Ceph‏ با بزرگ‌تر شدن کلاستر بهتر می‌شود؟
    بازسازی ‏RAID‏ به سرعت نوشتن یک دیسک یدک محدود است و با بزرگ شدن دیسک‌ها زمانش خطی زیاد می‌شود. در ‏Ceph‏ داده‌ی ‏OSD‏ خراب در صدها ‏PG‏ پخش است و همه‌ی ‏OSD‏های سالم موازی می‌خوانند و می‌نویسند؛ هرچه ‏OSD‏ بیشتری باشد، سهم هر کدام کمتر و ترمیم سریع‌تر است.
  3. ۳. نقش ‏MON‏ و ‏OSD‏ را در مسیر نوشتن یک شیء مقایسه کنید. آیا داده از ‏MON‏ عبور می‌کند؟
    ‏MON‏ فقط نقشه‌ی کلاستر را به کلاینت می‌دهد و در اجماع درباره‌ی تغییر نقشه شرکت می‌کند. داده از ‏MON‏ عبور نمی‌کند؛ کلاینت مستقیم به ‏OSD‏ اصلی می‌نویسد و ‏OSD‏ اصلی تکثیر به ثانویه‌ها را هماهنگ می‌کند.
  4. ۴. لایه‌ی ‏PG‏ چه مشکلی را حل می‌کند و اگر وجود نداشت چه می‌شد؟
    ‏PG‏ میلیاردها شیء را در چند هزار گروه تجمیع می‌کند تا همتاسازی، بازیابی و ‏scrub‏ در سطح گروه انجام شود. بدون آن، ‏OSD‏ها باید وضعیت هر شیء را جداگانه ردیابی می‌کردند و سربار حافظه و پیام‌رسانی غیرقابل‌تحمل می‌شد.
  5. ۵. چرا تعداد ‏MON‏ها فرد انتخاب می‌شود؟ چهار ‏MON‏ چند خرابی را تحمل می‌کنند؟
    برای تصمیم‌گیری اکثریت (‏quorum‏) لازم است؛ با عدد فرد، بیشترین تحمل خرابی به ازای کمترین عضو به دست می‌آید. چهار ‏MON‏ به اکثریت سه نیاز دارند و فقط یک خرابی را تحمل می‌کنند، یعنی همان سه ‏MON‏.
  6. ۶. تفاوت ‏size‏ و ‏min_size‏ چیست و چرا ‏min_size=1‏ خطرناک است؟
    ‏size‏ تعداد نسخه‌های مطلوب است و ‏min_size‏ کمترین تعداد نسخه‌ی در دسترس برای پذیرش ‏I/O‏. با ‏min_size=1‏ ممکن است نوشتنی فقط روی یک ‏OSD‏ تأیید شود و با خرابی همان ‏OSD‏، داده‌ی تأییدشده از دست برود.
  7. ۷. چه زمانی شبکه‌ی کلاستر جداگانه مفید است و چه خطری دارد؟
    وقتی ترافیک تکثیر و بازیابی آن‌قدر زیاد است که با ترافیک کلاینت رقابت می‌کند، جداسازی مفید است. خطرش این است که اگر شبکه‌ی کلاستر جزئی خراب شود، ‏OSD‏ها همدیگر را ‏down‏ گزارش می‌کنند در حالی که از دید ‏MON‏ زنده‌اند و ‏flapping‏ رخ می‌دهد.
  8. ۸. چرا ‏SSD‏ بدون ‏PLP‏ برای ‏Ceph‏ نامناسب است؟
    ‏Ceph‏ برای هر نوشتن پایدار ‏flush‏ می‌کند؛ ‏SSD‏ بدون ‏PLP‏ باید ‏cache‏ را واقعاً روی ‏flash‏ بنویسد و بسیار کند می‌شود، و در قطع برق ممکن است داده‌ی تأییدشده را از دست بدهد.
  9. ۹. ‏cephadm‏ در ‏bootstrap‏ چه فایل‌هایی در ‏/etc/ceph‏ می‌سازد و کدام‌یک حساس‌ترین است؟
    ‏ceph.conf‏ حداقلی، ‏ceph.client.admin.keyring‏ و ‏ceph.pub‏. حساس‌ترین فایل ‏keyring‏ مدیر است که دسترسی کامل به کلاستر می‌دهد.
  10. ۱۰. دو تغییر پیش‌فرض ‏Umbrella‏ که می‌تواند پس از ارتقا رفتار کلاستر را عوض کند کدام‌اند؟
    افزایش ‏mon_target_pg_per_osd‏ از ۱۰۰ به ۲۰۰ و ‏mon_max_pg_per_osd‏ از ۲۵۰ به ۵۰۰، که می‌تواند باعث افزایش ‏PG‏های ‏pool‏ها پس از ارتقا شود. (تغییر تنظیمات ‏shard‏ در زمان‌بند ‏mClock‏ برای ‏HDD‏ هم نمونه‌ی دیگری است.)

فصل ۲: کار با ‏Ceph Block Device‏ (RBD)#

  1. ۱. یک ‏image‏ صد گیگابایتی تازه‌ساخته‌شده که هنوز در آن نوشته نشده، چند شیء در ‏RADOS‏ دارد؟ چرا؟
    تقریباً هیچ شیء داده‌ای؛ فقط اشیای فراداده (‏header‏، ‏id‏ و ورودی در ‏directory‏ و در صورت فعال بودن ‏object map‏). ‏RBD thin‏ است و شیء داده فقط پس از نخستین نوشتن در بازه‌ی متناظرش ساخته می‌شود.
  2. ۲. تفاوت ‏krbd‏، ‏librbd‏ و ‏rbd-nbd‏ چیست و هر کدام کجا مناسب است؟
    ‏krbd‏ راه‌انداز هسته است و دستگاه ‏/dev/rbdX‏ می‌سازد؛ سریع و مناسب میزبان‌های فیزیکی و ‏Kubernetes‏، اما ویژگی‌هایش وابسته به نسخه‌ی هسته است. ‏librbd‏ کتابخانه‌ی کامل فضای کاربر است که ‏QEMU‏ و ‏OpenStack‏ از آن استفاده می‌کنند. ‏rbd-nbd‏ دستگاه بلوکی هسته را روی ‏librbd‏ می‌سازد؛ وقتی به ویژگی‌ای نیاز دارید که ‏krbd‏ ندارد.
  3. ۳. چرا ویژگی ‏object-map‏ به ‏exclusive-lock‏ وابسته است؟
    ‏object-map‏ وضعیت وجود اشیاء را در حافظه‌ی کلاینت نگه می‌دارد و فقط وقتی معتبر است که یک کلاینت تنها نویسنده باشد؛ ‏exclusive-lock‏ همین انحصار را تضمین می‌کند.
  4. ۴. ‏snapshot crash-consistent‏ با ‏application-consistent‏ چه فرقی دارد و چطور دومی را به دست می‌آوریم؟
    ‏crash-consistent‏ مثل قطع برق است: هر چه روی دیسک بود ثبت شده، اما ‏buffer‏ و تراکنش‌های نیمه‌کاره نه. ‏application-consistent‏ با منجمد کردن فایل‌سیستم (‏fsfreeze‏ یا ‏guest agent‏) یا سازوکار خود برنامه (حالت ‏backup‏ پایگاه داده) پیش از ‏snapshot‏ به دست می‌آید.
  5. ۵. در قالب ‏clone‏ نسخه‌ی ۲ چه چیزی نسبت به نسخه‌ی ۱ عوض شده است؟
    در نسخه‌ی ۲ نیازی به ‏snap protect‏ نیست و ‏snapshot‏ والد دارای فرزند را می‌توان «حذف» کرد؛ ‏snapshot‏ به ‏trash‏ منتقل می‌شود تا آخرین فرزند ‏flatten‏ یا حذف شود. نیازمند حداقل کلاینت سازگار ‏Mimic‏ است.
  6. ۶. حالت‌های ‏journal‏ و ‏snapshot‏ در ‏mirroring‏ را از نظر ‏RPO‏، سربار و سازگاری با ‏krbd‏ مقایسه کنید.
    ‏journal: RPO‏ چندثانیه‌ای، تقریباً دو برابر نوشتن، فقط ‏librbd. snapshot: RPO‏ برابر فاصله‌ی زمان‌بندی، سربار کم، با ‏krbd‏ هم کار می‌کند.
  7. ۷. تفاوت ‏--direction rx-only‏ و ‏rx-tx‏ در ‏bootstrap import‏ چیست؟
    ‏rx-only‏ یعنی کلاستر محلی فقط دریافت‌کننده است (یک‌طرفه). ‏rx-tx‏ یعنی هر دو کلاستر می‌توانند مبدأ و مقصد باشند (دوطرفه) و پس از ‏failover‏ نیاز به پیکربندی دوباره نیست.
  8. ۸. چرا ‏promote‏ اجباری بدون ‏fencing‏ خطرناک است؟
    اگر سایت اصلی هنوز زنده باشد و کلاینت‌هایش بنویسند، دو ‏primary‏ با تاریخچه‌ی متفاوت به وجود می‌آید (‏split-brain‏) و یکی از دو مجموعه‌ی تغییرات باید دور ریخته شود.
  9. ۹. گام‌های ‏failback‏ پس از بازگشت سایت اصلی کدام‌اند؟
    ‏demote image‏ در سایت اصلی، ‏resync‏ آن از ‏primary‏ فعلی، صبر تا وضعیت ‏up+replaying‏، سپس ‏demote‏ در سایت پشتیبان و ‏promote‏ در سایت اصلی.
  10. ۱۰. برای میزبان ‏VMware‏ که کلاینت ‏Ceph‏ ندارد، امروز کدام راه برای استفاده از ‏RBD‏ توصیه می‌شود؟
    دروازه‌ی ‏NVMe-oF‏ روی ‏TCP‏ با دست‌کم دو دروازه در یک ‏gateway group‏ برای ‏HA‏؛ ‏iSCSI‏ در حالت نگه‌داری است.

فصل ۳: ‏Ceph‏ و ‏OpenStack‏#

  1. ۱. سه دلیل اصلی که ‏Ceph‏ را به پشتوانه‌ی محبوب ‏OpenStack‏ تبدیل کرده کدام‌اند؟
    یک پشتوانه‌ی واحد برای همه‌ی سرویس‌ها (بلوک، ‏image‏، ‏backup‏، فایل و شیء)، ‏copy-on-write‏ سرتاسری که ساخت ‏VM‏ را آنی می‌کند، و ذخیره‌سازی مشترک که ‏live migration‏ و ‏evacuate‏ را بدون انتقال دیسک ممکن می‌کند؛ به‌علاوه‌ی مقیاس افقی و متن‌باز بودن.
  2. ۲. چرا ‏client.cinder‏ روی ‏pool‏ ‏images‏ فقط مجوز خواندن دارد؟
    ‏Cinder‏ و ‏Nova‏ فقط باید از ‏snapshot image‏ها ‏clone‏ بسازند؛ نوشتن یا حذف ‏image‏ وظیفه‌ی ‏Glance‏ است. اصل کمترین دسترسی از ‏image‏ها در برابر خطا یا نفوذ در ‏cinder‏ محافظت می‌کند.
  3. ۳. چه دو شرطی برای ‏copy-on-write‏ بین ‏Glance‏ و ‏Cinder‏ لازم است؟
    ‏image‏ در ‏Glance‏ با قالب ‏raw‏ ذخیره شده باشد و ‏show_image_direct_url = True‏ باشد تا ‏Cinder‏ نشانی ‏RBD‏ را ببیند؛ و طبعاً هر دو سرویس به همان کلاستر ‏Ceph‏ متصل باشند.
  4. ۴. ‏secret‏ در ‏libvirt‏ چه نقشی دارد و چرا ‏UUID‏ آن باید روی همه‌ی ‏compute‏ها یکسان باشد؟
    ‏QEMU‏ کلید ‏Ceph‏ را از ‏libvirt‏ می‌گیرد و ‏XML‏ دامنه فقط به ‏UUID secret‏ ارجاع می‌دهد. در ‏live migration‏ همان ‏XML‏ به میزبان مقصد می‌رود، پس ‏secret‏ با همان ‏UUID‏ باید آن‌جا هم وجود داشته باشد.
  5. ۵. گزینه‌ی ‏images_type = rbd‏ در ‏Nova‏ چه چیزی را عوض می‌کند و چه مزیتی برای ‏evacuate‏ دارد؟
    دیسک ریشه‌ی ‏VM‏ به‌جای فایل روی دیسک محلی، یک ‏image‏ در ‏pool‏ ‏vms‏ می‌شود. اگر ‏compute‏ خراب شود، می‌توان ‏VM‏ را روی ‏compute‏ دیگری ‏evacuate‏ کرد چون دیسکش روی ‏Ceph‏ سالم است.
  6. ۶. ‏rbd_flatten_volume_from_snapshot‏ و ‏rbd_max_clone_depth‏ چه مصالحه‌ای را کنترل می‌کنند؟
    سرعت ساخت ‏volume‏ (بدون ‏flatten‏ و با ‏clone‏ عمیق) در برابر وابستگی‌های زنجیره و کارایی خواندن. ‏flatten‏ زنجیره را قطع می‌کند اما زمان و فضای بیشتری می‌گیرد.
  7. ۷. چرا ‏backup‏ روی همان کلاستر ‏Ceph‏ کافی نیست؟
    چون در برابر خرابی یا خطای همان کلاستر (حذف اشتباه، باگ، دسترسی مهاجم به کلید مدیر) محافظتی ندارد. ‏backup‏ باید در کلاستر یا سایت دیگری باشد.
  8. ۸. دو درایور ‏Manila‏ برای ‏CephFS‏ چه تفاوتی دارند؟
    درایور بومی کلاینت ‏CephFS‏ را مستقیم در مهمان استفاده می‌کند (سریع اما نیازمند دسترسی شبکه‌ای مهمان به ‏Ceph‏)، درایور ‏NFS‏ اشتراک‌ها را از طریق ‏NFS-Ganesha‏ صادر می‌کند (جداسازی بهتر، یک لایه‌ی اضافه).
  9. ۹. ‏disk_cachemodes = "network=writeback"‏ چرا امن است؟
    چون ‏librbd flush‏های مهمان را رعایت می‌کند و با ‏rbd cache writethrough until flush‏ تا وقتی مهمان ‏flush‏ نفرستاده، ‏cache‏ در حالت ‏writethrough‏ می‌ماند.
  10. ۱۰. چرا بهتر است ‏Ceph‏ را مستقل از ابزار استقرار ‏OpenStack‏ مدیریت کنیم؟
    تا چرخه‌ی عمر و ارتقای دو سیستم مستقل باشد، مشکل یکی به دیگری سرایت نکند، و ‏Ceph‏ بتواند هم‌زمان به مصرف‌کنندگان دیگر (‏Kubernetes‏، ‏S3‏) هم سرویس دهد.

فصل ۴: ذخیره‌سازی شیء با ‏RADOS Gateway‏#

  1. ۱. چرا ‏RGW‏ را «بدون حالت» می‌نامیم و این چه اثری بر طراحی دسترس‌پذیری بالا دارد؟
    چون هیچ داده یا وضعیت پایداری در خود فرایند ‏radosgw‏ نگه داشته نمی‌شود و همه‌چیز در ‏RADOS‏ است. پس هر تعداد نمونه را می‌توان پشت ‏load balancer‏ قرار داد و خرابی یک نمونه فقط درخواست‌های در جریانش را تحت تأثیر قرار می‌دهد.
  2. ۲. یک شیء ‏S3‏ بیست‌مگابایتی در ‏RADOS‏ به چه اشیایی تبدیل می‌شود؟
    یک ‏head object‏ (حدود ۴ مگابایت نخست داده به‌همراه فراداده و ‏manifest‏)، چند ‏tail object‏ برای بقیه‌ی داده، و یک ورودی ‏omap‏ در یکی از ‏shard‏های ‏index bucket‏.
  3. ۳. چرا ‏pool index‏ نباید ‏EC‏ یا روی ‏HDD‏ باشد؟
    ‏index‏ در ‏omap‏ نگه داشته می‌شود که ‏EC‏ از آن پشتیبانی نمی‌کند؛ و هر ‏PUT‏ و ‏DELETE‏ یک به‌روزرسانی ‏index‏ است، پس تأخیر ‏HDD‏ مستقیماً تأخیر همه‌ی عملیات می‌شود.
  4. ۴. ‏resharding‏ پویا چه مشکلی را حل می‌کند و آستانه‌ی پیش‌فرض آن چیست؟
    از بزرگ شدن بیش از حد ‏shard‏های ‏index‏ (اشیای ‏omap‏ غول‌پیکر) جلوگیری می‌کند؛ با رسیدن تعداد اشیاء هر ‏shard‏ به ‏rgw_max_objs_per_shard‏ (پیش‌فرض ۱۰۰٬۰۰۰) ‏shard‏ها خودکار افزایش می‌یابند.
  5. ۵. تفاوت ‏tenant‏ و ‏account‏ چیست؟
    ‏tenant‏ یک فضای نام برای ‏bucket‏ها و کاربران است؛ ‏account‏ (از ‏Squid‏) یک واحد مالکیت به سبک ‏AWS‏ است که کاربر ریشه‌اش کاربران، گروه‌ها، نقش‌ها و سیاست‌ها را با ‏API IAM‏ خودش مدیریت می‌کند.
  6. ۶. برای دسترسی ‏virtual-hosted-style‏ چه پیکربندی‌هایی لازم است؟
    رکورد ‏DNS wildcard‏ برای دامنه، تنظیم ‏rgw_dns_name‏ (یا ‏hostnames‏ در ‏zonegroup‏) و گواهی ‏TLS wildcard‏.
  7. ۷. دو حالت ‏GOVERNANCE‏ و ‏COMPLIANCE‏ در ‏object lock‏ چه فرقی دارند؟
    در ‏GOVERNANCE‏ کاربر دارای مجوز ‏bypass‏ می‌تواند قفل را دور بزند؛ در ‏COMPLIANCE‏ هیچ کاربر ‏S3‏ای تا پایان مهلت نمی‌تواند نسخه را حذف یا مدت را کوتاه کند.
  8. ۸. چرا پس از حذف انبوه اشیاء، فضای کلاستر فوراً آزاد نمی‌شود؟
    فقط ‏head object‏ فوراً حذف می‌شود؛ ‏tail‏ها به ‏garbage collector‏ سپرده می‌شوند و پس از ‏rgw_gc_obj_min_wait‏ پاک می‌شوند.
  9. ۹. گزینه‌ی ‏rgw_s3_auth_use_keystone‏ چه امکانی فراهم می‌کند؟
    اجازه می‌دهد کلاینت ‏S3‏ با اعتبارنامه‌های ‏EC2‏ که در ‏Keystone‏ ساخته شده‌اند احراز هویت شود و ‏RGW‏ آن‌ها را نزد ‏Keystone‏ اعتبارسنجی کند.
  10. ۱۰. چرا ‏S3A committers‏ برای ‏Spark‏ روی ‏RGW‏ مهم‌اند؟
    چون ‏commit‏ سنتی ‏Hadoop‏ با ‏rename‏ کار می‌کند که در ‏S3‏ یعنی کپی و حذف همه‌ی اشیاء؛ ‏committer‏های ‏S3A‏ با ‏multipart upload‏ که فقط در ‏commit‏ نهایی تکمیل می‌شود، این هزینه را حذف می‌کنند و خروجی را امن و سریع می‌نویسند.

فصل ۵: ذخیره‌سازی شیء چندسایتی با ‏RGW Multi-Site‏#

  1. ۱. تفاوت نقش ‏zonegroup‏ و ‏realm‏ در تکثیر داده و فراداده چیست؟
    ‏zonegroup‏ مرز تکثیر داده است: داده‌ی ‏bucket‏ها فقط بین ‏zone‏های یک ‏zonegroup‏ تکثیر می‌شود. ‏realm‏ مرز فضای نام و فراداده است: کاربران و ‏bucket‏ها در کل ‏realm‏ یکتا و همگام‌اند.
  2. ۲. ‏period‏ چیست و چرا پس از تغییرات ساختاری باید ‏commit‏ شود؟
    ‏period‏ نسخه‌ی نام‌دار و ‏epoch‏‌دار پیکربندی ‏realm‏ است. ‏commit‏ آن، پیکربندی جدید را به همه‌ی ‏zone‏ها منتشر می‌کند تا همه درباره‌ی ساختار و ‏master‏ توافق داشته باشند.
  3. ۳. سه تفاوت اصلی ‏multisite‏ نسخه‌ی ۲ با پیکربندی ‏federated‏ در ‏Hammer‏ کدام‌اند؟
    همگام‌سازی درون ‏radosgw‏ به‌جای ‏radosgw-agent‏ بیرونی؛ ‏active-active‏ به‌جای ‏slave‏ فقط‌خواندنی؛ و مفهوم ‏realm‏ و ‏period‏ برای پیکربندی نسخه‌دار و ‏failover‏.
  4. ۴. چرا ساخت ‏bucket‏ در ‏zone‏ غیر ‏master‏ هنگام از دست رفتن ‏master‏ شکست می‌خورد اما نوشتن شیء نه؟
    ساخت ‏bucket‏ عملیات فراداده‌ای است که باید در ‏master zone‏ ثبت شود و درخواست به ‏master forward‏ می‌شود؛ نوشتن شیء در ‏bucket‏ موجود محلی است و بعداً همگام می‌شود.
  5. ۵. کاربر ‏system‏ چه نقشی دارد و چرا باید به‌شدت حفاظت شود؟
    ‏zone‏ها با کلید آن لاگ‌ها و اشیای همدیگر را می‌خوانند؛ دسترسی کامل به داده و فراداده‌ی ‏realm‏ دارد، پس افشای آن یعنی افشای کل داده.
  6. ۶. در خروجی ‏sync status‏ عبارت «‏oldest incremental change not applied‏» چه اطلاعاتی می‌دهد؟
    زمان قدیمی‌ترین تغییری که هنوز در این ‏zone‏ اعمال نشده؛ تفاوت آن با زمان فعلی برآورد ‏RPO‏ واقعی است.
  7. ۷. گام‌های ‏failover‏ و بازگرداندن ‏master‏ قدیمی را بنویسید.
    ‏failover‏: در ‏zone‏ سالم ‏zone modify --master --default‏، ‏period update --commit‏ و راه‌اندازی دوباره‌ی ‏RGW‏، سپس تغییر ‏DNS‏. بازگشت: در ‏zone‏ قدیمی ‏realm pull‏ و ‏period pull‏، بررسی ‏caught up‏ بودن، و در صورت تمایل ‏master‏ کردن دوباره‌ی آن با ‏commit period‏.
  8. ۸. تفاوت وضعیت‌های ‏enabled‏، ‏allowed‏ و ‏forbidden‏ در ‏sync policy‏ چیست؟
    ‏enabled‏ یعنی همگام‌سازی انجام می‌شود؛ ‏allowed‏ یعنی مجاز است اما سطح پایین‌تر باید فعالش کند؛ ‏forbidden‏ یعنی ممنوع است و سطح پایین‌تر هم نمی‌تواند فعالش کند.
  9. ۹. ‏archive zone‏ چه مشکلی را حل می‌کند؟
    حفاظت در برابر حذف یا بازنویسی تصادفی و مخرب با نگه‌داری همه‌ی نسخه‌ها در یک ‏zone‏ جداگانه، بدون نیاز به ‏versioning‏ در ‏zone‏های کاربر.
  10. ۱۰. چرا ‏resharding‏ پیش از ‏Reef‏ در ‏multisite‏ مشکل‌ساز بود و امروز چطور حل شده است؟
    ‏reshard‏ تعداد و چیدمان ‏shard‏های ‏index‏ را عوض می‌کرد و همگام‌سازی که بر پایه‌ی ‏bilog‏ هر ‏shard‏ است مختل می‌شد؛ از ‏Reef‏ با ‏zone feature‏ به نام ‏resharding‏ هر ‏zone‏ مستقل ‏reshard‏ می‌کند بدون قطع تکثیر.

فصل ۶: سامانه‌ی فایل ‏Ceph‏ (CephFS)#

  1. ۱. چرا ‏MDS‏ در مسیر داده‌ی فایل‌ها قرار ندارد و این چه مزیتی دارد؟
    ‏MDS‏ فقط فراداده را مدیریت می‌کند و پس از دادن ‏capability‏، کلاینت داده را مستقیم با ‏OSD‏ها رد و بدل می‌کند؛ بنابراین پهنای باند داده با تعداد ‏OSD‏ها مقیاس می‌پذیرد و ‏MDS‏ گلوگاه نمی‌شود.
  2. ۲. ‏capability‏ چیست و چه زمانی ‏MDS‏ یک کلاینت را ‏evict‏ می‌کند؟
    ‏capability‏ مجوزی است که ‏MDS‏ روی هر ‏inode‏ به کلاینت می‌دهد (خواندن، نوشتن، ‏cache‏، ‏buffer‏) و در صورت نیاز پس می‌گیرد. اگر کلاینت در مهلت مقرر پاسخ ندهد یا ‏session‏ آن منقضی شود، ‏MDS‏ آن را ‏evict‏ و در ‏blocklist‏ می‌گذارد.
  3. ۳. تفاوت ‏standby‏ و ‏standby-replay‏ چیست؟
    ‏standby‏ بیکار است و هنگام جایگزینی باید کل ‏journal‏ را بازپخش کند؛ ‏standby-replay journal‏ یک ‏rank‏ مشخص را دائماً دنبال می‌کند و ‏cache‏ گرم دارد، پس ‏failover‏ سریع‌تر است.
  4. ۴. چرا ‏pool‏ داده‌ی پیش‌فرض ‏CephFS‏ نباید ‏EC‏ باشد؟
    چون فراداده‌ی ‏backtrace‏ همه‌ی فایل‌ها در ‏pool‏ داده‌ی پیش‌فرض نوشته می‌شود و این عملیات کوچک روی ‏EC‏ ناکارآمد است؛ ‏pool EC‏ را به‌عنوان ‏pool‏ دوم اضافه و با ‏layout‏ استفاده کنید.
  5. ۵. چه زمانی چند ‏MDS‏ فعال لازم است و چرا ‏pinning‏ صریح توصیه می‌شود؟
    وقتی بار فراداده (تعداد فایل، کلاینت یا عملیات در ثانیه) از توان یک ‏MDS‏ بیشتر شود. ‏balancer‏ خودکار سابقه‌ی جابه‌جایی‌های ناپایدار دارد و ‏pinning‏ صریح رفتار قابل پیش‌بینی می‌دهد.
  6. ۶. کلاینت هسته و ‏ceph-fuse‏ را از نظر کارایی و به‌روز بودن مقایسه کنید.
    کلاینت هسته سریع‌تر است ولی به نسخه‌ی هسته وابسته است؛ ‏ceph-fuse‏ کندتر ولی هم‌نسخه با ‏Ceph‏، ساده‌تر برای اشکال‌زدایی و با خطای محدود به یک فرایند.
  7. ۷. چرا ‏NFS-Ganesha‏ پیکربندی ‏export‏ها را در ‏RADOS‏ نگه می‌دارد؟
    تا همه‌ی ‏daemon‏های ‏Ganesha‏ پیکربندی یکسان و متمرکز داشته باشند و افزودن یا جابه‌جایی ‏daemon‏ نیاز به همگام‌سازی فایل نداشته باشد.
  8. ۸. چرا ‏quota‏ در ‏CephFS‏ «همکارانه» نامیده می‌شود؟
    چون خود کلاینت مصرف را دنبال و نوشتن را متوقف می‌کند؛ ممکن است با تأخیر کمی بیش از سقف بنویسد و کلاینت مخرب می‌تواند آن را نادیده بگیرد.
  9. ۹. چرا تغییر ‏layout‏ یک پوشه فایل‌های موجود را جابه‌جا نمی‌کند؟
    ‏layout‏ هنگام ساخت فایل روی آن ثبت می‌شود و جای اشیای موجود را تغییر نمی‌دهد؛ ‏rename‏ هم فقط فراداده را عوض می‌کند. برای انتقال باید فایل را کپی کرد.
  10. ۱۰. امروز جایگزین معمول «‏Hadoop‏ روی ‏CephFS‏» چیست؟
    اجرای ‏Spark‏، ‏Trino‏ یا ‏Hive‏ روی ‏RGW‏ از طریق رابط ‏S3A‏؛ برای بارهای ‏POSIX‏، ‏mount‏ مستقیم ‏CephFS‏.

فصل ۷: راهبری و مدیریت کلاستر ‏Ceph‏#

  1. ۱. چرا توقف ‏daemon‏ با ‏systemctl‏ در ‏cephadm‏ توصیه نمی‌شود؟
    چون ‏orchestrator‏ از توقف خبر ندارد و ممکن است ‏daemon‏ را دوباره راه بیندازد یا گزارش خطا بدهد؛ برای کارهای برنامه‌ریزی‌شده باید از ‏ceph orch‏ یا حالت نگهداری استفاده کرد.
  2. ۲. ترتیب اولویت منابع پیکربندی چیست و مقدار مؤثر را چطور می‌بینید؟
    از کم به زیاد: پیش‌فرض کامپایل‌شده، پایگاه پیکربندی ‏MON‏، ‏ceph.conf‏ محلی، آرگومان خط فرمان و تغییر زمان اجرا. مقدار مؤثر با ‏ceph config show <daemon>‏ دیده می‌شود.
  3. ۳. تفاوت ‏ceph tell‏ و ‏ceph daemon‏ چیست؟
    ‏ceph tell‏ از طریق شبکه و ‏MON/‏مسیر پیام‌رسانی به ‏daemon‏ می‌رسد؛ ‏ceph daemon‏ از ‏admin socket‏ محلی و فقط روی میزبان همان ‏daemon‏ استفاده می‌کند.
  4. ۴. مزایا و معایب ‏scale-up‏ و ‏scale-out‏ را از نظر دامنه‌ی خرابی مقایسه کنید.
    ‏scale-up‏ هزینه‌ی هر ترابایت را کم می‌کند اما دامنه‌ی خرابی و حجم بازیابی بزرگ‌تری دارد؛ ‏scale-out‏ دامنه‌ی خرابی کوچک‌تر و کارایی خطی‌تر دارد اما فضای رک و شبکه‌ی بیشتری می‌خواهد.
  5. ۵. چرا هنگام افزودن تعداد زیادی ‏OSD‏، پرچم‌های ‏norebalance‏ و ‏nobackfill‏ مفیدند؟
    تا ‏PG‏ها یک بار و پس از ساخته شدن همه‌ی ‏OSD‏ها جابه‌جا شوند، نه پس از هر ‏OSD‏.
  6. ۶. تفاوت ‏ok-to-stop‏ و ‏safe-to-destroy‏ چیست؟
    ‏ok-to-stop‏ می‌پرسد آیا توقف موقت باعث از دسترس رفتن ‏PG‏ می‌شود؛ ‏safe-to-destroy‏ می‌پرسد آیا حذف دائمی بدون از دست رفتن داده ممکن است.
  7. ۷. گزینه‌ی ‏--replace‏ در حذف ‏OSD‏ چه مزیتی دارد؟
    ‏id‏ و جایگاه ‏OSD‏ در ‏CRUSH‏ حفظ می‌شود و ‏OSD‏ تازه با همان ‏id‏ ساخته می‌شود؛ تغییر نقشه و جابه‌جایی داده کمتر است.
  8. ۸. حالت نگهداری ‏cephadm‏ چه کاری انجام می‌دهد؟
    همه‌ی ‏daemon‏های میزبان را متوقف می‌کند و ‏noout‏ را برای همان میزبان تنظیم می‌کند تا بازیابی بی‌مورد شروع نشود.
  9. ۹. چرا در ‏mClock‏ تنظیم مستقیم ‏osd_max_backfills‏ اثر ندارد و راه درست چیست؟
    چون ‏mClock‏ این تنظیمات را خودش مدیریت می‌کند؛ راه درست تغییر ‏osd_mclock_profile‏ است، یا در صورت نیاز فعال کردن ‏osd_mclock_override_recovery_settings‏.
  10. ۱۰. ارتقای ‏OSD‏ به ترتیب ‏bucket‏های ‏CRUSH‏ در ‏Umbrella‏ چه ریسکی را کاهش می‌دهد؟
    ارتقای هم‌زمان ‏OSD‏هایی را که نسخه‌های یک ‏PG‏ را نگه می‌دارند محدود می‌کند و با ‏ok-to-upgrade‏ مطمئن می‌شود دسترس‌پذیری داده حفظ می‌شود.

فصل ۸: ‏Ceph‏ از درون: ‏CRUSH‏، نقشه‌ها، احراز هویت و ‏PG‏ها#

  1. ۱. دو مرحله‌ی نگاشت شیء به ‏OSD‏ کدام‌اند و چرا ‏PG‏ لازم است؟
    شیء با ‏hash‏ نامش به یک ‏PG‏ نگاشت می‌شود و ‏CRUSH‏ آن ‏PG‏ را به مجموعه‌ای از ‏OSD‏ها نگاشت می‌کند. ‏PG‏ لازم است چون پیگیری وضعیت تکثیر، بازیابی و ‏scrub‏ برای هر شیء جداگانه در مقیاس میلیاردی ممکن نیست.
  2. ۲. تفاوت ‏up set‏ و ‏acting set‏ چیست؟
    ‏up set‏ خروجی خالص ‏CRUSH‏ است؛ ‏acting set‏ مجموعه‌ای است که واقعاً ‏I/O‏ را سرویس می‌دهد و ممکن است به دلیل ‏pg_temp‏ یا ‏upmap‏ با ‏up set‏ فرق کند.
  3. ۳. مزیت ‏straw2‏ نسبت به الگوریتم‌های قبلی چیست؟
    با تغییر وزن یک آیتم، داده فقط بین همان آیتم و بقیه جابه‌جا می‌شود و جابه‌جایی‌های بی‌مورد بین آیتم‌های دیگر رخ نمی‌دهد.
  4. ۴. چرا تغییر ‏tunable‏ها باعث جابه‌جایی داده می‌شود و پیش از آن چه چیزی را باید بررسی کرد؟
    چون نتیجه‌ی محاسبه‌ی ‏CRUSH‏ برای بسیاری از ‏PG‏ها تغییر می‌کند. پیش از آن باید سازگاری همه‌ی کلاینت‌ها (‏ceph features‏) و ظرفیت کلاستر برای جابه‌جایی را بررسی کرد.
  5. ۵. چرا چهار ‏MON‏ از سه ‏MON‏ تحمل خرابی بیشتری ندارد؟
    چون اکثریت چهار ‏MON‏ سه است و فقط یک خرابی تحمل می‌شود، همانند سه ‏MON‏.
  6. ۶. ‏OSD‏ها نقشه‌ی جدید را از کجا دریافت می‌کنند؟
    از ‏MON‏ یا از همتایانشان (‏OSD‏ها و کلاینت‌ها) که در پیام‌ها ‏epoch‏ جدیدتر را منتشر می‌کنند.
  7. ۷. چرا ‏cephx‏ از ‏ticket‏ استفاده می‌کند؟
    تا ‏OSD‏ها بدون مراجعه به ‏MON‏ برای هر درخواست، اعتبار کلاینت را بررسی کنند و ‏MON‏ گلوگاه نشود؛ کلید مخفی هم روی شبکه ارسال نمی‌شود.
  8. ۸. چرا تأخیر نوشتن به کندترین ‏OSD acting set‏ بستگی دارد؟
    چون ‏primary‏ فقط پس از ‏commit‏ همه‌ی نسخه‌ها ‏ack‏ می‌دهد.
  9. ۹. حالت‌های ‏incomplete‏ و ‏inconsistent‏ چه تفاوتی دارند؟
    ‏incomplete‏ یعنی نسخه‌ی معتبر کافی برای فعال شدن ‏PG‏ نیست و ‏I/O‏ متوقف است؛ ‏inconsistent‏ یعنی ‏PG‏ فعال است اما ‏scrub‏ بین نسخه‌ها ناسازگاری پیدا کرده است.
  10. ۱۰. راه توصیه‌شده برای قرار دادن یک ‏pool‏ روی ‏OSD‏های خاص چیست؟
    تعریف کلاس دستگاه (پیش‌فرض یا دلخواه)، ساختن قانون ‏CRUSH‏ با آن کلاس و اختصاص قانون به ‏pool‏.

فصل ۹: از ‏VSM‏ تا ‏Ceph Dashboard‏: مدیریت گرافیکی کلاستر#

  1. ۱. چرا ‏VSM‏ امروز گزینه‌ی مناسبی نیست؟
    مخزن آن آرشیو شده، آخرین نسخه‌اش ۲۰۱۶ است، فقط با نسخه‌های قدیمی ‏Ceph‏ کار می‌کرد و هیچ نگهداری یا به‌روزرسانی امنیتی ندارد.
  2. ۲. کدام ایده‌های ‏VSM‏ در ‏Ceph‏ امروزی ادامه یافته‌اند و به چه شکلی؟
    گروه‌های ذخیره‌سازی به کلاس دستگاه و قانون‌های ‏CRUSH‏، ‏manifest‏ سخت‌افزار به ‏spec‏های ‏cephadm‏ و رابط وب به ‏Ceph Dashboard‏ تبدیل شدند.
  3. ۳. چرا ‏Dashboard‏ فقط روی ‏MGR‏ فعال سرویس می‌دهد و این چه پیامدی دارد؟
    چون یک ماژول ‏MGR‏ است و فقط ماژول‌های ‏MGR‏ فعال اجرا می‌شوند؛ با جابه‌جایی ‏MGR‏ آدرس تغییر می‌کند، مگر این‌که از ‏redirect‏، ‏load balancer‏ یا ‏mgmt-gateway‏ استفاده شود.
  4. ۴. نقش ‏orchestrator‏ در ‏Dashboard‏ چیست؟
    ‏Dashboard‏ عملیات استقرار (میزبان، ‏OSD‏، سرویس) را از طریق ‏orchestrator‏ (cephadm یا ‏Rook‏) انجام می‌دهد؛ بدون آن این بخش‌ها فقط‌خواندنی‌اند.
  5. ۵. چرا رمز عبور را با ‏-i‏ از فایل می‌خوانیم؟
    تا رمز در تاریخچه‌ی ‏shell‏ و فهرست فرایندها دیده نشود.
  6. ۶. تفاوت نقش و ‏scope‏ در ‏RBAC Dashboard‏ چیست؟
    ‏scope‏ حوزه‌ای از منابع (مثل ‏pool‏ یا ‏rbd-image‏) است و نقش مجموعه‌ای از مجوزها (‏read‏، ‏create‏، ‏update‏، ‏delete‏) روی چند ‏scope‏.
  7. ۷. چرا ‏SSO‏ به تنهایی برای دسترسی کافی نیست؟
    چون ‏SSO‏ فقط هویت را تأیید می‌کند؛ کاربر باید در ‏Dashboard‏ تعریف شده باشد تا نقش و مجوزش مشخص شود.
  8. ۸. ‏mgmt-gateway‏ چه مشکلی را حل می‌کند؟
    نقطه‌ی ورود واحد با ‏TLS‏ برای ‏Dashboard‏ و ابزارهای پایش فراهم می‌کند و وابستگی آدرس به ‏MGR‏ فعال را حذف می‌کند؛ با ‏oauth2-proxy‏ احراز هویت متمرکز هم ممکن می‌شود.
  9. ۹. پس از حذف ماژول ‏restful‏، چه جایگزینی برای خودکارسازی وجود دارد؟
    ‏REST API‏ نسخه‌دار ‏Dashboard‏ برای عملیات، و ‏Prometheus‏ برای متریک‌ها.
  10. ۱۰. چرا نباید پایش اصلی کلاستر فقط به ‏Dashboard‏ وابسته باشد؟
    چون ‏Dashboard‏ به ‏MGR‏ و ‏MON‏ها وابسته است و در بحران‌های جدی اولین چیزی است که از دسترس خارج می‌شود؛ پایش و هشدار باید مسیر مستقل داشته باشند.

فصل ۱۰: سنجش کارایی و ابزارهای کارشناسی ‏Ceph‏#

  1. ۱. چرا سنجش کارایی باید لایه‌به‌لایه انجام شود؟
    چون بدون دانستن سقف لایه‌های پایین (دیسک و شبکه) نمی‌توان فهمید کمبود کارایی در کدام لایه ایجاد شده است.
  2. ۲. چرا ‏fio‏ برای سنجش دیسک بر ‏dd‏ ترجیح دارد؟
    ‏fio‏ عمق صف، الگوی تصادفی/ترتیبی، ‏direct I/O‏ و ‏sync‏ را کنترل می‌کند و صدک‌های تأخیر را گزارش می‌دهد؛ ‏dd‏ فقط یک الگوی ترتیبی ساده را می‌سنجد.
  3. ۳. چرا آزمایش نوشتن ‏sync‏ با عمق صف ۱ برای انتخاب ‏SSD‏ مهم است؟
    چون ‏WAL‏ و ‏DB‏ در ‏BlueStore‏ با نوشتن‌های کوچک ‏sync‏ کار می‌کنند و ‏SSD‏های بدون حفاظت در برابر قطع برق در این الگو بسیار کندند.
  4. ۴. ‏MTU‏ ناهماهنگ چه علائمی در ‏Ceph‏ ایجاد می‌کند؟
    ‏heartbeat‏های کوچک رد می‌شوند و ‏OSD‏ها ‏up‏ به نظر می‌رسند، ولی پیام‌های بزرگ گم می‌شوند و عملیات کند یا معلق می‌شوند.
  5. ۵. در مثال سقف نظری، چرا شبکه گلوگاه شد؟
    چون هر بایت ورودی باید دو بار دیگر روی شبکه به ‏OSD‏های ثانویه برود و پهنای باند شبکه‌ی هر گره از توان مجموع دیسک‌هایش بسیار کمتر بود.
  6. ۶. تفاوت ‏ceph tell osd.N bench‏ و ‏rados bench‏ چیست؟
    ‏ceph tell osd.N bench‏ فقط ‏BlueStore‏ یک ‏OSD‏ را بدون شبکه و تکثیر می‌سنجد؛ ‏rados bench‏ مسیر کامل ‏RADOS‏ شامل شبکه و تکثیر را روی یک ‏pool‏ می‌سنجد.
  7. ۷. چرا باید ‏image RBD‏ را پیش از سنجش نوشتن تصادفی پر کرد؟
    چون اولین نوشتن روی هر بخش، شیء ‏RADOS‏ تازه می‌سازد و کندتر از بازنویسی است؛ بدون پر کردن، نتیجه ترکیبی و گمراه‌کننده است.
  8. ۸. تفاوت ‏admin socket‏ و ‏ceph tell‏ چیست و هر کدام چه زمانی مفیدترند؟
    ‏admin socket‏ محلی است و بدون شبکه یا ‏MON‏ کار می‌کند (مفید وقتی ‏daemon‏ به پیام‌های شبکه پاسخ نمی‌دهد)؛ ‏ceph tell‏ از هر جای کلاستر در دسترس است.
  9. ۹. در خروجی ‏heap stats‏، حافظه‌ی ‏freelist‏ چه معنایی دارد؟
    حافظه‌ای است که برنامه آزاد کرده اما ‏tcmalloc‏ هنوز به سیستم‌عامل برنگردانده؛ ‏heap release‏ آن را برمی‌گرداند.
  10. ۱۰. پیش از استفاده از ‏ceph-objectstore-tool‏ چه اقدام‌هایی لازم است؟
    توقف ‏OSD‏، گرفتن ‏export‏ پشتیبان از ‏PG‏، استفاده از ‏dry-run‏ در صورت امکان و اطمینان از شکست روال‌های عادی بازیابی.

فصل ۱۱: استقرار ‏Ceph‏: آزمایشگاه، ‏cephadm‏، ‏Ansible‏ و ‏Rook‏#

  1. ۱. چرا ‏ceph-deploy‏ دیگر گزینه‌ی مناسبی نیست؟
    مخزن آن آرشیو شده و با نسخه‌های جدید ‏Ceph‏ و مدل کانتینری کار نمی‌کند.
  2. ۲. تفاوت فلسفی ‏ceph-ansible‏ و ‏cephadm‏ چیست؟
    ‏ceph-ansible‏ دستوری است و فقط هنگام اجرای ‏playbook‏ وضعیت را اصلاح می‌کند؛ ‏cephadm‏ اعلانی و پیوسته است و وضعیت مطلوب را درون کلاستر نگه می‌دارد و مدام با وضعیت واقعی تطبیق می‌دهد.
  3. ۳. چرا برای آزمایشگاه ‏Umbrella‏ باید مدل ‏CPU‏ مجازی را بررسی کرد؟
    چون ‏image‏‌های ‏Umbrella‏ به ‏CPU‏ با سطح ‏x86-64-v3‏ نیاز دارند و مدل‌های ‏CPU‏ مجازی عمومی ممکن است آن را اعلام نکنند.
  4. ۴. گزینه‌ی ‏--single-host-defaults‏ چه کاری می‌کند و محدودیت کلاستر تک‌گره چیست؟
    تنظیماتی مناسب یک میزبان (مثلاً دامنه‌ی خرابی ‏OSD‏) اعمال می‌کند؛ کلاستر تک‌گره در برابر خرابی میزبان هیچ حفاظتی ندارد و برای تمرین خرابی مناسب نیست.
  5. ۵. چرا ‏--dry-run‏ پیش از اعمال ‏spec OSD‏ مهم است؟
    چون نشان می‌دهد کدام ‏OSD‏ها روی کدام دیسک‌ها ساخته می‌شوند و از ‏OSD‏ شدن ناخواسته‌ی دیسک‌ها جلوگیری می‌کند.
  6. ۶. چرا فیلتر ‏rotational‏ در محیط مجازی ممکن است گمراه‌کننده باشد؟
    چون دیسک‌های مجازی ممکن است خود را چرخان یا غیرچرخان معرفی کنند بی‌ارتباط با سخت‌افزار واقعی.
  7. ۷. تقسیم کار پیشنهادی بین ‏Ansible‏ و ‏cephadm‏ چیست؟
    ‏Ansible‏ برای سیستم‌عامل، بسته‌ها، شبکه، زمان و کلیدها؛ ‏cephadm‏ برای همه‌ی ‏daemon‏ها، ‏spec‏ها و ارتقای ‏Ceph‏.
  8. ۸. مسیر مهاجرت از ‏ceph-ansible‏ به ‏cephadm‏ چیست؟
    استفاده از ‏cephadm adopt‏ (یا ‏playbook‏ ‏cephadm-adopt.yml‏) برای تحویل گرفتن ‏daemon‏ها یکی‌یکی، پس از تمرین در آزمایشگاه و با کلاستر سالم.
  9. ۹. ریسک اجرای ‏Ceph‏ درون همان کلاستر ‏Kubernetes‏ برنامه‌ها چیست و راه کاهش آن کدام است؟
    وابستگی چرخه‌ای بین ‏Kubernetes‏ و ذخیره‌سازی؛ با جدا کردن گره‌های ذخیره‌سازی یا استقرار ‏Ceph‏ بیرون از ‏Kubernetes‏ و حالت ‏external cluster‏ کاهش می‌یابد.
  10. ۱۰. تشخیص ‏drift‏ چه فایده‌ای دارد؟
    تغییرات دستی یا خودکار ثبت‌نشده را آشکار می‌کند تا یا به ‏Git‏ برگردند یا اصلاح شوند.

فصل ۱۲: ‏BlueStore‏: موتور ذخیره‌سازی ‏OSD‏#

  1. ۱. سه محدودیت اصلی ‏FileStore‏ کدام بودند؟
    نوشتن دوباره به دلیل ‏journal‏ جدا، لایه‌های اضافه‌ی فایل‌سیستم ‏POSIX‏ با رفتار غیرقابل پیش‌بینی، و نبود ‏checksum‏ سرتاسری (به‌علاوه‌ی فهرست‌گیری کند).
  2. ۲. چرا ‏BlueStore‏ برای نوشتن‌های بزرگ نیازی به ‏journal‏ جدا ندارد؟
    چون داده را در فضای تازه می‌نویسد و فقط پس از ‏commit‏ فراداده در ‏RocksDB‏ به آن اشاره می‌کند؛ نسخه‌ی قبلی تا آن لحظه دست‌نخورده است.
  3. ۳. ‏BlueFS‏ چیست و چرا ‏Ceph‏ از ‏XFS‏ برای ‏RocksDB‏ استفاده نمی‌کند؟
    یک فایل‌سیستم کوچک مخصوص فایل‌های ‏RocksDB‏ که روی دستگاه خام کار می‌کند و سربار و پیچیدگی یک فایل‌سیستم عمومی را ندارد.
  4. ۴. سرریز ‏BlueFS‏ چیست و چه اثری دارد؟
    وقتی ‏block.db‏ پر شود، فایل‌های ‏RocksDB‏ روی دستگاه کند ‏block‏ نوشته می‌شوند و کارایی فراداده افت می‌کند؛ هشدار ‏BLUEFS_SPILLOVER‏.
  5. ۵. شرط ‏deferred‏ شدن یک نوشتن در ‏_defer_or_allocate‏ چیست؟
    اندازه‌ی لازم از فضای آزادشده توسط همان نوشتن بیشتر نباشد و این فضا از ‏prefer_deferred_size‏ کوچک‌تر باشد.
  6. ۶. چرا ‏ack‏ به کلاینت پس از ‏KV_DONE‏ ایمن است؟
    چون داده‌ی ‏deferred‏ همراه رکورد ‏L‏ در ‏WAL RocksDB‏ پایدار شده و هنگام ‏mount‏ با _‏deferred_replay‏ دوباره اعمال می‌شود.
  7. ۷. سه نسل ‏omap‏ در فضای کلید ‏BlueStore‏ کدام‌اند و چرا ‏per-PG‏ بهتر است؟
    ‏M‏ (مشترک)، ‏m‏ (per-pool) و ‏p‏ (per-PG)؛ ‏per-PG‏ حذف و انتقال ‏PG‏ را با بازه‌ی پیوسته‌ی کلیدها ممکن و آمار را دقیق می‌کند.
  8. ۸. چرا ‏min_alloc_size‏ از ۶۴ کیلوبایت به ۴ کیلوبایت کاهش یافت؟
    برای کاهش هدررفت فضا با اشیای کوچک، به‌ویژه در ‏RGW‏.
  9. ۹. ‏HybridAllocator‏ چه مصالحه‌ای بین ‏AVL‏ و ‏bitmap‏ برقرار می‌کند؟
    ‏AVL‏ جست‌وجوی سریع بازه‌های آزاد دارد اما حافظه‌اش با تکه‌تکگی رشد می‌کند؛ پس از سقف حافظه، بازه‌ها به ‏bitmap‏ با حافظه‌ی ثابت سرریز می‌شوند.
  10. ۱۰. خرابی یک ‏NVMe‏ پشتیبان ‏db‏ چه اثری بر کلاستر دارد؟
    همه‌ی ‏OSD‏هایی که ‏db‏ آن‌ها روی آن ‏NVMe‏ است هم‌زمان از دست می‌روند و بازیابی گسترده آغاز می‌شود.

فصل ۱۳: کدگذاری پاک‌شونده (‏Erasure Coding‏) برای بهره‌وری ذخیره‌سازی#

  1. ۱. سربار و تحمل خرابی ‏EC 8+3‏ در مقایسه با تکثیر سه‌تایی چیست؟
    سربار ۱.۳۷۵ برابر در برابر ۳ برابر، با تحمل سه خرابی در برابر دو خرابی؛ اما دست‌کم یازده دامنه‌ی خرابی لازم است.
  2. ۲. چرا هر زیرماتریس ‏k‏×‏k‏ ماتریس مولد باید وارون‌پذیر باشد؟
    چون هر ‏k shard‏ در دسترس باید برای بازسازی کافی باشد و این فقط وقتی ممکن است که زیرماتریس متناظر معکوس داشته باشد.
  3. ۳. تفاوت ‏shard‏ در ‏EC‏ و نسخه در تکثیر چیست؟
    هر ‏shard‏ فقط قطعه‌ی ‏i‏ از هر ‏stripe‏ را نگه می‌دارد و جایگاهش معنا دارد؛ در تکثیر هر نسخه کل شیء را دارد و قابل جابه‌جایی است.
  4. ۴. چرا نوشتن کوچک در ‏EC‏ قدیمی پرهزینه بود؟
    چون بازنویسی بخشی از ‏stripe‏ نیازمند خواندن بقیه‌ی ‏stripe‏، ‏encode‏ دوباره و نوشتن همه‌ی ‏shard‏ها بود.
  5. ۵. ‏parity delta‏ بر چه ویژگی ریاضی تکیه دارد؟
    خطی بودن کد روی میدان گالوا: ‏parity‏ جدید برابر ‏parity‏ قدیم به‌علاوه‌ی ضریب ضربدر تفاوت داده‌ی قدیم و جدید است.
  6. ۶. محدودیت‌های فعال‌سازی ‏FastEC‏ کدام‌اند؟
    همه‌ی ‏MON‏ و ‏OSD‏ها ‏Tentacle+‏، فقط ‏ISA-L‏ یا ‏Jerasure reed_sol_van‏، ‏stripe_unit‏ مضرب ۴‏K‏، و غیرقابل خاموش شدن پس از فعال‌سازی.
  7. ۷. چرا پرچم ‏allow_ec_optimizations‏ برگشت‌پذیر نیست؟
    چون قالب ذخیره‌ی داده‌ی جدید را تغییر می‌دهد و پیاده‌سازی قدیمی (‏ECBackendL‏) نمی‌تواند آن را بخواند.
  8. ۸. ‏CLAY‏ و ‏LRC‏ چطور ترافیک بازیابی را کاهش می‌دهند؟
    ‏LRC‏ با ‏parity‏ محلی، بازسازی را به گروه کوچکی محدود می‌کند؛ ‏CLAY‏ با ‏sub-chunk‏ها فقط بخشی از داده‌ی کمک‌کننده‌ها را می‌خواند.
  9. ۹. عدد ۲۱۴۷۴۸۳۶۴۷ در نگاشت ‏PG‏ چه معنایی دارد و علت‌های رایج آن کدام‌اند؟
    همان ‏CRUSH_ITEM_NONE‏ است: ‏CRUSH‏ برای آن جایگاه ‏shard OSD‏ پیدا نکرده؛ علت‌ها: دامنه‌ی خرابی ناکافی، ‏OSD‏های ‏out‏، قانون نادرست یا تلاش ناکافی ‏CRUSH‏.
  10. ۱۰. چرا در ‏pool‏ بهینه، ‏primary‏ همیشه ‏shard 0‏ نیست؟
    چون در نوشتن جزئی برخی ‏shard‏های داده به‌روز نمی‌شوند و نمی‌توانند ‏log‏ کامل ‏PG‏ را داشته باشند؛ ‏pgtemp_primaryfirst shard‏های مجاز را جلو می‌آورد.

فصل ۱۴: برنامه‌نویسی با ‏librados‏#

  1. ۱. سه بخش مستقل یک شیء ‏RADOS‏ کدام‌اند؟
    داده (بایت‌ها با ‏offset‏)، ‏xattr‏ها و ‏omap‏ (کلید-مقدار مرتب).
  2. ۲. ‏namespace‏ چه فرقی با ‏pool‏ دارد و چه زمانی مفید است؟
    ‏namespace‏ زیرفضای نام درون یک ‏pool‏ است و قانون ‏CRUSH‏ و ‏PG‏ جدا ندارد؛ برای جداسازی مستأجران بدون ساختن ‏pool‏ جدید و با ‏capability‏ محدود به ‏namespace‏ مفید است.
  3. ۳. چرا ‏omap‏ در ‏pool EC‏ پشتیبانی نمی‌شود و چه پیامدی برای طراحی دارد؟
    چون پیاده‌سازی ‏EC‏ روی ‏shard‏ها برای داده طراحی شده و ‏omap‏ کلید-مقدار را پوشش نمی‌دهد؛ فراداده و شاخص‌ها باید در ‏pool‏ تکثیری باشند.
  4. ۴. عملیات مرکب چه تضمینی می‌دهد و چه تضمینی نمی‌دهد؟
    اجرای اتمی همه‌ی عملیات روی یک شیء (همه یا هیچ)؛ تراکنش بین چند شیء را تضمین نمی‌کند.
  5. ۵. ‏assert_version‏ در چه حالت‌هایی ‏ERANGE‏ و ‏EOVERFLOW‏ برمی‌گرداند؟
    ‏ERANGE‏ وقتی نسخه‌ی داده‌شده کمتر از نسخه‌ی فعلی شیء است (کهنه)؛ ‏EOVERFLOW‏ وقتی بیشتر است.
  6. ۶. چرا قفل مشورتی به تنهایی برای ایمنی کافی نیست؟
    چون فقط کلاینت‌های همکار آن را رعایت می‌کنند و کلاینت کند ممکن است بی‌خبر از انقضای قفل ادامه دهد؛ باید با ‏guard‏ یا ‏blocklist‏ ترکیب شود.
  7. ۷. ‏watch‏ در ‏Objecter‏ چگونه پس از تغییر نقشه حفظ می‌شود؟
    به‌صورت عملیات ‏linger‏ که ‏Objecter‏ با هر نقشه‌ی جدید یا قطع اتصال، هدفش را دوباره محاسبه و به ‏primary‏ جدید ارسال می‌کند.
  8. ۸. چرا بازارسال ‏Op‏ پس از تغییر نقشه ایمن است؟
    چون هر ‏Op‏ شناسه‌ی یکتا دارد و ‏OSD‏ درخواست‌های تکراری را از روی ‏log PG‏ تشخیص می‌دهد و دوباره اجرا نمی‌کند.
  9. ۹. چه زمانی باید ‏rados_osd_op_timeout‏ را تنظیم کرد؟
    وقتی برنامه باید در زمان محدود پاسخ یا خطا بدهد، چون پیش‌فرض بدون ‏timeout‏ است و ‏Op‏ تا ‏active‏ شدن ‏PG‏ منتظر می‌ماند.
  10. ۱۰. برای ذخیره‌ی داده‌ی چندگیگابایتی روی ‏RADOS‏ چه الگویی مناسب است؟
    شکستن داده به اشیای چندمگابایتی (‏striping‏)، مثلاً با ‏libradosstriper‏، همانند ‏RBD‏ و ‏CephFS‏.

فصل ۱۵: کلاس‌های ‏RADOS‏: محاسبه در کنار داده#

  1. ۱. سه مزیت اصلی اجرای منطق در کلاس به جای کلاینت چیست؟
    کاهش رفت‌وبرگشت شبکه، اجرای اتمی درون تراکنش ‏PG‏، و کاهش انتقال داده با پردازش کنار داده.
  2. ۲. چرا متد کلاس نمی‌تواند شیء دیگری را تغییر دهد؟
    چون شیء دیگر ممکن است در ‏PG‏ و ‏OSD‏ دیگری باشد و متد فقط در بافت تراکنش همان شیء اجرا می‌شود.
  3. ۳. تفاوت ‏osd_class_load_list‏ و ‏osd_class_default_list‏ چیست؟
    ‏load_list‏ تعیین می‌کند کدام کلاس‌ها اصلاً بارگذاری شوند؛ ‏default_list‏ تعیین می‌کند کدام‌ها با ‏cap‏های عمومی (‏x‏، ‏class-read‏، ‏class-write‏) مجازند.
  4. ۴. اگر متدی بدون پرچم ‏WR‏ بنویسد چه رخ می‌دهد و چرا؟
    ‏OSD‏ پس از اجرا شمارنده‌ی ‏num_write‏ را بررسی می‌کند و -‏EIO‏ برمی‌گرداند، چون عملیات نوشتنی باید به‌عنوان نوشتن پردازش، ثبت و تکثیر شود.
  5. ۵. ‏cap‏ «‏allow class numops add‏» دقیقاً چه چیزی را مجاز می‌کند؟
    فقط فراخوانی متد ‏add‏ از کلاس ‏numops‏ (با محدوده‌ی ‏match‏ مشخص‌شده، مثلاً ‏pool‏).
  6. ۶. چرا ‏cls_lua‏ به‌صورت پیش‌فرض بارگذاری نمی‌شود؟
    چون اجرای کد دلخواه درون ‏OSD‏ را ممکن می‌کند و بدون ‏sandbox‏ یا ‏timeout‏ می‌تواند ‏PG‏ را مسدود کند.
  7. ۷. در ‏cephadm‏ چگونه کلاس سفارشی را مستقر می‌کنید؟
    با ساخت ‏image‏ سفارشی بر پایه‌ی ‏image‏ رسمی هم‌نسخه که ‏libcls_*.so‏ را در ‏osd_class_dir‏ دارد، و ارتقا یا تنظیم ‏container_image‏ به آن، سپس افزودن کلاس به فهرست‌ها.
  8. ۸. چه تغییری در رابط ثبت متدها در ‏Umbrella‏ رخ داد؟
    ثبت از ‏cls_register_cxx_method‏ با پرچم صریح به ‏ClassRegistrar‏ و ‏ClsMethod‏ نوع‌دار با ‏Tag‏های ‏RD/WR/PROMOTE‏ تغییر کرد.
  9. ۹. متد کند چه اثری بر سایر عملیات ‏PG‏ دارد؟
    چون زیر قفل ‏PG‏ در ‏thread‏ پردازش اجرا می‌شود، سایر عملیات همان ‏PG‏ منتظر می‌مانند و ‏slow ops‏ ایجاد می‌شود.
  10. ۱۰. ‏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‏#

  1. ۱. وضعیت رسمی ‏cache tiering‏ در نسخه‌های جاری چیست؟
    از ‏Reef‏ منسوخ شده، نگه‌دارنده ندارد و ممکن است بدون اطلاع حذف شود؛ نباید ‏tier‏ جدید ساخت و موارد موجود باید مهاجرت کنند.
  2. ۲. ‏overlay‏ چگونه درخواست کلاینت را به ‏pool‏ کش می‌برد؟
    ‏set-overlay‏ فیلدهای ‏read_tier‏ و ‏write_tier pool‏ پایه را در ‏OSDMap‏ به ‏pool‏ کش اشاره می‌دهد و ‏Objecter‏ درخواست را به آن ‏pool‏ می‌فرستد.
  3. ۳. ‏HitSet‏ نوع ‏bloom‏ چه مزیتی دارد و ‏min_read_recency_for_promote‏ چه می‌کند؟
    حافظه‌ی کم با خطای مثبت کنترل‌شده؛ ‏min_read_recency_for_promote‏ تعداد ‏HitSet‏های اخیری است که شیء باید در آن‌ها دیده شده باشد تا روی خواندن ‏promote‏ شود (۰ یعنی همیشه).
  4. ۴. چرا ‏cache tiering‏ برای بیشتر بارهای ‏RBD‏ کارایی را کاهش می‌داد؟
    چون دسترسی‌ها پراکنده‌اند و هر ‏promote‏ و ‏evict‏ هزینه‌ی خواندن و نوشتن اضافه دارد؛ کش گرم نمی‌شود و ‏I/O‏ بیشتر می‌شود.
  5. ۵. عامل کش چگونه هدف کل ‏pool‏ را به سهم هر ‏PG‏ تبدیل می‌کند؟
    با تقسیم هدف بر ‏get_pg_num_divisor‏ که تعداد ‏PG‏ها را با در نظر گرفتن تقسیم ناتمام برمی‌گرداند.
  6. ۶. نقش ‏osd_agent_slop‏ چیست؟
    هیسترزیس: آستانه‌ی ورود به حالت بالاتر و آستانه‌ی خروج پایین‌تر از هدف تا از نوسان بین حالت‌ها جلوگیری شود (پیش‌فرض ۰.۰۲).
  7. ۷. ‏evict‏ در حالت ‏SOME‏ چگونه قربانی را انتخاب می‌کند؟
    دمای شیء از ‏HitSet‏های وزن‌دار تخمین زده و در هیستوگرام قرار می‌گیرد؛ اگر جایگاهش در بخش داغ‌تر از ‏evict_effort‏ باشد نگه داشته می‌شود، وگرنه ‏evict‏.
  8. ۸. مراحل حذف یک ‏cache tier writeback‏ را بنویسید.
    ‏cache-mode proxy‏، ‏rados cache-flush-evict-all‏ تا خالی شدن، ‏tier remove-overlay‏ روی ‏pool‏ پایه، ‏tier remove‏.
  9. ۹. چه چیزی دلیل تاریخی ‏cache tier‏ جلوی ‏pool EC‏ را از بین برد؟
    پشتیبانی از ‏overwrite‏ در ‏pool EC‏ (allow_ec_overwrites از ‏Luminous‏) و بهینه‌سازی‌های ‏FastEC‏ در ‏Tentacle‏.
  10. ۱۰. برای داده‌ی شیء با عمر مشخص چه جایگزینی پیشنهاد می‌شود؟
    ‏storage class‏ و قانون ‏lifecycle‏ در ‏RGW‏ (و ‏cloud transition‏ برای بایگانی بیرونی).

فصل ۱۷: عیب‌یابی ‏Ceph‏: از ‏HEALTH_WARN‏ تا ماشین حالت ‏Peering‏#

  1. ۱. نخستین دو فرمان در هر حادثه کدام‌اند و چرا؟
    ‏ceph‏ -‏s‏ برای نمای کلی و ‏ceph health detail‏ برای کد دقیق هر هشدار؛ این دو لایه‌ی درگیر را نشان می‌دهند.
  2. ۲. تفاوت ‏degraded‏، ‏undersized‏ و ‏remapped‏ چیست؟
    ‏degraded‏: برخی اشیا نسخه‌ی کافی ندارند؛ ‏undersized‏: تعداد ‏OSD‏های ‏acting‏ کمتر از ‏size‏ است؛ ‏remapped: acting‏ با ‏up‏ متفاوت است (به دلیل ‏pg_temp‏ یا ‏backfill‏).
  3. ۳. حالت ‏WaitUpThru‏ چه مشکلی را حل می‌کند؟
    تضمین می‌کند ‏MON‏ ثبت کرده که ‏OSD‏ تا این ‏epoch‏ زنده بوده؛ پس در ‏peering‏های بعدی می‌توان فهمید آیا آن ‏interval‏ ممکن بوده نوشتن بپذیرد.
  4. ۴. چرا ‏PG‏ به حالت ‏down‏ می‌رود و فیلد ‏down_osds_we_would_probe‏ چه می‌گوید؟
    چون ‏interval‏ی وجود دارد که ممکن است در آن نوشتن رخ داده باشد و هیچ ‏OSD‏ آن در دسترس نیست؛ فیلد، ‏OSD‏هایی را نشان می‌دهد که بازگشتشان ‏peering‏ را ممکن می‌کند.
  5. ۵. ‏find_best_info‏ در ‏pool‏ تکثیری و ‏EC‏ چه تفاوتی دارد و چرا؟
    در تکثیری بیشترین ‏last_update‏ مرجع است؛ در ‏EC‏ کمترین ‏last_update‏ که همه‌ی ‏shard‏ها بتوانند به آن ‏rollback‏ کنند، چون نوشتن ناقص ‏EC‏ قابل بازسازی نیست.
  6. ۶. آخرین رویداد ‏sub_op_sent‏ در یک ‏slow op‏ چه معنایی دارد؟
    عملیات به ‏replica‏ها ارسال شده ولی ‏ack‏ همه نرسیده؛ ‏OSD replica‏ یا شبکه‌ی آن کند است.
  7. ۷. ‏scrub‏ چگونه با نوشتن‌های در جریان هماهنگ می‌شود؟
    ‏scrub‏ تکه‌به‌تکه پیش می‌رود و برای هر بازه تا پایان نوشتن‌های در جریان و هم‌گام شدن ‏last_update‏ منتظر می‌ماند (‏RangeBlocked‏، ‏WaitPushes‏، ‏WaitLastUpdate‏).
  8. ۸. پیش از ‏ceph pg repair‏ چه چیزی را باید بررسی کنید؟
    خروجی ‏rados list-inconsistent-obj‏ برای اینکه بدانید خطا روی کدام ‏shard‏ یا ‏OSD‏ است و نسخه‌ی معتبر روشن است؛ و سلامت دیسک مقصر.
  9. ۹. ‏ceph osd lost‏ چه خطری دارد؟
    نوشتن‌های تأییدشده‌ای که فقط روی آن ‏OSD‏ بوده‌اند برای همیشه از دست می‌روند.
  10. ۱۰. چرا ‏nodown‏ و ‏noout‏ باید موقت باشند؟
    ‏nodown‏ روی ‏OSD‏ مرده کلاینت‌ها را منتظر نگه می‌دارد و ‏noout‏ مانع بازیابی خودکار می‌شود؛ هر دو کلاستر را از رفتار ترمیمی خود محروم می‌کنند.

فصل ۱۸: بازیابی از فاجعه: ‏rbd-mirror‏، ‏stretch mode‏ و نجات کلاستر#

  1. ۱. چرا تکثیر جایگزین پشتیبان نیست؟
    چون حذف اشتباه، باج‌افزار و خرابی منطقی هم تکثیر می‌شوند؛ پشتیبان باید از دسترس همان اعتبارنامه‌ها و عملیات خارج باشد.
  2. ۲. تفاوت ‏mirroring‏ مبتنی بر ‏journal‏ و ‏snapshot‏ در سربار و ‏RPO‏ چیست؟
    ‏journal‏ هر نوشتن را دو بار انجام می‌دهد و ‏RPO‏ چندثانیه‌ای دارد؛ ‏snapshot‏ سربار کمی دارد و ‏RPO‏ آن برابر بازه‌ی زمان‌بندی است.
  3. ۳. فیلد ‏complete‏ در ‏MirrorSnapshotNamespace‏ چه نقشی دارد؟
    نشان می‌دهد کپی تفاوت برای آن ‏snapshot‏ مقصد تمام شده است؛ ‏snapshot‏ ناقص یعنی تصویر ممکن است ناسازگار باشد و آخرین نقطه‌ی سازگار ‏snapshot‏ کامل قبلی است.
  4. ۴. ‏rbd-mirror‏ در کدام کلاستر اجرا می‌شود و چرا ‏pull‏ می‌کند؟
    در کلاستر مقصد؛ از مبدأ می‌کشد تا مبدأ نیازی به دانستن یا دسترسی به مقصد نداشته باشد و ‏daemon‏ کنار نسخه‌ای که می‌نویسد اجرا شود.
  5. ۵. پس از ‏promote‏ --‏force‏ و بازگشت سایت قبلی چه باید کرد؟
    تصویر سایت قبلی را ‏demote‏ و سپس ‏resync‏ کنید تا از ‏primary‏ فعلی دوباره همگام شود؛ نوشتن‌های پس از قطع روی آن سایت از دست می‌روند.
  6. ۶. نقش ‏MON‏ داور در ‏stretch mode‏ چیست؟
    ‏MON‏ بدون داده در سایت سوم که هنگام قطع ارتباط دو سایت با ‏quorum‏ تعیین می‌کند کدام سایت فعال بماند.
  7. ۷. ‏stretch mode‏ چه اثری بر تأخیر نوشتن دارد؟
    تأخیر هر نوشتن به اندازه‌ی رفت‌وبرگشت بین دو سایت افزایش می‌یابد، چون نوشتن پیش از ‏ack‏ باید در هر دو سایت ثبت شود.
  8. ۸. چه اطلاعاتی در بازسازی ‏MON‏ از ‏OSD‏ها از دست می‌رود؟
    ‏keyring‏های ‏MDS‏ و بیشتر ‏keyring‏های دیگر، وضعیت ‏pool‏های در حال ساخت، و برخی تنظیمات صرفاً ‏MON‏.
  9. ۹. ‏Umbrella‏ چه ابزاری برای پشتیبان ‏MON‏ افزوده است؟
    پشتیبان دوره‌ای ‏RocksDB‏ مانیتور (‏mon_backup_interval‏)، فرمان ‏ceph tell mon.* backup‏ و بازیابی با ‏ceph-mon‏ --‏restore-backup‏.
  10. ۱۰. ‏ceph-objectstore-tool‏ در ‏DR‏ چه کاربردی دارد و پیش‌شرطش چیست؟
    صدور ‏PG‏ از ‏OSD‏ مرده‌ی خوانا و ورود آن به ‏OSD‏ دیگر برای نجات ‏PG incomplete‏ یا ‏down‏؛ پیش‌شرط: ‏OSD‏های مبدأ و مقصد متوقف باشند.

فصل ۱۹: راهبری و نگه‌داری روزمره: ارتقا، جایگزینی دیسک، ‏autoscaler‏ و ‏balancer‏#

  1. ۱. ترتیب ارتقای ‏daemon‏ها در ‏cephadm‏ چیست و چرا ‏mgr‏ اول است؟
    ‏mgr‏، سپس ‏mon‏ یکی‌یکی، سپس ‏OSD‏ها و در پایان سایر سرویس‌ها؛ ‏mgr‏ اول است چون ماژول ‏cephadm‏ که ارتقا را هدایت می‌کند در ‏mgr‏ اجرا می‌شود و باید نسخه‌ی جدید باشد.
  2. ۲. ارتقای ‏OSD‏ بر اساس ‏bucket CRUSH‏ چه مزیتی دارد؟
    همه‌ی ‏OSD‏های یک دامنه‌ی خرابی با هم و با تأیید ‏ok-to-upgrade‏ ارتقا می‌یابند؛ زمان ارتقای کلاستر بزرگ بسیار کم می‌شود بدون نقض در دسترس بودن.
  3. ۳. چرا ‏--replace‏ جابه‌جایی داده را کم می‌کند؟
    ‏OSD‏ در وضعیت ‏destroyed‏ با همان شناسه و جایگاه ‏CRUSH‏ می‌ماند؛ پس فقط ‏PG‏های همان ‏OSD‏ دوباره پر می‌شوند و بازتوزیع کلی رخ نمی‌دهد.
  4. ۴. ‏maintenance enter‏ چه کاری با پرچم ‏noout‏ انجام می‌دهد؟
    با ‏osd set-group‏، ‏noout‏ را برای زیردرخت ‏CRUSH‏ میزبان تنظیم و در خروج برمی‌دارد.
  5. ۵. فرمول پایه‌ی ‏pg_target‏ در ‏autoscaler‏ چیست؟
    ‏pg_target‏ = نسبت ظرفیت ‏pool‏ × (تعداد ‏OSD‏های ریشه × ‏mon_target_pg_per_osd‏) × ‏bias‏ / ‏size‏، سپس گرد کردن به توان ۲.
  6. ۶. آستانه‌ی ‏autoscaler‏ چه مشکلی را حل می‌کند و آستانه‌ی پویا چه زمانی اعمال می‌شود؟
    از تغییرات کوچک و پرتکرار ‏pg_num‏ جلوگیری می‌کند (تغییر فقط با اختلاف سه‌برابری)؛ آستانه‌ی پویا در افزایش به ۵۱۲ و ۱۰۲۴ (آستانه ۱) و ۲۰۴۸ (آستانه ۲) اعمال می‌شود.
  7. ۷. تغییر پیش‌فرض ‏mon_target_pg_per_osd‏ در ‏Umbrella‏ چه پیامدی دارد؟
    مقدار از ۱۰۰ به ۲۰۰ رسیده؛ پس از ارتقا ‏autoscaler‏ ممکن است ‏PG‏ها را تقسیم کند و داده جابه‌جا شود.
  8. ۸. ‏upmap balancer‏ چگونه ‏PG‏ی را برای جابه‌جایی انتخاب می‌کند؟
    ‏OSD‏هایی با انحراف بیش از ‏max_deviation‏ از سهم وزن‌دار را می‌یابد و ‏PG‏ی از ‏OSD‏ پر را به ‏OSD‏ کم‌بار منتقل می‌کند به‌شرطی که قانون ‏CRUSH‏ نقض نشود.
  9. ۹. چرا ‏upmap‏ ایمن‌تر از تغییر دستی وزن‌هاست؟
    روی خروجی ‏CRUSH‏ اعمال می‌شود و اگر قانون را نقض کند نادیده گرفته و پاک می‌شود؛ تغییر وزن کل نگاشت را تغییر می‌دهد و پیش‌بینی‌پذیر نیست.
  10. ۱۰. تفاوت ‏ceph config set‏ و ‏injectargs‏ چیست؟
    ‏ceph config set‏ در پایگاه داده‌ی ‏MON‏ ماندگار و قابل بازگشت است؛ ‏injectargs‏ فقط مقدار در حافظه‌ی ‏daemon‏ را موقتاً تغییر می‌دهد.

فصل ۲۰: پایش ‏Ceph: Prometheus‏، ‏ceph-exporter‏، هشدارها و مشاهده‌پذیری#

  1. ۱. چرا ‏perf counters‏ از ماژول ‏prometheus‏ به ‏ceph-exporter‏ منتقل شدند؟
    جمع‌آوری همه‌ی شمارنده‌های همه‌ی ‏daemon‏ها از یک ‏mgr‏ در کلاسترهای بزرگ کارایی ‏mgr‏ را کاهش می‌داد؛ ‏ceph-exporter‏ روی هر میزبان فقط ‏daemon‏های محلی را از ‏admin socket‏ می‌خواند.
  2. ۲. چرا باید همه‌ی ‏mgr‏ها یا ‏service discovery‏ را برای ‏scrape‏ تعریف کرد؟
    فقط ‏mgr‏ فعال متریک‌های کلاستر را منتشر می‌کند؛ پس از ‏failover‏، هدف ثابت به ‏mgr‏ قبلی نقطه‌ی کور می‌سازد.
  3. ۳. اولویت شمارنده و ‏exporter_prio_limit‏ چه رابطه‌ای دارند؟
    ‏ceph-exporter‏ فقط شمارنده‌هایی با اولویت دست‌کم ‏exporter_prio_limit‏ (پیش‌فرض ۵) را منتشر می‌کند.
  4. ۴. میانگین تأخیر یک بازه از شمارنده‌ی ‏time_avg‏ چگونه محاسبه می‌شود؟
    نسبت افزایش ‏sum‏ به افزایش ‏avgcount‏ در آن بازه؛ در ‏PromQL‏ نسبت ‏rate‏ دو سری _‏sum‏ و _‏count‏.
  5. ۵. متریک ‏ceph_health_detail‏ چه کاربردی دارد؟
    یک سری برای هر کد سلامت فعال با برچسب ‏name‏؛ امکان هشدار دقیق بر اساس کدهایی مانند ‏SLOW_OPS‏ یا ‏MON_DOWN‏.
  6. ۶. نقش ‏for‏ در قاعده‌ی هشدار چیست؟
    شرط باید در تمام مدت ‏for‏ برقرار بماند تا هشدار فعال شود؛ از هشدار برای پدیده‌های گذرا جلوگیری می‌کند.
  7. ۷. ‏inhibit‏ در ‏Alertmanager‏ چه مشکلی را حل می‌کند؟
    وقتی هشدار ریشه (مثلاً میزبان ‏down‏) فعال است، هشدارهای فرعی ناشی از آن (‏OSD‏های ‏down‏ همان میزبان) را خاموش می‌کند.
  8. ۸. ‏mgmt-gateway‏ چه مزایایی دارد؟
    یک نقطه‌ی ورود با ‏TLS‏ و نشانی مجازی برای همه‌ی رابط‌ها، امکان احراز هویت متمرکز با ‏oauth2-proxy‏ و امن شدن ‏endpoint‏های پایش.
  9. ۹. چرا ‏Prometheus‏ نباید مستقیماً در معرض کاربران باشد؟
    مدل امنیتی ‏Prometheus‏ فرض می‌کند داده‌ها برای هر دارنده‌ی دسترسی آشکار است؛ ‏API‏ آن همه‌ی (فرا)داده‌های جمع‌آوری‌شده را نشان می‌دهد.
  10. ۱۰. چند ‏SLI‏ مناسب برای سرویس ‏RBD‏ نام ببرید.
    درصد زمان فعال بودن همه‌ی ‏PG‏های ‏pool‏، صدک ۹۹ تأخیر نوشتن، و برای تصاویر ‏mirror‏ شده ‏RPO‏ (اختلاف ‏timestamp‏).

فصل ۲۱: تنظیم کارایی ‏Ceph‏: از ‏mClock‏ تا هسته و شبکه#

  1. ۱. چرا تنظیم کارایی باید با خط پایه و یک تغییر در هر زمان انجام شود؟
    چون بدون خط پایه نمی‌توان اثر را سنجید و با چند تغییر هم‌زمان نمی‌توان فهمید کدام مؤثر بوده یا آسیب زده است.
  2. ۲. شارد هر ‏PG‏ چگونه تعیین می‌شود و چرا همه‌ی عملیات یک ‏PG‏ در یک شارد است؟
    با ‏pgid.hash_to_shard‏(num_shards)؛ تا ترتیب عملیات یک ‏PG‏ حفظ شود و نیاز به هماهنگی بین شاردها نباشد.
  3. ۳. ‏Squid 19.2.1‏ چه تغییری در پیش‌فرض شاردهای ‏HDD‏ داد و چرا معقول است؟
    از ۵ شارد با ۱ ‏thread‏ به ۱ شارد با ۵ ‏thread‏؛ با یک شارد، ‏mClock‏ دید کامل از همه‌ی درخواست‌های ‏OSD‏ دارد و سهم‌ها را دقیق‌تر اعمال می‌کند.
  4. ۴. سه پارامتر ‏mClock‏ را تعریف کنید.
    ‏reservation‏ حداقل سهم تضمین‌شده، ‏weight‏ سهم نسبی از ظرفیت اضافه، ‏limit‏ سقف سهم.
  5. ۵. برچسب ‏R‏ در ‏dmclock‏ چگونه محاسبه می‌شود و ‏max‏(now, ...) چه نقشی دارد؟
    ‏R‏ = ‏max‏(now, R_prev + ‏increment‏ × (δ + ‏cost‏)) با ‏increment‏ = ۱/‏reservation‏؛ ‏max‏(now, ...) مانع انباشت اعتبار برای کلاس بی‌کار می‌شود.
  6. ۶. پروفایل ‏high_client_ops‏ چه تفاوتی با ‏balanced‏ دارد؟
    رزرو کلاینت ۶۰٪ با وزن ۲ در برابر ۵۰٪ با وزن ۱، رزرو بازیابی ۴۰٪، و سقف ‏best-effort‏ ۷۰٪ به جای ۹۰٪.
  7. ۷. چرا تغییر ‏osd_max_backfills‏ در پروفایل‌های داخلی اثری ندارد؟
    چون پروفایل‌های داخلی ‏mClock‏ این مقادیر را مدیریت می‌کنند و فقط با ‏osd_mclock_override_recovery_settings=true‏ می‌توان آن‌ها را تغییر داد.
  8. ۸. ‏OSD‏ ظرفیت ‏IOPS‏ خود را چگونه تعیین می‌کند و چه زمانی نتیجه را کنار می‌گذارد؟
    هنگام شروع، اگر مقدار ظرفیت پیش‌فرض باشد و سنجش رد نشده باشد، یک سنجش داخلی اجرا می‌کند؛ اگر نتیجه بیرون از بازه‌ی آستانه‌های پایین و بالا باشد، مقدار پیش‌فرض را به کار می‌برد.
  9. ۹. سه تنظیم سیستم‌عامل یا شبکه که بیشترین اثر را دارند نام ببرید.
    پروفایل ‏CPU‏ (tuned و ‏C-state‏)، ‏MTU‏ یکسان و شبکه‌ی ‏cluster‏ کافی، و زمان‌بند ‏I/O‏ مناسب (‏none‏ برای ‏NVMe‏).
  10. ۱۰. چرا باید صدک‌ها را به جای میانگین گزارش کرد؟
    چون میانگین دم توزیع را پنهان می‌کند؛ تجربه‌ی کاربر و ‏SLO‏ها را صدک‌های بالا تعیین می‌کنند.

فصل ۲۲: معماری کد ‏Ceph‏ و مسیر درخواست‌ها از درون#

  1. ۱. چرا ‏OSD‏ مستقیم روی دیسک نمی‌نویسد و از ‏ObjectStore::Transaction‏ استفاده می‌کند؟
    چون ‏Transaction‏ اتمیک است: داده‌ی شیء، ‏xattr‏، ‏omap‏ و ورودی ‏pg log‏ با هم پایدار می‌شوند یا هیچ‌کدام. همچنین ‏backend‏ (BlueStore، ‏MemStore‏، ‏SeaStore‏) قابل تعویض می‌ماند.
  2. ۲. ‏_calc_target‏ در ‏Objecter‏ چه ورودی‌هایی دارد و چه زمانی ‏op‏ دوباره ارسال می‌شود؟
    ورودی‌ها نام شیء، ‏pool‏، ‏namespace‏، ‏snap‏ و ‏OSDMap‏ جاری هستند و خروجی ‏pg‏، ‏acting‏ و ‏primary‏ است. اگر با نقشه‌ی جدید ‏primary‏ یا ‏acting‏ تغییر کند، ‏op‏ به ‏OSD‏ درست دوباره ارسال می‌شود.
  3. ۳. چرا ‏op‏ هر ‏PG‏ همیشه به یک ‏OSDShard‏ می‌رود؟
    چون شارد از ‏hash‏ شناسه‌ی ‏PG‏ به دست می‌آید. این کار ترتیب ‏op‏های یک ‏PG‏ را بدون هماهنگی بین شاردها حفظ می‌کند.
  4. ۴. نقش ‏ms_fast_dispatch‏ چیست و چه کاری نباید در آن انجام شود؟
    تحویل سریع پیام در همان ‏thread‏ شبکه و صف کردن آن در شارد. هیچ کار مسدودکننده یا قفل طولانی نباید در آن انجام شود.
  5. ۵. ‏ENCODE_START(v, compat, bl)‏ چگونه ارتقای غلتان را ممکن می‌کند؟
    ‏v‏ نسخه‌ی فعلی و ‏compat‏ کمترین نسخه‌ی ‏decoder‏ سازگار است. طول بلوک ذخیره می‌شود تا ‏decoder‏ قدیمی فیلدهای جدید را رد کند.
  6. ۶. تفاوت مسیر مستقیم و ‏deferred‏ در ‏BlueStore‏ چیست و چرا پیش‌فرض ‏SSD‏ صفر است؟
    در مسیر مستقیم داده با ‏aio‏ در فضای تازه نوشته می‌شود. در ‏deferred‏، داده‌ی کوچک ابتدا در ‏WAL RocksDB‏ ثبت و بعداً نوشته می‌شود. روی ‏SSD‏، ‏seek‏ گران نیست و دوبار نوشتن فقط ‏write amplification‏ اضافه می‌کند.
  7. ۷. ‏primary‏ در ‏replication‏ چه زمانی به کلاینت پاسخ می‌دهد؟
    وقتی همه‌ی اعضای ‏acting‏ (و خود ‏primary‏) تراکنش را ‏commit‏ کرده باشند؛ ‏eval_repop‏ این را بررسی می‌کند.
  8. ۸. در ‏RGW‏، کدام تابع ورودی ‏index‏ را از ‏pending‏ به ‏complete‏ می‌برد؟
    متد ‏cls‏ به نام ‏bucket_complete_op‏ که از طریق ‏UpdateIndex::complete‏ فراخوانی می‌شود.
  9. ۹. در ‏CephFS‏، چرا ‏MDS‏ در مسیر داده نیست و نبودِ ‏cap Fb‏ چه اثری دارد؟
    چون کلاینت با ‏Striper‏ و ‏Objecter‏ مستقیم به ‏OSD‏ می‌نویسد. بدون ‏Fb‏، کلاینت نمی‌تواند بافر کند و هر نوشتن هم‌گام به ‏OSD‏ می‌رود.
  10. ۱۰. برای یافتن پیش‌فرض واقعی یک گزینه در یک نسخه‌ی مشخص، به کجا مراجعه می‌کنید؟
    فایل ‏src/common/options/*.yaml.in‏ در ‏tag‏ همان نسخه (مثلاً ‏v20.2.0‏) در مخزن ‏ceph/ceph‏.

فصل ۲۳: لایه‌های پایینی (۱): دستگاه بلوکی، ‏bufferlist‏، ‏mempool‏ و ‏crc32c‏#

  1. ۱. چرا ‏KernelDevice‏ برای هر ‏write hint‏ یک ‏fd‏ جدا باز می‌کند؟
    تا روی هسته‌هایی که ‏F_SET_FILE_RW_HINT‏ را پشتیبانی می‌کنند، ‏hint‏ طول عمر داده (برای ‏SSD‏های دارای ‏streams‏) روی هر ‏fd‏ ثابت تنظیم شود و هر نوشتن بسته به ‏hint‏ از ‏fd‏ مناسب برود.
  2. ۲. هم‌ترازی ‏O_DIRECT‏ چه محدودیتی بر کوچک‌ترین نوشتن ‏BlueStore‏ می‌گذارد؟
    ‏offset‏، طول و آدرس بافر باید با بلوک (۴‏K‏) هم‌تراز باشند. بنابراین کوچک‌ترین نوشتن ۴‏K‏ است و نوشتن‌های کوچک‌تر یا ‏RMW‏ می‌شوند یا ‏deferred‏.
  3. ۳. نقش ‏bdev_aio_max_queue_depth‏ و ‏bdev_aio_reap_max‏ چیست؟
    اولی حداکثر تعداد ‏I/O‏ در حال اجرا در صف را تعیین می‌کند و دومی حداکثر تعداد تکمیلی را که در هر دور برداشته می‌شود.
  4. ۴. چه زمانی ‏BlueStore flush‏ جداگانه‌ی دستگاه داده را اجباری می‌کند؟
    وقتی داده و ‏DB‏ روی دستگاه‌های جدا باشند، یا چیزی برای ‏commit‏ در ‏RocksDB‏ نباشد؛ در این حالت ‏flush‏ لاگ ‏BlueFS‏ دستگاه داده را پوشش نمی‌دهد.
  5. ۵. چرا ‏discard‏ به‌طور پیش‌فرض خاموش است؟
    چون ‏TRIM‏ روی بسیاری از دستگاه‌ها هم‌گام و کند است و تأخیر را بالا می‌برد؛ دستگاه‌های امروزی ‏NVMe‏ بدون آن هم خوب کار می‌کنند.
  6. ۶. تفاوت ‏buffer::ptr‏ و ‏buffer::raw‏ چیست؟
    ‏raw‏ مالک حافظه است و شمارنده‌ی ارجاع دارد؛ ‏ptr‏ فقط پنجره‌ای (‏offset‏ و طول) روی یک ‏raw‏ است.
  7. ۷. چرا ‏bufferlist::c_str()‏ می‌تواند گران باشد؟
    چون اگر لیست چندتکه باشد، ‏rebuild‏ همه‌ی داده را در یک حافظه‌ی پیوسته‌ی جدید کپی می‌کند.
  8. ۸. ‏mempool‏ چگونه به ‏autotune‏ حافظه کمک می‌کند؟
    مصرف هر بخش را دقیق و شاردشده ثبت می‌کند و ‏autotune‏ با مقایسه‌ی آن با ‏osd_memory_target‏، سهم کش‌ها را تنظیم می‌کند.
  9. ۹. چرا ‏crc32c‏ مقدار ‏"123456789"‏ در ‏Ceph‏ با مقدار مرجع استاندارد فرق دارد؟
    چون ‏ceph_crc32c‏ ‏XOR‏ نهایی را انجام نمی‌دهد؛ ۰‏x1CF96D7C‏ پس از ‏XOR‏ با ۰‏xFFFFFFFF‏ برابر ۰‏xE3069283‏ می‌شود.
  10. ۱۰. سربار ‏checksum‏ با ‏chunk‏ ۴‏K‏ چقدر است و بزرگ کردن ‏chunk‏ چه بده‌بستانی دارد؟
    حدود ۰.۱٪ (۴ بایت برای هر ۴۰۹۶ بایت). ‏chunk‏ بزرگ‌تر سربار را کم می‌کند ولی خواندن کوچک را مجبور به خواندن کل ‏chunk‏ می‌کند.

فصل ۲۴: لایه‌های پایینی (۲): قالب روی‌دیسک ‏BlueStore‏ و ‏BlueFS‏#

  1. ۱. ۶۰ بایت اول ‏label‏ شامل چیست و چرا ‏decoder‏ از آن می‌پرد؟
    رشته‌ی «‏bluestore block device‏\‏n‏»، ‏uuid‏ مربوط به ‏OSD‏ به شکل متن و یک \‏n‏؛ این بخش فقط برای خوانایی انسان است و داده‌ی کدگذاری‌شده پس از آن آغاز می‌شود.
  2. ۲. چرا ‏superblock‏ مربوط به ‏BlueFS‏ همیشه در ‏offset 4096‏ است؟
    چون بلوک اول به ‏label‏ اختصاص دارد و ‏BlueFS‏ آگاهانه همین فرض (بلوک دوم) را دارد؛ این در ‏bluestore_common.h‏ ثابت شده است.
  3. ۳. ‏denc_lba‏ برای ‏offset‏ هم‌تراز با ۴‏K‏ چند بایت مصرف می‌کند و چرا؟
    معمولاً ۴ بایت؛ ۱۲ بیت صفر انتهایی با یک بیت نوع حذف می‌شود و ۳۰ بیت داده تا حدود ۴ ترابایت آدرس‌دهی را پوشش می‌دهد.
  4. ۴. چه شرطی فشرده‌سازی لاگ ‏BlueFS‏ را آغاز می‌کند؟
    اندازه‌ی لاگ حداقل ‏bluefs_log_compact_min_size‏ (۱۶‏M‏) باشد و نسبت آن به اندازه‌ی تخمینی حداقل ‏bluefs_log_compact_min_ratio‏ (۵) باشد.
  5. ۵. چرا ‏hash‏ در کلید ‏onode‏ بیت‌معکوس است؟
    تا اشیای یک ‏PG‏ که بیت‌های پایینی ‏hash‏ مشترک دارند، یک بازه‌ی پیوسته در فضای کلید بسازند و ‏list‏ و ‏scrub‏ با ‏range scan‏ انجام شود.
  6. ۶. پرچم‌های ‏BLOBID‏ در ‏extent map‏ چه صرفه‌جویی‌ای ایجاد می‌کنند؟
    ‏logical_offset‏، ‏blob_offset‏ یا ‏length‏ تکراری نوشته نمی‌شوند؛ یک ‏lextent‏ معمولی ۱ تا ۲ بایت می‌شود.
  7. ۷. چرا ‏checksum‏ بزرگ‌ترین بخش یک ‏blob‏ کدگذاری‌شده است؟
    با ‏crc32c‏ و ‏chunk‏ ۴‏K‏، هر ‏blob‏ ۶۴‏K‏ برابر ۶۴ بایت ‏checksum‏ دارد، در حالی که ‏pextent‏ها چند بایت‌اند.
  8. ۸. ‏hybrid allocator‏ چگونه مصرف حافظه را محدود می‌کند؟
    با سقف ‏bluestore_hybrid_alloc_mem_cap‏ (۶۴‏M‏) برای ‏AVL‏؛ قطعه‌های اضافی به ‏Bitmap‏ با حافظه‌ی ثابت سرریز می‌کنند.
  9. ۹. چرا ‏freelist‏ از ‏merge‏ با ‏XOR‏ استفاده می‌کند؟
    چون ‏XOR‏ جابه‌جاپذیر و خودمعکوس است؛ تخصیص و آزادسازی بدون خواندن مقدار قبلی به یک ‏merge‏ تبدیل می‌شوند.
  10. ۱۰. الگوریتم ۲‏Q‏ چه مشکلی از ‏LRU‏ را حل می‌کند؟
    یک اسکن ترتیبی یک‌باره کش داده‌های پرکاربرد را خالی نمی‌کند، چون داده فقط با دیده شدن دوباره به ‏hot‏ می‌رود.

فصل ۲۵: لایه‌های پایینی (۳): ‏RocksDB‏ درون ‏BlueStore‏#

  1. ۱. ‏group commit‏ در ‏_kv_sync_thread‏ چگونه تعداد ‏fsync‏ها را کم می‌کند؟
    چند تراکنش آماده در یک ‏WriteBatch‏ پشت سر هم ثبت می‌شوند و فقط آخرین آن‌ها ‏sync‏ است؛ یک ‏fsync‏ روی ‏WAL‏ همه را پایدار می‌کند.
  2. ۲. سرآیند رکورد ‏WAL‏ چند بایت است و چه فیلدهایی دارد؟
    ۷ بایت: ‏crc32c‏ ماسک‌شده (۴)، طول (۲) و نوع (۱)؛ در حالت ‏recyclable‏ ۴ بایت شماره‌ی لاگ هم اضافه می‌شود.
  3. ۳. چرا ‏min_write_buffer_number_to_merge=6‏ برای ‏Ceph‏ مهم است؟
    چون کلیدهای کوتاه‌عمر (‏deferred‏ و ‏pg log‏) در ادغام ‏memtable‏ها حذف می‌شوند و هرگز به ‏SST‏ نمی‌رسند، که ‏write amplification‏ را بسیار کم می‌کند.
  4. ۴. چرا برای ‏CF‏های ‏L‏ و ‏P‏ این عدد ۳۲ است؟
    چون عمر کلیدهای ‏deferred‏ (‏L‏) و ‏pgmeta‏ (‏P‏) بسیار کوتاه است و ادغام بیشتر یعنی حذف بیشتر پیش از ‏flush‏.
  5. ۵. بلوک ‏filter‏ در ‏SST‏ چه نقشی در مسیر خواندن دارد؟
    بدون خواندن بلوک داده تعیین می‌کند کلید احتمالاً در این فایل نیست و بیشتر خواندن‌های بی‌فایده‌ی ‏L0‏ تا ‏Ln‏ را حذف می‌کند.
  6. ۶. با پیش‌فرض‌ها اندازه‌ی ‏L3‏ چقدر است؟
    حدود ۶۴‏G‏ (۱G × ۸ × ۸).
  7. ۷. ‏use_some_extra‏ چه تفاوتی با ‏rocksdb_original‏ دارد؟
    ‏rocksdb_original‏ فقط سطوح کامل را روی ‏DB‏ می‌گذارد؛ ‏use_some_extra‏ فضای اضافه را برای بخشی از سطح بعدی استفاده می‌کند.
  8. ۸. چگونه ‏CF‏ یک کلید ‏omap per-pg‏ انتخاب می‌شود؟
    بایت‌های ۰ تا ۱۲ کلید با ‏ceph_str_hash_rjenkins‏ هش می‌شوند و باقیمانده بر ۳ شماره‌ی ‏CF‏ را می‌دهد.
  9. ۹. چرا ‏omap‏ یک ‏PG‏ باید در یک ‏shard‏ بماند؟
    تا پیمایش ‏omap‏ یک شیء یا ‏PG‏ در یک ‏CF‏ و یک ‏range scan‏ انجام شود.
  10. ۱۰. چرا تغییر کل رشته‌ی ‏bluestore_rocksdb_options‏ خطرناک است و جایگزین آن چیست؟
    چون پیش‌فرض‌های مهم (مثل ادغام ‏memtable‏ و ‏LZ4‏) ناخواسته حذف می‌شوند؛ ‏bluestore_rocksdb_options_annex‏ فقط کلیدهای تغییرکرده را اضافه می‌کند.

فصل ۲۶: لایه‌های پایینی (۴): ‏msgr2‏ در سطح بایت، ‏AsyncConnection‏ و ‏EventCenter‏#

  1. ۱. ساختار ‏banner‏ در ‏msgr2‏ چیست و ویژگی‌های فعلی کدام‌اند؟
    «‏ceph v2‏\‏n‏»، طول ‏u16‏ (۱۶) و دو ‏u64‏ برای ویژگی‌های ‏supported‏ و ‏required‏؛ ویژگی‌های فعلی ‏REVISION_1‏ و ‏COMPRESSION‏ هستند.
  2. ۲. چرا ‏preamble‏ دقیقاً ۳۲ بایت است؟
    تا مضرب بلوک ‏AES‏ (۱۶) باشد و در حالت ‏secure‏ بدون ‏padding‏ اضافه رمز شود.
  3. ۳. ‏crc‏ مربوط به ‏preamble‏ و ‏crc‏ مربوط به ‏segment‏ با چه ‏seed‏هایی محاسبه می‌شوند؟
    ‏preamble‏ با ‏seed‏ صفر روی ۲۸ بایت اول؛ ‏segment‏ها با ‏seed‏ برابر ۰‏xFFFFFFFF‏ (−۱).
  4. ۴. چرا ‏segment‏ داده هم‌ترازی ۴۰۹۶ دارد؟
    تا گیرنده بافر هم‌تراز با صفحه تخصیص دهد و داده را بدون کپی به ‏O_DIRECT‏ برساند.
  5. ۵. ‏inline‏ کردن ۴۸ بایت در حالت ‏secure‏ چه سودی دارد؟
    ‏header‏ پیام و ‏frame‏های کنترلی کوچک با یک رمزگشایی و یک ‏tag‏ خوانده می‌شوند و طول بقیه‌ی ‏frame‏ بلافاصله معلوم می‌شود.
  6. ۶. ‏AUTH_SIGNATURE‏ از چه حمله‌ای جلوگیری می‌کند؟
    از حمله‌ی ‏downgrade‏ یا دستکاری بایت‌های رمزنشده‌ی پیش از ‏auth‏، مثل تغییر ‏preferred_modes‏.
  7. ۷. ‏SESSION_RESET‏ و ‏SESSION_RETRY_GLOBAL‏ چه زمانی ارسال می‌شوند؟
    ‏RESET‏ وقتی ‏cookie‏ جلسه برای سرور ناشناخته است (مثلاً پس از ‏restart‏)؛ ‏RETRY_GLOBAL‏ وقتی ‏global_seq‏ کلاینت از آنچه سرور دیده قدیمی‌تر است.
  8. ۸. سه ‏throttler‏ در دریافت پیام کدام‌اند و چگونه ‏backpressure‏ ایجاد می‌کنند؟
    تعداد پیام، بایت‌های ‏policy‏ و صف ‏dispatch‏؛ با پر شدن هرکدام خواندن از سوکت متوقف می‌شود و پنجره‌ی ‏TCP‏ فرستنده را کند می‌کند.
  9. ۹. چرا ‏handler‏ها در ‏EventCenter‏ باید تا ‏EAGAIN‏ بخوانند؟
    چون ‏epoll‏ در حالت ‏edge-triggered‏ است و داده‌ی خوانده‌نشده رویداد جدیدی ایجاد نمی‌کند.
  10. ۱۰. ‏thread‏ دیگری چگونه یک ‏worker‏ را برای ارسال پیام بیدار می‌کند؟
    رویداد را در ‏external_events‏ صف می‌کند و با نوشتن در ‏eventfd‏ (یا ‏pipe‏)، ‏epoll_wait‏ آن ‏worker‏ را بیدار می‌کند.

فصل ۲۷: لایه‌های پایینی (۵): ریاضیات ‏erasure coding‏، از ‏GF‏(۲⁸) تا ‏FastEC‏#

  1. ۱. چرا جمع و تفریق در ‏GF(28)\mathrm{GF}(2^8)‏ هر دو ‏XOR‏ هستند؟
    چون ضرایب در ‏GF‏(۲) هستند و ۱ + ۱ = ۰؛ پس جمع بیت‌به‌بیت همان ‏XOR‏ است و هر عنصر قرینه‌ی خودش است.
  2. ۲. ۰‏x56‏ × ۰‏x04‏ در ‏GF(28)\mathrm{GF}(2^8)‏ با ۰‏x11D‏ چگونه محاسبه می‌شود؟
    ۰‏x56‏ دو بار شیفت می‌شود و ۰‏x158‏ به دست می‌آید؛ چون بیت ۸ روشن است، ۰‏x58‏ ⊕ ۰‏x1D‏ = ۰‏x45‏.
  3. ۳. کد ‏MDS‏ چیست و چرا ‏Vandermonde‏ ساده‌ی ‏ISA-L‏ همیشه ‏MDS‏ نیست؟
    کدی که هر ‏k chunk‏ از ‏k+m‏ برای بازسازی کافی باشد؛ در ‏Vandermonde‏ ساده برخی زیرماتریس‌های ‏k‏×‏k‏ در ‏GF(28)\mathrm{GF}(2^8)‏ معکوس‌پذیر نیستند.
  4. ۴. ‏Ceph‏ در چه شرایطی خودکار به ‏cauchy‏ تغییر می‌دهد؟
    وقتی ‏m‏ > ۴ باشد، یا ‏m‏ = ۴ و ‏k‏ > ۲۱.
  5. ۵. در مثال این فصل، ‏P0‏ و ‏P1‏ چگونه به دست آمدند؟
    ‏P0‏ برابر ‏XOR‏ چهار بایت (۰‏x08‏) است و ‏P1‏ برابر ۱۲ ⊕ ۲·۳۴ ⊕ ۴·۵۶ ⊕ ۸·۷۸ = ۰‏xD8‏.
  6. ۶. چرا ضرایب ‏decode‏ کش می‌شوند؟
    چون معکوس کردن ماتریس برای هر الگوی خرابی گران است و همان الگو بارها در ‏recovery‏ تکرار می‌شود.
  7. ۷. ‏PSHUFB‏ چگونه ضرب در ثابت را سریع می‌کند؟
    ضرب به دو جست‌وجوی ۱۶ خانه‌ای برای ‏nibble‏ها تبدیل می‌شود و ‏PSHUFB‏ ده‌ها جست‌وجو را در یک دستور انجام می‌دهد.
  8. ۸. ‏parity delta‏ چیست و چرا درست است؟
    به‌روزرسانی ‏parity‏ با ‏P′=P⊕g⋅(D⊕D′)P' = P \oplus g \cdot (D \oplus D')‏؛ چون کد خطی است، تغییر یک ‏chunk‏ داده اثر خطی جداگانه‌ای بر هر ‏parity‏ دارد.
  9. ۹. ‏stripe_unit‏ پیش‌فرض در ‏pool‏ بهینه چقدر است و چرا؟
    ۱۶‏K‏؛ چون با نوشتن جزئی بهینه، ‏stripe‏ بزرگ‌تر هزینه‌ی ‏RMW‏ ندارد و خواندن ترتیبی و فراداده کاراتر می‌شوند.
  10. ۱۰. پهنای باند ترمیم ‏CLAY‏ با ‏k=8‏، ‏m=4‏ و ‏d=11‏ چقدر است و هزینه‌ی آن چیست؟
    ۲.۷۵‏S‏ در برابر ۸‏S‏؛ هزینه‌ی آن ۶۴ ‏sub-chunk‏ در هر ‏chunk‏ و خواندن‌های ریز و پراکنده است.

فصل ۲۸: لایه‌های پایینی (۶): ‏CRUSH‏ در سطح بیت، از ‏rjenkins‏ تا ‏upmap‏#

  1. ۱. ‏ceph_stable_mod‏ چگونه حرکت داده را هنگام افزایش ‏pg_num‏ محدود می‌کند؟
    فقط ‏PG‏هایی که بیت جدید ‏mask‏ را دارند و شماره‌شان از ‏pg_num‏ کمتر می‌شود جابه‌جا (‏split‏) می‌شوند؛ بقیه همان شماره را نگه می‌دارند.
  2. ۲. چرا ‏HASHPSPOOL‏ لازم است؟
    تا ‏PG‏های هم‌شماره در ‏pool‏های مختلف به یک ‏x‏ نرسند و روی همان ‏OSD‏ها انباشته نشوند.
  3. ۳. چرا ‏CRUSH‏ فقط از عملیات صحیح استفاده می‌کند؟
    تا نتیجه روی همه‌ی معماری‌ها و در هسته و فضای کاربر بیت‌به‌بیت یکسان باشد.
  4. ۴. در ‏straw2‏، ‏draw‏ چگونه محاسبه می‌شود و چرا بیشترین ‏draw‏ برنده است؟
    ‏draw‏ = ‏(crush_ln(u)−248)/w(\mathrm{crush\_ln}(u) - 2^{48}) / w‏؛ چون ‏ln‏ منفی است، وزن بیشتر ‏draw‏ بزرگ‌تر (کم‌منفی‌تر) می‌دهد. این معادل کمینه‌ی متغیرهای نمایی است.
  5. ۵. ‏crush_ln‏ چه چیزی را با چه دقتی برمی‌گرداند؟
    ‏244⋅log⁡2(x+1)2^{44} \cdot \log_2(x+1)‏ را با دو جدول و عملیات صحیح، با دقت کافی برای توزیع ۱۶ بیتی، برمی‌گرداند.
  6. ۶. چرا ‏straw2‏ حرکت حداقلی دارد و ‏straw‏ قدیمی نداشت؟
    چون ‏draw‏ هر آیتم فقط به وزن خودش بستگی دارد؛ در ‏straw‏ طول نی‌ها نسبی و وابسته به همه‌ی وزن‌ها بود.
  7. ۷. تصادم در ‏firstn‏ چگونه حل می‌شود و سقف آن چیست؟
    ‏ftotal‏ افزایش و ‏r‏ = ‏rep‏ + ‏ftotal‏ می‌شود؛ تا ‏choose_total_tries=50‏.
  8. ۸. تفاوت ‏firstn‏ و ‏indep‏ برای ‏EC‏ چیست؟
    در ‏firstn‏ موقعیت‌ها جابه‌جا می‌شوند؛ در ‏indep‏ جایگاه هر ‏shard‏ ثابت است و فقط ‏shard‏ گم‌شده دوباره انتخاب می‌شود.
  9. ۹. ‏weight-set‏ در ‏choose_args‏ چه مشکلی را حل می‌کند؟
    انحراف توزیع ‏replica‏های دوم و سوم از وزن‌ها را با وزن جداگانه برای هر ‏position‏ اصلاح می‌کند، بدون تغییر وزن‌های اصلی.
  10. ۱۰. ترتیب اعمال ‏upmap‏ها چیست و ‏mon‏ با ‏upmap‏ نامعتبر چه می‌کند؟
    ‏pg_upmap‏، سپس ‏pg_upmap_items‏ و سپس ‏pg_upmap_primary‏؛ ‏mon upmap‏هایی را که قاعده را نقض کنند حذف می‌کند.

فصل ۲۹: لایه‌های پایینی (۷): کلاینت‌های هسته‌ی لینوکس، ‏libceph‏، ‏krbd‏ و ‏ceph.ko‏#

  1. ۱. ‏libceph‏ از چه بخش‌هایی تشکیل شده است و چرا ‏CRUSH‏ در هسته هم هست؟
    ‏messenger‏، ‏mon_client‏، ‏osd_client‏، ‏osdmap‏ و ‏CRUSH‏، ‏cephx‏ و ‏striper‏؛ ‏CRUSH‏ در هسته هست تا کلاینت خودش ‏PG‏→‏OSD‏ را بدون واسطه حساب کند.
  2. ۲. یک ‏request‏ در ‏blk-mq‏ چگونه به ‏obj_request‏ها تقسیم می‌شود؟
    ‏img_request‏ بازه‌ی بایت را با ‏striper‏ و اندازه‌ی شیء به بازه‌های هر شیء می‌شکند و برای هرکدام یک ‏obj_request‏ می‌سازد.
  3. ۳. چه زمانی ‏krbd‏ به‌جای ‏WRITE‏ از ‏WRITEFULL‏، ‏ZERO‏، ‏TRUNCATE‏ یا ‏DELETE‏ استفاده می‌کند؟
    ‏WRITEFULL‏ برای پوشش کامل شیء؛ ‏ZERO‏ برای صفر کردن میانه؛ ‏TRUNCATE‏ برای صفر کردن انتها؛ ‏DELETE‏ برای ‏discard‏ کل شیء بدون ‏parent‏.
  4. ۴. ‏copyup‏ در ‏krbd‏ چه زمانی رخ می‌دهد؟
    وقتی در یک ‏clone‏ روی شیئی نوشته می‌شود که هنوز وجود ندارد و ‏parent‏ در آن بازه داده دارد.
  5. ۵. چرا کلاینت هسته در برابر ‏pool‏ پر گیر می‌کند و چگونه می‌توان آن را محدود کرد؟
    چون درخواست‌ها با ‏PAUSEWR‏ یا ‏pool_full‏ نگه داشته می‌شوند تا نقشه‌ی بعدی؛ با ‏osd_request_timeout‏ محدود می‌شود.
  6. ۶. مقادیر ‏io_opt‏ و ‏io_min‏ در ‏krbd‏ از کجا می‌آیند؟
    ‏io_opt‏ از ‏object_size‏ × ‏stripe_count‏ و ‏io_min‏ از ‏alloc_size‏ (پیش‌فرض ۶۴‏K‏).
  7. ۷. رشته‌ی ‏caps‏ به شکل ‏pAsLsXsFrwcb‏ را تفسیر کنید.
    ‏pin‏؛ ‏Auth shared‏؛ ‏Link shared‏؛ ‏Xattr shared‏؛ ‏File read‏، ‏write‏، ‏cache‏ و ‏buffer‏.
  8. ۸. چرا خواننده‌ی دوم یک فایل در حال نوشتن، ‏Fc‏ نمی‌گیرد؟
    چون با وجود نویسنده‌ی هم‌زمان، داده‌ی کش‌شده ممکن است کهنه باشد؛ ‏MDS‏ فقط ‏Fr‏ می‌دهد و خواندن مستقیم از ‏OSD‏ انجام می‌شود.
  9. ۹. هشدار ‏MDS_HEALTH_CLIENT_LATE_RELEASE‏ چه معنایی دارد؟
    یک کلاینت به درخواست ‏revoke caps‏ پاسخ نداده است و کلاینت‌های دیگر منتظرند.
  10. ۱۰. دو مزیت و دو عیب ‏krbd‏ نسبت به ‏librbd‏ را بگویید.
    مزایا: سربار کم و عدم نیاز به فرایند کاربر؛ معایب: ویژگی‌های محدود (بدون ‏journaling‏) و نیاز به هسته‌ی جدید برای ارتقا.

فصل ۳۰: لایه‌های پایینی (۸): ‏Crimson‏ و ‏Seastar‏، ‏OSD‏ تک‌هسته‌ای و ‏SeaStore‏#

  1. ۱. چرا مدل ‏thread pool‏ در ‏OSD‏ کلاسیک روی ‏NVMe‏ هزینه‌بر است؟
    هر درخواست چند بار بین ‏thread‏ها و قفل‌ها جابه‌جا می‌شود و هزینه‌ی ‏context switch‏ و ‏cache miss‏ با تأخیر چند ده میکروثانیه‌ای ‏NVMe‏ قابل مقایسه است.
  2. ۲. ‏future‏ و ‏continuation‏ در ‏Seastar‏ چگونه جایگزین بلوکه شدن می‌شوند؟
    تابع ناهم‌گام بی‌درنگ ‏future‏ برمی‌گرداند؛ ادامه با ‏then‏ وصل می‌شود و پس از ‏set_value‏ در صف همان ‏reactor‏ اجرا می‌شود.
  3. ۳. ‏crimson_reactor_task_quota_ms‏ چه چیزی را محدود می‌کند و یک ‏continuation‏ طولانی چه اثری دارد؟
    بیشینه‌ی زمانی که ‏reactor‏ پیش از ‏poll‏ دوباره ‏task‏ها را اجرا می‌کند؛ ‏continuation‏ طولانی همه‌ی ‏PG‏های آن هسته را متوقف می‌کند (‏stall‏).
  4. ۴. ‏PG‏ تازه چگونه به یک هسته نسبت داده می‌شود و این روش چه ضعفی دارد؟
    هسته‌ی ۰ کم‌بارترین هسته از نظر تعداد ‏PG‏ را با ‏min_element‏ انتخاب می‌کند؛ بار ‏PG‏ها در نظر گرفته نمی‌شود و ‏work-stealing‏ ندارد.
  5. ۵. تفاوت ‏phase‏های ‏exclusive‏ و ‏concurrent‏ را با مثال ‏WaitRepop‏ توضیح دهید.
    ‏exclusive‏ یک عملیات در لحظه و ترتیب ورود؛ ‏concurrent‏ چند عملیات هم‌زمان با خروج به ترتیب؛ ‏WaitRepop‏ اجازه می‌دهد چند نوشتن هم‌زمان منتظر ‏replica‏ها باشند.
  6. ۶. ‏AlienStore‏ چرا لازم است و چه هزینه‌ای دارد؟
    برای اجرای ‏BlueStore‏ و ‏MemStore‏ کلاسیک خارج از ‏reactor‏؛ هزینه‌ی دو گذر از مرز ‏reactor/thread‏ و رقابت ‏CPU‏.
  7. ۷. ‏laddr‏ و ‏paddr‏ در ‏SeaStore‏ چه تفاوتی دارند و چرا این جداسازی هزینه‌ی ‏GC‏ را کم می‌کند؟
    ‏laddr‏ منطقی و پایدار است و ‏paddr‏ فیزیکی؛ با جابه‌جایی بلوک فقط ‏LBA tree‏ به‌روز می‌شود.
  8. ۸. ساختار ۶۴ بیتی ‏paddr_t‏ را برای ‏segment‏ و ‏RBM‏ شرح دهید.
    ۸ بیت ‏device_id‏؛ ‏segment‏: ۲۴ بیت شماره‌ی ‏segment‏ و ۳۲ بیت آفست؛ ‏RBM‏: ۵۶ بیت آفست مطلق.
  9. ۹. فرمول ‏cost-benefit‏ را بنویسید و ‏autotune‏ را با مثال توضیح دهید.
    ‏(1−u)⋅age/(2u)(1-u) \cdot \mathit{age} / (2u)‏؛ اگر سهم آزاد ‏greedy‏ دست‌کم ‏ratio‏ برابر سهم آزاد انتخاب فرمول باشد، انتخاب ‏greedy‏ جایگزین می‌شود.
  10. ۱۰. سه پرچمی که برای فعال کردن ‏Crimson‏ لازم‌اند کدام‌اند؟
    ویژگی آزمایشی ‏crimson‏، پرچم ‏allow_crimson‏ در ‏OSDMap‏ (set-allow-crimson) و ‏osd_pool_default_crimson‏ برای ‏pool‏ها.

فصل ۳۱: لایه‌های پایینی (۹): ‏SPDK‏ و ‏NVMe‏، از صف‌های سخت‌افزاری تا درگاه ‏NVMe-oF‏#

  1. ۱. ‏SQ‏ و ‏CQ‏ کجا قرار دارند و چه کسی در هرکدام می‌نویسد؟
    هر دو در حافظه‌ی میزبان‌اند؛ میزبان در ‏SQ‏ فرمان می‌نویسد و کنترلر در ‏CQ‏ نتیجه.
  2. ۲. ‏Phase Tag‏ چگونه بدون خواندن ثبات دستگاه، ‏CQE‏ تازه را مشخص می‌کند؟
    کنترلر در هر دور صف مقدار ‏P‏ را وارونه می‌نویسد؛ میزبان ورودی‌ای را تازه می‌داند که ‏P‏ آن با ‏cq_phase‏ فعلی برابر باشد.
  3. ۳. چرا هسته نوشتن ‏doorbell‏ را تا پایان دسته به تعویق می‌اندازد؟
    هر ‏doorbell‏ یک نوشتن ‏MMIO‏ گران از راه ‏PCIe‏ است؛ یک نوشتن برای کل دسته کافی است.
  4. ۴. فیلد ‏length‏ در فرمان ‏Read‏ چرا صفرمبناست و برای ۸ بلوک چه مقداری دارد؟
    چون صفر بلوک بی‌معناست و بیشینه‌ی ۶۵۵۳۶ بلوک در ۱۶ بیت جا می‌گیرد؛ برای ۸ بلوک مقدار ۷.
  5. ۵. چرا ‏NVMEDevice‏ داده را در بافرهای ‏DMA‏ کپی می‌کند؟
    کنترلر حافظه‌ی ‏pinned‏ با ‏IOVA‏ معلوم (‏hugepage‏ مربوط به ‏DPDK‏) لازم دارد و ‏bufferlist‏ چنین نیست.
  6. ۶. ‏thread_local SharedDriverQueueData‏ چه سودی و چه هزینه‌ای دارد؟
    سود: ‏qpair‏ و مخزن بافر بدون قفل؛ هزینه: هر ‏thread‏ تازه ۸ ‏MiB‏ بافر ‏DMA‏ و یک ‏qpair‏ مصرف می‌کند.
  7. ۷. ‏aio_submit‏ در ‏NVMEDevice‏ از نظر بلوکه شدن با ‏KernelDevice‏ چه تفاوتی دارد؟
    ‏NVMEDevice‏ تا تکمیل همه‌ی ‏I/O‏های ‏IOContext‏ در همان ‏thread poll‏ می‌کند؛ ‏KernelDevice‏ فقط ارسال می‌کند.
  8. ۸. مسیر یک نوشتن از ‏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‏.
  9. ۹. چرا درگاه جایگزین پیش از ‏ACTIVE‏ شدن باید منتظر ‏blocklist‏ باشد؟
    تا درگاه قبلی، اگر هنوز زنده است، نتواند بنویسد و دو نویسنده‌ی هم‌زمان روی یک ‏namespace‏ پدید نیاید (‏fencing‏).
  10. ۱۰. الگوریتم انتخاب درگاه جایگزین چه زمانی -‏EBUSY‏ و چه زمانی -‏ENOENT‏ برمی‌گرداند؟
    -‏EBUSY‏ اگر نامزدی نباشد ولی دست‌کم یک درگاه در حال گذار باشد؛ -‏ENOENT‏ اگر هیچ درگاه در دسترسی در محدوده نباشد.

فصل ۳۲: لایه‌های پایینی (۱۰): ‏scrub‏، ‏recovery‏، ‏backfill‏ و ‏repair‏ در سطح کد#

  1. ۱. زمان ‏scrub‏ بعدی ‏shallow‏ و ‏deep‏ با پیش‌فرض‌ها در چه بازه‌ای است و چرا توزیع ‏deep‏ در لبه‌ها قله دارد؟
    ‏shallow‏ یکنواخت در [۲۴، ۳۶) ساعت؛ ‏deep‏ نرمال با میانگین ۷ روز و انحراف ۱.۴ روز که به [۴.۲، ۹.۸] روز بریده می‌شود. بریدن احتمال دنباله‌ها را روی لبه‌ها جمع می‌کند.
  2. ۲. هشدار ‏PG_NOT_DEEP_SCRUBBED‏ دقیقاً پس از چه مدتی داده می‌شود؟
    وقتی از آخرین ‏deep scrub‏ بیش از ‏deep_interval‏ × (۱ + ۰.۷۵) یعنی ۱۲.۲۵ روز گذشته باشد.
  3. ۳. چرا ‏chunk scrub‏ نباید ‏head‏ را از ‏clone‏هایش جدا کند؟
    ‏clone‏ تازه همیشه درست کنار ‏head‏ ساخته می‌شود و ممکن است میان دو ‏chunk‏ دیده نشود.
  4. ۴. پس از سه ‏preemption‏ در ‏deep scrub‏، بیشینه‌ی اندازه‌ی ‏chunk‏ چقدر است؟
    ‏divisor‏ برابر ۸ است و ۱۵/۸=۱، اما حداقل ۵ است، پس ۵.
  5. ۵. در ‏select_auth_object‏، اگر نسخه‌ها برابر باشند، چه معیاری برنده را تعیین می‌کند؟
    شمار ‏digest‏های ثبت‌شده (‏dcount‏) و در تساوی کامل، ترتیب نامزدها که با ‏primary‏ شروع می‌شود.
  6. ۶. اولویت ‏backfill‏ یک ‏PG undersized‏ با ‏size=3‏ و دو عضو ‏acting‏ چقدر است؟
    ۱۴۰ + ۱ + ۱۰ = ۱۵۱.
  7. ۷. چرا حتی با ‏recovery_priority=0‏ اولویت ۱۰ واحد بالا می‌رود؟
    ‏clamp_recovery_priority‏ بازه‌ی −۱۰ تا +۱۰ را به ۰ تا ۲۰ منتقل می‌کند.
  8. ۸. ‏AsyncReserver‏ در چه شرطی یک رزرو در جریان را پس می‌گیرد؟
    وقتی خانه‌ها پرند و درخواست صف‌شده اولویتی بیشتر از کم‌اولویت‌ترین رزرو قابل‌‏preempt‏ دارد، یا ‏min_priority‏ بالا رفته یا ‏max‏ پایین آمده است.
  9. ۹. ‏async recovery‏ چه هدفی را از ‏acting‏ بیرون می‌گذارد و چه شرطی آن را محدود می‌کند؟
    عضوی با هزینه‌ی (فاصله‌ی نسخه + اشیای گم‌شده) بیش از ۱۰۰، به شرط آنکه ‏acting‏ باقی‌مانده هنوز قابل نوشتن باشد.
  10. ۱۰. چرا ‏repair‏ همان محدودیت‌های ‏recovery‏ را دارد؟
    چون ‏repair‏ فقط ‏shard‏های خراب را ‏missing‏ علامت می‌زند و کپی را به ‏recovery‏ عادی می‌سپارد.

فصل ۳۳: لایه‌های پایینی (۱۱): حافظه و ‏CPU‏ درون ‏OSD‏، از ‏mempool‏ تا ‏NUMA‏ و پروفایل‌گیری#

  1. ۱. چرا ‏mempool‏ به‌جای یک شمارنده‌ی ‏atomic‏ مشترک از ‏shard‏ استفاده می‌کند و ‏shard‏ چگونه انتخاب می‌شود؟
    تا ‏cache line‏ شمارنده میان هسته‌ها رفت و برگشت نکند؛ با ‏sched_getcpu‏() & (‏num_shards‏−۱)، یا ‏round-robin‏ ثابت برای هر ‏thread‏.
  2. ۲. اندازه‌ی ‏shard_t‏ چرا مضرب ۱۲۸ است؟
    ‏aligned‏(۱۲۸) تا دو ‏shard‏ هرگز یک ‏cache line‏ مشترک نداشته باشند.
  3. ۳. دو عددی را که از ‏osd_memory_target‏ به‌عنوان ‏max‏ و ‏min‏ بودجه‌ی ‏cache‏ به دست می‌آیند با پیش‌فرض‌ها محاسبه کنید.
    ‏max‏ = ۰.۸۵ × ۴۰۹۶ − ۷۶۸ = ۲۷۱۳.۶ ‏MiB‏ و ‏min‏ = ‏osd_memory_cache_min‏ = ۱۲۸ ‏MiB‏.
  4. ۴. ‏tune_memory‏ در افزایش و کاهش چه رفتار متفاوتی دارد؟
    افزایش متناسب با (۱ − ‏mapped/target‏) × فاصله تا ‏max‏، و کاهش متناسب با (۱ − ‏target/mapped‏) × فاصله تا ‏min‏.
  5. ۵. چرا ‏osd_memory_target‏ سقف سخت نیست؟
    چون فقط اندازه‌ی ‏cache‏ها را کم می‌کند؛ حافظه‌ی حساب‌نشده می‌تواند خودش از هدف بگذرد.
  6. ۶. در ‏balance‏، ‏cache‏ی که کمتر از سهمش می‌خواهد چه می‌شود و باقی‌مانده به چه کسی می‌رسد؟
    همان مقدار را می‌گیرد و از دورهای بعد خارج می‌شود؛ باقی‌مانده بر پایه‌ی نسبت میان ‏cache‏های ناراضی تقسیم می‌شود.
  7. ۷. ‏get_chunk‏ برای ‏tuned_mem‏ برابر ۱۶۷۲ ‏MiB‏ چه مقداری دارد؟
    ‏chunk‏ = ۸ ‏MiB‏؛ ‏get_chunk‏(۱) = ۷۲ ‏MiB‏.
  8. ۸. چرا افزایش ‏threads_per_shard‏ برای یک ‏PG‏ داغ کمکی نمی‌کند؟
    چون قفل ‏PG‏ اجرای موازی ‏op‏های یک ‏PG‏ را محدود می‌کند و همه‌ی ‏op‏های آن ‏PG‏ به یک ‏shard‏ می‌روند.
  9. ۹. ‏OSD‏ در چه شرطی خودکار وابستگی ‏NUMA‏ تنظیم می‌کند؟
    وقتی گره دستگاه ذخیره‌سازی و گره رابط‌های ‏public‏ و ‏cluster‏ یکی باشد و ‏osd_numa_auto_affinity=true‏؛ یا با ‏osd_numa_node‏ صریح.
  10. ۱۰. «بودجه‌ی ‏CPU‏ برای هر ‏op‏» را چگونه حساب می‌کنید و از آن چه نتیجه‌ای می‌گیرید؟
    هسته‌های مصرف‌شده تقسیم بر ‏op‏ در ثانیه؛ سپس سهم هر لایه از ‏flame graph‏ را در آن ضرب کنید تا سقف صرفه‌جویی هر تنظیم معلوم شود.

فصل ۳۴: بخش تخصصی (۱): ‏RADOS‏ — هویت شیء، فراداده و مسیر ‏op‏ درون ‏OSD‏#

  1. ۱. ‏hobject_t‏ به چه ترتیبی مقایسه می‌شود؟
    ‏max‏، ‏pool‏، کلید بیتی (‏hash‏ برعکس‌شده)، ‏nspace‏، ‏key‏ مؤثر (اگر یکی از دو ‏key‏ خالی نباشد)، ‏oid‏ و در پایان ‏snap‏.
  2. ۲. چرا کلید بیتی ‏hash‏ را برعکس می‌کند؟
    تا بیت‌های پایین ‏hash‏ که ‏PG‏ را تعیین می‌کنند به بالای کلید بروند و همه‌ی اشیای یک ‏PG‏ یک بازه‌ی پیوسته در ترتیب مرتب‌سازی بسازند.
  3. ۳. پس از دوبرابر شدن ‏pg_num‏، بازه‌ی کلید بیتی ‏PG‏ ‏‏0x1f‏ چگونه تقسیم می‌شود؟
    به دو نیمه‌ی پیوسته: ‏PG‏ ‏۰‏x1f‏ بازه‌ی [۰‏xf8000000, 0xfbffffff]‏ و ‏PG‏ تازه‌ی ۰‏x3f‏ بازه‌ی [۰‏xfc000000, 0xffffffff]‏.
  4. ۴. ‏xattr‏های ‏_‏ و ‏snapset‏ چه چیزی نگه می‌دارند؟
    ‏‏_‏ همان ‏object_info_t‏ (نسخه، اندازه، پرچم‌ها، ‏digest‏ها، ‏watcher‏ها) و ‏snapset‏ همان ‏SnapSet‏ شیء ‏head‏ است.
  5. ۵. ‏shard‏ یک ‏op‏ چگونه انتخاب می‌شود و پیش‌فرض‌ها روی ‏SSD‏ چیست؟
    ‏shard‏ = ‏ps‏ % ‏num_shards‏؛ روی ‏SSD‏ پیش‌فرض ۸ ‏shard‏ و ۲ ‏thread‏ در هر ‏shard‏ است.
  6. ۶. اگر شیء روی ‏primary missing‏ باشد، ‏op‏ در کدام صف می‌ماند؟
    ‏‏waiting_for_unreadable_object‏ با متن «‏waiting for missing object‏».
  7. ۷. درخواست تکراری چگونه تشخیص داده می‌شود و ‏dups‏ چه نقشی دارند؟
    با جست‌وجوی ‏reqid‏ در ‏caller_ops‏ و ‏extra_caller_ops‏ و ‏dup_index‏؛ ‏dups‏ نتیجه‌ی درخواست‌هایی را نگه می‌دارند که ورودی ‏log‏ آن‌ها ‏trim‏ شده است.
  8. ۸. ‏user_version‏ چگونه محاسبه می‌شود و چرا ممکن است برای یک شیء پیوسته نباشد؟
    ‏max‏(last_user_version مربوط به ‏PG, user_version‏ شیء) + ۱ (و حداقل به اندازه‌ی ‏at_version.version‏)؛ چون شمارنده در سطح ‏PG‏ افزایش می‌یابد، نه در سطح شیء.
  9. ۹. پاسخ نوشتن ‏replicated‏ چه زمانی به کلاینت فرستاده می‌شود؟
    وقتی همه‌ی اعضای ‏acting‏ (از جمله خود ‏primary) commit‏ را گزارش کرده باشند.
  10. ۱۰. کلید یک ورودی ‏pg log‏ چه قالبی دارد و چرا طول آن ثابت است؟
    ‏%۰۱۰‏u‏.%۰۲۰‏llu‏ از ‏epoch‏ و ‏version‏ (و برای ‏dup‏ پیشوند ‏dup_‏)؛ طول ثابت باعث می‌شود ترتیب رشته‌ای با ترتیب عددی یکی باشد.

فصل ۳۵: بخش تخصصی (۲): ‏RADOS‏ — ‏pg log‏، ‏interval‏ها، ‏missing‏ و سازوکار ‏recovery‏ و ‏backfill‏#

  1. ۱. چه تغییرهایی در ‏OSDMap‏ یک ‏interval‏ تازه می‌سازند؟ سه مورد غیر از ‏up‏ و ‏acting‏ نام ببرید.
    افزون بر ‏up‏ و ‏acting‏ و ‏primary‏ها: تغییر ‏size‏ یا ‏min_size‏، ‏split‏ یا ‏merge‏، ‏sort_bitwise‏، ‏recovery_deletes‏، پارامترهای ‏stretch‏ در ‏CRUSH‏ و روشن شدن بهینه‌سازی‌های ‏EC‏.
  2. ۲. ‏maybe_went_rw‏ در چه شرایطی ‏true‏ است؟
    وقتی ‏acting‏ قابل نوشتن بوده (دست‌کم ‏min_size‏) و یا ‏up_thru primary‏ آغاز ‏interval‏ را پوشانده یا ‏last_epoch_clean‏ درون آن ‏interval‏ بوده است.
  3. ۳. چرا ‏up_thru‏ برای ایمنی ‏peering‏ لازم است؟
    چون ‏primary‏ فقط پس از ثبت ‏up_thru‏ در ‏mon active‏ می‌شود؛ پس ‏interval‏ی که ‏up_thru‏ در آن ثبت نشده نوشتنی نداشته و لازم نیست منتظر اعضایش ماند.
  4. ۴. چه زمانی ‏PG‏ ‏‏down‏ می‌شود و ‏blocked_by‏ چه کسی را نشان می‌دهد؟
    وقتی برای ‏interval‏ی با ‏maybe_went_rw‏ اعضای ‏up‏ یا ‏lost‏ کافی نباشند (‏replicated‏: هیچ، ‏EC‏: کمتر از ‏k‏) و دست‌کم یک عضو آن ‏down‏ باشد؛ ‏blocked_by‏ همان ‏OSD‏های ‏down‏ است.
  5. ۵. ‏merge_log‏ وقتی ‏log‏ معتبر جلوتر است چه کار می‌کند؟
    ورودی‌های بعد از ‏lower_bound‏ را اضافه می‌کند، ‏missing‏ را برای هر کدام به‌روز می‌کند، ورودی‌های محلی بعد از ‏lower_bound‏ را ‏divergent‏ می‌شمارد و ‏last_update‏ را برابر سر ‏log‏ معتبر می‌کند.
  6. ۶. ورودی ‏divergent‏ چیست و چرا برگرداندن آن ایمن است؟
    ورودی‌ای که در ‏log‏ معتبر نیست؛ چون پاسخ کلاینت فقط پس از ‏commit‏ همه‌ی ‏acting‏ داده می‌شود، کلاینت آن نوشتن را موفق ندیده است.
  7. ۷. حالت‌های ۴ و ۵ رسیدگی به ‏divergent‏ چه فرقی دارند؟
    در ۴ همه‌ی ورودی‌ها ‏rollback‏ دارند و شیء محلی برگردانده می‌شود؛ در ۵ شیء حذف و با ‏need=prior‏ در ‏missing‏ گذاشته می‌شود تا از عضو دیگری بازیابی شود.
  8. ۸. هدف طول ‏log‏ برای ‏OSD‏ی با ۶۰۰ ‏PG‏ با پیش‌فرض‌ها چقدر است؟
    ‏۳۰۰۰۰۰/۶۰۰ = ۵۰۰، که بین ۲۵۰ و ۱۰۰۰۰ است؛ پس ۵۰۰.
  9. ۹. چه شرطی تعیین می‌کند یک عضو ‏backfill‏ شود؟
    اگر ‏log_tail‏ ما از ‏last_update‏ آن عضو جلوتر باشد یا ‏last_backfill‏ آن خالی باشد (عضو تازه).
  10. ۱۰. ‏backfill‏ چگونه تشخیص می‌دهد شیئی باید از هدف حذف شود؟
    شیئی که در بازه‌ی هدف هست ولی کوچک‌تر از کوچک‌ترین شیء باقی‌مانده‌ی بازه‌ی ‏primary‏ است، یعنی در ‏primary‏ وجود ندارد.

فصل ۳۶: بخش تخصصی (۳): ‏RADOS‏ — ‏snapshot‏ و ‏clone‏، ‏watch/notify‏ و ‏cls‏ در سمت ‏OSD‏، و مرجع ‏rados‏ و ‏pool‏#

  1. ۱. چرا یک ‏pool‏ نمی‌تواند هم ‏pool snapshot‏ و هم ‏self-managed snapshot‏ داشته باشد؟
    چون هر دو از یک ‏snap_seq‏ شماره می‌گیرند و ‏SnapContext‏ در یکی را ‏OSD‏ و در دیگری کلاینت تعیین می‌کند؛ ترکیب آن‌ها مالکیت شماره‌ها را مبهم می‌کند و ‏mon‏ آن را رد می‌کند.
  2. ۲. ‏SnapContext‏ چه فیلدهایی دارد و در ‏RBD‏ چه کسی آن را می‌فرستد؟
    ‏seq‏ و فهرست نزولی ‏snaps‏؛ ‏librbd‏ آن را از ‏header‏ تصویر می‌خواند و در هر نوشتن روی اشیای داده می‌فرستد.
  3. ۳. شرط ساختن ‏clone‏ در ‏make_writeable‏ چیست؟
    ‏head‏ وجود داشته باشد و ‏whiteout‏ نباشد، ‏SnapContext‏ دست‌کم یک ‏snap‏ داشته باشد و ‏snaps[0]‏ از ‏snapset.seq‏ بزرگ‌تر باشد.
  4. ۴. ‏clone‏ با چه شماره‌ای نام‌گذاری می‌شود؟
    با ‏snapc.seq‏، یعنی بزرگ‌ترین ‏snap‏ تازه‌ای که ‏clone‏ نماینده‌ی آن است.
  5. ۵. در مثال فصل، خواندن در ‏snap 5‏ و ‏snap 3‏ به چه نتیجه‌ای می‌رسد؟
    ‏snap 5‏ به ‏clone‏ ‏@۶ می‌رسد چون ۵ در ‏clone_snaps[6]‏ است؛ ‏snap 3‏ به @۴ می‌رسد ولی ۳ در [۴] نیست، پس ‏ENOENT‏.
  6. ۶. ‏whiteout‏ چیست و چه زمانی حذف می‌شود؟
    ‏head‏ حذف‌شده‌ای که برای نگه داشتن ‏SnapSet‏ باقی می‌ماند؛ وقتی ‏snaptrim‏ آخرین ‏clone‏ را حذف کند، ‏whiteout‏ هم حذف می‌شود.
  7. ۷. کلید ‏SNA_‏ در ‏SnapMapper‏ چه ساختاری دارد و چرا به این شکل است؟
    ‏‏SNA_<pool>_<snap‏ به ‏hex‏ شانزده‌رقمی>_ سپس پیشوند ‏shard‏ و ‏hobject.to_str‏()؛ تا همه‌ی ‏clone‏های یک ‏snap‏ با یک اسکن بازه‌ای پیدا شوند.
  8. ۸. وقتی ‏clone‏ دیگر هیچ ‏snap‏ی ندارد، با ‏clone_overlap‏ چه می‌شود؟
    اگر ‏clone‏ قدیمی‌تری باشد، ‏overlap‏ آن با ‏overlap clone‏ حذف‌شده اشتراک گرفته می‌شود؛ سپس ورودی‌های ‏clone‏ از ‏clones‏ و ‏clone_overlap‏ و ‏clone_size‏ و ‏clone_snaps‏ پاک می‌شوند.
  9. ۹. ‏watch‏ منقضی‌شده چگونه حذف می‌شود و چرا ممکن است تا مدتی بماند؟
    پس از ‏osd_client_watch_timeout‏ بدون ‏ping‏، با یک نوشتن روی شیء از ‏object_info_t‏ حذف می‌شود؛ اگر ‏PG‏ نوشتن نپذیرد، تا بازگشت آن می‌ماند.
  10. ۱۰. چرا فراخوانی ‏cls‏ با بقیه‌ی ‏op‏های یک پیام اتمی است؟
    چون متد روی همان ‏OpContext‏ اجرا می‌شود و همه‌ی ‏cls_cxx_*‏ها به همان تراکنش و همان ورودی ‏log‏ اضافه می‌شوند.

فصل ۳۷: بخش تخصصی (۴): ‏RBD‏ — چیدمان روی ‏RADOS‏، ‏striping‏، ‏object map‏ و ‏fast-diff‏، و مرجع ‏rbd‏#

  1. ۱. کدام کلیدهای ‏header‏ برای ساختن نام اشیای داده لازم‌اند؟
    ‏‏object_prefix‏ و ‏order‏ (و در صورت ‏striping‏ سفارشی، ‏stripe_unit‏ و ‏stripe_count‏)؛ نام هر شیء ‏object_prefix‏ به‌همراه شماره‌ی شیء به ‏hex‏ شانزده‌رقمی است.
  2. ۲. با ‏data pool‏ جدا، نام اشیای داده چه تغییری می‌کند و چرا؟
    پیشوند به ‏rbd_data.<‏شناسه‌ی ‏pool‏ فراداده>.<‏id>‏ تبدیل می‌شود تا اشیای ‏image‏های چند ‏pool‏ که یک ‏data pool‏ مشترک دارند با هم برخورد نکنند.
  3. ۳. ‏rbd_directory‏ چه دو نوع کلیدی دارد؟
    ‏‏name_<name>‏ که به ‏id‏ اشاره می‌کند و ‏id_<id>‏ که به نام اشاره می‌کند.
  4. ۴. در مثال ‏striping‏، بایت آفست ۱۱۰۰۰۰۰ در کدام شیء و کدام آفست است؟
    ‏‏block 16‏، ‏stripe 4‏، ‏stripepos 0‏؛ پس شیء ۰ در آفست ۳۱۳۵۶۸.
  5. ۵. ‏object map‏ هر شیء را با چند بیت نگه می‌دارد و شیء ۰ در کدام بیت‌های بایت اول است؟
    دو بیت؛ شیء ۰ در دو بیت بالای بایت اول است (‏shift‏ = ۶).
  6. ۶. چرا ‏footer object map‏ برای هر بلوک ۴ ‏KiB‏ یک ‏crc‏ جدا دارد؟
    تا به‌روزرسانی یک شیء فقط همان بلوک ۴ ‏KiB‏ و ‏crc‏ آن را بازنویسی کند و کل نقشه لازم نباشد.
  7. ۷. ‏EXISTS_CLEAN‏ چه زمانی تنظیم و چه زمانی پاک می‌شود؟
    هنگام گرفتن ‏snapshot‏ همه‌ی ‏EXISTS‏های ‏head‏ به ‏EXISTS_CLEAN‏ تبدیل می‌شوند؛ نخستین نوشتن بعدی روی آن شیء آن را به ‏EXISTS‏ برمی‌گرداند.
  8. ۸. در ‏fast-diff‏ اگر شیء در ‏from_snap‏ ‏‏DATA‏ و در ‏head‏ ‏‏EXISTS‏ باشد، نتیجه چیست؟
    ‏‏DATA_UPDATED‏، چون حالت ‏EXISTS‏ (نه ‏EXISTS_CLEAN‏) یعنی شیء پس از ‏snapshot‏ نوشته شده است.
  9. ۹. چرا ‏object map‏ به ‏exclusive-lock‏ وابسته است؟
    چون فقط یک نویسنده باید نقشه را تغییر دهد تا حالت حافظه و ‏RADOS‏ سازگار بمانند؛ مالک قفل همان نویسنده است.
  10. ۱۰. ‏namespace‏ در ‏RBD‏ چگونه پیاده شده و چه مزیتی دارد؟
    همان ‏namespace‏ در ‏RADOS‏ است و همه‌ی اشیای فهرست (‏rbd_directory‏ و دیگران) در هر ‏namespace‏ جدا ساخته می‌شوند؛ می‌توان با ‏cap‏ یک کلاینت را به یک ‏namespace‏ محدود کرد بی‌آنکه ‏pool‏ جدا ساخت.

فصل ۳۸: بخش تخصصی (۵): ‏RBD‏ — مسیر ‏I/O‏ در ‏librbd‏، ‏layering‏ و ‏copyup‏، ‏exclusive-lock‏، ‏cache‏ و ‏QoS‏#

  1. ۱. لایه‌ی ‏EXCLUSIVE_LOCK‏ پیش از کدام لایه‌ها اجرا می‌شود و چرا؟
    پیش از ‏REFRESH‏، ‏MIGRATION‏، ‏JOURNAL‏، ‏WRITE_BLOCK‏، ‏WRITEBACK_CACHE‏ و ‏CORE‏؛ چون ‏journal‏، ‏object map‏ و ‏cache‏ فقط برای مالک قفل معتبرند و نوشتن باید پیش از رسیدن به آن‌ها منتظر قفل بماند.
  2. ۲. چه زمانی ‏copyup‏ بدون فرستادن نخستین نوشتن انجام می‌شود؟
    وقتی ‏object map‏ می‌گوید شیء در ‏clone‏ وجود ندارد و ‏extent‏ در ‏overlap‏ والد است؛ ‏librbd‏ مستقیم ‏copyup‏ می‌کند و نوشتن را به همان ‏op‏ می‌چسباند.
  3. ۳. چرا متد ‏cls‏ ‏‏copyup‏ اگر شیء وجود داشته باشد کاری نمی‌کند؟
    چون اگر کلاینت دیگری زودتر ‏copyup‏ کرده باشد، داده‌ی والد نباید روی نوشتن‌های تازه‌تر کلاینت دیگر بازنویسی شود؛ نوشتن همراه در همان ‏op‏ به‌هرحال اعمال می‌شود.
  4. ۴. ‏deep-flatten‏ چه چیزی را اضافه می‌کند؟
    ‏copyup‏ به ‏snapshot‏های ‏clone‏ هم می‌رسد (‏copyup‏ جدا با ‏SnapContext‏ خالی و به‌روزرسانی ‏object map snapshot‏ها)، پس ‏snapshot‏های ‏clone‏ هم از والد مستقل می‌شوند.
  5. ۵. ‏cookie‏ قفل ‏rbd_lock‏ چه ساختاری دارد و به چه کاری می‌آید؟
    ‏«‏auto‏ <‏watch handle>‏» با ‏tag‏ ‏‏internal‏؛ با مقایسه‌ی آدرس و ‏handle‏ با ‏list_watchers‏ می‌توان فهمید مالک قفل هنوز ‏watch‏ زنده دارد.
  6. ۶. چرا شکستن قفل بدون ‏blocklist‏ خطرناک است؟
    چون مالک قدیمی ممکن است فقط از شبکه جدا شده باشد و نوشتن‌های در مسیرش بعداً روی داده‌ی مالک جدید فرود آیند.
  7. ۷. ‏writearound‏ چه زمانی نوشتن را بلافاصله تأیید نمی‌کند؟
    وقتی ‏max_dirty‏ صفر باشد یا پرچم ‏FUA‏ داده شود، وقتی ‏extent‏ با نوشتن در جریان هم‌پوشانی داشته باشد، یا وقتی بایت‌های در جریان به ‏rbd_cache_max_dirty‏ رسیده باشند.
  8. ۸. ‏rbd_cache_writethrough_until_flush‏ از چه چیزی محافظت می‌کند؟
    از مهمانی که هرگز ‏flush‏ نمی‌فرستد؛ تا نخستین ‏flush‏ همه‌ی نوشتن‌ها همگام‌اند.
  9. ۹. با ‏rbd_qos_iops_limit = 1000‏ و ‏tick‏ ‏۵۰ ‏ms‏، در هر ‏tick‏ چند توکن اضافه می‌شود؟
    ‏۱۰۰۰ × ۰.۰۵ = ۵۰ توکن.
  10. ۱۰. دو دلیل برای استفاده از ‏rbd-nbd‏ به‌جای ‏krbd‏ نام ببرید.
    نیاز به ویژگی‌هایی که ‏krbd‏ ندارد (‏journaling‏، ‏cache‏ یا ‏QoS‏ در ‏librbd‏، ‏LUKS‏ در ‏librbd‏) و هسته‌ی قدیمی که ویژگی‌های ‏image‏ را پشتیبانی نمی‌کند.

فصل ۳۹: بخش تخصصی (۶): ‏RBD‏ — درون ‏rbd-mirror: journal‏ در برابر ‏snapshot‏#

  1. ۱. نام اشیای ‏header‏ و داده‌ی ‏journal‏ چیست؟
    ‏header‏ در ‏journal.<image-id>‏ و داده در ‏journal_data.<pool-id>.<image-id>.<n>‏.
  2. ۲. رویداد با ‏entry_tid‏ ‏۱۲۳۴ در ‏journal‏ با ‏splay_width‏ ‏۴ و ‏active_set‏ ‏۹ در کدام شیء نوشته می‌شود؟
    ‏‏splay_offset‏ = ۱۲۳۴ % ۴ = ۲؛ شیء ۹ × ۴ + ۲ = ۳۸، یعنی ‏journal_data.<pool>.<id>.38‏.
  3. ۳. سربار ثابت هر رویداد ‏journal‏ چند بایت است و از چه فیلدهایی تشکیل می‌شود؟
    ‏۳۳ بایت: ‏preamble‏ ‏۸، ‏version‏ ‏۱، ‏entry tid‏ ‏۸، ‏tag tid‏ ‏۸، طول داده ‏۴ و ‏crc32c‏ ‏۴.
  4. ۴. چرا نوشتن داده باید منتظر ‏SAFE‏ شدن رویداد بماند؟
    تا اگر کلاینت پس از نوشتن داده و پیش از ثبت رویداد از کار بیفتد، مقصد (و ‏replay‏ محلی) تغییری را ببیند که در ‏journal‏ نیست؛ ترتیب «اول رویداد» تضمین می‌کند هر تغییر داده در ‏journal‏ هست.
  5. ۵. چه چیزی جلوی ‏trim‏ شدن ‏journal‏ را می‌گیرد؟
    ‏commit position‏ کندترین ‏client‏ ثبت‌شده؛ ‏set‏های پیش از کمترین ‏commit set‏ حذف نمی‌شوند.
  6. ۶. چرا مقصد در حالت ‏journal‏ همیشه ‏crash-consistent‏ است؟
    چون رویدادها با همان ترتیب و نقاط ‏flush‏ مبدأ ‏replay‏ می‌شوند، پس مقصد همیشه حالت مبدأ در یک لحظه‌ی گذشته را دارد.
  7. ۷. چهار حالت ‏snapshot‏ ‏‏mirror‏ کدام‌اند؟
    ‏‏PRIMARY‏، ‏PRIMARY_DEMOTED‏، ‏NON_PRIMARY‏ و ‏NON_PRIMARY_DEMOTED‏.
  8. ۸. ‏rbd-mirror‏ در حالت ‏snapshot‏ چگونه اشیای تغییرکرده را پیدا می‌کند؟
    با ‏object map diff‏ (fast-diff) میان دو ‏snapshot‏ ‏‏mirror‏ متوالی در مبدأ و کپی فقط اشیای ‏DATA_UPDATED‏ یا ‏HOLE_UPDATED‏.
  9. ۹. چه زمانی حالت ‏snapshot‏ پهنای باند بیشتری از حالت ‏journal‏ مصرف می‌کند؟
    وقتی نوشتن‌ها کوچک و پراکنده روی اشیای زیاد باشند؛ هر شیء تغییرکرده کامل (تا ۴ ‏MiB‏) منتقل می‌شود.
  10. ۱۰. ‏leader‏ در ‏rbd-mirror‏ چگونه انتخاب می‌شود و پس از چه مدتی جایگزین می‌شود؟
    با قفل ‏cls_lock‏ انحصاری روی ‏rbd_mirror_leader‏ و ‏heartbeat‏ هر ۵ ثانیه؛ پس از دو ‏heartbeat‏ از دست رفته، دیگران قفل را می‌شکنند و ‏leader‏ تازه انتخاب می‌شود.

فصل ۴۰: بخش تخصصی (۷): ‏RGW‏ — مدل داده روی ‏RADOS‏: فراداده، ‏bucket index‏، نسخه‌بندی، ‏manifest‏ و ‏multipart‏#

  1. ۱. ‏entrypoint‏ و ‏instance‏ یک ‏bucket‏ چه فرقی دارند و ‏reshard‏ کدام را عوض می‌کند؟
    ‏entrypoint‏ با نام ‏bucket‏ فقط به ‏instance‏ فعلی اشاره می‌کند؛ ‏instance‏ ‏(‏.bucket.meta.<bucket>:<id>‏) همه‌ی ویژگی‌ها و ‏layout‏ ایندکس را دارد. ‏reshard‏ یک ‏instance‏ تازه با ‏bucket_id‏ جدید می‌سازد و ‏entrypoint‏ را به آن می‌برد؛ ‏marker‏ ثابت می‌ماند.
  2. ۲. کلید ورودی ‏bilog‏ در ‏omap‏ ایندکس چه ساختاری دارد؟
    در حالت ‏InIndex‏: بایت ۰‏x80‏، پیشوند ‏0_‏، سپس ‏index_ver‏ با قالب ‏%011llu‏، نقطه، نسخه‌ی ‏OSD‏ و نقطه و شماره‌ی ‏subop‏.
  3. ۳. چرا کلیدهای ویژه با بایت ۰‏x80‏ شروع می‌شوند؟
    تا از نام‌های معمولی جدا شوند: در ‏UTF-8‏ هیچ نامی با ۰‏x80‏ شروع نمی‌شود، پس بایت اول نوع کلید را معلوم می‌کند. فهرست‌گیری باید بازه‌ی ۰‏x80‏ را رد کند چون نام‌های غیر ‏ASCII‏ پس از آن مرتب می‌شوند.
  4. ۴. ‏size‏ و ‏accounted_size‏ در ورودی ایندکس چه فرقی دارند؟
    ‏size‏ حجم واقعی ذخیره‌شده (پس از فشرده‌سازی یا رمزنگاری) است و ‏accounted_size‏ حجمی که کاربر فرستاده و دیده؛ سهمیه و آمار بر پایه‌ی دومی است.
  5. ۵. اگر ‏RGW‏ پس از ‏prepare‏ و نوشتن داده ولی پیش از ‏complete‏ از کار بیفتد، ورودی چگونه ترمیم می‌شود؟
    برچسب در ‏pending_map‏ می‌ماند. فهرست‌گیری بعدی وقتی برچسب از ‏rgw_pending_bucket_index_op_expiration‏ ‏(۱۲۰ ثانیه) قدیمی‌تر باشد، ‏head‏ را با ‏check_disk_state‏ می‌خواند و با ‏dir_suggest_changes‏ ورودی را به‌روز یا حذف می‌کند. ‏bucket check --fix‏ هم همین کار را برای همه انجام می‌دهد.
  6. ۶. ‏OLH‏ چیست و در کجا ذخیره می‌شود؟
    ‏object logical head‏؛ نشانگر نسخه‌ی جاری. یک ورودی ‏1001_<name>‏ در ایندکس (با ‏log‏ تغییرات) و یک شیء ‏head‏ بی‌داده با نام اصلی که ‏xattr‏های ‏user.rgw.olh.*‏ دارد.
  7. ۷. حذف بدون ‏versionId‏ در ‏bucket‏ نسخه‌دار چه می‌کند؟
    یک ‏instance‏ تازه از نوع ‏delete marker‏ می‌سازد و با ‏link_olh‏ آن را نسخه‌ی جاری می‌کند؛ هیچ داده‌ای پاک نمی‌شود و ‏GET‏ بدون ‏versionId‏ ‏۴۰۴ می‌دهد.
  8. ۸. ‏head‏ یک شیء ‏COLD‏ در کدام ‏pool‏ است و چه دارد؟
    در ‏pool‏ ‏‏STANDARD placement‏ ‏‏bucket‏؛ بدون داده، فقط ‏manifest‏ و ‏xattr‏ها. همه‌ی داده در ‏tail‏های ‏pool‏ ‏‏COLD‏ است.
  9. ۹. ‏ETag‏ آپلود سه‌بخشی چگونه ساخته می‌شود؟
    ‏md5‏ الحاق ‏ETag‏های دودویی بخش‌ها به ترتیب، به‌صورت ‏hex‏، به‌اضافه‌ی ‏-‏ و تعداد بخش‌ها.
  10. ۱۰. پیشوند ‏2~‏ در ‏upload_id‏ چه چیزی را نشان می‌دهد؟
    ‏upload‏ با قالب جدید (‏v2‏) ساخته شده و کلیدهای ‏omap‏ بخش‌ها ‏part.%08d‏ و در نتیجه به‌ترتیب عددی مرتب‌اند.

فصل ۴۱: بخش تخصصی (۸): ‏RGW‏ — مسیر درخواست، ‏SigV4‏، سهمیه، محدودیت نرخ، ‏gc‏ و ‏lifecycle‏#

  1. ۱. مراحل اصلی ‏rgw_process_authenticated‏ به ترتیب کدام‌اند؟
    ‏init permissions‏ و خواندن مجوزها، ‏init op‏، بررسی ‏op mask‏، بررسی ‏CORS‏، بررسی مجوز ‏op‏، بررسی پارامترها، ‏pre-exec‏، بررسی محدودیت نرخ، ‏execute‏ و ‏complete‏.
  2. ۲. ‏RGW‏ اختلاف زمان مجاز درخواست ‏SigV4‏ را چقدر می‌گیرد و چه خطایی می‌دهد؟
    ‏‏RGW_AUTH_GRACE‏ یعنی ۱۵ دقیقه؛ بیش از آن با ‏RequestTimeTooSkewed‏ رد می‌شود.
  3. ۳. کلید امضای ‏SigV4‏ چگونه از کلید محرمانه مشتق می‌شود؟
    چهار ‏HMAC-SHA256‏ زنجیره‌ای: کلید اول «‏AWS4‏» به‌اضافه‌ی ‏secret‏ روی تاریخ، سپس ‏region‏، سپس نام سرویس ‏s3‏ و در پایان رشته‌ی ‏aws4_request‏.
  4. ۴. چه چیزی توان یک جریان ‏PUT‏ را محدود می‌کند و کدام گزینه آن را تنظیم می‌کند؟
    حجم داده‌ی در پرواز تقسیم بر تأخیر نوشتن ‏RADOS‏؛ با ‏rgw_put_obj_min_window_size‏ ‏(۱۶ ‏MiB‏) تنظیم می‌شود (برای ‏GET‏ ‏‏rgw_get_obj_window_size‏).
  5. ۵. در حالت پیش‌فرض، سهمیه‌ی حجم شیء ۱۰۰ بایتی را چقدر حساب می‌کند؟
    ‏۴۰۹۶ بایت، چون ‏DefApplier‏ اندازه را تا مضرب ۴ ‏KiB‏ گرد می‌کند (مگر ‏check_on_raw‏ روشن باشد).
  6. ۶. چرا سهمیه در ‏RGW‏ «نرم» است؟
    هر ‏RGW‏ آمار را از ‏cache‏ خود می‌خواند و ‏cache‏ پس از ‏rgw_bucket_quota_ttl‏ تازه می‌شود؛ چند ‏RGW‏ هم‌زمان می‌توانند کمی از سقف عبور کنند.
  7. ۷. محدودیت نرخ ۶۰۰ ‏read op‏ در دقیقه پشت سه ‏RGW‏ در عمل چقدر است؟
    تا حدود ۱۸۰۰ در دقیقه، چون هر ‏RGW‏ سطل توکن مستقل دارد.
  8. ۸. ‏shard‏ ‏‏gc‏ یک زنجیره چگونه انتخاب می‌شود و چرا ‏tail‏ فوراً حذف نمی‌شود؟
    ‏‏XXH64‏ برچسب با ‏seed‏ ثابت به پیمانه‌ی ‏rgw_gc_max_objs‏ ‏(۳۲). ‏tail‏ دست‌کم ‏rgw_gc_obj_min_wait‏ ‏(۲ ساعت) نگه داشته می‌شود تا ‏GET‏های در جریان که ‏manifest‏ قدیمی را دارند ناقص نمانند.
  9. ۹. ‏lifecycle‏ چگونه ‏bucket‏ را به ‏shard‏ می‌برد و در چه بازه‌ای کار می‌کند؟
    کلید «‏tenant:bucket:marker‏» با ‏ceph_str_hash_linux‏ به پیمانه‌ی ۷۸۷۷ و سپس ‏rgw_lc_max_objs‏ به یک شیء ‏lc.N‏ می‌رود؛ کارگرها فقط در ‏rgw_lifecycle_work_time‏ ‏(۰۰:۰۰ تا ۰۶:۰۰) کار می‌کنند.
  10. ۱۰. چرا ‏bucket_lc_process‏ مقدار ‏marker‏ را بررسی می‌کند؟
    اگر ‏bucket‏ حذف و با همان نام دوباره ساخته شده باشد، ‏marker‏ فرق دارد و ورودی کهنه نباید روی ‏bucket‏ جدید اجرا شود.

فصل ۴۲: بخش تخصصی (۹): ‏RGW‏ — درون ‏multisite: period‏، قالب لاگ‌ها، نسل‌های ‏bucket‏ و موتور همگام‌سازی#

  1. ۱. ‏commit‏ یک ‏period‏ چه سه شرطی را پیش از هر چیز بررسی می‌کند؟
    ‏commit‏ فقط روی ‏master zone‏ انجام می‌شود، ‏predecessor_uuid‏ باید برابر ‏period‏ جاری باشد و ‏realm_epoch‏ باید دقیقاً یکی بیشتر از ‏period‏ جاری باشد.
  2. ۲. چه زمانی ‏commit‏ شناسه‌ی ‏period‏ را عوض می‌کند و پیامدش برای ‏mdlog‏ چیست؟
    وقتی ‏master zone‏ تغییر کند؛ ‏period‏ جدید با ‏epoch‏ اول ساخته می‌شود و ‏mdlog‏ با پیشوند تازه‌ی ‏meta.log.<period>.‏ شروع می‌شود، پس ‏zone‏ها باید لاگ ‏period‏ قدیمی را تا انتها بخوانند و سپس سراغ لاگ جدید بروند.
  3. ۳. ‏zones_trace‏ در ‏bilog‏ چه مشکلی را حل می‌کند؟
    از رفت‌وبرگشت بی‌پایان تغییرها در ‏active-active‏ جلوگیری می‌کند: ‏zone‏هایی که تغییر از آن‌ها گذشته ثبت می‌شوند و دوباره برایشان فرستاده نمی‌شود.
  4. ۴. کلید یک ورودی ‏datalog‏ چه چیزی را مشخص می‌کند؟
    یک ‏bucket shard‏ (bucket:instance:shard) و در صورت نیاز نسل آن؛ یعنی «در این ‏shard‏ چیزی تغییر کرده، ‏bilog‏ آن را بخوان».
  5. ۵. وضعیت همگام‌سازی یک ‏bucket shard‏ در کدام شیء و کدام ‏pool‏ است؟
    در ‏bucket.sync-status.<src-zone>:<bucket>:<shard>‏ (با پسوند نسل در صورت وجود) در ‏pool‏ لاگ ‏zone‏ مقصد.
  6. ۶. چرا ‏marker shard‏ ‏‏datalog‏ با وجود شکست یک ‏bucket‏ جلو می‌رود و شکست کجا ثبت می‌شود؟
    تا یک ‏bucket‏ خراب کل ‏shard‏ را متوقف نکند. کلید شکست‌خورده در ‏error repo‏ یعنی ‏omap‏ شیء ‏datalog.sync-status.shard.<zone>.<N>.retry‏ ثبت و جداگانه تکرار می‌شود.
  7. ۷. ‏lease‏ و ‏bid‏ در همگام‌سازی چه نقشی دارند؟
    تضمین می‌کنند هر ‏shard‏ در هر لحظه فقط یک پردازش‌گر داشته باشد (‏lease‏ با ‏rgw_sync_lease_period‏) و ‏bid shard‏ها را میان ‏RGW‏ها پخش می‌کند.
  8. ۸. پس از ‏reshard‏ در ‏zone‏ مبدأ، ‏zone‏ مقصد چگونه بدون ‏full sync‏ ادامه می‌دهد؟
    مبدأ ‏bilog‏های نسل قبلی را نگه می‌دارد؛ مقصد همه‌ی ‏shard‏های نسل قدیم را تمام می‌کند (‏shards_done_with_gen‏)، سپس ‏incremental_gen‏ را به نسل جدید با تعداد ‏shard‏ تازه می‌برد.
  9. ۹. تعارض نوشتن هم‌زمان با چه ترتیبی از معیارها حل می‌شود؟
    ‏‏mtime‏ (با دقت ثانیه مگر ‏high precision‏)، سپس ‏zone_short_id‏ و در پایان ‏pg_ver‏.
  10. ۱۰. چرا ساختن ‏bucket‏ در ‏zone‏ غیر ‏master‏ به در دسترس بودن ‏master‏ وابسته است؟
    فراداده (کاربر، ‏bucket‏) فقط در ‏master‏ نوشته می‌شود؛ ‏zone‏های دیگر درخواست را به ‏master‏ می‌فرستند و آن را با ‏metadata sync‏ دریافت می‌کنند.

راهنمای جامع Ceph · ۱٫۶ · آبان ۱۴۰۵
© 2026 Ramin Najarbashi · CC BY-NC-SA 4.0

حریم خصوصی: این سایت کوکی نمی‌گذارد. برای شمارش بازدیدها از Cloudflare Web Analytics استفاده می‌شود که کوکی ندارد و افراد را دنبال نمی‌کند.