Refactoring Wordpress untuk meningkatkan kinerja memori [tertutup]

63

Saya melihat dari dekat pada konsumsi memori Wordpress. Di situs saya, tampaknya setiap halaman mencapai 20MB RAM dialokasikan, hanya untuk mempersiapkan lingkungan yang nyaman untuk semua plugin untuk dijalankan. Saya merencanakannya sebagai berikut:

Tidak ada satu pun tempat untuk dioptimalkan, tidak ada satu pun orang jahat yang makan sebagian besar memori. Konsumsi semua tersebar di banyak banyak modul php.

Bagaimana kita bisa membuat Wordpress menginisialisasi lingkungannya dalam memori hanya sekali, dan kemudian menggunakannya kembali berkali-kali untuk setiap klik? Saya tidak ingin PHP lambat memakan 20 MB di setiap klik pengguna - bahkan pada server dengan banyak memori, perlu beberapa detik untuk menyelesaikan semua pekerjaan. Pada dasarnya Anda membutuhkan potongan memori hanya baca yang dapat digunakan kembali.

Juga ... mengapa 20MB? Adakah yang bisa memberikan wawasan tentang ini?

Sunting: Ini adalah output WinCacheGrind di Wordpress yang berjalan di mesin pengembangan saya (jauh lebih cepat dari shared hosting). Seperti yang Anda lihat, dibutuhkan lebih dari sedetik untuk menghasilkan HTML halaman utama. Lambatkan itu dengan shared hosting dan Anda memiliki resep untuk masalah. Saya memilih metode yang menghabiskan sebagian besar waktu. Bagaimana cara Anda mengoptimalkan ini?

Sunting: Berikut ini adalah statistik kueri dari alat profil.fp yang fantastis ini .

Muat: 12 kueri - 532ms - 19.1MB - 43 hit cache / 53
Permintaan: 15 pertanyaan - 563ms - 19.0MB - 72 hit cache / 86
Tampilan: 21 kueri - 705ms - 19.2MB - 234 hit cache / 257

Sunting: Apakah Anda ingin melihat sesuatu yang dijamin membuat Anda takut? Masukkan baris ini di akhir index.php:


echo "<pre>\n";
print_r(get_defined_vars());
echo "</pre>\n";

Saya mencoba menghitung berapa kali isi postingan saat ini disimpan dalam memori. Saya menghitung 20 contoh. Kemudian saya menyadari bahwa PHP memiliki penghitungan referensi, sehingga jumlah salinan dikurangi menjadi hanya tiga: dua tampaknya dalam WP_Query, satu di cache objek. Saya sedang menyelidiki lebih lanjut.

Inilah mengapa saya pikir WordPress perlu refactoring menargetkan masalah memori. Anda tidak dapat lagi menyalahkan konsumsi memorinya pada kerumitan semata dari apa yang dilakukannya. Itu hanya melakukan banyak hal yang salah .

Sunting: Setelah seharian mencoba mencari tahu ini, berikut adalah temuan saya:

1) 88% dari semua memori berasal dari permintaan atau sertakan atau sertakan jenis panggilan:

2) File php termasuk sebagian besar terjadi selama bagian pertama melayani permintaan (tidak mengherankan), yang juga merupakan tempat semua memori habis:

3) Cukup menarik untuk memplot semua fungsi yang sedang dieksekusi saat membuat permintaan. Ada total lebih dari 12000 panggilan. Saya gugup agar lebih terlihat (sumbu Level pada dasarnya adalah kedalaman tumpukan):

4) Satu-satunya cara maju yang dapat saya pikirkan adalah meminimalkan jumlah file .php yang disertakan. Jika saya membagi fungsi per file asalnya, Anda dapat melihat bahwa banyak file paling banyak dipukul sekali atau dua kali. Kita perlu cara bagaimana melompati mereka ketika mereka tidak diperlukan. Misalnya plugin cadangan basis data jauh saya dimuat dan terdaftar, hanya untuk tidak pernah digunakan sama sekali. Berikut adalah plot di atas dengan nama file:

Saya menawarkan hadiah yang layak untuk semua reputasi saya :) untuk refactor yang akan menyebabkan pemotongan jejak memori blog saya hingga 30% atau lebih.

Sunting: Saya menginstal WP 3.1, ini adalah perbandingan dengan versi yang lama.

Biru adalah WP 3.1, merah adalah 3.0.4. WP baru lebih cepat, tetapi juga memakan lebih banyak memori.

Berikut adalah daftar dengan memasukkan file.

Ini biarkan saya menyadari betapa banyak memori yang dimakan oleh "paket SEO All In One" - satu jalan adalah dengan menggunakan hanya sebagian kecil dari fungsi plugin untuk mendapatkan apa yang saya inginkan. Juga, plugin saya sendiri sepertinya sangat buruk.

Saya ingin mencoba memuat bersyarat pada misal comment.php (saya melarang komentar di blog saya) dan beberapa lainnya. Saya menghapus semua kode yang sudah usang. Saya memangkas kses.php untuk hanya memuat tabel globalnya sesuai permintaan. Saya menyederhanakan l10n (saya tidak melakukan pelokalan), membuat fungsinya mengembalikan string segera, tanpa pencarian. Saya masih jauh dari angka 30% yang saya set up secara sewenang-wenang.

Sunting: Saya mengunduh dan mengaktifkan APC dengan pengaturan default (32MB cache opcode). Berikut ini perbandingannya:

Anda dapat melihat bahwa pemuatan kode dipercepat secara besar-besaran, dan kode juga membutuhkan lebih sedikit ruang dalam memori (mungkin karena kita hanya berurusan dengan opcodes, bukan sumber aslinya). Namun konsumsi memori masih cukup tinggi.

Roman Zenka
sumber
Bisakah Anda mengunggah file cachegrind sendiri di suatu tempat? Catat saja, saya tidak ingat apakah sesuatu yang layak dirahasiakan termasuk di dalamnya, jika - maka jangan.
Pertama
@ Pertama Harusnya baik-baik saja. foxloft.com/files/mbala/cachegrind.out
Roman
1
hm, saya setuju dengan kesimpulan Anda - tidak ada yang benar-benar keluar, meminta diperbaiki. Saya telah membuang profil baru pada tumpukan uji lokal saya (3.1, MS, Dua Puluh Sepuluh, data Uji Unit Tema) dan mendapat 1,5s (sebagian besar perbedaan tampaknya karena menu khusus - sesuatu adalah slooow). Jadi saya kira tidak ada yang bisa diperbaiki = caching research.
Pertama
@ Pertama, Terima kasih banyak atas bantuan Anda. Saya pikir ada hal-hal untuk diperbaiki, tetapi akan memerlukan perubahan arsitektur Wordpress ke beberapa filosofi yang sama sekali berbeda, dan itu terlalu banyak pekerjaan.
Roman Zenka

Jawaban:

25

Tidak sepadan dengan masalahnya. WordPress tidak memakan banyak memori hanya karena. Ini memakan banyak memori karena menjalankan banyak fungsi di bawah tenda.

Jauh lebih mudah dan efisien untuk men-cache hasil (halaman dihasilkan) dengan plugin cache statis dan sajikan. Dengan begitu sebagian besar pengunjung bahkan tidak akan menekan WP itu sendiri.

Jarang
sumber
2
Saya sudah menggunakan cache, tetapi saya masih memiliki beberapa halaman yang benar-benar dinamis (misalnya keranjang belanja). Dan ketika bintang-bintang tidak disejajarkan dengan benar, pengguna dapat menunggu selama 20 detik - yaitu, diberikan, di GoDaddy, tetapi bahkan jika tidak, saya pikir setidaknya ~ 3 detik. Saya benar-benar tidak dapat memberikan jenis pengalaman yang benar-benar tajam digunakan orang dari Google.
Roman Zenka
8
@Roman Zenka jika Anda memiliki kebutuhan kinerja spesifik, maka Anda lebih baik mencari solusi spesifik, daripada berharap bahwa WordPress itu sendiri secara ajaib akan menjadi super cepat dan ringan pada sumber daya. Hal pertama yang saya sarankan untuk dilihat adalah opcode cache dan fragmen caching statis ... Tapi sebelum itu Anda perlu melakukan benchmark heck keluar dan menentukan tidak hanya di mana memori akan pergi, tetapi juga di mana waktu dihabiskan. WordPress adalah lingkungan, bukan hambatan dengan sendirinya. Bottleneck ada dalam apa yang Anda lakukan.
Pertama
@ Pertama, saya benar-benar melakukan benchmark penggunaan CPU dan saya tidak bisa menunjukkan jari pada tempat tertentu yang menyebabkan masalah. Mirip dengan memori - tampaknya tersebar di semua tempat. Namun, pembandingan saya mungkin tidak dilakukan secara optimal - saya menggunakan XDebug profiler dan Cachegrind - misalnya cukup sulit untuk membedakan latensi karena panggilan basis data. Saya akan berterima kasih atas petunjuk tentang teknik pembuatan profil yang lebih baik.
Roman Zenka
Screenshot @Rarst Profileing telah ditambahkan.
Roman Zenka
4
Bisa juga server GoDaddy sedang lambat. Mereka dikenal karena tidak memiliki perangkat keras terbesar dan akan " lebih suka membayar iklan televisi daripada memutakhirkan server mereka "
Zack
23

Dan inilah mengapa saya pikir WordPress sangat membutuhkan penulisan ulang. Anda tidak dapat lagi menyalahkan konsumsi memorinya pada kerumitan semata dari apa yang dilakukannya. Itu hanya melakukan kesalahan.

Kesimpulan yang naif. Baca Hal Anda Tidak Harus Lakukan, Bagian I .

Terima kasih untuk plot penggunaan memori.

Sunting jauh kemudian: Autommatic telah merilis perpustakaan bernama prefork yang tampaknya melakukan apa yang Anda minta: memuat kode WordPress dalam RAM hanya sekali.

scribu
sumber
Benar, itu naif. Mungkin saya seharusnya mengatakan "refactor" daripada "menulis ulang", maka itu terdengar jauh lebih baik. Pos diperbarui.
Roman Zenka
2
Ok, well, jika Anda memiliki saran spesifik (terutama tambalan), Anda dapat mempostingnya di trac: core.trac.wordpress.org
scribu
Saya sedang mengerjakannya sekarang. Saya mencoba untuk memetakan peta objek dalam memori, sehingga saya bisa melihat berapa banyak yang digunakan oleh apa. Apakah ada alat yang akan mengambil memori dump dan plot itu?
Roman Zenka
5
@scribu - +1 untuk tautan ke pos Joel!
MikeSchinkel
1
Ok, perlu diingat bahwa WP_Object_Cache dapat diganti dengan implementasi memcached dll.
scribu
17

Dimulai dengan WordPress 3.2, PHP 5.2 akan menjadi persyaratan minimum. Saya pikir dengan itu di bawah ikat pinggang kami, bit inti dapat mulai direstrukturisasi, dan menggunakan kelas dengan memuat otomatis. Ini akan memungkinkan kita menghindari memuat beberapa potongan kode kecuali mereka benar - benar diperlukan. Misalnya, jika tidak ada embed atau galeri dalam tampilan halaman, kami mungkin dapat menghindari memuat banyak kode media.

Namun, bahkan jika mereka memutuskan untuk menempuh rute itu, saya akan berharap itu menjadi evolusi yang lambat (seperti banyak perubahan lain yang terjadi). Ini akan memerlukan pengocokan lokasi banyak file dan kode, yang mungkin dapat merusak kompatibilitas untuk beberapa plugin.

Bagian dari masalah (jika memang bisa disebut itu) adalah bahwa tanpa pemuatan bersyarat semacam itu, kerangka inti tidak dapat mengetahui sebelumnya tentang fungsi mana yang akan dibutuhkan atau tidak perlu untuk menghasilkan tampilan konten. Jadi banyak fungsi yang harus dimuat kalau -kalau dibutuhkan.

Dougal Campbell
sumber
@Dougal Campbell Saya memulai pemberian hadiah untuk pertanyaan ini, untuk melihat apakah kita bisa meretas setidaknya satu contoh WordPress ini cukup buruk untuk mendapatkan setidaknya 30% peningkatan konsumsi memori sekarang, relatif tanpa rasa sakit. Ini bisa menginspirasi beberapa perkembangan di masa depan.
Roman Zenka
Pemuatan bersyarat, sementara berpotensi mengurangi konsumsi memori, merusak kecepatan ketika caching opcode terlibat. Kami cenderung menyukai kecepatan.
scribu
Lebih banyak pemikiran tentang autoloading: stackoverflow.com/questions/4788452/…
scribu
@scribu Ketika Anda mengatakan "pemuatan bersyarat", apakah Anda berbicara tentang autoloading, atau sebenarnya memuat kode berdasarkan suatu kondisi? Seberapa sakit kecepatannya?
Roman Zenka
1
Terima kasih! Seperti yang saya katakan, saya tidak tahu apakah inti WP akan pernah mengambil rute itu (refactoring yang diperlukan mungkin terlalu ekstrim). Tapi saya sangat terkesan dengan upaya yang Anda lakukan dalam menganalisis ini, dan grafik yang Anda hasilkan. Pertahankan kerja bagus!
Dougal Campbell
16

Bagaimana kita bisa membuat Wordpress menginisialisasi lingkungannya dalam memori hanya sekali, dan kemudian menggunakannya kembali berkali-kali untuk setiap klik?

Ini disebut opcode-caching.

http://en.wikipedia.org/wiki/PHP_accelerator

Otto
sumber
1
Saya akan mencoba APC dan melihat apa yang terjadi. Ketika saya awalnya mengajukan pertanyaan itu, maksud saya lebih dari sekadar caching opcode - maksud saya menggunakan kembali seluruh lingkungan yang dibangun WordPress - kode + data. Memcached akan membantu Anda mendapatkan data lebih cepat, tetapi Anda akan tetap mengkloning data dalam memori server. Sekarang tampaknya caching opcode berpotensi untuk menangani ~ 90% dari semua konsumsi memori.
Roman
Jika Anda memiliki sumber daya untuk beberapa percobaan, Anda juga dapat mencoba menyiapkan lingkungan FastCGI. Saya akan sangat tertarik pada beberapa perbandingan antara mod_php dan berjalan di bawah FastCGI.
Dougal Campbell
5

Anda mungkin tidak akan berhasil mengurangi penggunaan ram sebanyak itu. Tetapi jika Anda menggunakan mod_php, Anda mungkin ingin beralih ke mod_fcgidgantinya.

sementara mod_php sedikit lebih lambat, ia memuat php bahkan ketika itu tidak perlu, seperti melayani gambar, file statis, atau bahkan caching. Jika Anda memiliki banyak permintaan, ini banyak ram.

menggunakan fcgid akan mengurangi ini banyak.

juga, menggunakan cache statis (seperti cache w3total) akan menghindari memanggil php sama sekali yang merupakan keuntungan yang sangat besar: penggunaan ram lebih sedikit, koneksi db lebih sedikit.

boyska
sumber
4

Ha. Saya sedang mengerjakan aplikasi web sekarang karena saya sepenuhnya bermaksud untuk membebani data dan penggunaan melebihi apa yang bisa ditangani oleh akun hosting bersama saya, jadi saya memutuskan - walaupun akan sangat mudah dibuat di WP - untuk mencoba bekerja dari BackPress sebagai kerangka kerja dan membangun hanya apa yang saya butuhkan untuk kasus penggunaan khusus saya.

Jadi saya sudah bisa mengurangi lingkungan inti saya dari ratusan file PHP di WP menjadi hanya dua puluh atau lebih yang sebenarnya saya butuhkan, sementara masih bisa memanfaatkan semua db, HTTP, manajemen pengguna, format, dan cron fungsi yang saya sukai di WordPress.

Masalahnya adalah itu banyak pekerjaan, dan saya tidak akan pernah mempercayai hackjob saya untuk apa pun di luar penggunaan pribadi saya. Jika Anda ingin menggunakan lingkungan WP lengkap, ambil apa adanya. Sebagus itu karena ratusan pengembang menyelaraskannya selama beberapa tahun. Seperti semua orang di sini mengatakan, Anda akan mendapatkan lebih jauh dengan menemukan rencana hosting yang lebih baik dan meneliti teknik caching daripada yang mungkin Anda dapatkan dengan meretas inti.

lempengan emas
sumber
1
Saya setuju bahwa WP telah disetel untuk waktu yang lama. Tapi saya tidak berpikir itu baik-baik saja untuk bekerja pada hosting jelek, dengan campuran plugin tertentu. Saya ingin tahu seberapa jauh saya bisa mendorongnya. Sekalipun perubahan tidak membuatnya menjadi inti, ada baiknya memiliki cara terdokumentasi untuk meretas inti jika Anda pikir Anda harus.
Roman Zenka
3

Ya, WordPress memuat semuanya terlebih dahulu dan kemudian melakukan apa yang kami minta. Saya dapat mengingat di suatu tempat bahwa kita dapat membuat kumpulan virtual dalam RAM tempat kita dapat meletakkan file. Saya memiliki ide untuk menempatkan seluruh WordPress dalam memori (<10MB) & kemudian kita dapat menghemat banyak I / O yang mana saja seharusnya memberikan peningkatan kecepatan. Tetapi saya tidak pernah mendapat kesempatan untuk mencobanya dan terlebih lagi saya tidak begitu mahir dalam mengejar sesuatu seperti itu. Tapi sepertinya patut dicoba.

Asfame
sumber
Dan saya setuju dengan Rarst untuk menggunakan plugin cache statis sehingga tidak ada pemrosesan yang dilakukan sama sekali. Tapi itu bisa digunakan dengan dinamika yang baik juga. :)
Ashfame
Saya suka ide itu. Saya tidak yakin seberapa besar masalah ini disebabkan oleh latensi I / O, dan berapa banyak yang disebabkan oleh PHP yang secara perlahan mengunyah data. Apakah Anda tahu cara mengatakannya?
Roman Zenka
Maaf itu hanya ide di kepalaku. Mungkin itu tidak mempengaruhi kinerja yang terlihat seperti data umumnya dibaca dari hard disk sebagai blok, sehingga banyak data lain yang diperlukan mungkin sudah diambil. Saya tidak terlalu yakin.
Ashfame
3

beberapa saran dasar:

  1. plugin cache total w3 untuk cache ..
  2. dapatkan memcache terinstal dan diaktifkan, juga aktifkan dari pengaturan cache total w3 (cache opcode adalah pilihan yang bagus juga tetapi itu tidak berjalan baik dengan plugin cache total w3)
  3. perkecil kueri untuk mengarahkan tautan dalam file tema ..
  4. Nonaktifkan semua plugin tambahan yang tidak digunakan dan hapus.
  5. mengoptimalkan Database.

saya menjalankan situs wordpress terkenal dengan lalu lintas yang besar setiap hari .. saya bahkan tidak pada dedicated, melakukan yang besar untuk saya :)

Ayaz Malik
sumber