ProHoster > Blog > İdarə > SRE: Performans Təhlili. Go-da sadə veb serverdən istifadə edərək konfiqurasiya üsulu
SRE: Performans Təhlili. Go-da sadə veb serverdən istifadə edərək konfiqurasiya üsulu
Performans təhlili və tənzimləmə müştərilər üçün performans uyğunluğunu yoxlamaq üçün güclü vasitədir.
Performans təhlili tənzimləmə təcrübələrini sınaqdan keçirmək üçün elmi yanaşma tətbiq etməklə proqramda darboğazları yoxlamaq üçün istifadə edilə bilər. Bu məqalə, nümunə kimi Go veb serverindən istifadə edərək, performans təhlili və tənzimləmə üçün ümumi yanaşmanı müəyyən edir.
Go burada xüsusilə yaxşıdır, çünki onun profil alətləri var pprof standart kitabxanada.
strategiya
Struktur təhlilimiz üçün ümumi siyahı yaradaq. İntuisiyaya və ya təxminlərə əsaslanaraq dəyişiklik etmək əvəzinə qərar qəbul etmək üçün bəzi məlumatlardan istifadə etməyə çalışacağıq. Bunu etmək üçün bunu edəcəyik:
Biz optimallaşdırma sərhədlərini (tələblərini) müəyyən edirik;
Sistem üçün əməliyyat yükünü hesablayırıq;
Testi həyata keçiririk (məlumat yaradırıq);
Biz müşahidə edirik;
Təhlil edirik - bütün tələblər yerinə yetirilirmi?
Biz bunu elmi şəkildə qururuq, fərziyyə edirik;
Bu fərziyyəni yoxlamaq üçün təcrübə aparırıq.
Sadə HTTP Server Arxitekturası
Bu məqalə üçün Golang-da kiçik HTTP serverindən istifadə edəcəyik. Bu məqalədəki bütün kodları tapa bilərsiniz burada.
Təhlil edilən proqram hər sorğu üçün Postgresql-i sorğulayan HTTP serveridir. Bundan əlavə, proqram və sistem ölçülərini toplamaq və göstərmək üçün Prometheus, node_exporter və Grafana mövcuddur.
Sadələşdirmək üçün hesab edirik ki, üfüqi miqyaslama (və hesablamaların sadələşdirilməsi) üçün hər bir xidmət və verilənlər bazası birlikdə yerləşdirilir:
Məqsədlərin müəyyənləşdirilməsi
Bu mərhələdə məqsədə qərar veririk. Nəyi təhlil etməyə çalışırıq? Bitmə vaxtının nə vaxt olduğunu necə bilirik? Bu yazıda müştərilərimizin olduğunu və xidmətimizin saniyədə 10 sorğunu emal edəcəyini təsəvvür edəcəyik.
В Google SRE Kitabı Seçim və modelləşdirmə üsulları ətraflı müzakirə olunur. Gəlin eyni şeyi edək və modellər yaradaq:
Gecikmə: sorğuların 99%-i 60 ms-dən az müddətdə tamamlanmalıdır;
Xərc: Xidmət ağlabatan mümkün hesab etdiyimiz minimum məbləği istehlak etməlidir. Bunun üçün ötürmə qabiliyyətini maksimuma çatdırırıq;
Bacarıqların planlaşdırılması: Ümumi miqyaslama funksionallığı da daxil olmaqla, tətbiqin neçə nümunəsinin işə salınmalı olduğunu və ilkin yükləmə və təminat tələblərinə cavab vermək üçün neçə nümunənin lazım olacağını başa düşmək və sənədləşdirmək tələb olunur. artıqlıq n+1.
Gecikmə təhlilə əlavə olaraq optimallaşdırma tələb edə bilər, lakin ötürmə qabiliyyəti aydın şəkildə təhlil edilməlidir. SRE SLO prosesindən istifadə edərkən gecikmə tələbi məhsul sahibi tərəfindən təmsil olunan müştəri və ya biznesdən gəlir. Xidmətimiz isə bu öhdəliyi heç bir parametr olmadan əvvəldən yerinə yetirəcək!
Test mühitinin qurulması
Test mühitinin köməyi ilə sistemimizə ölçülmüş yük yerləşdirə biləcəyik. Təhlil üçün veb xidmətin performansı haqqında məlumatlar yaradılacaq.
Əməliyyat yükü
Bu mühit istifadə edir Vegeta dayandırılana qədər xüsusi HTTP sorğu dərəcəsi yaratmaq üçün:
$ make load-test LOAD_TEST_RATE=50
echo "POST http://localhost:8080" | vegeta attack -body tests/fixtures/age_no_match.json -rate=50 -duration=0 | tee results.bin | vegeta report
Müşahidə
Əməliyyat yükü icra zamanı tətbiq olunacaq. Tətbiq (sorğuların sayı, cavab gecikməsi) və əməliyyat sistemi (yaddaş, CPU, IOPS) ölçülərinə əlavə olaraq, harada problemlərin olduğunu və CPU vaxtının necə sərf edildiyini anlamaq üçün proqram profili işlənəcək.
Profilləşdirmə
Profilləşdirmə, proqram işləyərkən CPU vaxtının hara getdiyini görməyə imkan verən ölçmə növüdür. Bu, prosessorun hara və nə qədər vaxt sərf olunduğunu dəqiq müəyyən etməyə imkan verir:
Bu məlumatlar boş CPU vaxtı və yerinə yetirilən lazımsız iş haqqında məlumat əldə etmək üçün təhlil zamanı istifadə edilə bilər. Go (pprof) standart alətlər dəstindən istifadə edərək profillər yarada və onları alov qrafikləri kimi görüntüləyə bilər. Onların istifadəsi və quraşdırma təlimatı haqqında daha sonra məqalədə danışacağam.
İcra, müşahidə, təhlil.
Bir təcrübə edək. Tamaşadan razı qalana qədər ifa edəcəyik, müşahidə edəcəyik və təhlil edəcəyik. İlk müşahidələrin nəticələrini əldə etmək üçün onu tətbiq etmək üçün özbaşına aşağı yük dəyəri seçək. Hər bir sonrakı addımda yükü müəyyən bir dəyişikliklə seçilmiş müəyyən bir miqyas amili ilə artıracağıq. Hər bir yük testi tələblərin sayına uyğun olaraq həyata keçirilir: make load-test LOAD_TEST_RATE=X.
Saniyədə 50 sorğu
Üst iki qrafikə diqqət yetirin. Yuxarı sol tərəf proqramımızın saniyədə 50 sorğu emal etdiyini (düşünür) və yuxarı sağda hər sorğunun müddətini göstərir. Hər iki parametr bizim performans sərhədlərimiz daxilində olub-olmadığımıza baxmağa və təhlil etməyə kömək edir. Qrafikdə qırmızı xətt HTTP Sorğunun Gecikməsi 60ms-də SLO göstərir. Xətt göstərir ki, biz maksimum cavab müddətimizdən xeyli aşağıyıq.
Gəlin xərc tərəfinə baxaq:
Saniyədə 10000 sorğu / server başına 50 sorğu = 200 server + 1
Biz bu rəqəmi hələ də yaxşılaşdıra bilərik.
Saniyədə 500 sorğu
Yük saniyədə 500 sorğuya çatdıqda daha maraqlı şeylər baş verməyə başlayır:
Yenə yuxarı sol qrafikdə proqramın normal yükü qeyd etdiyini görə bilərsiniz. Əgər belə deyilsə, proqramın işlədiyi serverdə problem var. Cavab gecikmə qrafiki yuxarı sağda yerləşir və saniyədə 500 sorğunun 25-40 ms cavab gecikməsi ilə nəticələndiyini göstərir. 99-cu faiz hələ də yuxarıda seçilmiş 60 ms SLO-ya gözəl uyğun gəlir.
Xərc baxımından:
Saniyədə 10000 sorğu / server başına 500 sorğu = 20 server + 1
Hər şeyi hələ də yaxşılaşdırmaq olar.
Saniyədə 1000 sorğu
Əla buraxılış! Tətbiq göstərir ki, o, saniyədə 1000 sorğu emal edib, lakin gecikmə limiti SLO tərəfindən pozulub. Bunu yuxarı sağdakı qrafikdə p99 sətirində görmək olar. p100 xəttinin daha yüksək olmasına baxmayaraq, faktiki gecikmələr maksimum 60ms-dən yüksəkdir. Tətbiqin əslində nə etdiyini öyrənmək üçün profilləşdirməyə başlayaq.
Profilləşdirmə
Profil yaratmaq üçün yükü saniyədə 1000 sorğuya təyin edirik, sonra istifadə edirik pprof proqramın CPU vaxtını hara xərclədiyini öyrənmək üçün məlumatları ələ keçirmək. Bu, HTTP son nöqtəsini aktivləşdirməklə edilə bilər pprof, və sonra yük altında, curl istifadə edərək nəticələri qeyd edin:
$ go tool pprof -http=:12345 cpu.1000_reqs_sec_no_optimizations.prof
Qrafik proqramın CPU vaxtını hara və nə qədər sərf etdiyini göstərir. Təsvirdən Brendan Gregg:
X oxu əlifba sırası ilə çeşidlənmiş yığın profilinin əhalisidir (bu vaxt deyil), Y oxu [yuxarıda] sıfırdan saymaqla yığının dərinliyini göstərir. Hər bir düzbucaqlı bir yığın çərçivəsidir. Çərçivə nə qədər geniş olsa, yığınlarda bir o qədər tez-tez olur. Üstündəkilər CPU-da işləyir, aşağıda olanlar isə uşaq elementlərdir. Rənglər adətən heç nə demək deyil, sadəcə olaraq çərçivələri fərqləndirmək üçün təsadüfi seçilir.
Təhlil - fərziyyə
Sazlama üçün biz boş CPU vaxtını tapmağa çalışacağıq. Biz faydasız xərclərin ən böyük mənbələrini axtaracağıq və onları aradan qaldıracağıq. Yaxşı, profilin tətbiqin prosessor vaxtını tam olaraq harada sərf etdiyini çox dəqiq şəkildə ortaya qoyduğunu nəzərə alsaq, bunu bir neçə dəfə etməli ola bilərsiniz, həmçinin tətbiqin mənbə kodunu dəyişdirməli, testləri təkrar keçirməli və performansın hədəfə yaxınlaşdığını görməli olacaqsınız.
Brendan Qreqin tövsiyələrinə əməl edərək, qrafiki yuxarıdan aşağı oxuyacağıq. Hər bir sətir yığın çərçivəsini (funksiya çağırışı) göstərir. Birinci sətir proqrama giriş nöqtəsidir, bütün digər zənglərin əsas hissəsidir (başqa sözlə, bütün digər zənglər öz yığınında olacaq). Növbəti sətir artıq fərqlidir:
Kursoru qrafikdəki funksiyanın adının üzərinə gətirsəniz, onun sazlama zamanı yığında olduğu ümumi vaxt göstəriləcək. HTTPServe funksiyası vaxtın 65%-də, digər iş vaxtı funksiyaları var idi runtime.mcall, mstart и gc, qalan vaxtını aldı. Əyləncəli fakt: ümumi vaxtın 5%-i DNS sorğularına sərf olunur:
Proqramın axtardığı ünvanlar Postgresql-ə aiddir. Basın FindByAge:
Maraqlıdır ki, proqram, prinsipcə, gecikmələri əlavə edən üç əsas mənbənin olduğunu göstərir: əlaqələri açmaq və bağlamaq, məlumat tələb etmək və verilənlər bazasına qoşulmaq. Qrafik göstərir ki, DNS sorğuları, bağlantıların açılması və bağlanması ümumi icra vaxtının təxminən 13%-ni təşkil edir.
Hipotez: Birləşmədən istifadə edərək əlaqələrin təkrar istifadəsi daha yüksək ötürmə qabiliyyətinə və daha az gecikməyə imkan verən tək HTTP sorğusunun vaxtını azaltmalıdır..
Tətbiqin qurulması - sınaq
Mənbə kodunu yeniləyirik, hər sorğu üçün Postgresql ilə əlaqəni aradan qaldırmağa çalışırıq. Birinci seçim istifadə etməkdir əlaqə hovuzu tətbiq səviyyəsində. Bu təcrübədə biz onu quraq getmək üçün sql sürücüsündən istifadə edərək əlaqənin birləşdirilməsi:
Testi saniyədə 1000 sorğu ilə yenidən başlatdıqdan sonra aydın olur ki, p99-un gecikmə səviyyələri 60 ms SLO ilə normal vəziyyətə qayıdır!
Xerci necedi?
Saniyədə 10000 sorğu / server başına 1000 sorğu = 10 server + 1
Gəlin bunu daha da yaxşı edək!
Saniyədə 2000 sorğu
Yükün ikiqat artması eyni şeyi göstərir, yuxarı sol qrafik proqramın saniyədə 2000 sorğu emal etməyi bacardığını göstərir, p100 60ms-dən aşağıdır, p99 SLO-nu təmin edir.
Xərc baxımından:
Saniyədə 10000 sorğu / server başına 2000 sorğu = 5 server + 1
Saniyədə 3000 sorğu
Burada proqram p3000 gecikmə müddəti 99 ms-dən az olan 60 sorğunu emal edə bilər. SLO pozulmur və xərc aşağıdakı kimi qəbul edilir:
Saniyədə 10000 3000 sorğu / server başına 4 1 sorğu = XNUMX server + XNUMX (müəllif tamamladı, təqribən. tərcüməçi)
Gəlin başqa bir təhlil mərhələsinə cəhd edək.
Təhlil - fərziyyə
Biz saniyədə 3000 sorğu ilə tətbiqin sazlanmasının nəticələrini toplayırıq və nümayiş etdiririk:
Hələ də vaxtın 6%-i əlaqələrin qurulmasına sərf olunur. Hovuzun qurulması performansı yaxşılaşdırdı, lakin siz hələ də proqramın verilənlər bazasına yeni bağlantılar yaratmaq üzərində işləməyə davam etdiyini görə bilərsiniz.
Hipotez: Bağlantılar, hovuzun olmasına baxmayaraq, hələ də atılır və təmizlənir, buna görə də proqram onları yenidən qurmalıdır. Gözləyən bağlantıların sayını hovuz ölçüsünə təyin etmək, tətbiqin əlaqə yaratmaq üçün sərf etdiyi vaxtı minimuma endirməklə gecikmə ilə kömək etməlidir..
Tətbiqin qurulması - sınaq
Quraşdırmağa çalışır MaxIdleConns hovuz ölçüsünə bərabərdir (həmçinin təsvir edilmişdir burada):
p99 əhəmiyyətli dərəcədə az p60 ilə 100ms-dən azdır!
Alov qrafikini yoxlamaq əlaqənin artıq nəzərə çarpmadığını göstərir! Daha ətraflı yoxlayaq pg(*conn).query - burada əlaqənin qurulduğunu da hiss etmirik.
Nəticə
Performans təhlili müştəri gözləntilərinin və qeyri-funksional tələblərin yerinə yetirildiyini başa düşmək üçün çox vacibdir. Müşahidələri müştəri gözləntiləri ilə müqayisə edərək təhlil nəyin məqbul, nəyin olmadığını müəyyən etməyə kömək edə bilər. Go analizi sadə və əlçatan edən standart kitabxanaya daxil edilmiş güclü alətlər təqdim edir.