Tuning Kinerja Server Apache Beban Tinggi

12

Saya ingin memahami beberapa masalah kinerja server yang saya lihat dengan server web (untuk kami) yang sarat muatan. Lingkungan adalah sebagai berikut:

  • Debian Lenny (semua paket stabil + di-patch ke pembaruan keamanan)
  • Apache 2.2.9
  • PHP 5.2.6
  • Amazon EC2 contoh besar

Perilaku yang kami lihat adalah bahwa web biasanya merasa responsif, tetapi dengan sedikit keterlambatan untuk mulai menangani permintaan - terkadang sepersekian detik, kadang-kadang 2-3 detik pada waktu penggunaan puncak kami. Beban aktual di server dilaporkan sangat tinggi - sering 10.xx atau 20.xx seperti yang dilaporkan oleh top. Lebih jauh lagi, menjalankan hal-hal lain di server selama waktu ini (bahkan vi) sangat lambat, sehingga bebannya pasti ada di sana. Anehnya Apache tetap sangat responsif, selain itu keterlambatan awal.

Kami telah mengkonfigurasi Apache sebagai berikut, menggunakan prefork:

StartServers          5
MinSpareServers       5
MaxSpareServers      10
MaxClients          150
MaxRequestsPerChild   0

Dan KeepAlive sebagai:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

Melihat halaman status server, bahkan pada saat-saat beban berat ini kita jarang memukul batas klien, biasanya melayani antara 80-100 permintaan dan banyak dari mereka dalam keadaan keepalive. Itu memberitahu saya untuk mengesampingkan kelambatan permintaan awal sebagai "menunggu penangan" tapi saya mungkin salah.

Pemantauan CloudWatch Amazon memberi tahu saya bahwa bahkan ketika OS kami melaporkan beban> 15, utilisasi CPU kami antara 75-80%.

Contoh output dari top:

top - 15:47:06 up 31 days,  1:38,  8 users,  load average: 11.46, 7.10, 6.56
Tasks: 221 total,  28 running, 193 sleeping,   0 stopped,   0 zombie
Cpu(s): 66.9%us, 22.1%sy,  0.0%ni,  2.6%id,  3.1%wa,  0.0%hi,  0.7%si,  4.5%st
Mem:   7871900k total,  7850624k used,    21276k free,    68728k buffers
Swap:        0k total,        0k used,        0k free,  3750664k cached

Sebagian besar prosesnya terlihat seperti:

24720 www-data  15   0  202m  26m 4412 S    9  0.3   0:02.97 apache2                                                                       
24530 www-data  15   0  212m  35m 4544 S    7  0.5   0:03.05 apache2                                                                       
24846 www-data  15   0  209m  33m 4420 S    7  0.4   0:01.03 apache2                                                                       
24083 www-data  15   0  211m  35m 4484 S    7  0.5   0:07.14 apache2                                                                       
24615 www-data  15   0  212m  35m 4404 S    7  0.5   0:02.89 apache2            

Contoh output dari vmstatpada saat yang sama seperti di atas:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 8  0      0 215084  68908 3774864    0    0   154   228    5    7 32 12 42  9
 6 21      0 198948  68936 3775740    0    0   676  2363 4022 1047 56 16  9 15
23  0      0 169460  68936 3776356    0    0   432  1372 3762  835 76 21  0  0
23  1      0 140412  68936 3776648    0    0   280     0 3157  827 70 25  0  0
20  1      0 115892  68936 3776792    0    0   188     8 2802  532 68 24  0  0
 6  1      0 133368  68936 3777780    0    0   752    71 3501  878 67 29  0  1
 0  1      0 146656  68944 3778064    0    0   308  2052 3312  850 38 17 19 24
 2  0      0 202104  68952 3778140    0    0    28    90 2617  700 44 13 33  5
 9  0      0 188960  68956 3778200    0    0     8     0 2226  475 59 17  6  2
 3  0      0 166364  68956 3778252    0    0     0    21 2288  386 65 19  1  0

Dan akhirnya, output dari Apache server-status:

Server uptime: 31 days 2 hours 18 minutes 31 seconds
Total accesses: 60102946 - Total Traffic: 974.5 GB
CPU Usage: u209.62 s75.19 cu0 cs0 - .0106% CPU load
22.4 requests/sec - 380.3 kB/second - 17.0 kB/request
107 requests currently being processed, 6 idle workers

C.KKKW..KWWKKWKW.KKKCKK..KKK.KKKK.KK._WK.K.K.KKKKK.K.R.KK..C.C.K
K.C.K..WK_K..KKW_CK.WK..W.KKKWKCKCKW.W_KKKKK.KKWKKKW._KKK.CKK...
KK_KWKKKWKCKCWKK.KKKCK..........................................
................................................................

Dari pengalaman saya yang terbatas, saya menarik kesimpulan / pertanyaan berikut:

  • Kami mungkin mengizinkan terlalu banyak KeepAlivepermintaan

  • Saya melihat beberapa waktu yang dihabiskan menunggu IO di vmstat walaupun tidak konsisten dan tidak banyak (saya pikir?) Jadi saya tidak yakin ini adalah masalah besar atau tidak, saya kurang berpengalaman dengan vmstat

  • Juga di vmstat, saya melihat di beberapa iterations sejumlah proses menunggu untuk dilayani, yang saya maksudkan dengan keterlambatan pemuatan halaman awal pada server web kami, mungkin secara keliru

  • Kami menyajikan campuran konten statis (75% atau lebih tinggi) dan konten skrip, dan konten skrip sering kali cukup intensif prosesor, sehingga menemukan keseimbangan yang tepat antara keduanya adalah penting; jangka panjang kami ingin memindahkan statika di tempat lain untuk mengoptimalkan kedua server tetapi perangkat lunak kami belum siap untuk itu hari ini

Saya senang memberikan informasi tambahan jika ada yang punya ide, catatan lainnya adalah ini adalah instalasi produksi ketersediaan tinggi jadi saya khawatir membuat tweak setelah tweak, dan itulah sebabnya saya belum bermain dengan hal-hal seperti KeepAlivenilai sendiri namun.

masa depan
sumber
+1 pertanyaan besar yang berdarah, kata-kata yang baik dan dipikirkan. Semoga Anda mendapatkan jawaban yang layak!
Dave Rix

Jawaban:

7

Saya akan mulai dengan mengakui bahwa saya tidak banyak tentang menjalankan hal-hal di awan - tetapi berdasarkan pengalaman saya di tempat lain, saya akan mengatakan bahwa konfigurasi server web ini mencerminkan volume lalu lintas yang cukup rendah. Bahwa runqueue sangat besar menunjukkan bahwa tidak ada cukup CPU yang tersedia untuk menghadapinya. Apa lagi yang ada di runqueue?

Kami mungkin mengizinkan terlalu banyak permintaan KeepAlive

Tidak - keeplive masih meningkatkan kinerja, peramban modern sangat pandai mengetahui kapan harus mengirim pipa dan kapan menjalankan permintaan secara paralel, meskipun batas waktu 5 detik masih agak tinggi, dan Anda punya BANYAK server yang menunggu - kecuali jika Anda ' punya masalah latensi BESAR Saya akan merekomendasikan cranking ke 2-3. Ini harus mempersingkat runqueue sedikit.

Jika Anda belum menginstal mod_deflate di server web - maka saya sarankan Anda melakukannya - dan tambahkan ob_gzhandler () ke skrip PHP Anda. Anda dapat melakukan ini sebagai otomatis digantungkan:

if(!ob_start("ob_gzhandler")) ob_start();

(ya, copression menggunakan lebih banyak CPU - tetapi Anda harus menyimpan CPU secara keseluruhan dengan membuat server keluar dari runqueue lebih cepat / menangani lebih sedikit paket TCP - dan sebagai bonus, situs Anda juga lebih cepat).

Saya akan merekomendasikan pengaturan batas atas pada MaxRequestsPerChild - katakan sesuatu seperti 500. Ini hanya memungkinkan beberapa pergantian proses jika Anda memiliki kebocoran memori di suatu tempat. Proses httpd Anda terlihat BESAR - pastikan Anda telah menghapus modul apache yang tidak Anda butuhkan dan pastikan Anda menyajikan konten statis dengan informasi caching yang baik.

Jika Anda masih melihat masalah, maka masalahnya mungkin dalam kode PHP (jika Anda beralih menggunakan fastCGI, ini harus jelas tanpa penalti kinerja utama).

memperbarui

Jika konten statis tidak banyak berbeda di seluruh halaman, maka mungkin layak untuk bereksperimen dengan:

if (count($_COOKIE)) {
    header('Connection: close');
}

pada skrip PHP juga.

symcbean
sumber
Di antara berbagai jawaban yang baik saya menandai ini sebagai yang diterima karena Anda dengan jelas menyatakan bahwa ini adalah masalah yang terikat CPU (sebagian besar disebabkan oleh aplikasi yang buruk yang kami jalankan) dan itu memang benar. Saya menggunakan kembali semuanya pada instance EC2 2xlarge (naik dari besar) dan sebagian besar masalah hilang, meskipun banyak karakteristik kinerja lainnya masih ada. Kami hanya memiliki satu aplikasi berjalan di server ini, dan itu hanya jelek.
futureal
4

Anda harus mempertimbangkan menginstal proxy terbalik asinkron, karena sejumlah proses dalam status W juga cukup tinggi. Proses Apache Anda tampaknya menghabiskan banyak waktu mengirimkan konten untuk memperlambat klien melalui jaringan yang diblokir karenanya. Nginx atau lighttpd sebagai frontend ke server Apache Anda dapat mengurangi sejumlah proses dalam kondisi W secara dramatis. Dan ya, Anda harus membatasi sejumlah permintaan keepalive. Mungkin ada baiknya mencoba mematikan keepalive.

BTW, 107 proses Apache terlalu tinggi untuk 22 rps, saya bisa melayani 100-120 rps hanya menggunakan 5 proses Apache. Mungkin, langkah selanjutnya adalah membuat profil aplikasi Anda.

Alex
sumber
Ya, pasti setuju bahwa aplikasi adalah sebagian besar masalah. Itu outsourcing dan sejak itu menjadi sasaran banyak tambalan dan lainnya yang hanya membuatnya lebih buruk, dan upaya mendesain ulang sedang berlangsung. Saya lakukan malam ini mencoba mematikan KeepAlive tanpa efek nyata, dan langkah berikutnya adalah mencoba proxy terbalik, mungkin dengan nginx berdasarkan semua yang telah saya baca.
futureal
Untuk menindaklanjutinya, saya telah mulai bereksperimen dengan proksi terbalik dan mungkin akan menggunakannya dalam produksi dalam waktu dekat. Terima kasih (dan yang lain yang menyarankannya) untuk ide itu, itu bukan sesuatu yang pernah saya mainkan sebelumnya, tetapi saya pikir itu akan berdampak sampai kita dapat melakukan desain ulang sepenuhnya.
futureal
1

Anda memiliki dua baris di vmstat Anda yang menunjukkan waktu tunggu CPU Anda cukup tinggi, dan di sekitar itu, Anda melakukan cukup banyak penulisan (io - bo) dan pengalihan konteks. Saya akan melihat apa yang menulis blok, dan bagaimana menghilangkan menunggu itu. Saya pikir peningkatan yang paling dapat ditemukan dalam meningkatkan IO disk Anda. Periksa syslog - atur untuk menulis async. Pastikan cache tulis pengontrol Anda berfungsi (periksa - Anda mungkin memiliki baterai yang buruk).

Keepalive tidak menyebabkan masalah kinerja Anda, ini menghemat waktu Anda pada pengaturan koneksi jika Anda tidak menjalankan cache di depan. Anda mungkin sedikit menabrak MaxSpareServers sehingga dalam krisis Anda tidak menunggu semua garpu.

kacang polong
sumber
Saya tidak cukup akrab dengan syslog untuk mengetahui bagaimana mengaturnya untuk menulis asinkron di bawah Apache, walaupun saya pasti akan mencari dan mencari itu. Saya memang membuat beberapa perubahan malam ini terkait dengan KeepAlive dan MaxSpareServers tanpa efek nyata, saya setuju tentang membiarkan lebih banyak suku cadang, saya melewatkannya. Salah satu (buruk) kualitas aplikasi kami adalah ia menulis banyak ke file sesi pengguna (ya, file) yang mana saya mulai berpikir kita menderita. Saya memiliki opsi untuk memindahkan manajemen sesi ke basis data, yang kemungkinan akan saya coba berikutnya.
Futureal
Ya, saya setuju bahwa penulisan sesi Anda adalah sumber masalahnya. Anda dapat kehilangan disk sesi menulis jika Anda menggunakan sesi php - instal memcache, dan atur sesi PHP.save_handler untuk memcache, dan session.save_path ke tcp : //127.0.0.1: 11211 (atau di mana pun Anda mengatur memcache). Logging Apache async secara default, tetapi kadang-kadang aplikasi web dapat menggunakan syslog, atau syslog bisa mengobrol dan itu melakukan sinkronisasi untuk setiap baris. Lagipula itu tidak terdengar seperti masalah dalam kasusmu. Anda dapat mengawali baris entri file dengan '-' di syslog.conf untuk menghilangkan sinkronisasi.
kacang
0

Anda harus mempertimbangkan mematikan keepalive sebagai percobaan pertama ...

dengan 107 permintaan yang diproses, saya akan membuat MaxSpareServers lebih tinggi dari yang Anda tetapkan ...

IMHO dalam nginx jangka panjang sebagai proxy terbalik untuk konten statis harus menjadi pertimbangan

evcz
sumber
0

Saran pertama: nonaktifkan keepalives. Saya hanya membutuhkannya ketika saya bisa mengidentifikasi situasi tertentu bahwa kinerja meningkat, tetapi secara umum permintaan / detik menurun dengan Keepalive diaktifkan.

Saran kedua: Tetapkan MaxRequestsPerChild. Saya gema symcbean di sini, ini akan membantu dengan proses rollover jika terjadi kebocoran memori. 500 adalah titik awal yang baik.

Saran Ketiga: Tingkatkan MaxClients. Perhitungan rata-rata untuk ini adalah (memori fisik - memori yang digunakan oleh proses non-httpd) / ukuran setiap proses httpd. Bergantung pada bagaimana httpd dikompilasi, angka ini maksimal pada 255. Saya menggunakan 250 untuk server publik saya untuk berurusan dengan google / yahoo / MS merangkak sistem.

Saran Keempat: Tingkatkan MaxSpareServers: sekitar 4-5x MinSpareServers.

Jika saran-saran itu gagal, saya akan melihat load-balancing dengan reverse-proxy atau memcache untuk DB.

Paul S
sumber