چگونه تأخیر و هزینه را در سامانه‌های توزیع‌شده (distributed systems) به حداقل برسانیم؟

چگونه تأخیر و هزینه را در سامانه‌های توزیع‌شده (Distributed Systems) به حداقل برسانیم؟

نکات کلیدی

  • سامانه‌های توزیع‌شده‌ای که روی چندین ناحیهٔ دسترس‌پذیری (Availability Zone) گسترده می‌شوند می‌توانند هزینه‌های قابل توجه انتقال داده و گلوگاه‌های عملکردی ایجاد کنند.

  • سازمان‌ها می‌توانند با به‌کارگیری تکنیک‌های مسیریابی آگاه از زون (zone aware routing) بدون قربانی کردن قابلیت اتکا و دسترس‌پذیری بالا، هزینه و تأخیر را کاهش دهند.

  • مسیریابی آگاه از زون راهبردی است که برای بهینه‌سازی هزینه‌های شبکه و تأخیر طراحی شده و تا حد ممکن ترافیک را به سرویس‌های داخل همان ناحیهٔ دسترس‌پذیری هدایت می‌کند.

  • پیاده‌سازی سرتاسری مسیریابی آگاه از زون به ابزارهای مختلفی مانند Istio نیاز دارد و همچنین مستلزم انتخاب پایگاه‌داده‌های توزیع‌شده‌ای است که از این قابلیت پشتیبانی کنند.

  • مراقب مشکلاتی باشید که وقتی سرویس‌ها به‌طور یکنواخت توزیع نشده‌اند رخ می‌دهد. نقاط داغ کلاستر (cluster hotspots) را مدیریت کنید و بتوانید یک سرویس را در محدودهٔ یک زون مشخص مقیاس دهید.

رویکرد معماری میکروسرویس‌ها به یکی از عوامل اصلی ساخت محصولات موفق تبدیل شده است. این رویکرد با پذیرش فناوری‌های پیشرفتهٔ ابری مانند سرویس‌مش (service mesh)، کانتینرها و رایانش سرورلس (serverless computing) ممکن شد. نیاز به رشد سریع، ایجاد قابلیت نگه‌داری، تاب‌آوری و دسترس‌پذیری بالا باعث شد تیم‌ها ساخت «سامانه‌های توزیع‌شدهٔ عمیق» را به یک استاندارد تبدیل کنند: سامانه‌هایی با لایه‌های متعدد میکروسرویس. سامانه‌هایی که در چندین ناحیهٔ دسترس‌پذیری (AZ) و حتی چندین منطقه (region) گسترده می‌شوند. این سامانه‌ها معمولاً با ده‌ها میکروسرویس پرگفت‌وگو (chatty) شناخته می‌شوند که باید مرتباً از طریق شبکه با هم ارتباط برقرار کنند.

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

مشکل

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

در برخی سامانه‌های حیاتی، توزیع منابع و داده میان چندین region و حتی چندین ارائه‌دهندهٔ ابر (cloud provider) برای تحمل خطا (fault tolerance) نیز رایج است.

توزیع سرویس‌ها در چندین AZ باعث می‌شود مجبور شویم داده را بین این AZها جابه‌جا کنیم. هر زمان دو میکروسرویس با هم ارتباط برقرار می‌کنند یا هر زمان یک سرویس داده را از یک پایگاه‌دادهٔ توزیع‌شده می‌خواند، این ارتباط احتمالاً از مرز AZ عبور می‌کند. این موضوع به ماهیت لودبالانسینگ برمی‌گردد.

معمولاً لودبالانسرها ترافیک را به‌طور یکنواخت بین نمونه‌های سرویس بالادستی (upstream service، یعنی سرویسی که فراخوانی می‌شود) توزیع می‌کنند بدون آن‌که از AZیی که سرویس مبدأ در آن قرار دارد آگاه باشند. بنابراین در عمل، وقتی سامانه‌ها روی چند AZ فراهم شده‌اند، ترافیک بین-AZ (cross-AZ) احتمالاً بسیار زیاد رخ می‌دهد.

اما چرا این موضوع هم یک بار هزینه‌ای ابری است و حتی می‌تواند یک گلوگاه عملکردی باشد؟ بیایید آن را باز کنیم.

چگونه تأخیر و هزینه را در سامانه‌های توزیع‌شده (distributed systems) به حداقل برسانیم؟
شکل ۱: نمایش جریان یک درخواست که از چندین ناحیهٔ دسترس‌پذیری عبور می‌کند

بار هزینه‌ای

هر بار که داده بین دو AZ منتقل می‌شود، معمولاً نزد ارائه‌دهندگان بزرگ ابر، برای انتقال دادهٔ بین-AZ در هر دو جهت هزینهٔ انتقال داده اعمال می‌شود: هم برای انتقال ورودی بین-AZ (ingress) و هم برای انتقال خروجی بین-AZ (egress). برای مثال، اگر هزینه در هر جهت $۰.۰۱/GB باشد، یک ترابایت دادهٔ منتقل‌شده بین دو ناحیهٔ دسترس‌پذیری در یک region، برای egress برابر $۱۰ و برای ingress برابر $۱۰ هزینه دارد، مجموعاً $۲۰. اما این هزینه‌ها در سامانه‌های توزیع‌شده می‌توانند خیلی سریع از کنترل خارج شوند. تصور کنید به‌عنوان بخشی از یک درخواست، نمونهٔ Load Balancer شما در AZ-1 به Service A در AZ-2 وصل می‌شود، آن هم Service B را در AZ-3 فراخوانی می‌کند، و آن سرویس یک رکورد کلید/مقدار را از DB در AZ-2 می‌خواند و اغلب به‌روزرسانی‌ها را از یک بروکر Kafka در AZ-1 مصرف می‌کند (شکل ۱ را ببینید).

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

گلوگاه عملکردی

AZها از نظر فیزیکی با فاصلهٔ معنی‌داری از AZهای دیگر در همان دیتاسنتر یا region جدا شده‌اند، هرچند همه در محدودهٔ چند مایل قرار دارند. این معمولاً یک تأخیر رفت‌وبرگشت حداقلی در حد چند میلی‌ثانیه تک‌رقمی بین AZها ایجاد می‌کند و گاهی حتی بیشتر. پس برگردیم به مثال‌مان که درخواست به Load Balancer در AZ-1 می‌رسد و به Service A در AZ-2 می‌رود، سپس Service B را در AZ-3 فراخوانی می‌کند، سپس از DB در AZ-2 یک رکورد کلید/مقدار می‌خواند و اغلب به‌روزرسانی‌ها را از یک بروکر Kafka در AZ-1 مصرف می‌کند. به این شکل، به‌راحتی می‌توانیم بیش از یک دوجین میلی‌ثانیه به هر درخواست اضافه کنیم. زمانی ارزشمند که وقتی سرویس‌ها در یک AZ هستند می‌تواند به زیر میلی‌ثانیه برسد. و همان‌طور که در بار هزینه‌ای هم گفتیم، هرچه سرویس بیشتری به پشته اضافه کنید، این بار بیشتر می‌شود.

پس چطور می‌توانیم قابلیت اتکا بین-AZ را بدون قربانی کردن عملکرد به دست آوریم؟ و آیا کاری می‌توان دربارهٔ این هزینه‌های اضافهٔ انتقال داده انجام داد؟

بیایید وارد این سؤال‌ها شویم.

مسیریابی آگاه از زون به کمک می‌آید

مسیریابی آگاه از زون (Zone Aware Routing) که با نام مسیریابی آگاه از توپولوژی (Topology Aware Routing) هم شناخته می‌شود، راه حل پرداختن به این مشکلات است. و ما در Aura از Unity طی یک سال گذشته به‌تدریج این قابلیت را پیاده‌سازی کرده‌ایم. دیدیم که در برخی سامانه‌ها ۶۰٪ از ترافیک بین-AZ را صرفه‌جویی کرده است. فهمیدیم چگونه از آن برای بهینه‌سازی عملکرد و کاهش چشمگیر هزینه‌های پهنای باند استفاده کنیم. همچنین کشف کردیم کجا مناسب نیست و باید از آن اجتناب کرد. پس بیایید مسیریابی آگاه از زون را توضیح دهیم و مواردی را که برای استفادهٔ درست از آن باید در نظر گرفت.

مسیریابی آگاه از زون چیست؟

مسیریابی آگاه از زون راهبردی است که برای بهینه‌سازی هزینه‌های شبکه و تأخیر طراحی شده و تا حد ممکن ترافیک را به سرویس‌های داخل همان ناحیهٔ دسترس‌پذیری هدایت می‌کند. این کار نیاز به انتقال داده بین زون‌ها را کمینه می‌کند و هزینه‌ها و تأخیرهای مرتبط را کاهش می‌دهد.

هدف مسیریابی آگاه از زون این است که همه یا بیشتر ترافیک از یک سرویس مبدأ به سرویس بالادستی را از طریق زون محلی هدایت کند. در حالت ایده‌آل، این‌که مسیردهی محلی انجام شود یا مسیردهی بین‌زون انجام گیرد باید به درصد نمونه‌های سالم سرویس بالادستی در زون محلیِ سرویس مبدأ بستگی داشته باشد. علاوه بر این، در صورت خرابی یا اختلال سرویس بالادستی در AZ فعلی، یک مؤلفهٔ مسیریابی آگاه از زون باید بتواند به‌صورت خودکار درخواست‌ها را بین AZها دوباره مسیردهی کند تا دسترس‌پذیری بالا و تحمل خطا حفظ شود.

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

به همین دلیل، مسیریابی آگاه از زون می‌تواند در محیط‌هایی با ترافیک و منابع زونیِ یکنواخت بسیار مفید باشد (برای مثال، وقتی ترافیک را ۵۰/۵۰ بین دو AZ تقسیم می‌کنید و به همان نسبت منابع دارید). اما در توزیع‌های زونیِ نامتوازن، می‌تواند به دلیل نیاز به متعادل‌سازی ترافیک بین چندین زون و غلبه بر نقاط داغ (نمونه‌های بمباران‌شده و اضافه‌بار گرفته، شکل ۲ را ببینید) کمتر مؤثر شود.

چگونه تأخیر و هزینه را در سامانه‌های توزیع‌شده (distributed systems) به حداقل برسانیم؟
شکل ۲: نمایش توزیع نامتوازن زونی. دو سرویس در دو زون.

آیا Service B دوام می‌آورد وقتی باید همهٔ درخواست‌های ورودی از AZ-2 را سرو کند؟

چگونه می‌توانم مسیریابی آگاه از زون را به کار بگیرم؟

مفهوم مسیریابی آگاه از زون پیاده‌سازی‌های مختلفی دارد. بنابراین پذیرش آن به پیدا کردن پیاده‌سازی‌هایی بستگی دارد که با تنظیمات و پشتهٔ فناوری شما سازگار باشند. بیایید چند گزینه را مرور کنیم:

لودبالانسینگ محلی Istio (Istio Locality Load Balancing)

Istio یک پلتفرم سرویس‌مش متن‌باز برای Kubernetes است. Istio احتمالاً امیدوارکننده‌ترین پیاده‌سازی مسیریابی آگاه از زون را دارد: Locality Load Balancing. این قابلیت در Istio اجازه می‌دهد درخواست‌ها بر اساس محلی‌بودن سرویس و نمونه‌های سرویس بالادستی، به نزدیک‌ترین نمونهٔ در دسترس مسیردهی شوند. وقتی Istio در یک کلاستر Kubernetes نصب و پیکربندی شود، محلی‌بودن می‌تواند بر اساس region جغرافیایی، ناحیهٔ دسترس‌پذیری و عوامل زیر-زون تعریف شود.

Locality Load Balancing در Istio اجازه می‌دهد درخواست‌ها ترجیحاً به نمونه‌ای از سرویس بالادستی که در همان locality (یعنی زون) سرویس مبدأ قرار دارد مسیردهی شوند. اگر در همان locality هیچ نمونهٔ سالمی از سرویس وجود نداشته باشد، Istio می‌تواند فیل‌اور کند و درخواست‌ها را به نزدیک‌ترین locality در دسترس (مثلاً یک زون دیگر و حتی یک region دیگر) دوباره مسیردهی کند. این کار دسترس‌پذیری بالا و تحمل خطا را تضمین می‌کند.

علاوه بر این، Istio اجازه می‌دهد برای localityهای مختلف وزن (weight) تعریف کنید تا بتوانید توزیع ترافیک را بین AZها بر اساس عواملی مانند ظرفیت یا اولویت کنترل کنید. این کار غلبه بر توزیع‌های نامتوازن زونی را آسان‌تر می‌کند، چون می‌توانید تنظیم کنید چه مقدار ترافیک در هر زون محلی بماند و چه مقدار ترافیک به زون‌های دیگر ارسال شود.

مسیریابی آگاه از توپولوژی (Topology Aware Routing) (یا Topology Aware Hints)

اگر با Kubernetes بدون Istio کار می‌کنید، Topology Aware Routing یک قابلیت بومی Kubernetes است که در نسخهٔ ۱.۱۷ (به‌صورت topology aware hints) معرفی شد. این قابلیت، هرچند ساده‌تر از چیزی است که Istio ارائه می‌دهد، اجازه می‌دهد زمان‌بند Kubernetes تصمیم‌های مسیردهی هوشمندانه بر اساس توپولوژی کلاستر بگیرد. اطلاعات توپولوژی مانند مکان جغرافیایی نود (مثلاً region) یا ناحیهٔ دسترس‌پذیری را در نظر می‌گیرد تا جای‌گذاری پادها و مسیردهی ترافیک بهینه شود.

Kubernetes همچنین چندین محافظ (safeguard) مهم پیرامون این قابلیت فراهم می‌کند. کنترل‌پلین Kubernetes پیش از استفاده از این قابلیت، آن قواعد محافظ را اعمال می‌کند. اگر این قواعد تأیید نکنند، Kubernetes درخواست را محلی نمی‌کند. در عوض، برای حفظ دسترس‌پذیری بالا و جلوگیری از اضافه‌بار روی یک زون یا نمونهٔ خاص، یک نمونه را بدون توجه به زون یا region انتخاب می‌کند. این قواعد می‌توانند ارزیابی کنند آیا در هر زون نمونه‌های در دسترس از یک سرویس وجود دارد یا آیا واقعاً می‌توان تخصیص متعادلی میان زون‌ها داشت، تا از ایجاد توزیع ترافیک نامتوازن در کلاستر جلوگیری شود.

در حالی که Topology Aware Routing امکان بهینه‌سازی ترافیک بین‌زون و مدیریت بار پنهانِ عملکرد و هزینه هنگام کار با چند AZ را فراهم می‌کند، کمی کمتر از Locality Load Balancing در Istio توانمند است. عیب اصلی این است که مانند Istio فیل‌اور را مدیریت نمی‌کند. در عوض، رویکرد محافظتی‌اش محلی‌بودن زون را به‌طور کامل برای آن سرویس خاموش می‌کند، که یک انتخاب طراحی سخت‌گیرانه‌تر است و نیاز دارد سرویس‌ها برای بهره‌مند شدن از این قواعد، به‌طور یکنواخت میان زون‌ها پخش شوند.

مسیریابی آگاه از زون به‌صورت سرتاسری (End-to-End Zone Aware Routing)

استفاده از Locality Load Balancing در Istio یا Topology Aware Routing در Kubernetes برای حفظ مسیریابی آگاه از زون، گامی بزرگ در مقابله با هزینه‌های انتقال داده و گلوگاه‌های عملکردی سامانه‌های توزیع‌شدهٔ ماست. با این حال، برای کامل کردن پذیرش سرتاسریِ مسیریابی آگاه از زون و رساندن انتقال داده بین-AZ به حداقل، باید بررسی کنیم آیا سرویس‌های ما قادرند دادهٔ خود را از پایگاه‌داده‌ها و صف‌های پیام (MQ) از طریق زون محلی بخوانند یا نه (شکل ۳ را ببینید).

چگونه تأخیر و هزینه را در سامانه‌های توزیع‌شده (distributed systems) به حداقل برسانیم؟
شکل ۳: نمایش جریان یک درخواست که سرتاسری روی یک AZ محلی‌سازی شده است

پایگاه‌داده‌ها و MQها معمولاً برای رسیدن به دسترس‌پذیری بالا در چند AZ توزیع می‌شوند و از هر قطعهٔ داده در هر AZ یک نسخه نگه می‌دارند. به همین دلیل، DBها و MQها مستعد این هستند که بین زون‌ها مورد دسترسی قرار بگیرند و در نتیجه سامانه را در معرض بار عملکردی و هزینه‌ای قرار دهند. پس آیا می‌توانیم با دسترسی به داده از طریق زون محلی، تأخیر خواندن DB را بهتر کنیم و هزینه‌های انتقال داده را کاهش دهیم بدون آن‌که تاب‌آوری را به خطر بیندازیم؟

در ادامه چند نمونه از DBها و MQهایی آمده که می‌توانند از مسیریابی آگاه از زون پشتیبانی کنند:

قابلیت Follower Fetching در Kafka

Apache Kafka یک پلتفرم متن‌باز و توزیع‌شدهٔ استریم رویداد است که برای پایپ‌لاین‌های داده با عملکرد بالا، تحلیل استریمینگ و یکپارچه‌سازی داده استفاده می‌شود. مثل سایر MQها، معمولاً برای اتصال میان میکروسرویس‌ها و جابه‌جایی داده در سامانه‌های توزیع‌شده به کار می‌رود.
Follower Fetching قابلیتی در کتابخانهٔ کلاینت Kafka است که به مصرف‌کننده‌ها اجازه می‌دهد ترجیحاً داده را از طریق ناحیهٔ دسترس‌پذیری محلی بخوانند، چه از نود رهبر (leader) چه از نود رپلیکا (replica). این قابلیت بر اساس ویژگی Rack Awareness در Kafka است که برای افزایش قابلیت اتکای داده و دسترس‌پذیری با استفاده از توپولوژی فیزیکی یا منطقی دیتاسنتر طراحی شده است.

Rack Awareness در Kafka نیاز دارد که به هر بروکر در کلاستر اطلاعات rack متناظر تخصیص داده شود (مثلاً شناسهٔ AZ آن) تا بتوان تضمین کرد رپلیکاهای پارتیشن‌های یک تاپیک میان AZهای مختلف توزیع شوند و ریسک از دست رفتن داده یا اختلال سرویس در صورت خرابی یک AZ یا نود کمینه شود. در حالی که rack awareness به‌طور مستقیم محلی‌بودن خواندن‌های کلاینت را کنترل نمی‌کند، اما باعث می‌شود بروکر بتواند اطلاعات مکان خود را از طریق rack tag ارائه دهد تا کتابخانه‌های کلاینت از آن استفاده کنند و تلاش کنند از رپلیکاهای مستقر در همان rack یا زون بخوانند، یا اگر بروکر محلی در دسترس نبود به زون دیگری فالبک کنند. بنابراین با مفهوم مسیریابی آگاه از زون هم‌سو است که هزینه‌های انتقال داده و تأخیر را بهینه می‌کند. برای استفاده از follower fetching، باید به مصرف‌کننده rack tag تخصیص دهیم که نشان دهد اکنون از کدام AZ اجرا می‌شود تا کتابخانهٔ کلاینت بتواند بروکری را در همان AZ پیدا کند.

توجه کنید وقتی از follower fetching در Kafka استفاده می‌کنید و تأخیر تکثیر (replication lag) بروکر محلی نسبت به leader وجود دارد، زمان انتظار مصرف‌کننده در همان زون محلی افزایش پیدا می‌کند به‌جای آن‌که روی مصرف‌کننده‌های تصادفی در زون‌های دیگر اثر بگذارد؛ بنابراین شعاع انفجار (blast radius) برخی مشکلات به زون محلی محدود می‌شود. همچنین مانند دیگر پیاده‌سازی‌های Zone Awareness، نسبت به توزیع نامتوازن زونیِ مصرف‌کننده‌ها بسیار حساس است؛ ممکن است باعث شود برخی بروکرها اضافه‌بار بگیرند و مصرف‌کننده‌ها نیاز به مدیریت فیل‌اور داشته باشند.

Redis و دیگر DBهای آگاه از زون

Redis یک پایگاه‌دادهٔ کلید-مقدار محبوب در سامانه‌های توزیع‌شده است. یکی از DBهایی است که در اپ‌های پُربازده و مقیاس بزرگ برای کش و دیگر پرس‌وجوهای زیرمیلی‌ثانیه‌ای استفاده می‌شود. پایگاه‌داده‌ای که معمولاً برای افزونگی در چند AZ توزیع می‌شود. بنابراین هر اپلیکیشن توزیع‌شدهٔ جغرافیایی که از Redis می‌خواند، از خواندن از طریق زون محلی سود عملکردی و هزینه‌ای زیادی می‌برد.

Redis به‌صورت داخلی پشتیبانی ندارد که به‌طور خودکار درخواست‌های خواندن را بر اساس AZ کلاینت به رپلیکای محلی مسیردهی کند. با این حال، می‌توانیم این قابلیت را با برخی کتابخانه‌های کلاینت Redis به دست آوریم. برای مثال، هنگام استفاده از Lettuce (یک کتابخانهٔ جاوا)، تنظیم گزینهٔ ReadFrom کلاینت روی LOWEST_LATENCY باعث می‌شود کلاینت از کم‌تأخیرترین نسخهٔ داده بخواند، چه روی رپلیکا باشد چه روی نود مستر. این نسخه معمولاً در زون محلی قرار دارد، بنابراین انتقال دادهٔ بین‌زون را کاهش می‌دهد.

اگر از کتابخانهٔ کلاینتی استفاده می‌کنید که انتخاب نزدیک‌ترین رپلیکا را پشتیبانی نمی‌کند، می‌توانید منطق سفارشی پیاده‌سازی کنید که با گرفتن داده از endpoint محلی Redis همین نتیجه را بدهد. و ترجیحاً در صورت نیاز به endpoint بین-AZ فالبک کنید.

فناوری‌های پایگاه‌دادهٔ محبوب دیگری هم هستند که مسیریابی آگاه از زون را پشتیبانی می‌کنند؛ این‌جا دو مورد که ارزش اشاره دارند:

Aerospike—یک پایگاه‌دادهٔ توزیع‌شدهٔ کلید-مقدار که برای عملیات داده با عملکرد بالا طراحی شده است. قابلیتی به نام rack awareness دارد که مانند Kafka سازوکاری فراهم می‌کند تا کلاینت‌ها ترجیحاً از نزدیک‌ترین rack یا زون بخوانند.

Vitess—یک نسخهٔ توزیع‌شده و مقیاس‌پذیر از MySQL که ابتدا توسط یوتیوب توسعه داده شد و با Local Topology Service خود مسیریابی آگاه از زون را ممکن می‌کند تا پرس‌وجوها را از طریق زون محلی مسیردهی کند.

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

یک بار هزینه‌ای دیگر در توزیع DBها و MQها در چند AZ این است که هر قطعهٔ داده‌ای که می‌نویسیم باید در خود کلاستر DB به هر زون تکثیر شود. این تکثیر به‌خودیِ خود می‌تواند مقدار قابل توجهی هزینهٔ انتقال داده ایجاد کند. در حالی که از نظر فنی کار خاصی برای حذف آن نمی‌توان انجام داد، مهم است توجه کنیم که معمولاً سرویس‌های DB مدیریت‌شده مانند AWS MSK (سرویس مدیریت‌شدهٔ آمازون برای Kafka)، AWS RDS (سرویس پایگاه‌دادهٔ رابطه‌ای آمازون)، Elasticache (سرویس مدیریت‌شدهٔ Redis آمازون) و موارد دیگر، برای انتقال دادهٔ بین-AZ داخل خود کلاستر از کاربران هزینه نمی‌گیرند و فقط برای داده‌ای که وارد کلاستر می‌شود و از کلاستر خارج می‌شود هزینه اعمال می‌کنند. بنابراین انتخاب سرویس مدیریت‌شده می‌تواند یک ملاحظهٔ هزینه‌ای مهم باشد اگر قصد دارید حجم زیادی داده را تکثیر کنید.

مدیریت نقاط داغ و توزیع نامتوازن سرویس

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

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

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

سپس باید ابزارهای درست را برای حذف یا کمینه‌سازی این فراخوانی‌های بین-AZ به کار بگیریم. این ابزارها و بهینه‌سازی‌ها به پشتهٔ فناوری ما بستگی دارند. برای پذیرش سرتاسری مسیریابی آگاه از زون، باید برای موارد استفادهٔ مختلف از ابزارهای مختلف استفاده کنیم. برخی ابزارها مانند Istio و قواعد Topology Aware Routing برای فعال کردن آگاهی زونی در ارتباط پادهای Kubernetes با هم طراحی شده‌اند. اما در مواردی که میکروسرویس‌های شما داده را از پایگاه‌داده‌ها یا صف‌های پیام از طریق AZ دیگر مصرف می‌کنند کاربردی نیستند. بنابراین باید DBها و MQهای درست را انتخاب کنیم که آگاهی زونی در کتابخانه‌های کلاینتشان تعبیه شده باشد.

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

در مجموع، بهینه‌سازی ترافیک بین-AZ حیاتی است؛ می‌تواند روی عملکرد، تأخیر و هزینهٔ اپلیکیشن‌های ما اثر بگذارد، اما باید با دقت مدیریت شود تا مطمئن شویم قابلیت اتکای اپ و دسترس‌پذیری بالای آن را قربانی نمی‌کنیم.

منظور از ساخت یک سامانهٔ کش جهانی در نتفلیکس (Netflix) چیست؟
چگونه یک سرور MCP برای یکپارچه‌سازی با Salesforce بسازیم؟

دیدگاهتان را بنویسید

سبد خرید
علاقه‌مندی‌ها
مشاهدات اخیر
دسته بندی ها