گاهی اوقات بیشتر کمتر است. هنگامی که کاهش بار منجر به افزایش تاخیر می شود

همانطور که در اکثر پست ها، یک سرویس توزیع شده مشکل دارد، بیایید این سرویس را الوین بنامیم. این بار من خودم مشکل را کشف نکردم، بچه های طرف مشتری به من اطلاع دادند.

یک روز با یک ایمیل ناراضی به دلیل تاخیرهای طولانی با Alvin از خواب بیدار شدم که قصد داشتیم در آینده نزدیک آن را راه اندازی کنیم. به طور خاص، مشتری تأخیر صدک 99 را در منطقه 50 میلی‌ثانیه تجربه کرد که بسیار بالاتر از بودجه تأخیر ما بود. این تعجب آور بود زیرا من این سرویس را به طور گسترده آزمایش کردم، به ویژه در مورد تأخیر، که یک شکایت رایج است.

قبل از اینکه Alvin را آزمایش کنم، آزمایش های زیادی را با 40k پرس و جو در ثانیه (QPS) انجام دادم که همگی تأخیر کمتر از 10ms را نشان می دادند. من آماده بودم که اعلام کنم با نتایج آنها موافق نیستم. اما با نگاهی دوباره به نامه، متوجه چیز جدیدی شدم: من دقیقاً شرایطی را که آنها ذکر کردند تست نکرده بودم، QPS آنها بسیار پایین تر از من بود. من با 40k QPS تست کردم، اما آنها فقط با 1k آزمایش کردند. من آزمایش دیگری را انجام دادم، این بار با QPS پایین تر، فقط برای خشنود کردن آنها.

از آنجایی که من در این مورد وبلاگ می نویسم، احتمالاً قبلاً متوجه شده اید که اعداد آنها درست بوده است. من مشتری مجازی خود را بارها و بارها با همین نتیجه آزمایش کردم: تعداد کم درخواست ها نه تنها تأخیر را افزایش می دهد، بلکه تعداد درخواست ها را با تأخیر بیش از 10 میلی ثانیه افزایش می دهد. به عبارت دیگر، اگر در 40k QPS حدود 50 درخواست در ثانیه از 50 میلی ثانیه بیشتر شود، در 1k QPS در هر ثانیه 100 درخواست بالای 50 میلی ثانیه وجود دارد. پارادوکس!

گاهی اوقات بیشتر کمتر است. هنگامی که کاهش بار منجر به افزایش تاخیر می شود

محدود کردن جستجو

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

گاهی اوقات بیشتر کمتر است. هنگامی که کاهش بار منجر به افزایش تاخیر می شود

یک نقطه شروع خوب، فهرستی از انتقال‌های I/O تکمیل‌شده (تماس‌های شبکه/جستجوی دیسک و غیره) است. بیایید سعی کنیم بفهمیم که تاخیر کجاست. علاوه بر ورودی/خروجی آشکار با مشتری، الوین یک گام اضافی برمی دارد: او به فروشگاه داده دسترسی پیدا می کند. با این حال، این ذخیره سازی در همان خوشه Alvin عمل می کند، بنابراین تأخیر در آنجا باید کمتر از مشتری باشد. بنابراین، لیست مظنونان:

  1. تماس شبکه از مشتری به الوین.
  2. تماس شبکه از آلوین به فروشگاه داده.
  3. جستجو در دیسک در فروشگاه داده.
  4. تماس شبکه از انبار داده به الوین.
  5. تماس شبکه از آلوین با مشتری.

بیایید سعی کنیم نکاتی را خط بزنیم.

ذخیره سازی اطلاعات هیچ ربطی به آن ندارد

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

گاهی اوقات بیشتر کمتر است. هنگامی که کاهش بار منجر به افزایش تاخیر می شود

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

  1. تماس شبکه از مشتری به الوین.
  2. تماس شبکه از آلوین با مشتری.

عالی! لیست به سرعت در حال کوچک شدن است. فکر کردم تقریبا دلیلش را فهمیده ام.

gRPC

اکنون زمان آن است که یک بازیکن جدید را به شما معرفی کنیم: gRPC. این یک کتابخانه منبع باز از Google برای ارتباط در فرآیند است RPC... اگر چه gRPC به خوبی بهینه شده و به طور گسترده مورد استفاده قرار می گیرد، این اولین بار بود که از آن در سیستمی با این اندازه استفاده می کردم و انتظار داشتم پیاده سازی من کمتر از حد بهینه باشد.

دسترسی gRPC در پشته یک سوال جدید ایجاد کرد: شاید اجرای من یا خودم باشد gRPC مشکل تأخیر ایجاد می کند؟ افزودن یک مظنون جدید به لیست:

  1. مشتری با کتابخانه تماس می گیرد gRPC
  2. کتابخانه gRPC یک تماس شبکه با کتابخانه روی کلاینت برقرار می کند gRPC در سرور
  3. کتابخانه gRPC مخاطبین آلوین (بدون عملیات در مورد سرور پینگ پنگ)

برای اینکه به شما ایده بدهم که کد چگونه به نظر می رسد، پیاده سازی کلاینت/آلوین من تفاوت چندانی با برنامه های کلاینت-سرور ندارد. نمونه های همگام.

توجه: لیست بالا کمی ساده شده است زیرا gRPC این امکان را فراهم می کند که از مدل رشته (الگوی؟) خود استفاده کنید، که در آن پشته اجرا در هم تنیده شده است. gRPC و پیاده سازی کاربر برای سادگی، ما به این مدل پایبند خواهیم بود.

پروفایل کردن همه چیز را درست می کند

پس از خط کشی از فروشگاه های داده، فکر کردم تقریباً تمام شده است: «اکنون آسان است! بیایید نمایه را اعمال کنیم و دریابیم که تاخیر در کجا رخ می دهد." من طرفدار بزرگ پروفایل سازی دقیق، زیرا CPU ها بسیار سریع هستند و اغلب گلوگاه نیستند. بیشتر تاخیرها زمانی اتفاق می‌افتند که پردازنده باید پردازش را متوقف کند تا کار دیگری انجام دهد. بررسی دقیق CPU دقیقاً این کار را انجام می دهد: همه چیز را با دقت ضبط می کند سوئیچ های زمینه و مشخص می کند که در کجا تاخیر رخ می دهد.

من چهار پروفایل گرفتم: با QPS بالا (تأخیر کم) و با یک سرور پینگ پنگ با QPS کم (تأخیر بالا)، هم در سمت مشتری و هم در سمت سرور. و برای هر موردی، نمونه مشخصات پردازنده را هم گرفتم. هنگام مقایسه پروفایل ها، من معمولا به دنبال یک پشته تماس غیرعادی می گردم. به عنوان مثال، در سمت بد با تأخیر بالا، سوئیچ های زمینه بسیار بیشتری وجود دارد (10 برابر یا بیشتر). اما در مورد من، تعداد سوئیچ های زمینه تقریباً یکسان بود. در کمال وحشت، هیچ چیز قابل توجهی در آنجا وجود نداشت.

اشکال زدایی اضافی

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

چه می شود اگر

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

طبق معمول، در گذشته به نظر می رسد که همه چیز واضح بود. من مشتری را روی همان ماشین آلوین قرار دادم - و درخواستی به آن فرستادم localhost. و افزایش تاخیر از بین رفته است!

گاهی اوقات بیشتر کمتر است. هنگامی که کاهش بار منجر به افزایش تاخیر می شود

مشکلی در شبکه وجود داشت.

یادگیری مهارت های مهندس شبکه

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

خوشبختانه اینترنت کسانی را که می خواهند یاد بگیرند را دوست دارد. ترکیب پینگ و ردیاب شروع به اندازه کافی خوب برای رفع اشکال مشکلات حمل و نقل شبکه به نظر می رسید.

اول راه اندازی کردم PsPing به پورت TCP آلوین. من از تنظیمات پیش فرض استفاده کردم - چیز خاصی نیست. از بیش از هزار پینگ، هیچ کدام از 10 میلی ثانیه تجاوز نکرد، به استثنای اولین پینگ برای گرم کردن. این برخلاف افزایش مشاهده‌شده در تأخیر 50 میلی‌ثانیه در صدک 99 است: در آنجا، به ازای هر 100 درخواست، باید حدود یک درخواست با تأخیر 50 میلی‌ثانیه مشاهده می‌کردیم.

بعد سعی کردم ردیابی: ممکن است در یکی از گره های مسیر بین الوین و کلاینت مشکلی وجود داشته باشد. اما ردیاب نیز دست خالی بازگشت.

بنابراین این کد من، اجرای gRPC یا شبکه نبود که باعث تاخیر شده است. کم کم داشتم نگران بودم که نخواهم فهمید.

حالا ما در چه سیستم عاملی هستیم

gRPC به طور گسترده در لینوکس استفاده می شود، اما عجیب و غریب در ویندوز. تصمیم گرفتم آزمایشی را امتحان کنم که جواب داد: یک ماشین مجازی لینوکس ایجاد کردم، Alvin را برای لینوکس کامپایل کردم و آن را به کار بردم.

گاهی اوقات بیشتر کمتر است. هنگامی که کاهش بار منجر به افزایش تاخیر می شود

و این چیزی است که اتفاق افتاد: سرور پینگ پنگ لینوکس مانند یک میزبان ویندوز مشابه، تاخیرهای مشابهی نداشت، اگرچه منبع داده تفاوتی نداشت. به نظر می رسد که مشکل در پیاده سازی gRPC برای ویندوز است.

الگوریتم ناگل

در تمام این مدت فکر می کردم که پرچمی را گم کرده ام gRPC. الان فهمیدم واقعا چیه gRPC پرچم ویندوز گم شده است. یک کتابخانه داخلی RPC پیدا کردم که مطمئن بودم برای همه پرچم‌های تنظیم شده به خوبی کار می‌کند Winsock. سپس همه این پرچم ها را به gRPC اضافه کردم و Alvin را در ویندوز، در یک سرور پینگ پنگ ویندوز وصله شده، مستقر کردم!

گاهی اوقات بیشتر کمتر است. هنگامی که کاهش بار منجر به افزایش تاخیر می شود

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

الگوریتم ناگل تلاش برای کاهش تعداد بسته های ارسال شده از طریق یک شبکه با تأخیر در ارسال پیام ها تا زمانی که اندازه بسته از تعداد مشخصی از بایت ها بیشتر شود. اگرچه این ممکن است برای کاربر معمولی خوب باشد، اما برای سرورهای بلادرنگ مخرب است زیرا سیستم عامل برخی از پیام‌ها را به تاخیر می‌اندازد و باعث تاخیر در QPS پایین می‌شود. U gRPC این پرچم در اجرای لینوکس برای سوکت های TCP تنظیم شده است، اما در ویندوز تنظیم نشده است. من این هستم تصحیح شده.

نتیجه

تأخیر بالاتر در QPS پایین توسط بهینه سازی سیستم عامل ایجاد شد. در گذشته نگر، نمایه سازی تأخیر را تشخیص نداد زیرا در حالت هسته انجام می شد نه در حالت حالت کاربر. نمی‌دانم الگوریتم Nagle را می‌توان از طریق عکس‌برداری ETW مشاهده کرد یا خیر، اما جالب است.

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

دفعه بعد که با کاهش تعداد درخواست ها در ثانیه شاهد افزایش تاخیر بودید، الگوریتم Nagle باید در لیست مشکوکان شما باشد!

منبع: www.habr.com

اضافه کردن نظر