Taktik untuk menggunakan PHP di situs beban tinggi

242

Sebelum Anda menjawab ini, saya belum pernah mengembangkan sesuatu yang cukup populer untuk mendapatkan banyak server. Perlakukan saya sebagai (mendesah) alien yang baru saja mendarat di planet ini, meskipun yang tahu PHP dan beberapa teknik optimasi.


Saya sedang mengembangkan alat dalam PHP yang dapat mencapai cukup banyak pengguna, jika itu berhasil. Namun sementara saya sepenuhnya mampu mengembangkan program saya cukup mengerti ketika membuat sesuatu yang dapat menangani lalu lintas besar. Jadi, inilah beberapa pertanyaan di atasnya (jangan ragu untuk mengubah pertanyaan ini menjadi utas sumber daya juga).

Basis data

Saat ini saya berencana untuk menggunakan fitur MySQLi di PHP5. Namun bagaimana saya harus mengatur basis data terkait dengan pengguna dan konten? Apakah saya benar - benar membutuhkan banyak basis data? Saat ini semuanya bercampur menjadi satu database - walaupun saya telah mempertimbangkan untuk menyebarkan data pengguna ke satu, konten yang sebenarnya ke yang lain dan akhirnya konten situs inti (master template dll) ke yang lain. Alasan saya di balik ini adalah bahwa mengirimkan pertanyaan ke database yang berbeda akan meringankan beban mereka sebagai satu database = 3 sumber beban. Juga apakah ini masih efektif jika mereka semua berada di server yang sama?

Caching

Saya memiliki sistem template yang digunakan untuk membangun halaman dan menukar variabel. Templat induk disimpan dalam basis data dan setiap kali templat disebut salinan temboloknya (dokumen html) dipanggil. Saat ini saya memiliki dua jenis variabel dalam template ini - var statis dan var dinamis. Vatic statis biasanya hal-hal seperti nama halaman, nama situs - hal-hal yang tidak sering berubah; vars dinamis adalah hal-hal yang berubah pada setiap memuat halaman.

Pertanyaan saya tentang ini:

Katakanlah saya punya komentar tentang artikel yang berbeda. Yang merupakan solusi yang lebih baik: simpan template komentar sederhana dan render komentar (dari panggilan DB) setiap kali halaman dimuat atau simpan salinan cache halaman komentar sebagai halaman html - setiap kali komentar ditambahkan / diedit / dihapus halaman tersebut di-recached.

Akhirnya

Adakah yang punya tips / petunjuk untuk menjalankan situs beban tinggi di PHP. Saya cukup yakin ini adalah bahasa yang bisa digunakan untuk digunakan - Facebook dan Yahoo! berikan prioritas besar - tetapi apakah ada pengalaman yang harus saya perhatikan?

Ross
sumber
9
3,5 tahun kemudian dan saya bahkan tidak dapat mengingat apa yang sedang saya kerjakan, saya ingin tahu apa yang saya pikir sangat keren juga :)
Ross
8
Biarkan ini menjadi pelajaran untuk Anda tentang pengoptimalan prematur :)
Rimu Atkinson

Jawaban:

89

Tidak ada dua situs yang sama. Anda benar-benar perlu mendapatkan alat seperti jmeter dan benchmark untuk melihat di mana poin masalah Anda akan. Anda dapat menghabiskan banyak waktu menebak dan meningkatkan, tetapi Anda tidak akan melihat hasil nyata sampai Anda mengukur dan membandingkan perubahan Anda.

Misalnya, selama bertahun-tahun, cache kueri MySQL adalah solusi untuk semua masalah kinerja kami. Jika situs Anda lambat, pakar MySQL menyarankan untuk mengaktifkan cache permintaan. Ternyata jika Anda memiliki beban tulis yang tinggi, cache sebenarnya melumpuhkan. Jika Anda menyalakannya tanpa pengujian, Anda tidak akan pernah tahu.

Dan jangan lupa bahwa Anda tidak pernah melakukan scaling. Situs yang menangani 10req / s akan membutuhkan perubahan untuk mendukung 1000req / s. Dan jika Anda cukup bersemangat untuk mendukung 10.000req / s, arsitektur Anda mungkin akan terlihat sangat berbeda juga.

Basis data

  • Jangan gunakan MySQLi - PDO adalah lapisan akses database OO 'modern'. Fitur terpenting untuk digunakan adalah placeholder dalam kueri Anda. Cukup cerdas untuk menggunakan persiapan sisi server dan optimasi lainnya untuk Anda juga.
  • Anda mungkin tidak ingin memecah database Anda saat ini. Jika Anda menemukan bahwa satu basis data tidak terpotong, ada beberapa teknik untuk meningkatkan, tergantung pada aplikasi Anda. Mereplikasi ke server tambahan biasanya bekerja dengan baik jika Anda memiliki lebih banyak membaca daripada menulis. Sharding adalah teknik untuk membagi data Anda ke banyak mesin.

Caching

  • Anda mungkin tidak ingin melakukan cache dalam basis data Anda. Basis data biasanya adalah hambatan Anda, jadi menambahkan lebih banyak IO ke dalamnya biasanya merupakan hal yang buruk. Ada beberapa cache PHP di luar sana yang melakukan hal serupa seperti APC dan Zend.
  • Ukur sistem Anda dengan caching on dan off. Saya yakin cache Anda lebih berat daripada melayani halaman secara langsung.
  • Jika butuh waktu lama untuk membangun komentar dan data artikel Anda dari db, integrasikan memcache ke dalam sistem Anda. Anda dapat men-cache hasil query dan menyimpannya dalam instance memcached. Penting untuk diingat bahwa mengambil data dari memcache harus lebih cepat daripada mengumpulkannya dari database untuk melihat manfaatnya.
  • Jika artikel Anda tidak dinamis, atau Anda memiliki perubahan dinamis sederhana setelah dibuat, pertimbangkan untuk menulis html atau php ke disk. Anda bisa memiliki halaman index.php yang terlihat pada disk untuk artikel tersebut, jika ada di sana, itu mengalir ke klien. Jika tidak, itu menghasilkan artikel, menulisnya ke disk dan mengirimkannya ke klien. Menghapus file dari disk akan menyebabkan halaman ditulis ulang. Jika komentar ditambahkan ke artikel, hapus salinan yang di-cache - itu akan dibuat ulang.
Gary Richardson
sumber
10
@ menulis ke disk. Anda bahkan bisa membuang index.php dan membiarkan Apache melakukan pekerjaan untuk Anda, sehingga index.php hanya dipanggil, jika path tidak ada. Anda akan menggunakan mode_rewrite untuk ini.
troelskn
5
-1, PDO secara signifikan lebih lambat daripada MySQLi atau bahkan ekstensi MySQL.
Alix Axel
4
PDO jauh lebih lambat daripada mysqli dan tidak berfungsi dengan benar untuk pertanyaan bersarang untuk saya. Mysqli juga mendukung persiapan sisi server dan parameter terikat seperti PDO.
Daren Schwenke
5
Saya tidak percaya ini diterima sebagai jawaban. Ini tidak terlalu bagus.
symcbean
1
about: caching - gambar, css, htm dan js akan membantu, matikan cookie pada gambar juga!
Talvi Watia
61

Saya adalah pengembang utama di situs dengan lebih dari 15 juta pengguna. Kami memiliki sedikit masalah penskalaan karena kami merencanakannya AWAL dan diskalakan dengan cermat. Berikut adalah beberapa strategi yang dapat saya sarankan dari pengalaman saya.

SCHEMA Pertama, denormalkan skema Anda. Ini berarti bahwa daripada memiliki beberapa tabel relasional, Anda harus memilih untuk memiliki satu tabel besar. Secara umum, gabungan adalah pemborosan sumber daya DB yang berharga karena melakukan banyak persiapan dan pemeriksaan membakar disk I / O. Hindari mereka saat Anda bisa.

Imbalannya di sini adalah Anda akan menyimpan / menarik data yang berlebihan, tetapi ini dapat diterima karena data dan bandwidth intra-sangkar sangat murah (disk lebih besar) sedangkan beberapa I / O persiapan adalah pesanan yang jauh lebih mahal (lebih banyak server) .

INDEXING Pastikan bahwa kueri Anda menggunakan setidaknya satu indeks. Namun berhati-hatilah, indeks itu akan dikenakan biaya jika Anda sering menulis atau memperbarui. Ada beberapa trik eksperimental untuk menghindari ini.

Anda dapat mencoba menambahkan kolom tambahan yang tidak diindeks yang berjalan paralel dengan kolom Anda yang diindeks. Kemudian Anda dapat memiliki proses offline yang menulis kolom yang tidak diindeks di atas kolom yang diindeks dalam batch. Dengan cara ini, Anda dapat mengontrol dengan lebih baik saat mySQL perlu menghitung ulang indeks.

Hindari kueri yang dihitung seperti wabah. Jika Anda harus menghitung kueri, coba lakukan ini satu kali pada saat penulisan.

CACHING Saya sangat merekomendasikan Memcached. Ini telah dibuktikan oleh pemain terbesar di tumpukan PHP (Facebook) dan sangat fleksibel. Ada dua metode untuk melakukan ini, satu adalah caching di lapisan DB Anda, yang lain adalah caching di lapisan logika bisnis Anda.

Opsi lapisan DB akan membutuhkan caching hasil query diambil dari DB. Anda dapat hash permintaan SQL Anda menggunakan md5 () dan menggunakannya sebagai kunci pencarian sebelum pergi ke database. Sisi positifnya adalah sangat mudah diterapkan. The downside (tergantung pada implementasi) adalah bahwa Anda kehilangan fleksibilitas karena Anda memperlakukan semua caching yang sama sehubungan dengan berakhirnya cache.

Di toko tempat saya bekerja, kami menggunakan caching layer bisnis, yang berarti setiap kelas konkret dalam sistem kami mengontrol skema caching dan waktu tunggu cache. Ini telah bekerja cukup baik bagi kami, tetapi perlu diketahui bahwa item yang diambil dari DB mungkin tidak sama dengan item dari cache, jadi Anda harus memperbarui cache dan DB secara bersamaan.

DATA SHARDING Replikasi hanya membuat Anda sejauh ini. Lebih cepat dari yang Anda harapkan, tulisan Anda akan menjadi hambatan. Untuk mengimbanginya, pastikan untuk mendukung data sharding sedini mungkin. Anda mungkin ingin menembak diri sendiri nanti jika tidak.

Ini sangat sederhana untuk diimplementasikan. Pada dasarnya, Anda ingin memisahkan otoritas utama dari penyimpanan data. Gunakan DB global untuk menyimpan pemetaan antara kunci primer dan id cluster. Anda meminta pemetaan ini untuk mendapatkan sebuah cluster, dan kemudian meminta cluster untuk mendapatkan data. Anda dapat melakukan cache keluar dari operasi pencarian ini yang akan membuatnya menjadi operasi yang dapat diabaikan.

Kelemahan dari ini adalah bahwa mungkin sulit untuk mengumpulkan data dari beberapa pecahan. Tapi, Anda juga bisa merekayasa hal itu.

PENGOLAHAN OFFLINE Jangan membuat pengguna menunggu backend Anda jika mereka tidak perlu. Buat antrean pekerjaan dan pindahkan pemrosesan apa pun yang Anda bisa luring, lakukan secara terpisah dari permintaan pengguna.

smartphone ini
sumber
9
+1 Tangan ke bawah, ini harus menjadi jawaban yang diterima. Sangat menarik bahwa semua yang pernah saya baca tentang membangun database selalu mengatakan "menormalkan semua data sebanyak mungkin" tanpa menyebutkan kinerja hit melakukan bergabung. Secara intuitif saya selalu merasa bahwa bergabung (terutama banyak) menambahkan banyak overhead tetapi belum pernah mendengarnya secara eksplisit sampai sekarang. Saya berharap saya lebih mengerti apa yang Anda bicarakan tentang pengendalian ketika MySQL menghitung indeks, sepertinya hack yang sangat menarik.
Evan Plaice
Sharding data sangat penting untuk database yang tumbuh terlalu besar. Google (perusahaan bukan mesin pencari) memiliki banyak hal menarik untuk dikatakan tentang penerapan skema sharding. Pemrosesan offline juga sangat besar ketika membatasi jumlah penulisan database (dan membatasi jumlah perhitungan ulang indeks tabel). Saya telah melihat banyak blog (dan saya pikir bahkan Stack Overflow) menggunakan teknik ini untuk sistem komentar / umpan balik yang dibuat pengguna.
Evan Plaice
1
Terima kasih atas komentarnya. Sungguh menakjubkan bahwa beberapa orang berpendapat untuk profiling kode tingkat menengah ketika jumlah waktu eksekusi VAST dihabiskan baik dalam data I / O atau client-server I / O. Optimasi rumit ubber menghemat 20% waktu eksekusi dari proses PHP yang memakan waktu 40 ms tidak ada artinya dibandingkan dengan penghematan 5% sederhana dari kueri basis data 1s.
smartphone
42

Saya telah bekerja di beberapa situs yang mendapat jutaan / hit / bulan didukung oleh PHP & MySQL. Berikut ini beberapa dasar:

  1. Cache, cache, cache. Caching adalah salah satu cara paling sederhana dan paling efektif untuk mengurangi beban pada server web dan basis data Anda. Tembolok konten halaman, kueri, perhitungan mahal, apa pun yang terikat I / O. Memcache sudah mati sederhana dan efektif.
  2. Gunakan beberapa server setelah Anda maksimal. Anda dapat memiliki beberapa server web dan beberapa server basis data (dengan replikasi).
  3. Kurangi # permintaan keseluruhan untuk pengunjung web Anda. Ini memerlukan caching JS, CSS, dan gambar menggunakan header yang kedaluwarsa. Anda juga dapat memindahkan konten statis ke CDN, yang akan mempercepat pengalaman pengguna Anda.
  4. Ukur & patokan. Jalankan Nagios pada mesin produksi Anda dan uji beban pada server dev / qa Anda. Anda perlu tahu kapan server Anda akan terbakar sehingga Anda dapat mencegahnya.

Saya akan merekomendasikan membaca Membangun Situs Web Scalable , itu ditulis oleh salah satu insinyur Flickr dan merupakan referensi yang bagus.

Lihat posting blog saya tentang skalabilitas juga, ia memiliki banyak tautan ke presentasi tentang penskalaan dengan berbagai bahasa dan platform: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/

Ryan Doherty
sumber
1
+1 Ada banyak info bagus di sini. Saya telah meneliti lebih lanjut tentang topik ini akhir-akhir ini dan jawaban Anda sesuai dengan semua yang saya baca. Memcache, caching, CDN untuk konten statis, mengurangi permintaan; semua barang bagus. Saya juga akan menambahkan, menghasilkan hash pada file konten statis (jika Anda berada di belakang CDN / cache) sisi server sehingga file yang diperbarui memiliki tanda tangan unik dalam cache. Juga, gabungkan file sumber statis (css, javascript) dengan cepat (dan cache dengan hash nama file) untuk mengurangi permintaan. Juga, hasilkan jempol secara dinamis (dan simpan di cache)
Evan Plaice
Google telah membuat modul apache yang disebut mod_pagespeed yang dapat menangani semua penggabungan file, minifikasi, penggantian nama file untuk memasukkan hash, dll untuk semua konten statis. Seharusnya hanya menambahkan sedikit overhead proses ke server pada awalnya sampai cache (dan CDN) diisi dengan sebagian besar konten. Juga, untuk keamanan, umumnya ide yang buruk untuk meletakkan tabel yang dapat diakses publik (pengguna) dalam database yang sama dengan tabel daripada menangani back-end (jika karena alasan salah satu tabel akan diretas).
Evan Plaice
39

Re: PDO / MySQLi / MySQLND

@ gary

Anda tidak bisa hanya mengatakan "jangan gunakan MySQLi" karena mereka memiliki tujuan yang berbeda. PDO hampir seperti lapisan abstraksi (meskipun sebenarnya tidak) dan dirancang untuk membuatnya mudah untuk menggunakan beberapa produk basis data sedangkan MySQLi khusus untuk koneksi MySQL. Adalah salah untuk mengatakan bahwa PDO adalah lapisan akses modern dalam konteks membandingkannya dengan MySQLi karena pernyataan Anda menyiratkan bahwa perkembangannya telah menjadi mysql -> mysqli -> PDO yang tidak demikian.

Pilihan antara MySQLi dan PDO sederhana - jika Anda perlu mendukung banyak produk basis data maka Anda menggunakan PDO. Jika Anda hanya menggunakan MySQL maka Anda dapat memilih antara PDO dan MySQLi.

Jadi mengapa Anda memilih MySQLi daripada PDO? Lihat di bawah...

@ross

Anda benar tentang MySQLnd yang merupakan pustaka tingkat bahasa inti MySQL terbaru, namun itu bukan pengganti untuk MySQLi. MySQLi (seperti halnya PDO) tetap dengan cara Anda berinteraksi dengan MySQL melalui kode PHP Anda. Keduanya menggunakan libmysql sebagai klien C di belakang kode PHP. Masalahnya adalah bahwa libmysql berada di luar mesin PHP inti dan di situlah mysqlnd masuk yaitu itu adalah Driver Asli yang memanfaatkan internal PHP inti untuk memaksimalkan efisiensi, khususnya terkait penggunaan memori.

MySQLnd sedang dikembangkan oleh MySQL sendiri dan baru-baru ini mendarat ke cabang PHP 5.3 yang dalam pengujian RC, siap untuk rilis akhir tahun ini. Anda kemudian dapat menggunakan MySQLnd dengan MySQLi ... tetapi tidak dengan PDO. Ini akan memberikan peningkatan kinerja MySQLi di banyak bidang (tidak semua) dan akan membuatnya menjadi pilihan terbaik untuk interaksi MySQL jika Anda tidak memerlukan abstraksi seperti kemampuan PDO.

Yang mengatakan, MySQLnd sekarang tersedia di PHP 5.3 untuk PDO dan jadi Anda bisa mendapatkan keuntungan dari peningkatan kinerja dari ND menjadi PDO, namun, PDO masih merupakan lapisan basis data generik dan karenanya tidak akan mungkin mendapatkan manfaat sebanyak dari perangkat tambahan di ND sebagai MySQLi bisa .

Beberapa tolok ukur yang berguna dapat ditemukan di sini meskipun berasal dari tahun 2006. Anda juga perlu mengetahui hal-hal seperti opsi ini .

Ada banyak pertimbangan yang perlu dipertimbangkan ketika memutuskan antara MySQLi dan PDO. Kenyataannya itu tidak akan menjadi masalah sampai Anda mendapatkan angka permintaan yang sangat tinggi dan dalam hal itu, lebih masuk akal untuk menggunakan ekstensi yang telah dirancang khusus untuk MySQL daripada yang abstrak dan terjadi untuk menyediakan driver MySQL .

Ini bukan masalah sederhana yang terbaik karena masing-masing memiliki kelebihan dan kekurangan. Anda perlu membaca tautan yang saya berikan dan membuat keputusan sendiri, lalu mengujinya dan mengetahuinya. Saya telah menggunakan PDO dalam proyek-proyek sebelumnya dan ini adalah ekstensi yang baik tetapi pilihan saya untuk kinerja murni adalah MySQLi dengan opsi MySQLND baru dikompilasi (ketika PHP 5.3 dirilis).

davidmytton
sumber
6
Saya beralih dari PDO ke mysqli dan permintaan reguler mulai dieksekusi tepat 2 kali lebih cepat.
serg
5
@erg: peduli untuk mengirim beberapa tes untuk mengonfirmasi ini?, karena saya benar-benar ragu bahwa dengan beralih dari PDO ke mysqli akan memberi Anda dorongan kecepatan.
Stann
23

Umum

  • Jangan mencoba mengoptimalkan sebelum Anda mulai melihat beban dunia nyata. Anda mungkin menebak dengan benar, tetapi jika tidak, Anda membuang-buang waktu.
  • Gunakan jmeter , xdebug atau alat lain untuk membuat tolok ukur situs.
  • Jika memuat mulai menjadi masalah, objek atau cache data kemungkinan akan terlibat, jadi bacalah opsi caching secara umum (memcached, opsi caching MySQL)

Kode

  • Profil kode Anda sehingga Anda tahu di mana hambatannya, dan apakah itu dalam kode atau database

Basis data

  • Gunakan MYSQLi jika portabilitas ke database lain tidak penting, PDO jika tidak
  • Jika tolok ukur mengungkapkan database adalah masalahnya, periksa kueri sebelum Anda mulai caching. Gunakan EXPLAIN untuk melihat di mana permintaan Anda melambat.
  • Setelah kueri dioptimalkan dan basis data di-cache dalam beberapa cara, Anda mungkin ingin menggunakan banyak basis data. Replikasi ke beberapa server atau sharding (memisahkan data melalui beberapa database / server) mungkin sesuai, tergantung pada data, kueri, dan jenis perilaku baca / tulis.

Caching

  • Banyak tulisan telah dilakukan pada kode caching, objek, dan data. Cari artikel di APC , Zend Optimizer , memcached , QuickCache , JPCache . Lakukan beberapa hal ini sebelum Anda benar-benar perlu, dan Anda akan kurang khawatir tentang memulai tidak dioptimalkan.
  • APC dan Zend Optimizer adalah cache opcode, mereka mempercepat kode PHP dengan menghindari reparasi dan kompilasi ulang kode. Umumnya mudah dipasang, layak dilakukan sejak dini.
  • Memcached adalah cache generik, yang dapat Anda gunakan untuk men-cache permintaan, fungsi atau objek PHP, atau seluruh halaman. Kode harus ditulis secara khusus untuk menggunakannya, yang dapat menjadi proses yang terlibat jika tidak ada titik pusat untuk menangani pembuatan, pembaruan, dan penghapusan objek yang di-cache.
  • QuickCache dan JPCache adalah cache file, atau mirip dengan Memcached. Konsep dasarnya sederhana, tetapi juga membutuhkan kode dan lebih mudah dengan titik pusat pembuatan, pembaruan, dan penghapusan.

Lain-lain

  • Pertimbangkan server web alternatif untuk beban tinggi. Server seperti lighthttp dan nginx dapat menangani lalu lintas dalam jumlah besar dalam memori yang jauh lebih sedikit daripada Apache , jika Anda dapat mengorbankan kekuatan dan fleksibilitas Apache (atau jika Anda tidak membutuhkan hal-hal itu, yang seringkali, Anda tidak perlu).
  • Ingatlah bahwa perangkat keras sangat murah akhir-akhir ini, jadi pastikan untuk mengeluarkan biaya untuk mengoptimalkan blok kode besar versus "mari kita beli server monster."
  • Pertimbangkan untuk menambahkan tag "MySQL" dan "scaling" ke pertanyaan ini
Paul Kroll
sumber
9

APC adalah keharusan mutlak. Tidak hanya itu membuat sistem caching yang hebat, tetapi keuntungan dari file-file PHP yang di-cache otomatis adalah anugerah. Adapun ide beberapa database, saya tidak berpikir Anda akan mendapatkan banyak dari memiliki database berbeda di server yang sama. Ini mungkin memberi Anda sedikit peningkatan kecepatan selama waktu kueri, tapi saya ragu upaya yang diperlukan untuk menyebarkan dan mempertahankan kode untuk ketiganya sambil memastikan mereka dalam sinkronisasi akan sepadan.

Saya juga sangat merekomendasikan menjalankan Xdebug untuk menemukan hambatan dalam program Anda. Itu membuat optimasi mudah bagi saya.

tslocum
sumber
9

Pertama, seperti yang saya pikir Knuth katakan, "Optimalisasi prematur adalah akar dari semua kejahatan". Jika Anda tidak harus berurusan dengan masalah-masalah ini saat ini juga, jangan fokus untuk memberikan sesuatu yang berfungsi dengan benar terlebih dahulu. Yang sedang berkata, jika optimasi tidak bisa menunggu.

Cobalah membuat profil kueri basis data Anda, cari tahu apa yang lambat dan apa yang terjadi, dan buatlah strategi pengoptimalan dari situ.

Saya akan menyelidiki Memcached karena apa yang digunakan oleh banyak situs pemuatan yang lebih tinggi untuk konten caching yang efisien dari semua jenis, dan antarmuka objek PHP cukup bagus.

Memisahkan basis data di antara server dan menggunakan semacam teknik penyeimbangan beban (mis., Menghasilkan angka acak antara 1 dan # basis data yang berlebihan dengan data yang diperlukan - dan menggunakan nomor itu untuk menentukan server basis data mana yang akan disambungkan) juga bisa menjadi cara terbaik untuk meningkatkan efisiensi.

Ini semua bekerja dengan sangat baik di masa lalu untuk beberapa situs beban yang cukup tinggi. Semoga ini bisa membantu Anda memulai :-)

Eric Scrivner
sumber
1
RequiredFullQuote: "Kita harus melupakan efisiensi kecil, katakanlah sekitar 97% dari waktu: optimasi prematur adalah akar dari semua kejahatan"
Alister Bulman
RequiredReallyFullQuote: "Programer menghabiskan banyak waktu memikirkan, atau mengkhawatirkan, kecepatan bagian nonkritis dari program mereka, dan upaya efisiensi ini sebenarnya memiliki dampak negatif yang kuat ketika debugging dan pemeliharaan dipertimbangkan. Kita harus melupakan efisiensi kecil, katakan sekitar 97% dari waktu: optimasi prematur adalah akar dari semua kejahatan. Namun kita tidak boleh melewatkan peluang kita dalam 3% kritis itu. "
cHao
6

Memprofilkan aplikasi Anda dengan sesuatu seperti Xdebug (disarankan tj9991) pasti akan menjadi keharusan. Itu tidak masuk akal untuk hanya berkeliling mengoptimalkan hal-hal secara membabi buta. Xdebug akan membantu Anda menemukan hambatan nyata dalam kode Anda sehingga Anda dapat menghabiskan waktu optimasi Anda dengan bijak dan memperbaiki potongan kode yang sebenarnya menyebabkan penurunan lambat.

Jika Anda menggunakan Apache, utilitas lain yang dapat membantu dalam pengujian adalah Siege . Ini akan membantu Anda mengantisipasi bagaimana server dan aplikasi Anda akan bereaksi terhadap beban tinggi dengan benar-benar menempatkannya di langkahnya.

Setiap jenis cache opcode untuk PHP (seperti APC atau yang lainnya) akan banyak membantu juga.

Bob Somers
sumber
6

Saya menjalankan situs web dengan 7-8 juta tampilan halaman per bulan. Tidak terlalu banyak, tetapi cukup bahwa server kami merasakan beban. Solusi yang kami pilih sederhana: Memcache di tingkat basis data. Solusi ini berfungsi dengan baik jika beban basis data adalah masalah utama Anda.

Kami mulai menggunakan Memcache untuk menembolok seluruh objek dan hasil basis data yang paling sering digunakan. Itu memang berhasil, tetapi juga menimbulkan bug (kami mungkin menghindari beberapa dari mereka jika kami lebih berhati-hati).

Jadi kami mengubah pendekatan kami. Kami membangun pembungkus basis data (dengan metode yang sama persis seperti basis data lama kami, sehingga mudah untuk beralih), dan kemudian kami mensubklasifikasikannya untuk menyediakan metode akses basis data memcached.

Sekarang yang harus Anda lakukan adalah memutuskan apakah kueri dapat menggunakan hasil yang di-cache (dan mungkin kedaluwarsa) atau tidak. Sebagian besar kueri yang dijalankan oleh pengguna sekarang diambil langsung dari Memcache. Pengecualiannya adalah pembaruan dan sisipan, yang untuk situs web utama hanya terjadi karena pencatatan. Ukuran yang agak sederhana ini mengurangi beban server kami sekitar 80%.

Vegard Larsen
sumber
6

Untuk apa nilainya, caching DIRT SIMPLE dalam PHP bahkan tanpa paket ekstensi / pembantu seperti memcached.

Yang perlu Anda lakukan adalah membuat buffer output menggunakan ob_start().

Buat fungsi cache global. Panggilanob_start , operasikan fungsinya sebagai panggilan balik. Dalam fungsinya, cari versi halaman yang di-cache. Jika ada, sajikan dan akhiri.

Jika tidak ada, skrip akan melanjutkan pemrosesan. Ketika mencapai ob_end yang cocok () itu akan memanggil fungsi yang Anda tentukan. Pada saat itu, Anda hanya mendapatkan isi buffer output, letakkan di file, simpan file, dan akhiri.

Tambahkan koleksi kadaluwarsa / sampah.

Dan banyak orang tidak menyadari bahwa Anda dapat bersarang ob_start()/ ob_end()menelepon. Jadi, jika Anda sudah menggunakan buffer output untuk, misalkan, mengurai dalam iklan atau melakukan penyorotan sintaks atau apa pun, Anda bisa membuat sarang ob_start/ob_endpanggilan lain .

AJ
sumber
+1 karena terlihat seperti ide yang menarik. Saya tidak tahu seberapa baik kerjanya kinerja-bijaksana
Sylverdrag
+1 karena ini adalah ide yang menarik. Panggilan balik itu bisa memanggil kelas caching saya untuk saya!
Xeoncross
5

Terima kasih atas saran tentang ekstensi caching PHP - dapatkah Anda menjelaskan alasan penggunaan satu sama lain? Saya pernah mendengar hal-hal hebat tentang memcached melalui IRC tetapi belum pernah mendengar tentang APC - apa pendapat Anda tentang mereka? Saya berasumsi menggunakan beberapa sistem caching cukup kontra-efektif.

Sebenarnya, banyak yang menggunakan APC dan memcached bersama ...

ceejayoz
sumber
4

Sepertinya saya salah . MySQLi masih dikembangkan. Tetapi menurut artikel tersebut, PDO_MySQL sekarang sedang dikontribusikan oleh tim MySQL. Dari artikel:

MySQL Improved Extension - mysqli - adalah andalannya. Ini mendukung semua fitur dari Server MySQL termasuk Charset, Pernyataan Disiapkan dan Prosedur Tersimpan. Driver menawarkan API hybrid: Anda dapat menggunakan gaya pemrograman prosedural atau berorientasi objek berdasarkan preferensi Anda. mysqli hadir dengan PHP 5 dan lebih tinggi. Perhatikan bahwa Akhir hidup untuk PHP 4 adalah 2008-08-08.

Objek Data PHP (PDO) adalah lapisan abstraksi akses database. PDO memungkinkan Anda untuk menggunakan panggilan API yang sama untuk berbagai database. PDO tidak menawarkan tingkat abstraksi SQL apa pun. PDO_MYSQL adalah driver MySQL untuk PDO. PDO_MYSQL hadir dengan PHP 5. Pada PHP 5.3, pengembang MySQL berkontribusi secara aktif. Keuntungan PDO dari API terpadu datang pada harga yang fitur-fitur spesifik MySQL, misalnya beberapa pernyataan, tidak sepenuhnya didukung melalui API terpadu.

Tolong berhenti menggunakan driver MySQL pertama untuk PHP yang pernah diterbitkan: ext / mysql. Sejak diperkenalkannya MySQL Improved Extension - mysqli - pada tahun 2004 dengan PHP 5, tidak ada alasan untuk tetap menggunakan driver tertua di sekitar. ext / mysql tidak mendukung Charset, Pernyataan yang Disiapkan, dan Prosedur yang Disimpan. Ini terbatas pada set fitur MySQL 4.0. Perhatikan bahwa Dukungan yang Diperpanjang untuk MySQL 4.0 berakhir pada 2008-12-31. Jangan membatasi diri Anda pada set fitur perangkat lunak lama seperti itu! Tingkatkan ke mysqli, lihat juga Converting_to_MySQLi. mysql dalam mode pemeliharaan saja dari sudut pandang kami.

Bagi saya, sepertinya artikel ini bias terhadap MySQLi. Saya kira saya bias terhadap PDO. Saya sangat suka PDO melalui MySQLi. Ini lurus ke depan bagi saya. API jauh lebih dekat dengan bahasa lain yang telah saya programkan. Antarmuka database OO tampaknya berfungsi lebih baik.

Saya belum menemukan fitur MySQL spesifik yang tidak tersedia melalui PDO. Saya akan terkejut jika saya melakukannya.

Gary Richardson
sumber
3

PDO juga sangat lambat dan API-nya cukup rumit. Tidak ada seorang pun di pikiran waras mereka yang boleh menggunakannya jika portabilitas bukan masalah. Dan mari kita hadapi itu, di 99% dari semua aplikasi web tidak. Anda tetap menggunakan MySQL atau PostrgreSQL, atau apa pun yang sedang Anda kerjakan.

Adapun pertanyaan PHP dan apa yang harus diperhitungkan. Saya pikir optimasi prematur adalah akar dari semua kejahatan. ;) Selesaikan aplikasi Anda terlebih dahulu, cobalah untuk tetap bersih ketika datang ke pemrograman, lakukan sedikit dokumentasi dan tulis tes unit. Dengan semua hal di atas, Anda tidak akan memiliki masalah kode refactoring ketika saatnya tiba. Tetapi pertama-tama Anda ingin dilakukan dan dorong keluar untuk melihat bagaimana orang bereaksi terhadapnya.

Sampai
sumber
2

Tentu PDO bagus, tetapi ada telah telah beberapa kontroversi tentang kinerja itu versus mysql dan mysqli, meskipun tampaknya tetap sekarang.

Anda harus menggunakan pdo jika Anda membayangkan portabilitas, tetapi jika tidak, mysqli harus menjadi caranya. Ini memiliki antarmuka OO, pernyataan yang disiapkan, dan sebagian besar dari apa yang ditawarkan pdo (kecuali, baik, mudah dibawa).

Plus, jika kinerja benar-benar diperlukan, bersiaplah untuk driver MysqLnd (asli mysql) di PHP 5.3, yang akan jauh lebih terintegrasi dengan php, dengan kinerja yang lebih baik dan penggunaan memori yang ditingkatkan (dan statistik untuk tuning kinerja).

Memcache bagus jika Anda memiliki server berkerumun (dan memuat seperti YouTube), tetapi saya juga akan mencoba APC terlebih dahulu.

Berzemus
sumber
2

Banyak jawaban bagus sudah diberikan, tetapi saya ingin mengarahkan Anda ke cache opcode alternatif yang disebut XCache . Itu dibuat oleh kontributor ringan.

Juga, jika Anda mungkin perlu menyeimbangkan server database Anda di masa depan, MySQL Proxy dapat sangat membantu Anda untuk mencapai ini.

Kedua alat tersebut harus cukup mudah dihubungkan ke aplikasi yang sudah ada, sehingga pengoptimalan ini dapat dilakukan saat Anda membutuhkannya, tanpa terlalu banyak kesulitan.

lengket
sumber
2

Pertanyaan pertama adalah seberapa besar yang Anda harapkan? Dan berapa banyak yang Anda rencanakan untuk berinvestasi dalam infrastruktur Anda. Karena Anda merasa perlu mengajukan pertanyaan di sini, saya menduga Anda akan memulai dari yang kecil dengan anggaran terbatas.

Performa tidak relevan jika situs tidak tersedia. Dan untuk ketersediaan Anda perlu penskalaan horizontal. Minimal yang dapat Anda masuki adalah 2 server, baik yang menjalankan apache, php dan mysql. Siapkan satu DBMS sebagai budak ke yang lain. Lakukan semua penulisan pada master, dan semua bacaan pada database lokal (apa pun itu) - kecuali karena alasan tertentu Anda perlu membaca kembali data yang baru saja Anda baca (gunakan master). Pastikan Anda memiliki mesin di tempat untuk secara otomatis mempromosikan budak dan pagar tuan. Gunakan round-robin DNS untuk alamat server web untuk memberikan lebih banyak afinitas untuk slave node.

Memartisi data Anda di berbagai basis data node pada tahap ini adalah ide yang sangat buruk - namun Anda mungkin ingin mempertimbangkan memecahnya di berbagai basis data di server yang sama (yang akan memudahkan pemartisian di seluruh node ketika Anda menyalip facebook).

Pastikan Anda memiliki alat pemantauan dan analisis data untuk mengukur kinerja situs Anda dan mengidentifikasi kemacetan. Sebagian besar masalah kinerja dapat diperbaiki dengan menulis SQL yang lebih baik / memperbaiki skema database.

Menyimpan cache templat Anda di basis data adalah ide yang bodoh - basis data harus menjadi pusat penyimpanan umum untuk data terstruktur. Simpan cache templat Anda pada sistem file lokal server web Anda - ini akan tersedia lebih cepat dan tidak akan memperlambat akses basis data Anda.

Gunakan cache kode-op.

Luangkan banyak waktu untuk mempelajari situs Anda dan log-nya untuk memahami mengapa hal ini berjalan sangat lambat.

Dorong caching sebanyak mungkin ke klien.

Gunakan mod_gzip untuk mengompres semua yang Anda bisa.

C.

symcbean
sumber
2

Saran pertama saya adalah memikirkan masalah ini dan mengingatnya saat mendesain situs tetapi jangan berlebihan . Seringkali sulit untuk memprediksi keberhasilan situs baru dan saya waktu Anda akan lebih baik dihabiskan untuk bangun lebih awal dan mengoptimalkannya nanti.

Secara umum, Simple cepat . Template memperlambat Anda. Database memperlambat Anda. Perpustakaan kompleks memperlambat Anda. Layering templat satu sama lain mengambilnya dari basis data dan menguraikannya di perpustakaan yang kompleks -> waktu tunda saling berlipat ganda.

Setelah Anda memiliki situs dasar dan menjalankan lakukan tes untuk menunjukkan di mana Anda menghabiskan upaya Anda. Sulit untuk melihat ke mana harus menargetkan. Seringkali untuk mempercepat Anda harus mengungkap kompleksitas kode, ini membuatnya lebih besar dan lebih sulit untuk dipelihara, jadi Anda hanya ingin melakukannya jika perlu.

Dalam pengalaman saya membangun koneksi basis data relatif mahal. Jika Anda dapat menghindarinya, jangan terhubung ke database untuk pengunjung umum pada halaman yang paling banyak dilalui seperti halaman depan ke situs. Membuat banyak koneksi basis data adalah kegilaan dengan sedikit manfaat.

penginapan
sumber
1

@ Gary

Jangan gunakan MySQLi - PDO adalah lapisan akses database OO 'modern'. Fitur terpenting untuk digunakan adalah placeholder dalam kueri Anda. Cukup cerdas untuk menggunakan persiapan sisi server dan optimasi lainnya untuk Anda juga.

Saya mencari PDO saat ini dan sepertinya Anda benar - namun saya tahu bahwa MySQL sedang mengembangkan ekstensi MySQLd untuk PHP - saya pikir untuk berhasil baik MySQL atau MySQLi - apa pendapat Anda tentang itu?


@ Ryan , Eric , tj9991

Terima kasih atas saran tentang ekstensi caching PHP - dapatkah Anda menjelaskan alasan penggunaan satu sama lain? Saya pernah mendengar hal-hal hebat tentang memcached melalui IRC tetapi belum pernah mendengar tentang APC - apa pendapat Anda tentang mereka? Saya berasumsi menggunakan beberapa sistem caching cukup kontra-efektif.

Saya pasti akan memilah beberapa penguji profiling - terima kasih banyak atas rekomendasi Anda pada mereka.

Ross
sumber
1

Saya tidak melihat diri saya beralih dari MySQL dalam waktu dekat - jadi saya kira saya tidak perlu kemampuan abstraksi dari PDO. Terima kasih untuk artikel-artikel DavidM, mereka telah banyak membantu saya.

Ross
sumber
1

Lihat ke mod_cache , cache output untuk server web Apache, mirip dengan caching output di ASP.NET.

Ya, saya dapat melihat bahwa ini masih eksperimental tetapi suatu hari akan final.

Andrei Rînea
sumber
1

Saya tidak percaya tidak ada yang pernah menyebutkan ini: Modularisasi dan Abstraksi. Jika Anda berpikir situs Anda harus tumbuh ke banyak mesin, Anda harus mendesainnya agar bisa! Itu berarti hal-hal bodoh seperti jangan menganggap database ada di localhost. Ini juga berarti hal-hal yang akan mengganggu pada awalnya, seperti menulis lapisan abstraksi basis data (seperti PDO, tetapi jauh lebih ringan karena hanya melakukan apa yang perlu Anda lakukan).

Dan itu berarti hal-hal seperti bekerja dengan kerangka kerja. Anda akan memerlukan lapisan untuk kode Anda sehingga nanti Anda bisa mendapatkan kinerja dengan refactoring lapisan abstraksi data, misalnya, dengan mengajarkannya bahwa beberapa objek berada di database yang berbeda - dan kode tidak harus tahu atau peduli .

Akhirnya, berhati-hatilah terhadap operasi intensif-memori, misalnya, penyalinan string yang tidak perlu. Jika Anda dapat menjaga penggunaan memori PHP tetap rendah, maka Anda akan mendapatkan lebih banyak kinerja dari server web Anda dan ini adalah sesuatu yang akan ditingkatkan ketika Anda pergi ke solusi beban-seimbang.

ahli statika
sumber
1

Jika Anda bekerja dengan sejumlah besar data, dan caching tidak memotongnya, lihat Sphinx. Kami memiliki hasil yang luar biasa dengan menggunakan SphinxSearch tidak hanya untuk pencarian teks yang lebih baik, tetapi juga sebagai pengganti pengambilan data untuk MySQL saat menangani tabel yang lebih besar. Jika Anda menggunakan SphinxSE (plugin MySQL), itu melampaui keuntungan kinerja kami yang kami dapatkan dari caching beberapa kali, dan implementasi aplikasi adalah hal yang aneh.


sumber
1

Poin yang dibuat tentang cache adalah spot-on; ini adalah bagian paling tidak rumit dan paling penting dalam membangun aplikasi yang efisien. Saya ingin menambahkan bahwa meskipun memcached bagus, APC sekitar lima kali lebih cepat jika aplikasi Anda hidup di satu server.

Posting "Perbandingan Kinerja Cache" di blog kinerja MySQL memiliki beberapa tolok ukur yang menarik pada subjek - http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/ .

Johannes Gorset
sumber