SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Analisis dan penalaan prestasi ialah alat yang berkuasa untuk mengesahkan pematuhan prestasi untuk pelanggan.

Analisis prestasi boleh digunakan untuk menyemak kesesakan dalam program dengan menggunakan pendekatan saintifik untuk menguji eksperimen penalaan. Artikel ini mentakrifkan pendekatan umum untuk analisis dan penalaan prestasi, menggunakan pelayan web Go sebagai contoh.

Go sangat bagus di sini kerana ia mempunyai alat pemprofilan pprof dalam perpustakaan standard.

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

strategi

Mari buat senarai ringkasan untuk analisis struktur kami. Kami akan cuba menggunakan beberapa data untuk membuat keputusan dan bukannya membuat perubahan berdasarkan gerak hati atau tekaan. Untuk melakukan ini kami akan melakukan ini:

  • Kami menentukan sempadan pengoptimuman (keperluan);
  • Kami mengira beban transaksi untuk sistem;
  • Kami melakukan ujian (buat data);
  • Kami memerhati;
  • Kami menganalisis - adakah semua keperluan dipenuhi?
  • Kami menetapkannya secara saintifik, membuat hipotesis;
  • Kami melakukan eksperimen untuk menguji hipotesis ini.

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Seni Bina Pelayan HTTP Mudah

Untuk artikel ini kami akan menggunakan pelayan HTTP kecil di Golang. Semua kod daripada artikel ini boleh didapati di sini.

Aplikasi yang dianalisis ialah pelayan HTTP yang mengundi Postgresql untuk setiap permintaan. Selain itu, terdapat Prometheus, node_exporter dan Grafana untuk mengumpul dan memaparkan metrik aplikasi dan sistem.

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Untuk memudahkan, kami menganggap bahawa untuk penskalaan mendatar (dan memudahkan pengiraan) setiap perkhidmatan dan pangkalan data digunakan bersama:

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Menentukan matlamat

Pada langkah ini, kami memutuskan matlamat. Apa yang kita cuba analisis? Bagaimana kita tahu bila sudah tiba masanya untuk tamat? Dalam artikel ini, kami akan membayangkan bahawa kami mempunyai pelanggan dan perkhidmatan kami akan memproses 10 permintaan sesaat.

Π’ Buku Google SRE Kaedah pemilihan dan pemodelan dibincangkan secara terperinci. Mari kita lakukan perkara yang sama dan bina model:

  • Kependaman: 99% permintaan hendaklah diselesaikan dalam masa kurang daripada 60ms;
  • Kos: Perkhidmatan harus menggunakan jumlah minimum wang yang kami fikir adalah munasabah. Untuk melakukan ini, kami memaksimumkan daya pengeluaran;
  • Perancangan kapasiti: Memerlukan pemahaman dan mendokumentasikan bilangan contoh aplikasi yang perlu dijalankan, termasuk fungsi penskalaan keseluruhan dan bilangan kejadian yang diperlukan untuk memenuhi keperluan beban dan peruntukan awal lebihan n+1.

Kependaman mungkin memerlukan pengoptimuman sebagai tambahan kepada analisis, tetapi daya pengeluaran perlu dianalisis dengan jelas. Apabila menggunakan proses SRE SLO, permintaan kelewatan datang daripada pelanggan atau perniagaan, yang diwakili oleh pemilik produk. Dan perkhidmatan kami akan memenuhi kewajipan ini dari awal lagi tanpa sebarang tetapan!

Menyediakan persekitaran ujian

Dengan bantuan persekitaran ujian, kami akan dapat meletakkan beban terukur pada sistem kami. Untuk analisis, data tentang prestasi perkhidmatan web akan dijana.

Beban transaksi

Persekitaran ini menggunakan seperti tumbuh-tumbuhan untuk membuat kadar permintaan HTTP tersuai sehingga dihentikan:

$ 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

Pemerhatian

Beban transaksi akan digunakan pada masa jalan. Selain metrik aplikasi (bilangan permintaan, kependaman respons) dan sistem pengendalian (memori, CPU, IOPS), pemprofilan aplikasi akan dijalankan untuk memahami di mana ia menghadapi masalah dan cara masa CPU digunakan.

Pemprofilan

Pemprofilan ialah sejenis ukuran yang membolehkan anda melihat ke mana masa CPU berjalan apabila aplikasi sedang berjalan. Ia membolehkan anda menentukan dengan tepat di mana dan berapa banyak masa pemproses dibelanjakan:

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Data ini boleh digunakan semasa analisis untuk mendapatkan cerapan tentang masa CPU yang terbuang dan kerja yang tidak perlu dilakukan. Go (pprof) boleh menjana profil dan menggambarkannya sebagai graf nyala menggunakan set alat standard. Saya akan bercakap tentang panduan penggunaan dan persediaan mereka kemudian dalam artikel.

Pelaksanaan, pemerhatian, analisis.

Jom buat eksperimen. Kami akan melakukan, memerhati dan menganalisis sehingga kami berpuas hati dengan prestasi tersebut. Marilah kita memilih nilai beban rendah secara sewenang-wenangnya untuk menggunakannya untuk mendapatkan hasil pemerhatian pertama. Pada setiap langkah seterusnya kami akan meningkatkan beban dengan faktor penskalaan tertentu, dipilih dengan beberapa variasi. Setiap ujian beban dijalankan dengan bilangan permintaan dilaraskan: make load-test LOAD_TEST_RATE=X.

50 permintaan sesaat

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Beri perhatian kepada dua graf teratas. Bahagian atas sebelah kiri menunjukkan bahawa aplikasi kami memproses 50 permintaan sesaat (kiranya) dan bahagian atas sebelah kanan menunjukkan tempoh setiap permintaan. Kedua-dua parameter membantu kami melihat dan menganalisis sama ada kami berada dalam sempadan prestasi kami atau tidak. Garis merah pada graf Latensi Permintaan HTTP menunjukkan SLO pada 60ms. Garis menunjukkan bahawa kami berada jauh di bawah masa tindak balas maksimum kami.

Mari lihat bahagian kos:

10000 permintaan sesaat / 50 permintaan setiap pelayan = 200 pelayan + 1

Kami masih boleh menambah baik angka ini.

500 permintaan sesaat

Perkara yang lebih menarik mula berlaku apabila beban mencapai 500 permintaan sesaat:

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Sekali lagi, di bahagian atas graf kiri anda boleh melihat bahawa aplikasi sedang merekodkan beban biasa. Jika ini tidak berlaku, terdapat masalah pada pelayan di mana aplikasi sedang berjalan. Graf kependaman respons terletak di bahagian atas sebelah kanan, menunjukkan bahawa 500 permintaan sesaat mengakibatkan kelewatan respons selama 25-40ms. Persentil ke-99 masih sesuai dengan SLO 60ms yang dipilih di atas.

Dari segi kos:

10000 permintaan sesaat / 500 permintaan setiap pelayan = 20 pelayan + 1

Semuanya masih boleh diperbaiki.

1000 permintaan sesaat

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Pelancaran hebat! Aplikasi menunjukkan bahawa ia memproses 1000 permintaan sesaat, tetapi had kependaman telah dilanggar oleh SLO. Ini boleh dilihat dalam baris p99 dalam graf kanan atas. Walaupun pada hakikatnya garis p100 jauh lebih tinggi, kelewatan sebenar adalah lebih tinggi daripada maksimum 60ms. Mari kita selami pemprofilan untuk mengetahui apa sebenarnya yang dilakukan oleh aplikasi itu.

Pemprofilan

Untuk pemprofilan, kami menetapkan beban kepada 1000 permintaan sesaat, kemudian gunakan pprof untuk menangkap data untuk mengetahui di mana aplikasi menghabiskan masa CPU. Ini boleh dilakukan dengan mengaktifkan titik akhir HTTP pprof, dan kemudian, di bawah beban, simpan hasil menggunakan curl:

$ curl http://localhost:8080/debug/pprof/profile?seconds=29 > cpu.1000_reqs_sec_no_optimizations.prof

Hasilnya boleh dipaparkan seperti ini:

$ go tool pprof -http=:12345 cpu.1000_reqs_sec_no_optimizations.prof

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Graf menunjukkan di mana dan berapa banyak aplikasi menghabiskan masa CPU. Daripada penerangan daripada Brendan Gregg:

Paksi X ialah populasi profil tindanan, diisih mengikut abjad (ini bukan masa), paksi Y menunjukkan kedalaman tindanan, mengira dari sifar di [atas]. Setiap segi empat tepat ialah bingkai tindanan. Lebih lebar bingkai, lebih kerap ia hadir dalam susunan. Perkara di atas dijalankan pada CPU, dan perkara di bawah ialah elemen kanak-kanak. Warna biasanya tidak bermakna apa-apa, tetapi hanya dipilih secara rawak untuk membezakan bingkai.

Analisis - hipotesis

Untuk penalaan, kami akan menumpukan pada usaha mencari masa CPU yang terbuang. Kami akan mencari sumber terbesar perbelanjaan tidak berguna dan mengeluarkannya. Nah, memandangkan pemprofilan mendedahkan dengan sangat tepat di mana aplikasi menghabiskan masa pemprosesnya, anda mungkin perlu melakukannya beberapa kali, dan anda juga perlu menukar kod sumber aplikasi, menjalankan semula ujian dan melihat bahawa prestasi menghampiri sasaran.

Mengikut cadangan Brendan Gregg, kami akan membaca carta dari atas ke bawah. Setiap baris memaparkan bingkai tindanan (panggilan fungsi). Baris pertama ialah titik masuk ke dalam program, induk kepada semua panggilan lain (dengan kata lain, semua panggilan lain akan mempunyainya pada timbunan mereka). Baris seterusnya sudah berbeza:

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Jika anda menuding kursor pada nama fungsi pada graf, jumlah masa ia berada pada timbunan semasa nyahpepijat akan dipaparkan. Fungsi HTTPServe berada di sana 65% daripada masa, fungsi masa jalan yang lain runtime.mcall, mstart ΠΈ gc, mengambil masa yang selebihnya. Fakta menarik: 5% daripada jumlah masa dihabiskan untuk pertanyaan DNS:

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Alamat yang dicari oleh program adalah milik Postgresql. Klik pada FindByAge:

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Menariknya, program ini menunjukkan bahawa, pada dasarnya, terdapat tiga sumber utama yang menambah kelewatan: membuka dan menutup sambungan, meminta data, dan menyambung ke pangkalan data. Graf menunjukkan bahawa permintaan DNS, membuka dan menutup sambungan mengambil kira-kira 13% daripada jumlah masa pelaksanaan.

Hipotesis: Menggunakan semula sambungan menggunakan pengumpulan harus mengurangkan masa permintaan HTTP tunggal, membolehkan daya pemprosesan yang lebih tinggi dan kependaman yang lebih rendah.

Menyediakan aplikasi - percubaan

Kami mengemas kini kod sumber, cuba alih keluar sambungan ke Postgresql untuk setiap permintaan. Pilihan pertama ialah menggunakan kolam sambungan di peringkat permohonan. Dalam eksperimen ini kita mari kita setelkannya penyatuan sambungan menggunakan pemacu sql untuk pergi:

db, err := sql.Open("postgres", dbConnectionString)
db.SetMaxOpenConns(8)

if err != nil {
   return nil, err
}

Pelaksanaan, pemerhatian, analisis

Selepas memulakan semula ujian dengan 1000 permintaan sesaat, adalah jelas bahawa tahap kependaman p99 telah kembali normal dengan SLO 60ms!

Berapa kosnya?

10000 permintaan sesaat / 1000 permintaan setiap pelayan = 10 pelayan + 1

Mari kita lakukan dengan lebih baik!

2000 permintaan sesaat

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Menggandakan beban menunjukkan perkara yang sama, graf kiri atas menunjukkan bahawa aplikasi berjaya memproses 2000 permintaan sesaat, p100 lebih rendah daripada 60ms, p99 memenuhi SLO.

Dari segi kos:

10000 permintaan sesaat / 2000 permintaan setiap pelayan = 5 pelayan + 1

3000 permintaan sesaat

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Di sini aplikasi boleh memproses 3000 permintaan dengan kependaman p99 kurang daripada 60ms. SLO tidak dilanggar, dan kosnya diterima seperti berikut:

10000 permintaan sesaat / setiap 3000 permintaan setiap pelayan = 4 pelayan + 1 (pengarang telah mengumpul, lebih kurang penterjemah)

Mari cuba satu lagi pusingan analisis.

Analisis - hipotesis

Kami mengumpul dan memaparkan hasil penyahpepijatan aplikasi pada 3000 permintaan sesaat:

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Masih 6% daripada masa dibelanjakan untuk mewujudkan sambungan. Penyediaan kumpulan telah meningkatkan prestasi, tetapi anda masih dapat melihat bahawa aplikasi terus berfungsi untuk mencipta sambungan baharu ke pangkalan data.

Hipotesis: Sambungan, walaupun terdapat kolam, masih digugurkan dan dibersihkan, jadi aplikasi perlu menetapkannya semula. Menetapkan bilangan sambungan yang belum selesai kepada saiz kolam akan membantu dengan kependaman dengan meminimumkan masa yang digunakan oleh aplikasi untuk membuat sambungan.

Menyediakan aplikasi - percubaan

Cuba pasang MaxIdleConns sama dengan saiz kolam (juga diterangkan di sini):

db, err := sql.Open("postgres", dbConnectionString)
db.SetMaxOpenConns(8)
db.SetMaxIdleConns(8)
if err != nil {
   return nil, err
}

Pelaksanaan, pemerhatian, analisis

3000 permintaan sesaat

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

p99 kurang daripada 60ms dengan p100 kurang ketara!

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Memeriksa graf nyalaan menunjukkan bahawa sambungan tidak lagi ketara! Mari semak dengan lebih terperinci pg(*conn).query β€” kami juga tidak perasan sambungan diwujudkan di sini.

SRE: Analisis Prestasi. Kaedah konfigurasi menggunakan pelayan web ringkas dalam Go

Kesimpulan

Analisis prestasi adalah penting untuk memahami bahawa jangkaan pelanggan dan keperluan tidak berfungsi sedang dipenuhi. Analisis dengan membandingkan pemerhatian dengan jangkaan pelanggan boleh membantu menentukan apa yang boleh diterima dan apa yang tidak. Go menyediakan alatan berkuasa terbina dalam pustaka standard yang menjadikan analisis mudah dan boleh diakses.

Sumber: www.habr.com

Tambah komen