Bagaimana cara menyelidiki kebocoran memori dengan Apache dan PHP?

16

Kami menjalankan situs web Drupal yang berat yang melakukan pemodelan keuangan. Kami tampaknya mengalami semacam kebocoran memori mengingat fakta bahwa memori lembur yang digunakan oleh apache bertambah sementara jumlah proses apache tetap stabil:

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Kami tahu masalah memori berasal dari apache / PHP karena setiap kali kami mengeluarkan /etc/init.d/httpd reloadpenurunan penggunaan memori (lihat tangkapan layar di atas dan di bawah keluaran CLI):

Sebelum httpd dimuat ulang

$ gratis
             total digunakan buffer bersama gratis di-cache
Mem: 49447692 45926468 3521224 0 191100 22609728
- / + buffer / cache: 23125640 26322052
Swap: 2097144 536552 1560592

Setelah httpd dimuat ulang

$ gratis
             total digunakan buffer bersama gratis di-cache
Mem: 49447692 28905752 20541940 0 191360 22598428
- / + buffer / cache: 6115964 43331728
Swap: 2097144 536552 1560592

Setiap utas apache diberi PHP memory_limitsebesar 512MB yang menjelaskan penggunaan memori yang tinggi mengurangi volume permintaan yang rendah, dan max_execution_time120 detik yang akan menghentikan utas yang membutuhkan waktu lebih lama, dan karenanya harus mencegah pertumbuhan konstan dalam penggunaan memori kami. melihat.

T: Bagaimana kami menyelidiki apa yang menyebabkan kebocoran memori ini?

Idealnya saya mencari langkah pemecahan masalah yang dapat saya lakukan pada sistem tanpa harus mengganggu tim pengembang.

Informasi tambahan:

OS: RHEL 5.6
PHP: 5.3
Drupal: 6.x
MySQL: 5.6

FYI kami mengetahui masalah swapping yang kami selidiki secara terpisah dan tidak ada hubungannya dengan kebocoran memori yang telah kami amati sebelum swapping mulai terjadi.

Maks
sumber
Terakhir kali saya mengalami masalah penggunaan memori yang parah dengan LAMP + Drupal adalah ketika saya menggunakan library PHP memcached. Setelah saya mengambilnya, penggunaan memori menurun dengan sangat dramatis. Tebakan saja. Ketikkan balasan yang tepat untuk Anda sedikit nanti.
Janne Pikkarainen
@JannePikkarainen: kami menggunakan memcachedperpustakaan PHP . Berdasarkan halaman admin memcache memcache.php, yang dapat kita lihat adalah bahwa kita telah mengalokasikan 5GBuntuk memcache, yang 3.3GBsedang digunakan. Akan lebih baik jika Anda dapat membantu kami lebih lanjut di sini.
Max
Ya, memcacheddaemon itu sendiri mungkin baik-baik saja. Ini adalah perpustakaan memcache PHP yang mungkin atau mungkin tidak bocor memori (dan karenanya menumbuhkan proses penggunaan memori oleh Apache). Masalah saya sekitar 1-2 tahun yang lalu, jadi mungkin sudah diperbaiki setelah itu. Bagaimanapun, jika memcached tidak wajib untuk Anda, coba nonaktifkan untuk sementara waktu dan lihat apakah penggunaan memori Apache masih tumbuh.
Janne Pikkarainen
Apa masalah sebenarnya? Apakah kinerjanya buruk? Anda memberi tahu kami gejala tanpa menjelaskan masalah apa yang seharusnya kami bantu Anda selesaikan. (Dan apa masalah pertukaran yang sedang Anda bicarakan? Apakah Anda bertukar begitu banyak sehingga berdampak pada kinerja?)
David Schwartz
@ Davidvidchwartz: masalahnya adalah jika kita tidak me-restart httpd, penggunaan memori terus bertambah dan kotak akhirnya crash dengan beberapa pesan kernel memori keluar. Performanya bagus (sampai penggunaan memori mendekati batas memori). Harap abaikan masalah pertukaran.
Max

Jawaban:

12

Kita tahu masalah memori berasal dari apache / PHP karena setiap kali kita mengeluarkan /etc/init.d/httpd memuat ulang penurunan penggunaan memori

Tidak - itu hanya berarti terkait dengan lalu lintas web. Anda telah menyebutkan bahwa Anda menjalankan mysql pada kotak - mungkin mengelola data untuk server web - bisa saja menjadi pelakunya di sini. Seperti halnya layanan lain yang menggunakan webstack Anda yang tidak Anda sebutkan.

Setiap utas apache diberi PHP memory_limit sebesar 512MB yang menjelaskan

Tidak, tidak. Anda melaporkan rata-rata 7 dan maksimal 25 server sibuk - namun grafik memori Anda menunjukkan delta sekitar 25Gb.

Benar-benar Anda harus mulai lagi dengan penyetelan HTTP dasar - Anda tampaknya menjalankan 256 httpds konstan, namun penggunaan puncak Anda adalah 25 - ini benar-benar bodoh.

dan max_execution_time dari 120 detik yang harus mengakhiri utas yang eksekusi lebih lama

Tidak - hanya jika utas eksekusi berada dalam juru bahasa PHP - bukan jika PHP diblokir.

yang melakukan pemodelan keuangan

(mendesah)

Akan sangat membantu jika Anda memberikan rincian tentang cara mengkonfigurasi Apache, berulir atau prefork, versi apa, bagaimana PHP dipanggil (modul, cgi, fastcgi), apakah Anda menggunakan koneksi persisten, apakah Anda menggunakan prosedur tersimpan.

Saya sarankan Anda mulai dengan memindahkan mysql ke mesin yang terpisah dan berhenti menggunakan koneksi persisten (jika saat ini Anda menggunakannya). Tetapkan batas memori jauh lebih rendah dan timpa ini berdasarkan per-skrip. Pastikan Anda memiliki pengumpul sampah referensi melingkar terinstal dan terkonfigurasi.

symcbean
sumber
2

Anda mungkin telah memecahkan masalah Anda sekarang. Sebagai sementara untuk menjaga server dari swapping / meronta-ronta saya menjalankan perintah berikut setiap jam dari cron:

#!/bin/sh 
sync; echo 3 > /proc/sys/vm/drop_caches

Saya tidak mengatakan ini adalah solusi, hanya cara untuk menjaga hal-hal berjalan dan untuk meminimalkan downtimw saat Anda menyelidiki penyebab sebenarnya dari kebocoran memori.

Rincian lebih lanjut dapat ditemukan di sini.

http://www.tecmint.com/clear-ram-memory-cache-buffer-and-swap-space-on-linux/

patrick
sumber
1

Rupanya ini adalah cara kerja PHP - dan jika Anda melakukan loop panjang di mana Anda mengalokasikan objek dan siapa tahu jika Anda juga melewatkannya melalui referensi, jadi satu-satunya cara untuk menghadapinya, adalah dengan setelah N meminta untuk setiap proses PHP untuk menghentikannya. Jika Anda menjalankan PHP sebagai CGI, setiap permintaan membuatnya respawning - jadi tidak ada kebocoran memori, dan penurunan kinerja mungkin tidak terlalu besar. Anda juga dapat menjalankan fast-cgi, di mana mis. Setiap 1000 meminta proses php-fcgi terbunuh dan ingatannya dilepaskan - sekali lagi tidak ada kebocoran memori. Jika Anda menjalankan PHP sebagai modul mod_php, Anda dapat mencoba mengatur maxrequests di httpd.conf untuk melihat apakah itu membantu. Saya akan mencoba untuk mengatur misalnya 10 - jika itu akan berfungsi, penurunan kinerja tidak akan tinggi, tetapi seharusnya tidak ada kebocoran memori,

Andrew Smith
sumber
-1

Periksa memori pada file global php.ini. jangan hanya decalre valure seperti 1 G dll ... Saya akan sangat menyarankan agar php.ini lokal dibawa ke akun itu agar tidak mempengaruhi seluruh server. Saya akan merekomendasikan pengaturan batas global php.ini menjadi sekitar 64 juta karena ini biasanya cukup untuk sebagian besar akun

periksa pengaturan apache Anda juga

Nikhil Babu
sumber