Rumah > Artikel > Tutorial sistem > Kaedah peningkatan prestasi pelayan web
Pengenalan | Dengan perkembangan Internet yang berterusan, semakin banyak keperluan dalam kehidupan seharian direalisasikan melalui Internet Daripada makanan, pakaian, perumahan dan pengangkutan kepada pendidikan kewangan, dari poket kepada identiti, orang ramai bergantung pada Internet sepanjang masa, dan. semakin ramai orang menggunakan Internet untuk memenuhi keperluan mereka sendiri. |
Sebagai pelayan web yang secara langsung menghadapi permintaan daripada pelanggan, ia sudah pasti perlu menahan lebih banyak permintaan pada masa yang sama dan memberikan pengguna pengalaman yang lebih baik. Pada masa ini, prestasi bahagian web sering menjadi halangan untuk pembangunan perniagaan, dan adalah penting untuk meningkatkan prestasi. Penulis artikel ini meringkaskan beberapa pengalaman dalam meningkatkan prestasi pelayan Web semasa proses pembangunan dan berkongsinya dengan semua orang.
Analisis MasalahUntuk prestasi pelayan Web, mula-mula kami menganalisis penunjuk yang berkaitan. Dari perspektif pengguna, apabila pengguna memanggil perkhidmatan Web, lebih pendek masa pemulangan permintaan, lebih baik pengalaman pengguna. Dari perspektif pelayan, semakin banyak bilangan permintaan pengguna yang boleh dibawa pada masa yang sama, semakin kuat prestasi pelayan. Menggabungkan kedua-dua aspek, kami meringkaskan dua arah pengoptimuman prestasi:
1. Tingkatkan bilangan maksimum permintaan serentak yang boleh disokong oleh pelayan
2. Meningkatkan kelajuan pemprosesan setiap permintaan.
Arah pengoptimuman diperjelaskan Pertama, kami memperkenalkan corak seni bina biasa pada bahagian pelayan, iaitu, permintaan Web daripada penyemak imbas atau Apl diproses dan dikembalikan melalui beberapa lapisan struktur di bahagian pelayan.
Mod seni bina: Imbangan beban IP->pelayan cache->proksi terbalik->pelayan aplikasi->pangkalan data
Seperti yang ditunjukkan dalam Rajah 1, untuk kemudahan penjelasan, mari berikan contoh praktikal: LVS(Keepalived)->Squid->nginx->Go->MySQL
Rajah 1: Seni bina sisi pelayan
Kami mengedarkan permintaan pada setiap lapisan, supaya berbilang cabang struktur peringkat rendah boleh berfungsi pada masa yang sama untuk meningkatkan jumlah maksimum keseluruhan mata wang.
Digabungkan dengan seni bina, kami akan menganalisis masalah yang biasanya menghalang prestasi dan mencari penyelesaian yang sepadan.
Dalam keadaan biasa, pengimbangan beban IP, pelayan cache dan lapisan proksi nginx adalah terutamanya isu kestabilan kelompok. Tempat yang sering berlaku kesesakan prestasi adalah pada lapisan pelayan aplikasi dan lapisan pangkalan data Mari senaraikan beberapa contoh di bawah:
1. Kesan halangan(1) Soalan:
Kebanyakan permintaan web bersifat menyekat Apabila permintaan diproses, proses akan digantung (menduduki CPU) sehingga permintaan selesai. Dalam kebanyakan kes, permintaan web selesai dengan cukup cepat sehingga masalah ini tidak menjadi kebimbangan. Walau bagaimanapun, bagi permintaan yang mengambil masa yang lama untuk diselesaikan (seperti permintaan yang mengembalikan sejumlah besar data atau API luaran), ini bermakna aplikasi dikunci sehingga tamat pemprosesan Dalam tempoh ini, permintaan lain tidak akan diproses. dan adalah jelas bahawa ini adalah tidak sah Masa menunggu adalah sia-sia dan sumber sistem diduduki, serius menjejaskan bilangan permintaan serentak yang kita mampu.
(2) Penyelesaian:
Sementara pelayan web sedang menunggu permintaan sebelumnya untuk diproses, kami boleh membiarkan gelung I/O terbuka untuk memproses permintaan aplikasi lain sehingga pemprosesan selesai, mulakan permintaan dan berikan maklum balas, bukannya tergantung sementara menunggu permintaan untuk diselesaikan. Dengan cara ini, kami boleh menjimatkan masa menunggu yang tidak perlu dan menggunakan masa ini untuk memproses lebih banyak permintaan, supaya kami dapat meningkatkan daya pemprosesan permintaan dengan banyak, yang bermaksud meningkatkan secara makroskopik bilangan permintaan serentak yang boleh kami kendalikan.
(3) Contoh
Di sini kami menggunakan Tornado, rangka kerja web Python, untuk menerangkan secara khusus cara menukar kaedah penyekatan untuk meningkatkan prestasi serentak.
Senario: Kami membina aplikasi web ringkas yang menghantar permintaan HTTP ke hujung jauh (laman web yang sangat stabil). Dalam tempoh ini, penghantaran rangkaian adalah stabil dan kami tidak mengambil kira kesan rangkaian.
Dalam contoh ini, kami menggunakan Siege (perisian ujian tekanan) untuk melaksanakan kira-kira 10 permintaan serentak dalam 10 saat pada pelayan.
Seperti yang ditunjukkan dalam Rajah 2, kita boleh melihat dengan mudah bahawa masalah di sini ialah tidak kira berapa cepat setiap permintaan itu sendiri kembali, permintaan akses pergi-balik pelayan ke hujung terpencil akan menghasilkan lag yang cukup besar, kerana proses tidak menunggu. sehingga permintaan selesai dan datanya Ia sentiasa dalam keadaan penggantungan paksa sebelum diproses. Ini belum menjadi masalah dengan satu atau dua permintaan, tetapi apabila anda mencapai 100 (atau 10) pengguna, ini bermakna kelembapan keseluruhan. Seperti yang ditunjukkan dalam rajah, purata masa tindak balas 10 pengguna serupa dalam masa kurang daripada 10 saat mencapai 1.99 saat, sebanyak 29 kali. Contoh ini hanya menunjukkan logik yang sangat mudah. Jika anda menambah logik perniagaan atau panggilan pangkalan data lain, hasilnya akan menjadi lebih teruk. Apabila lebih banyak permintaan pengguna ditambahkan, bilangan permintaan yang boleh diproses pada masa yang sama akan berkembang dengan perlahan, malah sesetengah permintaan mungkin tamat masa atau gagal.
Rajah 2: Menyekat tindak balas
Di bawah ini kami menggunakan Tornado untuk melaksanakan permintaan HTTP yang tidak menyekat.
Seperti yang ditunjukkan dalam Rajah 3, kami bertukar daripada 3.20 transaksi sesaat kepada 12.59, memberikan sejumlah 118 permintaan dalam jumlah masa yang sama. Ini benar-benar peningkatan yang besar! Seperti yang anda boleh bayangkan, apabila permintaan pengguna meningkat dan masa ujian meningkat, ia akan dapat menyediakan lebih banyak sambungan tanpa mengalami kelembapan yang dialami oleh versi di atas. Ini secara berterusan meningkatkan bilangan permintaan serentak yang boleh dimuatkan.
Amalan peningkatan prestasi pelayan web
Rajah 3: Tindak balas tidak menyekat
2. Kesan kecekapan pengkomputeran pada masa tindak balas dan bilangan mata wangPertama, mari perkenalkan pengetahuan asas: aplikasi ialah proses yang dijalankan pada mesin; Satu proses terdiri daripada satu atau lebih utas sistem pengendalian ini sebenarnya badan pelaksanaan yang berfungsi bersama dan berkongsi ruang alamat memori yang sama.
(1) Soalan
Kaedah pengkomputeran tradisional berjalan dalam satu utas, yang mempunyai kecekapan rendah dan kuasa pengkomputeran yang lemah.
(2) Penyelesaian
Satu penyelesaian adalah untuk mengelak menggunakan benang sama sekali. Sebagai contoh, anda boleh menggunakan berbilang proses untuk memunggah beban ke sistem pengendalian. Walau bagaimanapun, kelemahannya ialah kita perlu mengendalikan semua komunikasi antara proses, yang biasanya mempunyai lebih banyak overhed daripada model konkurensi memori kongsi.
Cara lain ialah menggunakan multi-threading untuk berfungsi Walau bagaimanapun, diakui bahawa aplikasi yang menggunakan multi-threading adalah sukar untuk tepat, menyegerakkan thread yang berbeza dan mengunci data, supaya hanya satu thread boleh menukar data pada masa yang sama. masa. Walau bagaimanapun, pengalaman pembangunan perisian yang lalu memberitahu kami bahawa ini akan membawa kerumitan yang lebih tinggi, kod yang lebih terdedah kepada ralat dan prestasi yang lebih rendah.
Masalah utama ialah perkongsian data dalam ingatan, yang akan dikendalikan dalam cara yang tidak dapat diramalkan oleh berbilang benang, yang membawa kepada beberapa keputusan yang tidak boleh dibuat semula atau rawak (dipanggil "keadaan perlumbaan"). Jadi pendekatan klasik ini jelas tidak lagi sesuai untuk pengaturcaraan berbilang teras/berbilang pemproses moden: model benang setiap sambungan tidak cukup cekap. Di antara banyak paradigma yang sesuai, terdapat satu yang dipanggil Proses Berjujukan Berkomunikasi (CSP, dicipta oleh C. Hoare) dan satu yang dipanggil model penghantaran mesej (sudah digunakan dalam bahasa lain , seperti Erlang).
Kaedah yang kami gunakan di sini ialah menggunakan seni bina selari untuk memproses tugasan Program serentak boleh menggunakan berbilang benang untuk melaksanakan tugas pada pemproses atau teras, tetapi hanya program yang sama boleh dijalankan pada berbilang teras atau berbilang pemproses pada titik tertentu. dalam masa.
Paralelisme ialah keupayaan untuk meningkatkan kelajuan dengan menggunakan berbilang pemproses. Jadi program serentak boleh selari atau tidak.
Mod selari boleh menggunakan berbilang benang, berbilang teras, berbilang pemproses, dan juga berbilang komputer pada masa yang sama Ini sudah pasti boleh menggerakkan lebih banyak sumber, dengan itu memampatkan masa tindak balas, meningkatkan kecekapan pengkomputeran dan meningkatkan prestasi pelayan. .
(3) Contoh
Berikut ialah penjelasan terperinci menggunakan Goroutine dalam bahasa Go.
Dalam bahasa Go, bahagian pemprosesan serentak aplikasi dipanggil goroutine (coroutines), yang boleh melakukan operasi serentak yang lebih cekap. Tiada hubungan satu-dengan-satu antara coroutine dan urutan sistem pengendalian: coroutine dipetakan (multipleks, dilaksanakan pada) satu atau lebih urutan berdasarkan ketersediaannya penjadual coroutine The Go menjalankan tugas ini dengan baik. Coroutine adalah ringan, lebih ringan daripada benang. Ia sangat tidak mencolok (dan menggunakan sejumlah kecil memori dan sumber): ia boleh dibuat dalam timbunan menggunakan hanya 4K memori tindanan. Kerana ia sangat murah untuk dibuat, mudah untuk mencipta dan menjalankan sejumlah besar coroutine (100,000 coroutine berturut-turut dalam ruang alamat yang sama) jika perlu. Dan mereka membahagikan tindanan untuk meningkatkan (atau mengurangkan) penggunaan memori secara dinamik, pengurusan tindanan adalah automatik, tetapi tidak diuruskan oleh pemungut sampah, tetapi dikeluarkan secara automatik selepas coroutine keluar. Coroutine boleh dijalankan antara berbilang rangkaian sistem pengendalian atau dalam rangkaian, membolehkan anda memproses sejumlah besar tugas dengan jejak memori yang kecil. Terima kasih kepada penghirisan masa coroutine pada urutan sistem pengendalian, anda boleh mempunyai seberapa banyak coroutine yang anda mahu menggunakan sebilangan kecil urutan sistem pengendalian, dan masa jalanan Go boleh menjadi pintar tentang coroutine yang disekat dan menahannya dan mengendalikan yang lain coroutine. Malah program boleh melaksanakan segmen kod yang berbeza secara serentak pada pemproses dan komputer yang berbeza.
Kami biasanya ingin membahagikan proses pengiraan yang panjang kepada beberapa bahagian, dan kemudian biarkan setiap goroutine bertanggungjawab untuk sesuatu kerja, supaya masa tindak balas untuk satu permintaan boleh digandakan.
Sebagai contoh, terdapat tugas yang dibahagikan kepada 3 peringkat Peringkat a pergi ke pangkalan data a untuk mengambil data, peringkat b pergi ke pangkalan data b untuk mengambil data, dan peringkat c menggabungkan data dan mengembalikannya. Selepas kita memulakan goroutine, fasa a dan b boleh dijalankan bersama-sama, yang sangat memendekkan masa tindak balas.
Secara terang-terangan, sebahagian daripada proses pengiraan ditukar daripada bersiri kepada selari Sesuatu tugasan tidak perlu menunggu tugasan lain yang tidak berkaitan untuk menyelesaikan pelaksanaan program yang selari akan menjadi lebih berguna dalam pengiraan sebenar.
Saya tidak akan menerangkan secara terperinci tentang bahagian data sokongan ini di sini. Pelajar yang berminat boleh melihat sendiri maklumat ini. Sebagai contoh, kisah lama tentang peningkatan prestasi sebanyak 15 kali apabila pelayan web ditukar daripada Ruby kepada Go (Ruby menggunakan benang hijau, iaitu hanya satu CPU digunakan). Walaupun cerita ini mungkin agak dibesar-besarkan, tidak ada keraguan tentang keuntungan prestasi yang dibawa oleh paralelisme. (Ruby bertukar kepada Go: http://www.vaikan.com/how-we-went-from-30-servers-to-2-go/).
3. Kesan cakera I/O pada prestasi(1) Soalan
Membaca data dari cakera bergantung pada pergerakan mekanikal Masa yang dihabiskan setiap kali membaca data boleh dibahagikan kepada tiga bahagian: masa mencari, kelewatan putaran dan masa penghantaran merujuk kepada masa yang diperlukan untuk lengan magnet bergerak ke trek masa yang ditentukan, cakera arus perdana biasanya di bawah 5ms kelewatan putaran adalah kelajuan cakera yang sering kita dengar. dan kelewatan putaran ialah 1/ 120/2 = 4.17ms masa penghantaran merujuk kepada masa untuk membaca dari cakera atau menulis data ke cakera, secara amnya beberapa persepuluh milisaat, yang boleh diabaikan berbanding dengan dua kali pertama. Kemudian masa untuk mengakses cakera, iaitu, masa untuk mengakses cakera I/O ialah kira-kira 9ms (5ms+4.17ms), yang kedengarannya agak bagus, tetapi anda mesti tahu bahawa mesin 500-MIPS boleh melaksanakan 500 juta item sesaat. Arahan, kerana arahan bergantung pada sifat elektrik, dengan kata lain, ia memerlukan 400,000 arahan untuk melaksanakan satu I/O Pangkalan data selalunya mengandungi ratusan ribu, berjuta-juta atau bahkan berpuluh-puluh juta data, dan setiap kali ia mengambil masa 9 milisaat, ia jelas satu bencana.
(2) Penyelesaian
Tiada penyelesaian asas kepada kesan I/O cakera pada prestasi pelayan, melainkan anda membuang cakera dan menggantikannya dengan sesuatu yang lain. Kami boleh mencari kelajuan tindak balas dan harga pelbagai media storan dalam talian Jika anda mempunyai wang, anda boleh menukar media storan sesuka hati.
Tanpa menukar medium storan, kami boleh mengurangkan bilangan akses cakera oleh aplikasi, seperti menyediakan cache, dan kami juga boleh meletakkan beberapa cakera I/O di luar kitaran permintaan, seperti menggunakan baris gilir dan tindanan untuk memproses data I /O. O et al.
4. Optimumkan pertanyaan pangkalan dataDengan perubahan dalam model pembangunan perniagaan, pembangunan tangkas diterima pakai oleh semakin banyak pasukan, dan kitaran semakin pendek dan banyak pernyataan pertanyaan pangkalan data ditulis mengikut logik perniagaan Dari masa ke masa, format pertanyaan SQL sering diabaikan . masalah, menyebabkan peningkatan tekanan pada pangkalan data dan memperlahankan tindak balas kepada pertanyaan pangkalan data. Berikut ialah pengenalan ringkas kepada beberapa masalah biasa dan kaedah pengoptimuman yang telah kami abaikan dalam pangkalan data MySQL:
Prinsip padanan awalan paling kiri ialah prinsip yang sangat penting MySQL akan terus memadankan ke kanan sehingga ia menemui pertanyaan julat (>, 3 dan d = 4 Jika anda mencipta indeks dalam susunan (a, b, c, d), indeks d tidak akan digunakan Jika anda mencipta indeks (a, b, d, c), anda boleh menggunakan kedua-dua a dan b , susunan d boleh dilaraskan sewenang-wenangnya.
Cuba pilih lajur dengan perbezaan yang tinggi sebagai indeks Formula untuk pembezaan ialah count(distinct col)/count(*), yang mewakili bahagian medan yang tidak diulang, semakin sedikit rekod yang diimbas kunci unik ialah 1. Sesetengah medan status dan jantina mungkin mempunyai perbezaan 0 dalam menghadapi data besar Kemudian seseorang mungkin bertanya, adakah nisbah ini mempunyai nilai empirikal? Senario penggunaan yang berbeza menjadikan nilai ini sukar ditentukan Secara amnya, kami memerlukan medan yang perlu dicantumkan melebihi 0.1, iaitu purata 10 rekod akan diimbas setiap satu.
Cuba gunakan medan angka Jika medan mengandungi maklumat berangka sahaja, cuba jangan reka bentuknya sebagai medan aksara Ini akan mengurangkan prestasi pertanyaan dan sambungan, dan meningkatkan overhed storan. Ini kerana enjin akan membandingkan setiap aksara dalam rentetan satu demi satu apabila memproses pertanyaan dan sambungan, dan hanya satu perbandingan yang mencukupi untuk jenis angka.
Lajur indeks tidak boleh mengambil bahagian dalam pengiraan. Pastikan lajur itu "bersih". dalam jadual data, tetapi Apabila mendapatkan semula, anda perlu menggunakan fungsi pada semua elemen untuk dibandingkan, yang jelas terlalu mahal. Oleh itu, pernyataan harus ditulis sebagai create_time = unix_timestamp('2014-05-29'); Cuba elakkan pertimbangan nilai nol pada medan dalam klausa where, jika tidak enjin akan berhenti menggunakannya.
Lakukan imbasan jadual penuh menggunakan indeks, seperti:
pilih id daripada t di mana nombor adalah batal
Anda boleh menetapkan nilai lalai 0 pada num, pastikan tiada nilai nol dalam lajur num dalam jadual, dan kemudian bertanya seperti ini:
pilih id daripada t di mana num=0
Cuba elakkan menggunakan atau dalam klausa tempat untuk memautkan keadaan, jika tidak enjin akan berhenti menggunakan indeks dan melakukan imbasan jadual penuh, seperti:
pilih id daripada t di mana num=10 atau num=20
Anda boleh bertanya seperti ini:
pilih id daripada t di mana num=10 kesatuan semua pilih id daripada t di mana num=20
Pertanyaan berikut juga akan menghasilkan imbasan jadual penuh (tiada tanda peratus pendahuluan):
pilih id daripada t di mana nama seperti '%abc%'
Untuk meningkatkan kecekapan, pertimbangkan carian teks penuh.
In dan not in juga harus digunakan dengan berhati-hati, jika tidak, ia akan membawa kepada imbasan jadual penuh, seperti:
pilih id daripada t di mana num dalam(1,2,3)
Untuk nilai berterusan, jangan gunakan in jika anda boleh menggunakan antara:
pilih id daripada t di mana nombor antara 1 dan 3
Atas ialah kandungan terperinci Kaedah peningkatan prestasi pelayan web. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!