شرکت های ابرمقیاس (Hyperscalers) مانند علی‌بابا، آمازون، بایت‌دنس، گوگل، متا، مایکروسافت و تنسنت، زیرساخت‌های در مقیاس کره‌زمین توسعه داده‌اند تا خدمات ابری، وب یا موبایل را به کاربران جهانی خود ارائه دهند. اگرچه ممکن است بیشتر متخصصان به طور مستقیم چنین زیرساخت‌های هایپرسکیل را نسازند، معتقدیم که یادگیری درباره‌ی آن‌ها مفید است. از نظر تاریخی، بسیاری از فناوری‌های پرکاربرد از محیط‌های پیشرفته سرچشمه گرفته‌اند، از جمله مین‌فریم‌ها (Mainframes) در دهه‌ی 1960 و زیرساخت‌های هایپرسکیل در دو دهه‌ی اخیر. به عنوان مثال، حافظه‌ی مجازی (Virtual Memory) ابتدا در مین‌فریم‌ها به وجود آمد و اکنون حتی در ساعت‌های هوشمند نیز رایج است. به طور مشابه، Kubernetes و PyTorch به ترتیب در گوگل و فیسبوک ایجاد شدند، اما توسط سازمان‌هایی با اندازه‌های مختلف مورد استفاده قرار گرفته‌اند. علاوه بر این فناوری‌های خاص، اصول و درس‌های آموخته شده از زیرساخت‌های هایپرسکیل ممکن است به متخصصان کمک کند تا به طور کلی سیستم‌های بهتری بسازند.

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

فرهنگ مهندسی

قبل از پرداختن به جزئیات زیرساخت‌های متا، ابتدا به چند جنبه از فرهنگ مهندسی این شرکت اشاره می‌کنیم، زیرا فرهنگ یک سازمان تأثیر زیادی بر فناوری آن دارد.

سرعت بالا

از زمان تأسیس، فیسبوک فرهنگ “سرعت بالا” را در خود نهادینه کرده و حفظ کرده است، فرهنگی که بر چابکی و تکرار سریع تأکید دارد. این فلسفه در تعهد قوی شرکت به استقرار مداوم نرم‌افزار (Continuous Software Deployment) مشهود است، جایی که آخرین تغییرات کد در اسرع وقت به محیط عملیاتی (Production) منتقل می‌شود. علاوه بر این، مهندسان محصول عمدتاً کدهای خود را در قالب توابع بدون حالت (Stateless) و سرورلس (Serverless) به زبان‌هایی مانند PHP، Python و Erlang می‌نویسند، زیرا این رویکرد سادگی، بهره‌وری و سرعت توسعه و به‌روزرسانی را افزایش می‌دهد. تیم‌ها این امکان را دارند که به‌سرعت اولویت‌های اجرایی خود را تغییر دهند، بدون آنکه نیاز به یک فرایند برنامه‌ریزی طولانی داشته باشند، و می‌توانند مسائل مبهم را در حین اجرای تدریجی حل کنند. این رویکرد به آن‌ها اجازه می‌دهد تا به‌سرعت با شرایط متغیر بازار سازگار شده و محصولات جدیدی را عرضه کنند.

باز بودن فناوری

متا از باز بودن فناوری، هم به صورت داخلی و هم خارجی، حمایت می‌کند. در داخل شرکت، ما از رویکرد مونورپو (Monorepo) استفاده می‌کنیم، جایی که کد تمام پروژه‌ها در یک مخزن واحد ذخیره می‌شود تا یافتن و استفاده مجدد از کد و همچنین مشارکت بین تیم‌ها تسهیل شود. در حالی که سازمان‌های دیگر نیز از مونورپو استفاده می‌کنند، میزان باز بودن آن‌ها در استفاده از این رویکرد متفاوت است. برخی از سازمان‌ها برای هر پروژه مالکانی تعیین می‌کنند و تنها این مالکان مجاز به پذیرش تغییرات کد هستند، اگرچه دیگران می‌توانند تغییرات را پیشنهاد دهند. در مقابل، با چند استثنا، اکثر پروژه‌ها در متا چنین قوانین سختگیرانه‌ای در مورد مالکیت اعمال نمی‌کنند. این باز بودن، مشارکت بین تیم‌ها و استفاده مجدد از کد را تشویق می‌کند و از نوشتن مجدد کدهای مشابه جلوگیری می‌کند.

در متا، مهندسان تغییرات کد را مستقیماً به خط اصلی (Mainline) مونورپو کامیت می‌کنند، و استقرار نرم‌افزارها از خط اصلی، یعنی از آخرین نسخه کد، کامپایل می‌شود، برخلاف برخی شاخه‌های پایدار. به عنوان مثال، هنگامی که یک کتابخانه پراستفاده، مانند کتابخانه RPC، به‌روزرسانی می‌شود، نسخه بعدی هر برنامه‌ای که به این کتابخانه وابسته است، به طور خودکار با آخرین نسخه آن کامپایل می‌شود.

در خارج از شرکت، تعهد متا به باز بودن فناوری از طریق طراحی‌های سخت‌افزاری متن‌باز در پروژه Open Compute و پروژه‌های نرم‌افزاری مانند PyTorch، Llama، Presto، RocksDB و Cassandra نشان داده می‌شود. همچنین، بخش زیادی از فناوری زیرساخت متا از طریق مقالات تحقیقاتی به اشتراک گذاشته شده است، که بسیاری از آن‌ها در مراجع این مقاله ذکر شده‌اند.

تحقیق در محیط عملیاتی

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

زیرساخت مشترک

در حالی که برخی سازمان‌ها به تیم‌های فردی اجازه می‌دهند تا در مورد پشته فناوری خود تصمیم‌گیری محلی داشته باشند، متا استانداردسازی و بهینه‌سازی جهانی را در اولویت قرار می‌دهد. در بخش سخت‌افزار، سرورهایی که از محصولات مختلف پشتیبانی می‌کنند، همگی از یک استخر سرور مشترک تخصیص داده می‌شوند. علاوه بر این، برای بارهای کاری غیرهوش مصنوعی (Non-AI Compute Workloads)، ما تنها یک نوع سرور ارائه می‌دهیم که مجهز به یک CPU و مقدار مشخصی از DRAM (قبلاً 64 گیگابایت، اکنون 256 گیگابایت) است. برخلاف ابرهای عمومی که باید انواع مختلف سرورها را برای تطبیق با برنامه‌های متنوع مشتریان ارائه دهند، متا می‌تواند برنامه‌های خود را برای تطبیق با سخت‌افزار بهینه‌سازی کند، و در نتیجه از افزایش انواع سرورها جلوگیری کند.

استانداردسازی در بخش نرم‌افزار نیز حاکم است. به عنوان مثال، محصولات مختلف متا قبلاً از Cassandra، HBase و ZippyDB برای ذخیره‌سازی کلید-مقدار (Key-Value Store) استفاده می‌کردند، اما اکنون همگی به ZippyDB روی آورده‌اند. علاوه بر این، هر قابلیت مشترک—مانند استقرار نرم‌افزار، مدیریت پیکربندی، شبکه سرویس (Service Mesh)، تست عملکرد قبل از تولید، نظارت بر عملکرد در محیط عملیاتی، و تست بار در محیط عملیاتی—توسط یک ابزار جهانی که به طور گسترده پذیرفته شده است، پشتیبانی می‌شود.

علاوه بر استانداردسازی، یک اصل کلیدی در دستیابی به زیرساخت مشترک، ترجیح ما برای استفاده از اجزای قابل استفاده مجدد به جای راه‌حل‌های یکپارچه (Monolithic) است. یک مثال خوب از این موضوع، زنجیره استفاده مجدد از اجزا در سیستم فایل توزیع‌شده ما به نام Tectonic است. Tectonic با استفاده از یک ذخیره‌سازی کلید-مقدار توزیع‌شده به نام ZippyDB، مقیاس‌پذیری خود را افزایش می‌دهد. ZippyDB نیز به نوبه خود از یک چارچوب مشترک برای مدیریت قطعات داده (Sharding) به نام Shard Manager استفاده می‌کند. Shard Manager نیز برای کشف قطعات و مسیریابی درخواست‌ها به ServiceRouter متا وابسته است. در نهایت، ServiceRouter داده‌های کشف سرویس و پیکربندی کل زیرساخت را در یک فضای ذخیره‌سازی داده بسیار قابل اعتماد و بدون وابستگی به نام Delos ذخیره می‌کند. بنابراین، زنجیره استفاده مجدد از اجزا به این شکل است: Tectonic → ZippyDB → Shard Manager → ServiceRouter → Delos. تمام این اجزای قابل استفاده مجدد، برای بسیاری از موارد استفاده دیگر نیز به کار می‌روند. در مقابل، HDFS، یکی از محبوب‌ترین سیستم‌های فایل توزیع‌شده متن‌باز، به‌صورت یکپارچه(monolithic) طراحی شده و تمامی این مؤلفه‌ها را درون خود مدیریت می‌کند.[که می‌تواند انعطاف‌پذیری و مقیاس‌پذیری را محدود کند.]

مطالعه موردی فرهنگ: برنامه Threads

توسعه برنامه Threads، که اغلب با توییتر/X مقایسه می‌شود، نمونه‌ای از فرهنگ ذکر شده است. با تأکید بر حرکت سریع، یک تیم کوچک Threads را تنها در پنج ماه کار فنی در محیطی شبیه به استارت‌آپ توسعه داد. علاوه بر این، پس از توسعه، تیم‌های زیرساخت تنها دو روز فرصت داشتند تا برای راه‌اندازی آن در محیط عملیاتی آماده شوند. بیشتر سازمان‌های بزرگ بیش از دو روز زمان صرف می‌کنند تا فقط [طرح] یک برنامه‌کاربردی را که شامل ده‌ها تیم وابسته به هم است را تدوین کنند، چه برسد به اجرای آن. اما در متا، ما به سرعت اتاق‌های جنگ (War Rooms) را در سایت‌های توزیع‌شده ایجاد کردیم و تیم‌های زیرساخت و محصول را گرد هم آوردیم تا مسائل را به صورت بلادرنگ حل‌وفصل کنند. با وجود زمان‌بندی فشرده، راه‌اندازی این برنامه بسیار موفقیت‌آمیز بود و تنها در پنج روز به 100 میلیون کاربر رسید، که آن را به سریع‌ترین برنامه در حال رشد در تاریخ تبدیل کرد.
زیرساخت مشترک نقش کلیدی در توانایی تیم‌ها برای پیاده‌سازی سریع Threads و مقیاس‌پذیری قابل اعتماد آن داشت. Threads از بک‌اند پایتون اینستاگرام و همچنین اجزای زیرساخت مشترک متا، مانند پایگاه داده گراف اجتماعی، ذخیره‌سازی کلید-مقدار، پلتفرم سرورلس، پلتفرم‌های آموزش و استنتاج یادگیری ماشین (ML)، و چارچوب مدیریت پیکربندی برای برنامه‌های موبایل، استفاده مجدد کرد.

باز بودن فناوری داخلی متا، با استفاده از مونوریپو، به Threads اجازه داد تا از برخی کدهای برنامه اینستاگرام استفاده مجدد کند و توسعه خود را تسریع بخشد. در مورد باز بودن فناوری خارجی، Threads قصد دارد با ActivityPub، پروتکل شبکه‌سازی اجتماعی متن‌باز، ادغام شود تا با سایر برنامه‌ها سازگاری داشته باشد. ما همچنین تجربیات خود را از توسعه سریع Threads به صورت عمومی به اشتراک گذاشته‌ایم.

جریان درخواست کاربر از ابتدا تا انتها

اکنون به بررسی فناوری زیرساخت متا می‌پردازیم. محصولات متا توسط یک زیرساخت خدمات مشترک پشتیبانی می‌شوند. برای ارائه یک دیدگاه جامع از این زیرساخت، توضیح می‌دهیم که چگونه یک درخواست کاربر از ابتدا تا انتها پردازش می‌شود و تمام اجزای درگیر را به تفصیل شرح می‌دهیم.

مسیریابی درخواست

نگاشت دینامیک DNS

هنگامی که کاربر درخواستی به facebook.com ارسال می‌کند، سرور DNS متا به صورت دینامیک یک آدرس IP برمی‌گرداند که به یک مرکز داده کوچک لبه (Edge Datacenter) که توسط متا اداره می‌شود و به عنوان نقطه حضور (Point of Presence یا PoP) شناخته می‌شود، نگاشت شده است (همانطور که در شکل ۱ نشان داده شده است). این نگاشت دینامیک DNS اطمینان می‌دهد که PoP انتخاب شده به کاربر نزدیک باشد و در عین حال بار را بین PoPها متعادل کند. اتصال TCP کاربر در PoP خاتمه می‌یابد، که اتصالات TCP جداگانه و طولانی‌مدتی با مراکز داده متا حفظ می‌کند. این تنظیم TCP تقسیم‌شده (Split-TCP) مزایای متعددی دارد، از جمله کاهش تأخیر ایجاد TCP از طریق استفاده مجدد از اتصالات از پیش برقرار شده بین PoPها و مراکز داده. یک PoP معمولاً صدها سرور دارد اما ممکن است تا چند هزار سرور نیز داشته باشد. صدها PoP در سراسر جهان قرار گرفته‌اند تا اطمینان حاصل شود که بیشتر کاربران یک PoP نزدیک به خود دارند، و در نتیجه تأخیر شبکه کوتاه‌مدت را تضمین کنند.

کش محتوای استاتیک

اگر درخواست کاربر برای محتوای استاتیک باشد، مانند تصاویر و ویدیوها، در صورتی که محتوا از قبل در PoP کش شده باشد، می‌تواند مستقیماً از PoP ارائه شود. علاوه بر این، محتوای استاتیک ممکن است توسط شبکه تحویل محتوا (CDN) نیز کش شود، همانطور که در شکل ۱ نشان داده شده است. هنگامی که حجم قابل توجهی از ترافیک محصولات متا از شبکه یک ارائه‌دهنده خدمات اینترنتی (ISP) سرچشمه می‌گیرد، متا به دنبال ایجاد یک مشارکت دوجانبه سودمند با ارائه تجهیزات شبکه متا (Meta Network Appliances) است که در شبکه ISP میزبانی می‌شوند تا محتوای استاتیک را کش کنند، و در نتیجه یک سایت CDN تشکیل دهند. یک سایت CDN معمولاً ده‌ها سرور دارد و برخی از آن‌ها بیش از صد سرور دارند. هزاران سایت CDN در سراسر جهان، شبکه CDN ما را برای توزیع محتوای استاتیک تشکیل می‌دهند.

محصولات متا از بازنویسی URL برای هدایت درخواست‌های کاربر به یک سایت CDN نزدیک استفاده می‌کنند. هنگامی که یک محصول متا یک URL برای دسترسی کاربر به محتوای استاتیک ارائه می‌دهد، URL را بازنویسی می‌کند، به عنوان مثال از facebook.com/image.jpg به CDN109.meta.com/image.jpg. اگر تصویر در CDN109 کش نشده باشد و کاربر آن را درخواست کند، CDN109 درخواست را به یک PoP نزدیک ارسال می‌کند. سپس PoP درخواست را به متعادل‌کننده بار (Load Balancer) در یک منطقه مرکز داده ارسال می‌کند، که تصویر را از سیستم ذخیره‌سازی بازیابی می‌کند. در مسیر بازگشت، هم PoP و هم سایت CDN تصویر را برای استفاده‌های بعدی کش می‌کنند.

مسیریابی درخواست محتواهای پویا

اگر درخواست کاربر برای محتوای دینامیک مانند فید خبری باشد، PoP آن را به یک منطقه مرکز داده ارسال می‌کند. انتخاب منطقه هدف توسط یک ابزار مهندسی ترافیک هدایت می‌شود که به طور دوره‌ای توزیع بهینه ترافیک جهانی از PoPها به مراکز داده را با در نظر گرفتن عواملی مانند ظرفیت مرکز داده و تأخیر شبکه محاسبه می‌کند.

ترافیک PoP به مرکز داده از طریق شبکه گسترده خصوصی (WAN) متا منتقل می‌شود، که PoPها و مراکز داده متا را در سطح جهانی با استفاده از فیبرهای نوری به طول ده‌ها هزار مایل به هم متصل می‌کند. ترافیک شبکه داخلی بین مراکز داده و PoPهای ما به طور قابل توجهی از ترافیک خارجی بین کاربران و PoPها بیشتر است، که این امر عمدتاً به دلیل تکثیر داده‌ها در مراکز داده و تعاملات بین سرویس‌های ریز (Microservices) ما است. شبکه WAN خصوصی پهنای باند بالایی را برای خدمت‌رسانی به این ترافیک داخلی فراهم می‌کند.

My image

شکل۱-زیرساخت جهانی متا!

توپولوژی زیرساخت

جدول ۱ اجزای زیرساختی که پیش‌تر ذکر شد را خلاصه می‌کند. در سطح جهانی، ده‌ها منطقه مرکز داده، صدها مرکز داده لبه (PoPها) و هزاران سایت CDN وجود دارد. هر منطقه مرکز داده شامل چندین مرکز داده است که در محدوده چند مایلی یکدیگر قرار دارند. هر مرکز داده از حداکثر یک دوجین تابلوهای اصلی سوئیچ (MSB) برای توزیع برق استفاده می‌کند، که به عنوان دامنه‌های خطای زیر-مرکز داده اصلی نیز عمل می‌کنند. خرابی یک MSB می‌تواند باعث از کار افتادن ۱۰ تا ۲۰ هزار سرور شود.

شبکه لبه (Edge Network)

یک PoP به چندین سیستم مستقل (Autonomous Systems) در اینترنت متصل است و معمولاً چندین مسیر برای دسترسی به شبکه کاربر دارد. هنگام انتخاب مسیر بین یک PoP و یک کاربر، پروتکل Border Gateway Protocol (BGP) به طور پیش‌فرض ظرفیت و عملکرد شبکه را در نظر نمی‌گیرد. با این حال، شبکه PoP این عوامل را در نظر می‌گیرد و مسیر ترجیحی خود را به یک پیشوند شبکه (Network Prefix) اعلام می‌کند.

شبکه مرکز داده (Datacenter Network)

سرورها در یک مرکز داده توسط یک شبکه داخلی مرکز داده (Datacenter Fabric) به هم متصل می‌شوند، جایی که سوئیچ‌های شبکه یک توپولوژی سه‌سطحی Clos تشکیل می‌دهند که می‌تواند به صورت افزایشی با افزودن سوئیچ‌های بیشتر در سطح بالایی مقیاس‌پذیر شود. با تعداد کافی سوئیچ‌های سطح بالا، این شبکه می‌تواند یک شبکه بدون انسداد (Non-Blocking) و بدون اشباع (Non-Oversubscribed) ارائه دهد که امکان ارتباط بین هر دو سرور با حداکثر پهنای باند NIC را فراهم می‌کند. ما در حال حرکت به سمت حذف اشباع شبکه (Network Oversubscription) در داخل یک مرکز داده هستیم.

شبکه منطقه‌ای (Regional Network)

یک تجمیع‌کننده شبکه (Fabric Aggregator) مراکز داده را در یک منطقه به هم متصل کرده و آن‌ها را به شبکه WAN خصوصی ما متصل می‌کند. تجمیع‌کننده شبکه از یک توپولوژی شبیه به درخت چاق (Fat-Tree) استفاده می‌کند که امکان افزودن سوئیچ‌های بیشتر برای افزایش پهنای باند را فراهم می‌کند. ما هدفمان این است که اشباع شبکه در یک منطقه را به طور قابل توجهی کاهش دهیم تا ارتباط بین مراکز داده درون یک منطقه به یک گلوگاه تبدیل نشود. این امر به اکثر سرویس‌ها (به جز آموزش یادگیری ماشین) اجازه می‌دهد تا در مراکز داده یک منطقه پراکنده شوند بدون اینکه نگران کاهش قابل توجه عملکرد باشند.

جدول۱-تعداد و اندازه‌ی اجزای زیرساخت متا
نوع زیرساختتعدادتعداد سرور در هر زیرساخت
منطقه‌ایO(10)یک میلیون
PoPO(100)از ده ها تا هزاران
سایت CDNO(1,000)ده‌ها تا بیش از صد
دیتاسنترچندین دیتاسنتر در هر منطقهصدهزاران
MSBده‌ها MSB در هر دیتاسنتربین ۱۰ هزار تا ۲۰ هزار

پردازش درخواست

پردازش آنلاین

هنگامی که یک درخواست کاربر به یک منطقه مرکز داده می‌رسد، در طول مسیری که در شکل ۲ نشان داده شده است، پردازش می‌شود. متعادل‌کننده بار (Load Balancer) درخواست‌های کاربر را بین ده‌ها هزار سرور توزیع می‌کند که “توابع سرورلس فرانت‌اند” را اجرا می‌کنند. برای پردازش یک درخواست کاربر، یک تابع سرورلس فرانت‌اند ممکن است بسیاری از سرویس‌های بک‌اند را فراخوانی کند، که برخی از آن‌ها ممکن است به “استنتاج یادگیری ماشین (ML Inference)” نیز متکی باشند، مثلاً برای بازیابی توصیه‌های تبلیغات یا محتوای فید خبری.
در طول اجرا، یک تابع سرورلس فرانت‌اند می‌تواند رویدادهایی را در “صف رویداد (Event Queue)” قرار دهد تا “توابع سرورلس رویداد-محور (Event-Driven Serverless Functions)” به صورت ناهمزمان آن‌ها را پردازش کنند. یکی از این رویدادها می‌تواند ارسال یک ایمیل تأیید پس از انجام یک عمل توسط کاربر در سایت باشد. در حالی که توابع سرورلس فرانت‌اند مستقیماً بر زمان پاسخ درک‌شده توسط کاربر تأثیر می‌گذارند و بنابراین دارای یک هدف سطح سرویس (SLO) سخت‌گیرانه برای تأخیر هستند، توابع سرورلس رویداد-محور به صورت ناهمزمان کار می‌کنند و بر زمان پاسخ درک‌شده توسط کاربر تأثیری ندارند، و برای توان عملیاتی (Throughput) و بهره‌وری سخت‌افزاری بهینه‌سازی شده‌اند، نه تأخیر. نسبت سرورهایی که توابع سرورلس فرانت‌اند را اجرا می‌کنند به سرورهایی که توابع سرورلس رویداد-محور را اجرا می‌کنند، تقریباً ۵ به ۱ است.

پردازش آفلاین

اجزای سمت راست شکل ۲ پردازش‌های آفلاین مختلفی را انجام می‌دهند تا به پردازش آنلاین در سمت چپ کمک کنند. جداسازی پردازش آنلاین و آفلاین امکان بهینه‌سازی مستقل بر اساس ویژگی‌های بار کاری هر یک را فراهم می‌کند. هنگام پردازش درخواست‌های کاربر، توابع سرورلس فرانت‌اند و سرویس‌های بک‌اند انواع مختلفی از داده‌ها، مانند معیارهای کلیک روی تبلیغات یا تماشای ویدیو، را در “انبار داده (Data Warehouse)” ثبت می‌کنند. این داده‌ها به عنوان ورودی برای پردازش‌های آفلاین مختلف استفاده می‌شوند. به عنوان مثال، “آموزش یادگیری ماشین (ML Training)” از این داده‌ها برای به‌روزرسانی مدل‌های یادگیری ماشین استفاده می‌کند، در حالی که “پردازش جریان (Stream Processing)” می‌تواند از این داده‌ها برای به‌روزرسانی موضوعات داغ سایت و ذخیره آن‌ها در “پایگاه‌های داده و کش‌ها (Databases and Caches)” استفاده کند، که سپس در طول پردازش درخواست‌های آنلاین کاربر مورد استفاده قرار می‌گیرند. علاوه بر این، “تحلیل دسته‌ای (Batch Analytics)” که توسط Spark و Presto پشتیبانی می‌شود، می‌تواند به طور دوره‌ای عملیاتی مانند به‌روزرسانی توصیه‌های دوستان در پاسخ به فعالیت‌های جدید در سایت را انجام دهد. در نهایت، به‌روزرسانی‌های داده در انبار داده به عنوان منبع اصلی رویداد عمل می‌کند که اجرای توابع سرورلس رویداد-محور را فعال می‌کند.

My image

شکل۲-معماری کلی اجزای نرم‌افزاری که در یک دیتاسنتر منطقه‌ای اجرا می‌شوند. این دیاگرام به‌شدت ساده‌سازی شده است، زیرا متا به‌صورت داخلی بیش از ۱۰,۰۰۰ سرویس بک‌اند دارد که دارای یک گراف فراخوانی پیچیده هستند.

افزایش بهره‌وری توسعه‌دهندگان

هدف اصلی یک زیرساخت مشترک، افزایش بهره‌وری توسعه‌دهندگان است. در حالی که به طور گسترده‌ای پذیرفته شده است که استقرار مداوم نرم‌افزار (continuous software deployment) و توابع سرورلس (serverless) می‌توانند به افزایش بهره‌وری توسعه‌دهندگان کمک کنند، ما این رویکردها را به حد افراط رسانده‌ایم.

استقرار مداوم

همسو با فرهنگ سرعت بالا، ما استقرار مداوم کد و پیکربندی را با سرعت و مقیاس بسیار بالا انجام می‌دهیم. این رویکرد به توسعه‌دهندگان امکان می‌دهد تا ویژگی‌های جدید و اصلاحات را به‌سرعت منتشر کنند، بازخورد فوری دریافت کنند و به‌صورت سریع و مداوم بهبودهای لازم را اعمال کنند.
برای تغییرات پیکربندی، ابزار مدیریت پیکربندی ما روزانه بیش از ۱۰۰,۰۰۰ تغییر زنده را در محیط تولید اجرا می‌کند که شامل O(10,000) سرویس و میلیون‌ها سرور می‌شود. این تغییرات وظایف مختلفی را تسهیل می‌کنند، از جمله توازن بار، عرضه ویژگی‌ها، تست‌های A/B و محافظت در برابر اضافه‌بار. در متا، تقریباً هر مهندسی که کد می‌نویسد، تغییرات پیکربندی زنده را نیز در محیط تولید اعمال می‌کند. با پیروی از پارادایم “پیکربندی به عنوان کد”، تغییرات دستی پیکربندی قبل از ثبت در مخزن کد، توسط هم‌تیمی‌ها بررسی می‌شوند. پس از ثبت، این تغییرات بلافاصله وارد خط لوله استقرار مداوم می‌شوند. در عرض چند ثانیه، پیکربندی به‌روزرسانی‌شده می‌تواند به میلیون‌ها فرآیند لینوکس مشترک ارسال شود و یک اعلان upcall را فعال کند. فرآیندها می‌توانند بلافاصله رفتار زمان اجرای خود را بدون نیاز به راه‌اندازی مجدد تنظیم کنند. علاوه بر تغییرات دستی، ابزارهای خودکار نیز تغییرات پیکربندی را هدایت می‌کنند، مثلاً برای توازن بار.

برای تغییرات کد، ابزار استقرار ما بیش از ۳۰,۰۰۰ خط لوله را برای استقرار ارتقاء نرم‌افزار مدیریت می‌کند. در متا، ۹۷٪ از سرویس‌ها از استقرار کاملاً خودکار نرم‌افزار بدون هیچ گونه مداخله دستی استفاده می‌کنند: ۵۵٪ از استقرار مداوم استفاده می‌کنند و هر تغییر کد را بلافاصله پس از گذراندن تست‌های خودکار به محیط تولید منتشر می‌کنند، در حالی که ۴۲٪ باقی‌مانده به طور خودکار در یک برنامه ثابت، معمولاً روزانه یا هفتگی، مستقر می‌شوند. به عنوان مثال، توابع سرورلس frontend در شکل ۲ را در نظر بگیرید. این توابع بر روی بیش از نیم میلیون سرور اجرا می‌شوند و بیش از ۱۰,۰۰۰ توسعه‌دهنده محصول هر روز کاری کد آن‌ها را تغییر می‌دهند و هزاران commit کد انجام می‌شود. با وجود این محیط بسیار پویا، هر سه ساعت یک بار نسخه جدیدی از تمام توابع سرورلس به محیط تولید منتشر می‌شود.

حتی نرم‌افزار شبکه ما نیز مانند سرویس‌های معمولی طراحی شده و برای به‌روزرسانی‌های مکرر بهینه‌سازی شده است. به عنوان مثال، شبکه خصوصی WAN ما توپولوژی شبکه را به چندین صفحه موازی تقسیم می‌کند که هر کدام مسئول بخشی از ترافیک هستند و کنترلر خود را دارند. این امر امکان به‌روزرسانی‌های مکرر نرم‌افزار کنترلر را فراهم می‌کند. توسعه‌دهندگان می‌توانند با هدایت ترافیک از یک صفحه و استقرار الگوریتم جدید فقط در آن صفحه، بدون تأثیر بر سایر صفحات، الگوریتم‌های کنترل جدید را آزمایش کنند. به طور مشابه، نرم‌افزار سوئیچ شبکه ما نیز مانند سرویس‌های استاندارد به‌روزرسانی‌های مکرر را انجام می‌دهد. با استفاده از ویژگی “warm boot” در ASIC سوئیچ، صفحه داده به انتقال ترافیک ادامه می‌دهد در حالی که نرم‌افزار سوئیچ در حال به‌روزرسانی است.

به‌روزرسانی‌های مکرر کد و پیکربندی، توسعه چابک نرم‌افزار را ممکن می‌سازد اما خطر قطعی سایت را افزایش می‌دهد. برای مقابله با این خطر، ما سرمایه‌گذاری زیادی در تست‌ها، عرضه‌های مرحله‌ای و بررسی‌های سلامت در طول به‌روزرسانی‌ها انجام داده‌ایم. پیش‌تر، یک کمپین شرکت‌محور برای افزایش خودکارسازی استقرار کد راه‌اندازی کردیم که باعث شد پذیرش استقرار کاملاً خودکار کد محافظت‌شده توسط بررسی‌های سلامت از ۱۲٪ به ۹۷٪ افزایش یابد. به طور مشابه، ابتکار دیگری را اجرا کردیم تا اطمینان حاصل کنیم که تمام تغییرات پیکربندی تحت تست‌های خودکار canary قرار می‌گیرند تا ایمنی پیکربندی حفظ شود. به طور کلی، ما این سرمایه‌گذاری‌ها در استقرار مداوم را ارزشمند می‌دانیم، زیرا به طور قابل توجهی بهره‌وری توسعه‌دهندگان را افزایش می‌دهد.

توابع سرورلس (Serverless functions):

استفاده گسترده از توابع سرورلس (که به عنوان Function-as-a-Service یا FaaS نیز شناخته می‌شوند) یکی دیگر از عوامل کلیدی است که بهره‌وری توسعه‌دهندگان را افزایش می‌دهد. برخلاف سرویس‌های بک‌اند سنتی که می‌توانند پیچیدگی‌های زیادی داشته باشند، FaaS بدون حالت (stateless) است و یک رابط(interface) ساده برای اجرای توابع ارائه می‌دهد. هر فراخوانی FaaS به طور مستقل مدیریت می‌شود و هیچ اثر جانبی بر فراخوانی‌های همزمان دیگر ندارد، مگر از طریق حالت‌هایی که در پایگاه‌های داده خارجی ذخیره شده‌اند. به دلیل ماهیت بدون حالت FaaS، این سیستم به شدت به سیستم‌های کش خارجی متکی است تا در هنگام دسترسی به پایگاه‌های داده، عملکرد خوبی را ارائه دهد.

توسعه‌دهندگان کد FaaS را می‌نویسند و بقیه کارها را به زیرساخت می‌سپارند تا از طریق اتوماسیون انجام شود، از جمله استقرار کد و مقیاس‌دهی خودکار در پاسخ به تغییرات بار. این سادگی به بیش از ۱۰,۰۰۰ توسعه‌دهنده محصول متا اجازه می‌دهد تا تنها بر روی منطق محصول تمرکز کنند و نگران مدیریت زیرساخت نباشند. علاوه بر این، این رویکرد از هدررفت منابع سخت‌افزاری ناشی از تأمین بیش از حد منابع توسط توسعه‌دهندگان محصول جلوگیری می‌کند.

متا استفاده از FaaS را به حد نهایی رسانده تا بهره‌وری توسعه‌دهندگان را به حداکثر برساند. از بین حدود ۱۰,۰۰۰ مهندس در متا، تعداد مهندسانی که کد FaaS می‌نویسند حدود ۵۰٪ بیشتر از کسانی است که کد برای سرویس‌های معمولی که خودشان مدیریت می‌کنند می‌نویسند. این موفقیت نه تنها به دلیل خلاصی مهندسان محصول از[شرّ] مدیریت زیرساخت، بلکه به دلیل قابلیت استفاده محیط توسعه یکپارچه (IDE) برای FaaS است. این IDE دسترسی آسان به پایگاه‌ داده گراف اجتماعی و سیستم‌های بک‌اند مختلف را از طریق ساختارهای زبان سطح بالا فراهم می‌کند. همچنین بازخورد سریع را از طریق تست‌های یکپارچه‌سازی مداوم ارائه می‌دهد.

همان‌طور که در شکل ۲ نشان داده شده است، متا دو پلتفرم FaaS را اداره می‌کند: یکی برای «توابع سرورلس فرانت‌اند» و دیگری برای «توابع سرورلس رویداد-محور». ما به ترتیب به آن‌ها FrontFaaS و XFaaS می‌گوییم. توابع FrontFaaS در PHP نوشته می‌شوند (ما پلتفرم‌های FaaS برای توابع پایتون، ارلنگ و Haskell نیز داریم). برای پشتیبانی از بار بالای تولید شده توسط میلیاردها کاربر، بیش از نیم میلیون سرور را نگهداری می‌کنیم که زمان اجرای PHP را همیشه فعال نگه می‌دارند. هنگامی که یک درخواست کاربر می‌رسد، به یکی از این سرورها هدایت می‌شود تا بلافاصله پردازش شود، بدون اینکه زمان شروع سرد (cold start) را تجربه کند. هنگامی که بار سایت کم است، از مقیاس‌دهی خودکار استفاده می‌کنیم تا برخی از سرورهای FrontFaaS را برای استفاده سایر سرویس‌ها آزاد کنیم.

XFaaS شباهت‌های زیادی با FrontFaaS دارد، با این تفاوت کلیدی که توابعی را اجرا می‌کند که به کاربر نهایی مربوط نمی‌شوند و نیازی به زمان پاسخ کمتر از یک ثانیه ندارند، اما الگوی بار بسیار ناگهانی (spiky) دارند. برای جلوگیری از تحمیل بیش‌ از حد بار روی زیرساخت‌ها، XFaaS از ترکیبی از بهینه‌سازی‌ها برای گسترش اجرای توابع استفاده می‌کند، از جمله به تعویق انداختن اجرای توابع تحمل‌پذیر، تأخیر به ساعات کم‌بار، متعادل‌سازی بار جهانی فراخوانی‌های توابع در مناطق مختلف و اعمال محدودیت بر اساس سهمیه‌ها.

توسعه‌دهندگان محصول در متا از اواخر دهه ۲۰۰۰ از FaaS به عنوان پارادایم اصلی کدنویسی خود استفاده کرده‌اند، حتی قبل از اینکه اصطلاح FaaS رایج شود. در مقایسه با پلتفرم‌های سرورلس در صنعت، یک جنبه منحصر به فرد پلتفرم‌های سرورلس ما این است که به چندین تابع اجازه می‌دهند به طور همزمان در یک فرآیند لینوکس اجرا شوند تا کارایی سخت‌افزاری بالاتری داشته باشند، برخلاف ابرهای عمومی که برای اطمینان از جداسازی قوی‌تر بین مشتریان مختلف، مجبورند یک تابع را در هر ماشین مجازی اجرا کنند.

کاهش هزینه‌های سخت‌افزاری

علاوه بر افزایش بهره‌وری توسعه‌دهندگان، هدف اصلی دیگر یک زیرساخت مشترک، کاهش هزینه‌های سخت‌افزاری است. در این بخش، به چند نمونه از نحوه کمک راه‌حل‌های نرم‌افزاری به کاهش هزینه‌های سخت‌افزاری اشاره می‌کنیم.

تمامی دیتاسنترهای جهانی به‌عنوان یک رایانه واحد
بیشتر ارائه دهندگان زیرساخت‌، مدیریت پیچیدگی‌های مربوط به دیتاسنترهای توزیع‌شده جغرافیایی را بر عهده‌ی کاربران می‌گذارند. کاربران باید به‌صورت دستی تعداد نسخه‌های کپی (replicas) سرویس‌های خود را تعیین کرده و مناطق مناسب برای استقرار را انتخاب کنند، درحالی‌که همچنان باید الزامات سطح سرویس (SLO) را رعایت کنند. این پیچیدگی اغلب منجر به هدررفت سخت‌افزار به دلیل تخصیص بیش از حد منابع، توزیع نامتعادل بار بین مناطق مختلف، و مهاجرت ناکافی سرویس‌ها بین مناطق برای انطباق با تغییرات در میزان تقاضای پردازشی و ظرفیت دیتاسنترها می‌شود.

در مقابل، متا در حال حرکت از رویکرد “دیتاسنتر به عنوان یک کامپیوتر” (DaaC) به سمت چشم‌انداز “تمامی دیتاسنترها در (سطح) جهان به عنوان یک کامپیوتر” (Global-DaaC) است. با Global-DaaC، کاربران به سادگی درخواست استقرار جهانی یک سرویس را می‌دهند و زیرساخت تمام جزئیات را مدیریت می‌کند: تعیین تعداد بهینه رپلیکاهای سرویس، قرار دادن این رپلیکاها در دیتاسنترهای منطقه‌ای بر اساس اهداف سطح سرویس و سخت‌افزار موجود، انتخاب نوع سخت‌افزار مناسب‌ترین، بهینه‌سازی مسیریابی ترافیک و تطبیق مداوم جایگاه سرویس در پاسخ به تغییرات بار کاری. در مقایسه با ابرهای عمومی، متا می‌تواند Global-DaaC را راحت‌تر محقق کند زیرا مالک تمام برنامه‌های خود است و می‌تواند آن‌ها را در صورت نیاز بین مناطق جابجا کند؛ در حالی که ابرهای عمومی این انعطاف‌پذیری را با برنامه‌های مشتریان خود ندارند.

برای پیاده‌سازی Global-DaaC، ابزارهای ما به طور یکپارچه تخصیص منابع را در تمام سطوح هماهنگ می‌کنند: جهانی، منطقه‌ای و سرورهای انحصاری. ابتدا، ابزار مدیریت ظرفیت جهانی ما با استفاده از ردیابی RPC وابستگی‌های سرویس را شناسایی کرده و مدل‌های مصرف منابع را می‌سازد، سپس از برنامه‌ریزی عدد صحیح مختلط (Mixed-Integer Programming) برای تقسیم نیازهای ظرفیت جهانی یک سرویس به سهمیه‌های منطقه‌ای استفاده می‌کند. در مرحله بعد، ابزار مدیریت ظرفیت منطقه‌ای ما منابع سرور را به این سهمیه‌های منطقه‌ای اختصاص می‌دهد تا خوشه‌های مجازی (Virtual Clusters) تشکیل دهد. برخلاف خوشه‌های فیزیکی، یک خوشه مجازی می‌تواند شامل سرورهایی از مراکز داده مختلف در یک منطقه باشد و اندازه آن می‌تواند به صورت پویا افزایش یا کاهش یابد. در زمان اجرا، ابزار مدیریت کانتینر ما کانتینرها را در این خوشه‌های مجازی تخصیص می‌دهد، که اغلب کانتینرهای یک کار را در چندین مرکز داده در یک منطقه پخش می‌کند تا تحمل خطا (Fault Tolerance) بهبود یابد. در نهایت، در سطح سرور، مکانیزم‌های کرنل ما اطمینان حاصل می‌کنند که حافظه و منابع I/O اختصاص داده شده به کانتینرهای فردی به درستی به اشتراک گذاشته شده و ایزوله شوند.

سرویس‌های stateful، مانند پایگاه‌های داده از Global-DaaC بهره می‌برند. این سرویس‌ها معمولاً به‌صورت sharded اجرا می‌شوند، به این معنا که هر کانتینر برای افزایش بهره‌وری، چندین بخش داده (shard) را میزبانی می‌کند. Global Service Placer(GSP) ما از الگوریتم‌های بهینه‌سازی با در نظر گرفتن محدودیت‌ها برای تعیین تعداد بهینه‌ی نسخه‌های کپی (replicas) برای هر بخش داده و توزیع آن‌ها در مناطق مختلف استفاده می‌کند. سپس، چارچوب شاردینگ ما در محدوده‌ی این قوانین عمل کرده و نسخه‌های داده را بین کانتینرها تخصیص می‌دهد و آن‌ها را به‌صورت پویا جابه‌جا می‌کند تا با تغییرات بار پردازشی سازگار شود.

به طور مشابه، بارکاری یادگیری ماشین (ML) نیز از Global-DaaC بهره می‌برند. برای استنتاج ML، مدل‌ها مشابه shardهای داده مدیریت می‌شوند، و تعداد رپلیکاهای مدل و مکان آن‌ها توسط GSP تعیین می‌شود. برای آموزش ML، نیاز به هم‌مکانی (Collocation) داده‌های آموزشی و GPUها در یک منطقه مرکز داده است. هر تیم یک سهمیه ظرفیت جهانی GPU دریافت می‌کند و کارهای آموزشی را به یک صف کار جهانی ارسال می‌کند. زمان‌بند آموزش ML ما به طور خودکار مناطق را برای تکثیر داده و تخصیص GPU انتخاب می‌کند تا هم‌مکانی داده و GPUها را تضمین کند و در عین حال بهره‌وری GPU را به حداکثر برساند.

طراحی مشارکتی سخت‌افزار و نرم‌افزار

در حالی که طراحی مشارکتی سخت‌افزار و نرم‌افزار در سطح یک سرور واحد رایج است، ما این مفهوم را به مقیاس جهانی ارتقا داده‌ایم تا با استفاده از راه‌حل‌های نرم‌افزاری، محدودیت‌های سخت‌افزاری را با هزینه‌ی کمتر برطرف کنیم.

تحمل خطای کم‌هزینه

ابرهای عمومی تمایل دارند سخت‌افزاری با دسترسی بالاتر ارائه دهند، زیرا برنامه‌های مشتریان آن‌ها ممکن است به اندازه کافی در برابر خطا مقاوم نباشند. در مقابل، از آنجا که تمام برنامه‌های ما تحت کنترل ما هستند، می‌توانیم اطمینان حاصل کنیم که آن‌ها به گونه‌ای پیاده‌سازی شده‌اند که در برابر خطا مقاوم باشند و روی سخت‌افزار ارزان‌تر با تضمین‌های دسترسی پایین‌تر اجرا شوند. به عنوان مثال، یک رک سرور در ابرهای عمومی ممکن است از دو منبع تغذیه و دو سوئیچ بالای رک (ToR) استفاده کند تا دسترسی بالا را تضمین کند و تعمیر و نگهداری سوئیچ‌ها بدون اختلال در بارهای کاری در حال اجرا انجام شود. در مقابل، رک‌های ما نه منبع تغذیه دوگانه دارند و نه سوئیچ‌های ToR دوگانه. در عوض، افزونگی سخت‌افزاری تنها در سطح بسیار بزرگ‌تری مانند تابلوهای اصلی سوئیچ (MSB) اتفاق می‌افتد، که هر کدام حدود ۱۰,۰۰۰ تا ۲۰,۰۰۰ سرور را پوشش می‌دهند. برای هر شش MSB، تنها یک MSB رزرو به عنوان پشتیبان وجود دارد. علاوه بر این، ماشین‌های مجازی (VM) در ابرهای عمومی اغلب از دستگاه‌های بلوک متصل به شبکه استفاده می‌کنند، که امکان مهاجرت زنده VM را فراهم می‌کند. در مقابل، کانتینرهای ما از SSDهای متصل مستقیم و کم‌هزینه برای دیسک‌های ریشه استفاده می‌کنند، که مهاجرت زنده کانتینر را در طول عملیات نگهداری مرکز داده دشوار می‌کند.

ما از راه‌حل‌های نرم‌افزاری برای غلبه بر محدودیت‌های سخت‌افزار کم‌هزینه استفاده می‌کنیم. اولاً، ابزارهای تخصیص منابع ما اطمینان می‌دهند که کانتینرها و shardهای داده یک سرویس به اندازه کافی در دامنه‌های خطای زیر-مرکز داده (MSBها) پخش شده‌اند تا تحمل خطا بهبود یابد. ثانیاً، از طریق یک پروتکل همکاری که به یک سرویس اجازه می‌دهد در مدیریت چرخه عمر کانتینرهای خود مشارکت کند، اطمینان حاصل می‌کنیم که عملیات نگهداری محدودیت‌های سطح برنامه را رعایت می‌کنند، مانند جلوگیری از خاموشی همزمان دو رپلیکا از یک shard داده. در نهایت، Global-DaaC اطمینان می‌دهد که سرویس‌ها به گونه‌ای مستقر می‌شوند که بتوانند از دست دادن همزمان یک منطقه کامل مرکز داده، یک MSB در هر منطقه و درصدی از سرورهای تصادفی در هر منطقه را تحمل کنند. ما به طور معمول تست‌هایی در محیط عملیاتی انجام می‌دهیم تا اطمینان حاصل کنیم که این ویژگی‌ها حفظ می‌شوند و سرویس‌های ما در برابر خطا مقاوم هستند.

در حالی که زیرساخت ما به گونه‌ای طراحی شده است که از دست دادن یک منطقه کامل مرکز داده را بدون تأثیر بر کاربران تحمل کند، افزایش تعداد مناطق احتمال تحت تأثیر قرار گرفتن همزمان دو منطقه نزدیک به هم توسط یک فاجعه طبیعی بزرگ، مانند طوفان، را افزایش داده است. به جای تأمین بیش از حد ظرفیت برای تحمل از دست دادن همزمان دو منطقه، ما از یک رویکرد نرم‌افزاری استفاده می‌کنیم که در صورت از دست دادن چندین منطقه، ویژگی‌های کم‌اهمیت‌تر محصول را غیرفعال کرده و کیفیت سرویس را به طور کنترل‌شده کاهش می‌دهد، مانند ارائه ویدیوهای با کیفیت پایین‌تر، تا فشار روی زیرساخت‌ها کاهش یابد.

حذف هزینه‌های پروکسی‌های مسیریابی

برخلاف شبکه‌های سرویس سنتی که عمدتاً از پروکسی‌های sidecar برای مسیریابی درخواست‌های RPC استفاده می‌کنند، شبکه سرویس متا از پروکسی‌ها تنها برای مسیریابی ۱٪ از درخواست‌های RPC در ناوگان ما استفاده می‌کند. ۹۹٪ باقی‌مانده از یک کتابخانه مسیریابی استفاده می‌کنند که به اجرایی‌های سرویس لینک شده است و مسیریابی مستقیم از کلاینت به سرور را انجام می‌دهد، بدون نیاز به پروکسی‌های واسطه. در حالی که این رویکرد غیرمعمول باعث صرفه‌جویی در O(100,000) سرور مورد نیاز برای پروکسی‌ها می‌شود، چالش‌های استقرار را به دلیل کامپایل شدن کتابخانه در حدود O(10,000) سرویس، هر کدام با برنامه استقرار خود، افزایش می‌دهد. ابزارهای استقرار نرم‌افزار و مدیریت پیکربندی ما به مدیریت این چالش‌ها کمک می‌کنند.

ذخیره‌سازی لایه‌ای و SSDهای محلی

بر اساس فرکانس دسترسی و تحمل تأخیر، داده‌ها را به سه دسته داغ (Hot)، گرم (Warm) و سرد (Cold) تقسیم می‌کنیم، که هر دسته از یک سیستم ذخیره‌سازی متفاوت برای بهینه‌سازی هزینه-کارایی استفاده می‌کند. پایگاه‌های داده و کش‌های داغ، مانند پایگاه داده گراف اجتماعی، داده‌ها را در حافظه و درایوهای حالت جامد (SSD) ذخیره می‌کنند.

داده‌های گرم، شامل ویدیوها، تصاویر و داده‌های موجود در انبار داده (مانند لاگ‌های فعالیت کاربر)، در یک سیستم فایل توزیع‌شده ذخیره می‌شوند که از درایوهای دیسک سخت (HDD) برای ذخیره داده استفاده می‌کند. هر سرور ذخیره‌سازی مجهز به یک CPU، ۳۶ HDD و دو SSD برای کش متادیتا است.

برای داده‌های سرد که به ندرت به آن‌ها دسترسی می‌شود، مانند یک ویدیوی با وضوح بالا که ده سال پیش ذخیره شده است، آن‌ها را در سرورهای HDD با چگالی بالا آرشیو می‌کنیم، که هر کدام دارای یک CPU و ۲۱۶ HDD هستند و تعادل خوبی بین هزینه کل مالکیت و سرعت بازیابی داده ارائه می‌دهند. این HDDها بیشتر اوقات خاموش هستند، زیرا در حال استفاده فعال نیستند.

در میان بارهای کاری که داده‌ها را روی SSD ذخیره می‌کنند، برخی می‌توانند تأخیرهای طولانی‌تر را تحمل کنند و برای استفاده بهتر از SSD، از ذخیره‌سازی اشتراکی مبتنی بر SSD استفاده می‌کنند. با این حال، بارهای کاری با نیازهای سخت‌گیرانه به تأخیر همچنان از SSDهای محلی متصل مستقیم استفاده می‌کنند. در مقایسه با سایر زیرساخت‌های هایپرسکیل، ما بیشتر از SSDهای محلی برای کاهش هزینه‌ها استفاده می‌کنیم، علیرغم پیچیدگی‌های مدیریتی که به همراه دارد. به عنوان مثال، توزیع نابرابر بار می‌تواند منجر به استفاده ناکافی و به‌دردنخور شدن SSDهای محلی شود. علاوه بر این، بازیابی پس از خطا به دلیل گیر کردن داده‌ها در SSDهای سرورهای خراب، پیچیده می‌شود. برای حل این چالش‌ها، از چارچوب sharding مشترک خود برای پیاده‌سازی سرویس‌های stateful با SSDهای محلی استفاده می‌کنیم، که این مشکلات را یک بار حل کرده و راه‌حل را در بسیاری از سرویس‌ها استفاده مجدد می‌کنیم.

طراحی اختصاصی سخت‌افزار

ما مراکز داده و سخت‌افزارهای خود—از جمله سرورها، سوئیچ‌های شبکه، شتاب‌دهنده‌های ویدیو و تراشه‌های هوش مصنوعی—را برای کاهش هزینه‌ها و بهبود بهره‌وری انرژی خودمان طراحی می‌کنیم. در مراکز داده، تامین برق بزرگ‌ترین محدودیت است، زیرا ظرفیت تأمین برق در زمان ساخت دیتاسنتر مشخص می‌شود و افزایش آن در طول عمر ۲۰ تا ۳۰ ساله‌ی دیتاسنتر بسیار دشوار است. در مقابل، شبکه و سرورها را می‌توان به‌روز کرد. برق در دیتاسنترها معمولاً بیش از ظرفیت اسمی تخصیص داده می‌شود (Oversubscribed)، به این معنا که مجموع نیازهای برق سرورها از مقدار واقعی برق قابل تأمین بیشتر در نظر گرفته می‌شود. برای جلوگیری از مصرف بیش از حد برق در زمان افزایش ناگهانی بار پردازشی، یک ابزار خودکار اقدامات محدودسازی مصرف برق را در سطوح مختلف سیستم تأمین برق هماهنگ می‌کند.

طراحی‌های سخت‌افزاری ما معمولاً از طریق هماهنگی بین سخت‌افزار و نرم‌افزار (مانند بهینه‌سازی استفاده از SRAM در تراشه‌های هوش مصنوعی بر اساس بارهای کاری) و حذف اجزای غیرضروری (مثل حذف سیستم‌های خنک‌کننده با کمپرسور) به صرفه‌جویی در هزینه و انرژی منجر می‌شوند. علاوه بر این، توسعه داخلی سوئیچ‌های شبکه و نرم‌افزارهای مرتبط، این امکان را فراهم می‌کند که نرم‌افزار سوئیچ را به‌عنوان یک سرویس معمولی در نظر گرفته و به‌روزرسانی‌ها را به‌طور مکرر انجام دهیم. بیشتر طراحی‌های سخت‌افزاری ما از طریق پروژه Open Compute به صورت متن‌باز در دسترس هستند.

طراحی سیستم‌های مقیاس‌پذیر

یک موضوع تکرارشونده در زیرساخت‌های هایپرسکیل، طراحی سیستم‌های مقیاس‌پذیر است. سیستم‌های غیرمتمرکز طراحی‌شده برای محیط اینترنت، مانند BGP، BitTorrent و جداول هش توزیع‌شده (DHTs)، اغلب به دلیل مقیاس‌پذیری مورد تحسین قرار می‌گیرند. با این حال، در محیط مرکز داده، که محدودیت منابع کمتری دارد و تحت کنترل یک سازمان واحد است، تجربیات ما نشان می‌دهد که کنترل‌کننده‌های متمرکز نه تنها مقیاس‌پذیری کافی را فراهم می‌کنند، بلکه ساده‌تر هستند و می‌توانند تصمیم‌گیری‌های با کیفیت‌تری انجام دهند.

**کنار گذاشتن کنترل‌کننده‌های غیرمتمرکز.**
در این بخش، چند نمونه از معاوضه بین کنترل‌کننده‌های متمرکز و غیرمتمرکز را بررسی می‌کنیم. برای سوئیچ‌های شبکه در شبکه داخلی مرکز داده ما، اگرچه آن‌ها هنوز از BGP برای سازگاری استفاده می‌کنند، شبکه دارای یک کنترل‌کننده متمرکز است که می‌تواند مسیرهای مسیریابی را در هنگام ازدحام شبکه یا خرابی لینک‌ها بازنویسی کند.

به جز BGP، ما تقریباً تمام کنترل‌کننده‌های غیرمتمرکز را به کنترل‌کننده‌های متمرکز منتقل کرده‌ایم. به عنوان مثال، در شبکه WAN خصوصی ما، از RSVP-TE غیرمتمرکز به یک کنترل‌کننده متمرکز منتقل کردیم تا مسیرهای ترافیک ترجیحی را محاسبه کرده و مسیرهای پشتیبان را برای سناریوهای خرابی رایج به‌طور پیش‌گیرانه ایجاد کند. این امر منجر به استفاده کارآمدتر از منابع شبکه و همگرایی سریع‌تر در هنگام خرابی شبکه شده است.

برای ذخیره‌سازی کلید-مقدار، DHTها از مسیریابی چند‌هاپ (Multi-Hop) برای تعیین سرور مسئول یک کلید مشخص استفاده می‌کنند، در حالی که Cassandra از هش سازگار (Consistent Hashing) برای این منظور استفاده می‌کند. هر دو بدون نیاز به یک کنترل‌کننده مرکزی عمل می‌کنند. در مقابل، برای دستیابی به تعادل بار بهتر، چارچوب sharding ما از یک کنترل‌کننده مرکزی استفاده می‌کند تا shardهای حاوی کلید را به صورت پویا به سرورها اختصاص دهد.

برای توزیع داده‌های حجیم، ما از BitTorrent به Owl مهاجرت کردیم. این تغییر باعث شد که تصمیم‌گیری درباره‌ی اینکه هر همتا (peer) داده را از کجا دریافت کند، به‌صورت متمرکز انجام شود. نتیجه‌ی این کار افزایش قابل‌توجه سرعت دانلود بود.لازم به ذکر است که هم Owl و هم شبکه‌ی WAN خصوصی ما، بخش کنترلی (control plane) را به‌صورت متمرکز مدیریت می‌کنند تا تصمیم‌گیری‌ها بهینه‌تر شوند، اما همچنان از بخش داده‌ای (data plane) غیرمتمرکز برای ارسال و دریافت واقعی داده‌ها استفاده می‌کنند.

برای توزیع متادیتاهای کوچک (که در شکل ۴ توضیح بیشتری داده شده است)، در ابتدا از یک درخت توزیع سه‌سطحی پیاده‌سازی‌شده در جاوا استفاده کردیم. گره‌های میانی این درخت، سرورهای پروکسی اختصاصی بودند و گره‌های برگ، مشترک‌های برنامه(application subscribers) بودند که می‌توانستند به صورت پویا به درخت اضافه یا از آن خارج شوند. هنگامی که این پیاده‌سازی دیگر نمی‌توانست مقیاس‌پذیری بیشتری داشته باشد، به یک درخت توزیع همتا به همتا (Peer-to-Peer) منتقل شدیم، جایی که گره‌های میانی نیز مشترک‌های برنامه بودند که داده‌ها را به سایر مشترک‌ها منتقل می‌کردند. با این حال، در میان میلیون‌ها مشترک برنامه، برخی از آن‌ها به دلیل ماهیت غیراختصاصی‌شان، اغلب با مشکلات عملکردی نویزی مواجه می‌شدند. در نتیجه، استفاده از آن‌ها به عنوان گره‌های میانی برای انتقال ترافیک، کمتر قابل اعتماد بود و منجر به اشکال‌زدایی مکرر و زمان‌بر می‌شد. در نهایت، پس از چند سال استفاده در محیط عملیاتی، درخت توزیع همتا به همتا را کنار گذاشتیم و به معماری اصلی که از سرورهای پروکسی اختصاصی استفاده می‌کرد، بازگشتیم. پیاده‌سازی اصلی جاوا را با یک پیاده‌سازی C++ با عملکرد بالاتر جایگزین کردیم، که به خوبی تا ده‌ها میلیون مشترک مقیاس‌پذیر بود.

**مطالعه موردی: شبکه سرویس مقیاس‌پذیر**
در این بخش، از شبکه سرویس متا، ServiceRouter، به عنوان یک مطالعه موردی استفاده می‌کنیم تا طراحی سیستم‌های مقیاس‌پذیر را نشان دهیم و اثبات کنیم که کنترل‌کننده‌های متمرکز در ترکیب با صفحه داده غیرمتمرکز می‌توانند به خوبی در محیط مرکز داده مقیاس‌پذیر باشند. ServiceRouter میلیاردها درخواست RPC در ثانیه را بین میلیون‌ها روتر لایه ۷ (L7، یعنی لایه کاربردی) مسیریابی می‌کند.

شکل ۳ یک شبکه سرویس رایج در صنعت را نشان می‌دهد، جایی که هر فرآیند سرویس با یک پروکسی sidecar لایه ۷ همراه است که درخواست‌های RPC را برای سرویس مسیریابی می‌کند. به عنوان مثال، هنگامی که سرویس A روی سرور ۱ درخواست‌هایی به سرویس B ارسال می‌کند، پروکسی روی سرور ۱ آن‌ها را بین سرورهای ۲، ۳ و ۴ متعادل می‌کند. در حالی که این راه‌حل به طور گسترده مورد استفاده قرار می‌گیرد، برای زیرساخت‌های هایپرسکیل مقیاس‌پذیر نیست، زیرا کنترل‌کننده مرکزی نمی‌تواند به طور مستقیم جداول مسیریابی میلیون‌ها پروکسی sidecar را پیکربندی کند. کنترل‌کننده مرکزی دو وظیفه دارد: تولید متادیتای مسیریابی جهانی و مدیریت هر روتر لایه ۷. برای مقیاس‌پذیری، ما وظیفه اول را در کنترل‌کننده مرکزی نگه می‌داریم، اما وظیفه دوم را به روترهای لایه ۷ منتقل می‌کنیم، به طوری که هر روتر لایه ۷ بتواند خود را پیکربندی و مدیریت کند.

مطالعه موردی: شبکه سرویس مقیاس‌پذیر

در این بخش، از شبکه سرویس متا به نام ServiceRouter به عنوان یک مطالعه موردی استفاده می‌کنیم تا طراحی سیستم‌های مقیاس‌پذیر را نشان دهیم و ثابت کنیم که ترکیب کنترلرهای متمرکز با یک صفحه داده غیرمتمرکز می‌تواند در محیط‌های دیتاسنتر به خوبی مقیاس‌پذیری داشته باشد. ServiceRouter میلیاردها درخواست RPC (فراخوانی رویه‌ی راه دور) را در هر ثانیه بین میلیون‌ها روتر لایه ۷ (L7، یعنی لایه کاربردی) مسیریابی می‌کند.

شکل ۳ یک شبکه سرویس رایج در صنعت را نشان می‌دهد که در آن هر فرآیند سرویس با یک پروکسی جانبی (sidecar) L7 همراه است که درخواست‌های RPC را برای سرویس مسیریابی می‌کند. به عنوان مثال، وقتی سرویس A روی سرور ۱ درخواست‌هایی به سرویس B ارسال می‌کند، پروکسی روی سرور ۱ این درخواست‌ها را بین سرورهای ۲، ۳ و ۴ متعادل می‌کند. اگرچه این راه‌حل به طور گسترده استفاده می‌شود، اما برای زیرساخت‌های بسیار بزرگ (hyperscale) مقیاس‌پذیر نیست، زیرا کنترلر مرکزی نمی‌تواند به طور مستقیم جدول‌های مسیریابی میلیون‌ها پروکسی جانبی را پیکربندی کند. کنترلر مرکزی دو وظیفه دارد: تولید ابرداده‌های مسیریابی جهانی و مدیریت هر روتر L7. برای دستیابی به مقیاس‌پذیری، ما وظیفه اول را در کنترلر مرکزی نگه می‌داریم، اما وظیفه دوم را به روترهای L7 منتقل می‌کنیم و هر روتر L7 را خودپیکربند و خودمدیریت می‌کنیم.

My image

شکل۳-شبکه‌ی سرویس (Service Mesh) مبتنی بر پروکسی سایدکار (Sidecar Proxy).

شکل ۴ معماری مقیاس‌پذیر ServiceRouter را نشان می‌دهد. در بالای شکل، کنترلرهای مختلف به طور مستقل وظایف متفاوتی مانند ثبت سرویس‌ها، به‌روزرسانی تاخیرهای شبکه اندازه‌گیری شده و محاسبه جدول مسیریابی بین‌منطقه‌ای برای هر سرویس را انجام می‌دهند. هر کنترلر به طور مستقل پایگاه اطلاعات مسیریابی مرکزی (RIB) را به‌روزرسانی می‌کند و نیازی به پیکربندی یا مدیریت تک‌تک روترهای L7 ندارد. RIB یک پایگاه داده مبتنی بر Paxos است و می‌تواند از طریق تقسیم‌بندی (sharding) مقیاس‌پذیری داشته باشد. با کمک RIB، کنترلرها بدون حالت (stateless) می‌شوند و به راحتی از طریق تقسیم‌بندی مقیاس‌پذیری پیدا می‌کنند. به عنوان مثال، چندین نمونه کنترلر می‌توانند به طور همزمان جدول‌های مسیریابی بین‌منطقه‌ای را برای سرویس‌های مختلف محاسبه کنند.

My image

شکل۴- معماری سطح بالا‌ی ServiceRouter

در وسط شکل ۴، لایه توزیع از هزاران نسخه تکثیرشده RIB استفاده می‌کند تا ترافیک خواندن از میلیون‌ها روتر L7 را مدیریت کند. در پایین شکل، هر روتر L7 با هدایت RIB، بدون نیاز به دخالت مستقیم صفحه کنترل، خود را پیکربندی می‌کند. روترهای L7 ناهمگون (heterogeneous) پشتیبانی می‌شوند که می‌توانند شامل متعادل‌کننده‌های بار (load balancers)، سرویس‌هایی با کتابخانه‌های مسیریابی توکار یا پروکسی‌های جانبی باشند.

با توجه به ServiceRouter، می‌توانیم با استفاده از تکنیک‌هایی مانند کنترل‌کننده‌های بدون حالت (stateless)، تکه‌تکه کردن (sharding) کنترل‌کننده‌ها و حذف عملکردهای غیرضروری از کنترل‌کننده‌های مرکزی – مثل مدیریت جداگانه‌ی مسیریاب‌های لایه ۷ – به مقیاس‌پذیری خوبی با کنترل‌کننده‌های متمرکز دست پیدا کنیم.

جهت‌گیری‌های آینده

علیرغم پیچیدگی زیرساخت‌های بسیار بزرگ (hyperscale) متا، در اینجا یک مرور کلی و مختصر ارائه کردیم و بر بینش‌های کلیدی حاصل از توسعه آن تأکید نمودیم. در پایان، دیدگاه‌های خود را درباره روندهای احتمالی آینده برای زیرساخت‌های بسیار بزرگ به اشتراک می‌گذاریم.

هوش مصنوعی (AI):
بارکاری هوش مصنوعی به بزرگ‌ترین دسته‌ی بارکاری در مراکز داده تبدیل شده‌اند. پیش‌بینی می‌کنیم که تا پایان این دهه، بیش از نیمی از انرژی دیتاسنترها به بارکاری‌های هوش مصنوعی اختصاص یابد. به دلیل ویژگی‌های متمایز هوش مصنوعی، مانند نیاز به منابع بیشتر و شبکه‌های با پهنای باند بالاتر، انتظار داریم که هوش مصنوعی هر جنبه‌ای از زیرساخت را به طور عمیقی متحول کند. در دو دهه گذشته، زیرساخت‌های بسیار بزرگ عمدتاً با استفاده از رویکرد مقیاس‌افقی (scaling-out) و بهره‌گیری از تعداد زیادی سرور کم‌هزینه موفق شده‌اند. با این حال، خوشه‌های آینده هوش مصنوعی به احتمال زیاد از رویکرد مقیاس‌عمودی (scale-up) استفاده خواهند کرد که در ابررایانه‌های گذشته دیده می‌شد، مانند استفاده از دسترسی مستقیم به حافظه از راه دور (RDMA) روی اترنت برای ارائه شبکه‌ای با پهنای باند بالا و تاخیر کم که برای آموزش مدل‌های یادگیری ماشین در مقیاس بزرگ ضروری است. رویکرد متا به هوش مصنوعی با طراحی همزمان تمام اجزای سیستم، از PyTorch تا مدل‌های یادگیری ماشین، تراشه‌های هوش مصنوعی، شبکه‌ها، دیتاسنترها، سرورها، ذخیره‌سازی، برق و خنک‌کننده متمایز می‌شود.

سخت‌افزارهای خاص حوزه (Domain-specific hardware):
برخلاف روند کاهش تنوع سخت‌افزاری در دهه ۲۰۰۰، پیش‌بینی می‌کنیم که شاهد گسترش سخت‌افزارهای سفارشی و تخصصی برای اهداف مختلف باشیم، مانند آموزش و استنتاج هوش مصنوعی، مجازی‌سازی، رمزگذاری ویدیو، رمزنگاری، فشرده‌سازی، حافظه‌های لایه‌بندی شده و همچنین پردازش درون شبکه و درون ذخیره‌سازی. دلیل این امر آن است مقیاس‌پذیری اقتصادی به شرکت‌های ابرمقیاس این امکان را می‌دهد که سخت‌افزارهای تخصصی را در ابعاد وسیع طراحی و مستقر کنند و هزینه‌ها را کاهش دهند. در نتیجه، این امر فرصت‌های جدیدی را برای پشته نرم‌افزاری فراهم می‌کند تا از یک ناوگان متنوع و پیشرفته به شکلی بهینه بهره‌برداری کند.

دیتاسنترهای لبه (Edge datacenters):
انتظار داریم که استفاده از برنامه‌های متاورس و اینترنت اشیا (IoT) به طور قابل توجهی افزایش یابند. به عنوان مثال، گیمینگ ابری (cloud gaming) رندرینگ گرافیکی را از دستگاه‌های کاربر به سرورهای GPU در دیتاسنترهای لبه منتقل می‌کند و نیازمند تاخیر شبکه کمتر از ۲۵ میلی‌ثانیه است. تقاضا برای پاسخگویی بلادرنگ احتمالاً باعث رشد قابل توجهی در تعداد و اندازه دیتاسنترهای لبه خواهد شد. در نتیجه، صفحه کنترل زیرساخت باید به گونه‌ای تطبیق یابد که بتواند ناوگانی پراکنده‌تر را مدیریت کند، ترجیحاً با بهبود Global-DaaC تا پیچیدگی زیرساخت پراکنده را از دید توسعه‌دهندگان برنامه‌ها پنهان کند.

بهره‌وری توسعه‌دهندگان:
در دو دهه گذشته، ابزارهای اتوماسیون به طور قابل توجهی بهره‌وری مدیران سیستم را افزایش داده‌اند و منجر به نسبت سرور به مدیر بسیار بالاتری شده‌اند. در مقابل، توسعه نرم‌افزارهای عمومی همچنان پرزحمت است و رشد بهره‌وری در این حوزه کندتر بوده است. در این دهه، انتظار داریم که این روند تغییر کند و بهره‌وری توسعه‌دهندگان به دو دلیل به سرعت افزایش یابد: تولید و اشکال‌زدایی کد با کمک هوش مصنوعی، و پارادایم‌های برنامه‌نویسی سرورلس (serverless) کاملاً یکپارچه در زمینه‌های تخصصی. FrontFaaS متا نمونه‌ای از مورد دوم است، و پیش‌بینی می‌کنیم که پارادایم‌های برنامه‌نویسی بسیار مولد برای زمینه‌های تخصصی بیشتری ظهور کنند.

ما پیش‌بینی می‌کنیم که نوآوری سریع در زیرساخت‌های هایپرسکیل که در دو دهه‌ی گذشته شاهد آن بوده‌ایم، در دهه‌ی آینده نیز ادامه یابد، به‌ویژه با پیشرفت‌های هوش مصنوعی. ما ابرشرکت‌ها را تشویق می‌کنیم که دیدگاه‌های خود را به اشتراک بگذارند تا جامعه بتواند به‌صورت جمعی روند پیشرفت را تسریع کند.