Bəzən daha çox az olur. Yükün azaldılması gecikmənin artmasına səbəb olur

İçində olduğu kimi əksər yazılar, paylanmış xidmətdə problem var, gəlin bu xidməti Alvin adlandıraq. Bu dəfə problemi özüm aşkar etmədim, müştəri tərəfindəki uşaqlar mənə məlumat verdilər.

Bir gün Alvinlə uzun gecikmələrə görə narazı e-poçta oyandım, yaxın gələcəkdə onu işə salmağı planlaşdırdıq. Xüsusilə, müştəri gecikmə büdcəmizdən xeyli yuxarı olan 99 ms bölgədə 50-cu faizlik gecikmə yaşadı. Xidməti geniş şəkildə sınaqdan keçirdiyim üçün bu təəccüblü idi, xüsusən də ümumi şikayət olan gecikmə.

Alvini sınaqdan keçirməzdən əvvəl, saniyədə 40k sorğu (QPS) ilə çoxlu təcrübələr apardım, bunların hamısı 10ms-dən az gecikməni göstərirdi. Mən onların nəticələri ilə razılaşmadığımı bəyan etməyə hazır idim. Amma məktuba bir daha nəzər saldıqda yeni bir şey gördüm: onların qeyd etdiyi şərtləri dəqiq sınaqdan keçirməmişdim, onların QPS göstəriciləri mənimkindən xeyli aşağı idi. Mən 40k QPS-də sınaqdan keçirdim, lakin onlar yalnız 1k-da. Mən onları sakitləşdirmək üçün bu dəfə daha aşağı QPS ilə başqa bir sınaq keçirdim.

Mən bu haqda bloq yazdığım üçün yəqin ki, onların saylarının doğru olduğunu artıq başa düşmüsünüz. Mən virtual müştərimi təkrar-təkrar sınaqdan keçirdim, eyni nəticə ilə: az sayda sorğu nəinki gecikməni artırır, həm də gecikmə müddəti 10 ms-dən çox olan sorğuların sayını artırır. Başqa sözlə, əgər 40k QPS-də saniyədə təxminən 50 sorğu 50 ms-i keçibsə, 1k QPS-də saniyədə 100 ms-dən yuxarı 50 sorğu var idi. Paradoks!

Bəzən daha çox az olur. Yükün azaldılması gecikmənin artmasına səbəb olur

Axtarışı daraltmaq

Çox komponentli paylanmış sistemdə gecikmə problemi ilə qarşılaşdıqda ilk addım şübhəlilərin qısa siyahısını yaratmaqdır. Gəlin Alvinin memarlığına bir az daha dərindən baxaq:

Bəzən daha çox az olur. Yükün azaldılması gecikmənin artmasına səbəb olur

Yaxşı başlanğıc nöqtəsi tamamlanmış giriş/çıxış keçidlərinin siyahısıdır (şəbəkə zəngləri/disk axtarışları və s.). Gecikmənin harada olduğunu anlamağa çalışaq. Müştəri ilə aşkar I/O ilə yanaşı, Alvin əlavə bir addım atır: o, məlumat anbarına daxil olur. Bununla belə, bu saxlama Alvin ilə eyni klasterdə işləyir, ona görə də orada gecikmə müştəri ilə müqayisədə daha az olmalıdır. Beləliklə, şübhəlilərin siyahısı:

  1. Müştəridən Alvinə şəbəkə zəngi.
  2. Alvindən məlumat anbarına şəbəkə zəngi.
  3. Məlumat anbarında diskdə axtarın.
  4. Məlumat anbarından Alvinə şəbəkə zəngi.
  5. Alvindən müştəriyə şəbəkə zəngi.

Bəzi məqamların üstündən xətt çəkməyə çalışaq.

Məlumat saxlama ilə heç bir əlaqəsi yoxdur

İlk etdiyim iş Alvini sorğuları emal etməyən ping-ping serverinə çevirmək oldu. Sorğu qəbul etdikdə boş cavab qaytarır. Gecikmə azalarsa, Alvin və ya məlumat anbarının tətbiqində bir səhv eşidilməmiş bir şey deyil. Birinci təcrübədə aşağıdakı qrafiki alırıq:

Bəzən daha çox az olur. Yükün azaldılması gecikmənin artmasına səbəb olur

Gördüyünüz kimi, ping-ping serverindən istifadə edərkən heç bir irəliləyiş yoxdur. Bu o deməkdir ki, məlumat anbarı gecikməni artırmır və şübhəlilərin siyahısı yarıya endirilir:

  1. Müştəridən Alvinə şəbəkə zəngi.
  2. Alvindən müştəriyə şəbəkə zəngi.

Əla! Siyahı sürətlə daralır. Səbəbini az qala anladığımı düşündüm.

gRPC

İndi sizi yeni oyunçu ilə tanış etməyin vaxtıdır: gRPC. Bu, prosesdaxili ünsiyyət üçün Google-dan açıq mənbə kitabxanasıdır RPC... Baxmayaraq ki gRPC yaxşı optimallaşdırılmış və geniş şəkildə istifadə edilmişdir, mən onu bu ölçüdə bir sistemdə ilk dəfə istifadə etdim və tətbiqimin optimal olmadığını - ən azı desək, gözlədim.

mövcudluğu gRPC yığında yeni bir sual doğurdu: bəlkə bu mənim tətbiqimdir və ya özüm gRPC gecikmə probleminə səbəb olur? Siyahıya yeni şübhəlinin əlavə edilməsi:

  1. Müştəri kitabxanaya zəng edir gRPC
  2. kitabxana gRPC müştəridəki kitabxanaya şəbəkə zəngi edir gRPC serverdə
  3. kitabxana gRPC kontaktlar Alvin (ping-pong serverində əməliyyat yoxdur)

Kodun necə göründüyü barədə bir fikir vermək üçün mənim müştərim/Alvin tətbiqi müştəri-serverdən çox da fərqlənmir. async nümunələri.

Qeyd: Yuxarıdakı siyahı bir az sadələşdirilmişdir, çünki gRPC icra yığınının bir-birinə qarışdığı öz (şablon?) iplik modelindən istifadə etməyə imkan verir. gRPC və istifadəçinin həyata keçirilməsi. Sadəlik üçün bu modelə sadiq qalacağıq.

Profilləmə hər şeyi düzəldəcək

Məlumat anbarlarının üstündən xətt çəkərək, demək olar ki, bitdiyimi düşündüm: “İndi asandır! Gəlin profili tətbiq edək və gecikmənin harada baş verdiyini öyrənək”. I dəqiq profilləşdirmənin böyük pərəstişkarı, çünki CPU-lar çox sürətlidir və çox vaxt darboğaz deyil. Əksər gecikmələr prosessorun başqa bir şey etmək üçün emalını dayandırmalı olduğu zaman baş verir. Dəqiq CPU Profilinqi məhz bunu edir: o, hər şeyi dəqiq qeyd edir kontekst açarları və gecikmələrin harada baş verdiyini aydınlaşdırır.

Dörd profil götürdüm: yüksək QPS (aşağı gecikmə) və həm müştəri tərəfində, həm də server tərəfində aşağı QPS (yüksək gecikmə) ilə stolüstü tennis serveri ilə. Və hər halda, mən də nümunə prosessor profili götürdüm. Profilləri müqayisə edərkən adətən anormal zəng yığını axtarıram. Məsələn, yüksək gecikmə ilə pis tərəfdə daha çox kontekst açarları var (10 dəfə və ya daha çox). Amma mənim vəziyyətimdə kontekst keçidlərinin sayı demək olar ki, eyni idi. Dəhşətim odur ki, orada əhəmiyyətli bir şey yox idi.

Əlavə sazlama

Mən çarəsiz idim. Mən başqa hansı vasitələrdən istifadə edə biləcəyimi bilmirdim və mənim növbəti planım problemi aydın şəkildə müəyyən etməkdənsə, təcrübələri fərqli variasiyalarla təkrarlamaq idi.

Birdən

Əvvəldən məni xüsusi 50 ms gecikmə narahat edirdi. Bu, çox böyük vaxtdır. Qərara gəldim ki, hansı hissənin bu xətaya səbəb olduğunu dəqiq bilənə qədər koddan parçaları kəsim. Sonra işə yarayan bir təcrübə gəldi.

Həmişə olduğu kimi, arxaya baxanda hər şeyin göz qabağında olduğu görünür. Mən müştərini Alvinlə eyni maşına yerləşdirdim və ona sorğu göndərdim localhost. Və gecikmə artımı getdi!

Bəzən daha çox az olur. Yükün azaldılması gecikmənin artmasına səbəb olur

Şəbəkədə nəsə xəta baş verdi.

Şəbəkə mühəndisi bacarıqlarını öyrənmək

Etiraf etməliyəm: şəbəkə texnologiyaları haqqında biliklərim dəhşətlidir, xüsusən də hər gün onlarla işlədiyimi nəzərə alsaq. Ancaq şəbəkə əsas şübhəli idi və mən onu necə ayırmağı öyrənməliydim.

Xoşbəxtlikdən İnternet öyrənmək istəyənləri sevir. Ping və tracert birləşməsi şəbəkə nəqliyyat problemlərinin aradan qaldırılması üçün kifayət qədər yaxşı başlanğıc kimi görünürdü.

Əvvəlcə işə başladım PsPing Alvinin TCP portuna. Mən standart parametrlərdən istifadə etdim - xüsusi bir şey yoxdur. Mindən çox pingdən birincisi istiləşmə üçün istisna olmaqla, heç biri 10 ms-i keçmədi. Bu, 50-cu faizdə müşahidə edilən 99 ms gecikmə artımına ziddir: orada hər 100 sorğu üçün 50 ms gecikmə ilə təxminən bir sorğu görməliydik.

Sonra cəhd etdim tracert: Alvin və müştəri arasında marşrut boyunca qovşaqlardan birində problem ola bilər. Amma izləyici də əliboş qayıtdı.

Beləliklə, gecikməyə səbəb olan mənim kodum, gRPC tətbiqi və ya şəbəkə deyildi. Bunu heç vaxt başa düşməyəcəyimdən narahat olmağa başladım.

İndi biz hansı OS-dəyik

gRPC Linux-da geniş istifadə olunur, lakin Windows-da ekzotik. Təcrübəni sınamaq qərarına gəldim, nəticə verdi: Linux virtual maşını yaratdım, Linux üçün Alvin tərtib etdim və onu yerləşdirdim.

Bəzən daha çox az olur. Yükün azaldılması gecikmənin artmasına səbəb olur

Və belə oldu: Linux stolüstü tennis serveri oxşar Windows hostu ilə eyni gecikmələrə malik deyildi, baxmayaraq ki, məlumat mənbəyi fərqli deyildi. Məlum oldu ki, problem Windows üçün gRPC tətbiqindədir.

Nagle alqoritmi

Bütün bu müddət ərzində bir bayraq əldən verdiyimi düşündüm gRPC. İndi bunun həqiqətən nə olduğunu başa düşürəm gRPC Windows bayrağı yoxdur. Bütün bayraqlar üçün yaxşı işləyəcəyinə əmin olduğum daxili RPC kitabxanası tapdım Winsock. Sonra bütün bu bayraqları gRPC-yə əlavə etdim və Alvin-i Windows-da yamaqlanmış Windows stolüstü tennis serverində yerləşdirdim!

Bəzən daha çox az olur. Yükün azaldılması gecikmənin artmasına səbəb olur

Demək olar ki Bitdi: Səbəbi dəqiq müəyyən etmək üçün reqressiya geri qayıdana qədər əlavə edilmiş bayraqları bir-bir silməyə başladım. Bu bədnam idi TCP_NODELAY, Naqlenin alqoritm açarı.

Nagle alqoritmi paket ölçüsü müəyyən bayt sayından artıq olana qədər mesajların ötürülməsini gecikdirməklə şəbəkə üzərindən göndərilən paketlərin sayını azaltmağa çalışır. Bu, adi istifadəçi üçün xoş olsa da, real vaxt serverləri üçün dağıdıcıdır, çünki ƏS bəzi mesajları gecikdirəcək və aşağı QPS-də gecikmələrə səbəb olacaq. U gRPC bu bayraq TCP soketləri üçün Linux tətbiqində quraşdırılıb, lakin Windows-da deyil. Mən buyam düzəldildi.

Nəticə

Aşağı QPS-də daha yüksək gecikmə OS optimallaşdırılması ilə əlaqədardır. Geriyə baxdıqda, profilləmə gecikməni aşkar etmədi, çünki o, nüvə rejimində deyil, nüvə rejimində edildi istifadəçi rejimi. Nagle-nin alqoritmini ETW tutmaları vasitəsilə müşahidə etmək mümkün olub-olmadığını bilmirəm, amma maraqlı olardı.

Localhost təcrübəsinə gəlincə, o, yəqin ki, faktiki şəbəkə koduna toxunmadı və Nagle-nin alqoritmi işləmədi, ona görə də müştəri localhost vasitəsilə Alvinə çatdıqda gecikmə problemləri aradan qalxdı.

Növbəti dəfə saniyədə sorğuların sayı azaldıqca gecikmə müddətinin artdığını görəndə Naqlenin alqoritmi şübhəlilər siyahısında olmalıdır!

Mənbə: www.habr.com

Добавить комментарий