Yüksek yüklü bir sitede PHP kullanma taktikleri


242

Buna cevap vermeden önce, yüksek sunucu yüklerine ulaşmak için yeterince popüler bir şey geliştirmedim. Bana PHP ve birkaç optimizasyon tekniğini bilen bir gezegen olsa da, gezegene yeni gelmiş bir uzaylı gibi davran.


PHP'de doğru çalışırsa, oldukça fazla kullanıcı elde edebilecek bir araç geliştiriyorum . Ancak programı tamamen geliştirebiliyorum, büyük trafikle baş edebilecek bir şey yapmak söz konusu olduğunda neredeyse hiç clueless. İşte size birkaç soru (bu soruyu bir kaynak dizisine dönüştürmekten çekinmeyin).

Veritabanları

Şu anda PHP5'te MySQLi özelliklerini kullanmayı planlıyorum. Ancak veritabanlarını kullanıcılar ve içerikle ilgili olarak nasıl ayarlamalıyım? Aslında birden fazla veritabanına ihtiyacım var mı? Şu anda her şey bir veritabanına karıştı - kullanıcı verilerini bir veriye yaymayı düşünmeme rağmen, gerçek içeriği başka bir içeriğe ve nihayetinde çekirdek site içeriğine (şablon yöneticileri vb.) Diğerine. Bunun arkasındaki akıl yürütme, farklı veritabanlarına sorgu göndermenin, bir veritabanı = 3 yük kaynağı olarak üzerlerindeki yükü hafifleteceğidir. Ayrıca hepsi aynı sunucudaysa bu yine de etkili olur mu?

Önbelleğe almak

Sayfaları oluşturmak ve değişkenleri takas için kullanılan bir şablon sistemi var. Ana şablonlar veritabanında saklanır ve bir şablon her çağrıldığında önbelleğe alınmış kopyası (html belgesi) çağrılır. Şu anda bu şablonlarda iki tür değişkenim var - statik bir değişken ve dinamik bir değişken. Statik değişkenler genellikle sayfa adları, sitenin adı - sık sık değişmeyen şeyler; dinamik değişkenler her sayfa yükünde değişen şeylerdir.

Bu konudaki sorum:

Farklı makaleler hakkında yorum yaptığımı söyle. Hangisi daha iyi bir çözümdür: Basit yorum şablonunu saklayın ve sayfa her yüklendiğinde (DB çağrısından) yorum yapın veya yorum sayfasının önbelleğe alınmış bir kopyasını html sayfası olarak saklayın - her yorum eklendiğinde / düzenlendiğinde / silindiğinde sayfa önbelleğe alınır.

En sonunda

Herkes PHP yüksek yük sitesi çalıştırmak için herhangi bir ipucu / işaretçiler var mı. Kullanılabilir bir dil olduğuna eminim - Facebook ve Yahoo! büyük bir öncelik verin - ama dikkat etmem gereken herhangi bir deneyim var mı?


9
3,5 yıl sonra ne üzerinde çalıştığımı bile hatırlayamıyorum, ben de neyin çok havalı olduğunu düşündüğümü bilmek istiyorum :)
Ross

8
Bu size erken optimizasyon hakkında bir ders olsun :)
Rimu Atkinson

Yanıtlar:


89

İki site birbirine benzemez. Sorun noktalarınızın nerede olacağını görmek için gerçekten jmeter ve benchmark gibi bir araç almanız gerekiyor. Tahmin etmek ve iyileştirmek için çok zaman harcayabilirsiniz, ancak değişikliklerinizi ölçüp karşılaştırana kadar gerçek sonuçları görmezsiniz.

Örneğin, uzun yıllar boyunca MySQL sorgu önbelleği, tüm performans sorunlarımızın çözümü oldu. Siteniz yavaşsa, MySQL uzmanları sorgu önbelleğini açmanızı önerdi. Yüksek bir yazma yükünüz varsa, önbellek aslında sakatlanıyor. Test etmeden açarsanız, asla bilemezsiniz.

Ve asla ölçeklendirme yapılmadığını unutmayın. 10req / s işleyen bir sitenin 1000req / s desteklemek için değişiklik yapması gerekir. Ve 10.000req / sn'yi destekleyecek kadar şanslıysanız, mimariniz de muhtemelen tamamen farklı görünecektir.

Veritabanları

  • MySQLi kullanmayın - PDO 'modern' OO veritabanı erişim katmanıdır. Kullanılacak en önemli özellik, sorgularınızdaki yer tutuculardır. Sizin için sunucu tarafı hazırlıkları ve diğer optimizasyonları kullanmak için yeterince akıllı.
  • Muhtemelen bu noktada veritabanınızı bölmek istemezsiniz. Bir veritabanının kesilmediğini fark ederseniz, uygulamanıza bağlı olarak ölçeklendirmek için birkaç teknik vardır. Ek sunuculara çoğaltma, yazma işleminden daha fazla okumanız varsa iyi çalışır. Parçalama, verilerinizi birçok makineye bölme tekniğidir.

Önbelleğe almak

  • Muhtemelen veritabanınızda önbellek istemezsiniz. Veritabanı genellikle darboğazınızdır, bu nedenle ona daha fazla IO eklemek genellikle kötü bir şeydir. APC ve Zend gibi benzer şeyleri gerçekleştiren birkaç PHP önbelleği var .
  • Sisteminizi önbellek açık ve kapalı olarak ölçün. Eminim önbelleğiniz sayfaları düz olarak sunmaktan daha ağırdır.
  • Yorumlarınızı ve makale verilerinizi db'den oluşturmak uzun zaman alıyorsa, memcache'ı sisteminize entegre edin. Sorgu sonuçlarını önbelleğe alabilir ve bunları memcached örneğinde saklayabilirsiniz. Herhangi bir fayda görmek için memcache'den veri almanın veritabanından birleştirilmesinden daha hızlı olması gerektiğini hatırlamak önemlidir.
  • Makaleleriniz dinamik değilse veya oluşturulduktan sonra basit dinamik değişiklikleriniz varsa, diske html veya php yazmayı düşünün. Makale için disk üzerinde görünen bir index.php sayfanız olabilir, varsa, istemciye aktarır. Değilse, makaleyi oluşturur, diske yazar ve istemciye gönderir. Dosyaları diskten silmek sayfaların yeniden yazılmasına neden olur. Bir makaleye yorum eklenirse, önbelleğe alınan kopyayı silin; yeniden oluşturulur.

10
@ diske yazma. Hatta index.php'yi halledebilir ve Apache'nin sizin için işi yapmasına izin verebilirsiniz, böylece index.php yalnızca yol yoksa çağrılır. Bunun için mode_rewrite kullanırdınız.
troelskn

5
-1, PDO, MySQLi ve hatta MySQL uzantısından önemli ölçüde yavaştır.
Alix Axel

4
PDO mysqli'den çok daha yavaştı ve benim için iç içe sorgular için doğru çalışmadı. Mysqli ayrıca PDO gibi sunucu tarafı hazırlıkları ve bağlı parametreleri de destekler.
Daren Schwenke

5
Bunun bir cevap olarak kabul edildiğine inanamıyorum. Bu hiç iyi değil.
symcbean

1
about: caching - resimler, css, htm ve js yardımcı olacak, resimlerdeki çerezleri de kapatacak!
Talvi Watia

61

15 milyondan fazla kullanıcısı olan bir sitede baş geliştiriciyim. Biz erken planlama ve düşünceli ölçekli çünkü çok az ölçekleme sorunları vardı. İşte deneyimlerimden önerebileceğim bazı stratejiler.

SCHEMA Öncelikle şemalarınızı denormalize edin. Bu, birden çok ilişkisel tabloya sahip olmak yerine, büyük bir tabloya sahip olmayı seçmeniz gerektiği anlamına gelir. Genel olarak, birleşimler değerli DB kaynaklarının israfıdır, çünkü çoklu hazırlıklar ve harmanlama yapmak disk G / Ç'lerini yakar. Yapabildiğiniz zaman kaçının.

Buradaki takas, gereksiz verileri depolayacağınız / çekeceğinizdir, ancak bu kabul edilebilir çünkü veri ve kafes içi bant genişliği çok ucuzdur (daha büyük diskler), ancak çoklu hazırlama G / Ç'leri büyüklük daha pahalıdır (daha fazla sunucu) .

ENDEKSLEME Sorgularınızda en az bir dizin kullandığınızdan emin olun. Ancak, sık sık yazıyorsanız veya güncellerseniz dizinlerin size maliyeti olacağını unutmayın. Bundan kaçınmak için bazı deneysel püf noktaları vardır.

Dizine eklenen ve dizine eklenen sütunlarınıza paralel olarak çalışan ek sütunlar eklemeyi deneyebilirsiniz. Ardından, dizinlenmemiş sütunları toplu olarak dizinlenmiş sütunların üzerine yazan çevrimdışı bir işleminiz olabilir. Bu şekilde, mySQL'in dizini yeniden hesaplaması gerektiğinde daha iyi kontrol edebilirsiniz.

Veba gibi hesaplanan sorgulardan kaçının. Bir sorgu hesaplamanız gerekiyorsa, bunu yazma zamanında bir kez yapmaya çalışın.

Önbellekleme Memcached tavsiye ederim. PHP yığınındaki (Facebook) en büyük oyuncular tarafından kanıtlanmıştır ve çok esnektir. Bunu yapmak için iki yöntem vardır, biri DB katmanınızda önbellekleme, diğeri iş mantığı katmanınızda önbellekleme.

DB katmanı seçeneği, DB'den alınan sorguların sonucunun önbelleğe alınmasını gerektirir. SQL sorgunuzu md5 () kullanarak özetleyebilir ve veritabanına gitmeden önce bunu bir arama anahtarı olarak kullanabilirsiniz. Bunun tersi, uygulanması oldukça kolaydır. Dezavantajı (uygulamaya bağlı olarak) esnekliği kaybetmenizdir, çünkü önbelleğin sona ermesiyle ilgili tüm önbelleğe alma işlemlerini aynı şekilde gerçekleştirirsiniz.

Çalıştığım dükkanda, iş katmanı önbellekleme kullanıyoruz, yani sistemimizdeki her beton sınıfı kendi önbellek şemasını ve önbellek zaman aşımlarını kontrol ediyor. Bu bizim için oldukça iyi çalıştı, ancak DB'den alınan öğelerin önbellekten alınan öğelerle aynı olmayabileceğini unutmayın, bu nedenle önbelleği ve DB'yi birlikte güncellemeniz gerekecektir.

VERİ PAYLAŞIMI Çoğaltma yalnızca size şimdiye kadar ulaşır . Beklediğinizden daha kısa sürede, yazılarınız bir darboğaz haline gelecektir. Telafi etmek için, veri parçalamayı olabildiğince erken desteklediğinizden emin olun. Muhtemelen daha sonra ateş etmek isteyeceksiniz.

Uygulaması oldukça basittir. Temel olarak, anahtar otoriteyi veri deposundan ayırmak istersiniz. Birincil anahtarlar ve küme kimlikleri arasında bir eşleme depolamak için genel bir DB kullanın. Bir küme almak için bu eşlemeyi sorgulayın ve sonra verileri almak için kümeyi sorgulayın. İhmal edilebilir bir işlem olmasını sağlayacak olan bu arama işleminden cehennemi önbelleğe alabilirsiniz.

Bunun dezavantajı, birden fazla parçadan verileri bir araya getirmenin zor olabileceğidir. Ancak, bu konuda da yolunuzu ayarlayabilirsiniz.

ÇEVRİMDIŞI İŞLEME Kullanıcı, gerekmedikçe arka ucunuzu beklemesini sağlamaz. Bir iş kuyruğu oluşturun ve çevrimdışı olarak yapabileceğiniz tüm işlemleri taşıyarak kullanıcının isteğinden ayrı yapın.


9
+1 Eller aşağı, bu kabul edilen cevap olmalı. Veritabanları oluşturmakla ilgili okuduğum her şeyin, birleştirme yapmanın performans hitinden bahsetmeden her zaman "tüm verileri olabildiğince normalleştirin" yazması ilginçtir. Her zaman sezgisel olarak birleşimlerin (özellikle çoklu) çok fazla yük getirdiğini hissettim, ancak şimdiye kadar açıkça söylediklerini duymadım. Keşke MySQL dizinleri hesaplarken kontrol etmek hakkında ne konuştuğunuzu daha iyi anlamış olsaydım, çok ilginç bir saldırı gibi geliyor.
Evan Plaice

Çok büyük büyüyen veritabanları için veri parçalama çok önemlidir. Google'ın (arama motoru değil şirket), parçalama düzenlerini uygulama hakkında söyleyecek çok ilginç şeyler var. Çevrimdışı işleme, veritabanı yazma sayısını sınırlamak (ve tablo dizini yeniden hesaplamalarının sayısını sınırlamak) söz konusu olduğunda da çok büyüktür. Bloglar çok gördüm (ve hatta Stack Overflow bile) kullanıcı tarafından oluşturulan yorum / geri bildirim sistemleri için bu tekniği kullanmak düşünüyorum.
Evan Plaice

1
Yorumlar için teşekkürler. Bazılarının veri G / Ç veya istemci-sunucu G / Ç'de VAST yürütme süresi harcandığında orta düzey kodun profilini oluşturması şaşırtıcıdır. 40 ms süren bir PHP işleminin yürütme süresinden% 20 tasarruf sağlayan ubber karmaşık optimizasyon, 1s veritabanı sorgusu üzerinden yapılan basit% 5 tasarrufla karşılaştırıldığında anlamsızdır.
thesmart

42

PHP ve MySQL tarafından milyonlarca / ayda / ayda desteklenen birkaç sitede çalıştım. İşte bazı temel bilgiler:

  1. Önbellek, önbellek, önbellek. Önbellekleme, web sunucunuz ve veritabanınızdaki yükü azaltmanın en basit ve en etkili yollarından biridir. Önbellek sayfası içeriği, sorgular, pahalı hesaplama, G / Ç bağlantılı her şey. Memcache çok basit ve etkilidir.
  2. En fazla kullanımdan sonra birden çok sunucu kullanın. Birden çok web sunucunuz ve birden çok veritabanı sunucunuz olabilir (çoğaltma ile).
  3. Web sunucularınız için genel istek sayısını azaltın. Bu, JS, CSS ve resimlerin sona erme başlıkları kullanılarak önbelleğe alınmasını gerektirir. Statik içeriğinizi, kullanıcı deneyiminizi hızlandıracak bir CDN'ye de taşıyabilirsiniz.
  4. Ölçü ve kıyaslama. Nagios'u üretim makinelerinizde çalıştırın ve dev / qa sunucunuzda yük testi yapın. Sunucunuzun ne zaman yanacağını bilmeniz gerekir, böylece önleyebilirsiniz.

Ölçeklenebilir Web Siteleri Oluşturmayı okumanızı tavsiye ederim , Flickr mühendislerinden biri tarafından yazılmıştır ve büyük bir referanstır.

Ölçeklenebilirlik hakkındaki blog gönderime de göz atın, birden fazla dil ve platformla ölçeklendirme hakkında sunumlara çok sayıda bağlantı var: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/


1
+1 Burada çok iyi bilgiler var. Son zamanlarda bu konuda daha fazla araştırma yapıyorum ve cevabınız okuduğum her şeyle aynı doğrultuda. Memcache, önbellekleme, statik içerik için CDN, istekleri azaltma; tüm iyi şeyler. Ayrıca, güncellenen dosyaların önbellekte benzersiz bir imzaya sahip olması için, sunucu tarafında statik içerik dosyalarında (CDN / önbellek arkasındaysa) karmalar oluşturup ekleyeceğim. Ayrıca, istekleri azaltmak için statik kaynak dosyalarını (css, javascript) anında birleştirin (ve dosya adı karmalarıyla önbelleğe alın). Ayrıca, dinamik olarak başparmak oluşturun (ve bunları önbellekte saklayın)
Evan Plaice

Google, tüm statik içerik için tüm dosya birleştirmelerini, küçültmeyi, hash içerecek dosya yeniden adlandırma işlemlerini gerçekleştirebilen mod_pagespeed adlı bir apache modülü oluşturdu. Önbellek (ve CDN (ler)) içeriğin çoğuyla dolduruluncaya kadar, sunuculara başlangıçta yalnızca küçük bir işlem yükü ekleyecektir. Ayrıca, güvenlik için, genel olarak erişilebilen (kullanıcılar) tabloları arka uçla işlemek yerine tablolarla aynı veritabanına koymak genellikle kötü bir fikirdir (eğer bir nedenle tablolardan biri saldırıya uğramışsa).
Evan Plaice

39

Yanıt: PDO / MySQLi / MySQLND

@ gary

Farklı hedefleri olduğu için "MySQLi kullanma" diyemezsiniz. PDO neredeyse bir soyutlama katmanı gibidir (gerçekte olmasa da) ve MySQLi MySQL bağlantılarına özgüyken, çoklu veritabanı ürünlerinin kullanımını kolaylaştırmak için tasarlanmıştır. İfadeniz ilerlemenin mysql -> mysqli -> PDO olduğunu ima ettiğinden PDO'nun MySQLi ile karşılaştırılması bağlamında modern erişim katmanı olduğunu söylemek yanlıştır.

MySQLi ve PDO arasındaki seçim basittir - birden fazla veritabanı ürününü desteklemeniz gerekiyorsa PDO kullanırsınız. Sadece MySQL kullanıyorsanız PDO ve MySQLi arasında seçim yapabilirsiniz.

Peki neden PDO üzerinden MySQLi'yi seçesiniz? Aşağıya bakınız...

@ross

En yeni MySQL temel dil seviyesi kütüphanesi olan MySQLnd hakkında haklısınız, ancak MySQLi'nin yerini tutmaz. MySQLi (PDO'da olduğu gibi) PHP kodunuz aracılığıyla MySQL ile etkileşime girme şekliniz olarak kalır. Her ikisi de PHP kodunun arkasındaki C istemcisi olarak libmysql kullanır. Sorun şu ki libmysql çekirdek PHP motorunun dışında ve mysqlnd devreye giriyor.

MySQLnd, MySQL tarafından geliştirilmektedir ve yakın zamanda RC testinde bulunan ve bu yıl piyasaya sürülmeye hazır olan PHP 5.3 şubesine yerleşmiştir. Daha sonra MySQLnd'i MySQLi ile kullanabileceksiniz ... ancak PDO ile kullanamayacaksınız. Bu, MySQLi'ye birçok alanda (hepsi değil) bir performans artışı sağlayacak ve PDO'nun soyutlama gibi yeteneklerine ihtiyacınız yoksa MySQL etkileşimi için en iyi seçim olacaktır.

Yani MySQLnd dedi PHP 5.3 artık kullanılabilir , ancak, PDO hala genel bir veritabanı tabakasıdır ve bu yüzden olacak PDO için ve PDO içine ND performans geliştirmeleri avantajlarını alabilirsiniz dan kadar parası edebilmek pek mümkün MySQLi gibi ND'deki geliştirmeler .

Bazı faydalı kriterler 2006'dan beri burada bulunabilir . Bu seçenek gibi şeylerin de farkında olmanız gerekir .

MySQLi ve PDO arasında karar verirken dikkate alınması gereken birçok husus vardır. Çok yüksek talep sayılarına ulaşana kadar önemli olmayacak ve bu durumda, şeyleri özetleyen ve bir MySQL sürücüsü sağlamaktan ziyade, MySQL için özel olarak tasarlanmış bir uzantı kullanmak daha mantıklı. .

Basit bir mesele değildir, çünkü her birinin avantajları ve dezavantajları vardır. Sağladığım bağlantıları okumalı ve kendi kararınızı vermeli, sonra test etmeli ve öğrenmelisiniz. Geçmiş projelerde PDO kullandım ve iyi bir uzantı ama saf performans için seçimim (PHP 5.3 yayınlandığında) derlenen yeni MySQLND seçeneği ile MySQLi olacaktır.


6
PDO'dan mysqli'ye geçtim ve düzenli sorgular tam olarak 2 kat daha hızlı yürütülmeye başladı.
serg

5
@serg: Bunu doğrulamak için bazı testler göndermeye özen gösterilsin mi? Çünkü ciddi bir şekilde PDO'dan mysqli'ye geçmenin size böyle bir hız artışı sağlayacağından şüpheliyim.
Stann

23

Genel

  • Gerçek dünya yükünü görmeye başlamadan önce optimizasyon yapmaya çalışmayın. Doğru tahmin edebilirsin, ama yapmazsan zamanını boşa harcadın.
  • Kullanım Jmeter , xdebug veya kriter başka aracı site.
  • Yük bir sorun olmaya başlarsa, nesne veya veri önbelleklemesi büyük olasılıkla söz konusu olacaktır, bu nedenle genellikle önbellek seçeneklerini (memcached, MySQL önbellek seçenekleri) okuyun

kod

  • Darboğazın nerede olduğunu ve kodda mı yoksa veritabanında mı olduğunu bilmeniz için kodunuzu biçimlendirin

Veritabanları

  • Diğer veritabanlarına taşınabilirlik hayati değilse MYSQLi kullanın , aksi takdirde PDO
  • Karşılaştırmalar veritabanının sorun olduğunu gösteriyorsa, önbelleğe almaya başlamadan önce sorguları kontrol edin. Sorgularınızın nerede yavaşladığını görmek için EXPLAIN kullanın .
  • Sorgular en iyileştirildikten ve veritabanı bir şekilde önbelleğe alındıktan sonra birden çok veritabanı kullanmak isteyebilirsiniz. Verilere, sorgulara ve okuma / yazma davranışının türüne bağlı olarak, birden çok sunucuya çoğaltma veya parçalama (verileri birden çok veritabanına / sunucuya bölme) uygun olabilir.

Önbelleğe almak

  • Önbellek kodu, nesneler ve veriler üzerine çok sayıda yazı yapılmıştır. APC , Zend Optimizer , memcached , QuickCache , JPCache ile ilgili makalelere bakın . Gerçekten ihtiyaç duymadan önce bunlardan bazılarını yapın ve optimize edilmemiş çalışmaya başlama konusunda daha az endişe duyarsınız.
  • APC ve Zend Optimizer opcode önbellekleridir, kodun yeniden oluşturulmasını ve yeniden derlenmesini önleyerek PHP kodunu hızlandırırlar. Genellikle kurulumu kolaydır, erken yapmaya değer.
  • Memcached, sorguları, PHP işlevlerini veya nesnelerini veya tüm sayfaları önbelleğe almak için kullanabileceğiniz genel bir önbellektir. Kod kullanmak için özel olarak yazılmalıdır, önbelleğe alınmış nesnelerin oluşturulması, güncellenmesi ve silinmesi için merkezi bir nokta yoksa ilgili bir süreç olabilir.
  • QuickCache ve JPCache dosya önbellekleridir, aksi takdirde Memcached'a benzer. Temel konsept basittir, ancak kod gerektirir ve merkezi oluşturma, güncelleme ve silme noktalarıyla daha kolaydır.

Çeşitli

  • Yüksek yük için alternatif web sunucularını düşünün. Lighthttp ve nginx gibi sunucular , Apache'nin gücünü ve esnekliğini feda edebilirseniz (ya da çoğu zaman ihtiyacınız olmayan şeylere ihtiyacınız yoksa) Apache'den çok daha az bellekte büyük miktarda trafiği işleyebilir .
  • Donanımın bu günlerde şaşırtıcı derecede ucuz olduğunu unutmayın, bu nedenle büyük bir kod bloğunu "bir canavar sunucu satın alalım" yerine optimize etme çabasını harcadığınızdan emin olun.
  • Bu soruya "MySQL" ve "ölçeklendirme" etiketlerini eklemeyi düşünün

9

APC mutlak bir zorunluluktur. Sadece harika bir önbellek sistemi yapmakla kalmaz, aynı zamanda otomatik önbelleğe alınmış PHP dosyalarından elde edilen kazanç da bir nimettir. Birden çok veritabanı fikrine gelince, aynı sunucuda farklı veritabanlarına sahip olmaktan çok fazla alacağınızı sanmıyorum. Sorgu süresi sırasında hızda biraz kazanç sağlayabilir, ancak senkronizasyonda olduklarından emin olurken üçünün kodunu dağıtmak ve korumak için gereken çabadan şüpheliyim.

Programınızdaki darboğazları bulmak için Xdebug'u çalıştırmanızı da şiddetle tavsiye ederim . Optimizasyonu benim için bir esinti yaptı.


9

İlk olarak, Knuth'un dediği gibi, "Erken optimizasyon tüm kötülüklerin köküdür". Şu anda bu sorunlarla uğraşmak zorunda değilseniz, önce doğru çalışan bir şey sunmaya odaklanın. Bununla birlikte, optimizasyonlar bekleyemezse.

Veritabanı sorgularınızı profillemeyi deneyin, neyin yavaş ve neyin çok olduğunu anlayın ve bundan bir optimizasyon stratejisi oluşturun.

Memcached , yüksek yük sitelerinin her türlü içeriği verimli bir şekilde önbelleğe almak için ne kullandığını araştırıyor ve PHP nesne arayüzü oldukça güzel.

Veritabanlarını sunucular arasında bölme ve bir çeşit yük dengeleme tekniği kullanma (örneğin, gerekli verilerle 1 ve # yedekli veritabanları arasında rastgele bir sayı oluşturma - ve bu sayıyı hangi veritabanı sunucusuna bağlanacağını belirlemek için kullanma) da artırmak için mükemmel bir yol olabilir verimlilik.

Bunların hepsi geçmişte oldukça yüksek yük alanları için oldukça iyi çalışmıştır. Umarım bu başlamanıza yardımcı olur :-)


1
RequiredFullQuote: "Küçük verimlilikleri unutmalıyız, zamanın yaklaşık% 97'sini söylemeliyiz: erken optimizasyon tüm kötülüklerin köküdür"
Alister Bulman

RequiredReallyFullQuote: "Programcılar, programlarının kritik olmayan bölümlerinin hızını düşünmek veya bunlardan endişe etmek için çok fazla zaman harcıyorlar ve bu verimlilik girişimleri hata ayıklama ve bakım dikkate alındığında gerçekten güçlü bir olumsuz etkiye sahip. zamanın yaklaşık% 97'sini söylüyor: erken optimizasyon tüm kötülüklerin köküdür. Yine de bu kritik% 3'teki fırsatlarımızı kaçırmamalıyız. "
cHao

6

Uygulamanızı Xdebug gibi bir şeyle profillemek (tj9991 önerilir) kesinlikle bir zorunluluktur. İşleri körü körüne optimize etmek için etrafta dolaşmak pek mantıklı değil. Xdebug, kodunuzdaki gerçek darboğazları bulmanıza yardımcı olur, böylece optimizasyon zamanınızı akıllıca harcayabilir ve gerçekten yavaşlamalara neden olan kod parçalarını düzeltebilirsiniz.

Apache kullanıyorsanız, testte yardımcı olabilecek başka bir yardımcı program Siege'dir . Sunucunuzun ve uygulamanızın yüksek yüklere gerçekten kendi hızlarına koyarak nasıl tepki vereceğini tahmin etmenize yardımcı olacaktır.

PHP için her türlü opcode önbellek (APC veya diğerlerinden biri gibi) de çok yardımcı olacaktır.


6

Ayda 7-8 milyon sayfa görüntülemeye sahip bir web sitesi işletiyorum. Çok fazla değil, ama yeterli sunucumuz yük hissetti. Seçtiğimiz çözüm basitti: Veritabanı düzeyinde Memcache. Veritabanı yüklemesi ana sorununuz ise bu çözüm iyi çalışır.

Tüm nesneleri ve en sık kullanılan veritabanı sonuçlarını önbelleğe almak için Memcache kullanmaya başladık. Bu işe yaradı, ama aynı zamanda hatalar tanıttı (biz daha dikkatli olsaydı bunlardan bazıları kaçınmış olabilir).

Bu yüzden yaklaşımımızı değiştirdik. Bir veritabanı sarmalayıcısı oluşturduk (eski veritabanımızla aynı yöntemlerle, geçiş yapmak kolaydı) ve sonra memcached veritabanı erişim yöntemleri sağlamak için alt sınıflandırma yaptık.

Şimdi tek yapmanız gereken bir sorgunun önbelleğe alınmış (ve muhtemelen eski) sonuçları kullanıp kullanamayacağına karar vermektir. Kullanıcılar tarafından çalıştırılan sorguların çoğu artık doğrudan Memcache'den getiriliyor. İstisnalar, ana web sitesi için yalnızca günlük kaydı nedeniyle gerçekleşen güncellemeler ve eklemelerdir. Bu oldukça basit önlem sunucu yükümüzü% 80 oranında azalttı.


6

Değer için, önbellek, memcached gibi bir uzantı / yardımcı paketi olmadan bile PHP'de DIRT SIMPLE'dir.

Tek yapmanız gereken kullanarak bir çıktı tamponu oluşturmak ob_start().

Genel bir önbellek işlevi oluşturun. Ara ob_start, işlevi geri arama olarak iletir. İşlevde, sayfanın önbelleğe alınmış bir sürümünü arayın. Varsa, servis yapın ve sonlandırın.

Yoksa, komut dosyası işlenmeye devam eder. Eşleşen ob_end () öğesine ulaştığında, belirttiğiniz işlevi çağırır. O zaman, çıktı tamponunun içeriğini alırsınız, bir dosyaya bırakırsınız, dosyayı kaydeder ve sonlandırırsınız.

Bazı son kullanma / çöp toplama ekleyin.

Ve birçok kişi yuva yapabileceğinizi ob_start()/ ob_end()çağrıları yapabileceğinizin farkında değildir . Dolayısıyla, reklamları ayrıştırmak veya sözdizimi vurgulaması veya başka bir şey yapmak için zaten bir çıktı arabelleği kullanıyorsanız, başka bir ob_start/ob_endaramayı iç içe yerleştirebilirsiniz .


+1 çünkü ilginç bir fikir gibi görünüyor. Performans açısından ne kadar iyi çalıştığını bilmiyorum
Sylverdrag

+1 çünkü bu ilginç bir fikir. Bu geri aramalar benim için önbellek dersimi çağırabilir!
Xeoncross

5

PHP'nin önbellek uzantıları hakkındaki öneri için teşekkürler - birini diğerinin üzerinde kullanma nedenlerini açıklayabilir misiniz? IRC aracılığıyla memcached hakkında harika şeyler duydum, ancak APC'yi hiç duymadım - onlar hakkında ne düşünüyorsunuz? Birden fazla önbellek sistemi kullanmanın oldukça ters etkili olduğunu varsayıyorum.

Aslında, birçoğu APC kullanıyor ve birlikte memcached ...


4

Öyle görünüyor ki yanılmışım . MySQLi hala geliştirilmektedir. Ancak makaleye göre, PDO_MySQL artık MySQL ekibi tarafından destekleniyor. Makaleden:

MySQL Geliştirilmiş Uzantısı - mysqli - amiral gemisi. Charsets, Hazırlanan Deyimler ve Saklı Yordamlar dahil olmak üzere MySQL Sunucusunun tüm özelliklerini destekler. Sürücü hibrit bir API sunar: tercihinize göre yordamsal veya nesne yönelimli bir programlama stili kullanabilirsiniz. mysqli PHP 5 ve üstü ile birlikte gelir. PHP 4 için Kullanım Ömrü Sonu'nun 2008-08-08 olduğunu unutmayın.

PHP Veri Nesneleri (PDO) bir veritabanı erişim soyutlama katmanıdır. PDO, çeşitli veritabanları için aynı API çağrılarını kullanmanızı sağlar. PDO herhangi bir derecede SQL soyutlaması sunmaz. PDO_MYSQL, PDO için bir MySQL sürücüsüdür. PDO_MYSQL PHP 5 ile birlikte gelir. PHP 5.3'ten itibaren MySQL geliştiricileri aktif olarak katkıda bulunur. Birleştirilmiş bir API'nın PDO avantajı, MySQL'e özgü özelliklerin, örneğin birden fazla ifadenin, birleştirilmiş API aracılığıyla tam olarak desteklenmemesi pahasına gelir.

Lütfen PHP için yayınlanmış ilk MySQL sürücüsünü kullanmayı bırakın: ext / mysql. MySQL Geliştirilmiş Uzantısı - mysqli - 2004'te PHP 5 ile piyasaya sürüldüğünden beri hala en eski sürücüyü kullanmak için bir neden yoktur. ext / mysql, Karakter Kümelerini, Hazırlanan Deyimleri ve Saklı Yordamları desteklemez. MySQL 4.0 özellik seti ile sınırlıdır. MySQL 4.0 için Genişletilmiş Desteğin 2008-12-31'de sona erdiğini unutmayın. Kendinizi böyle eski yazılımların özellik setiyle sınırlamayın! MySQL'e yükseltin, ayrıca bkz. Converting_to_MySQLi. mysql bizim açımızdan sadece bakım modunda.

Bana göre makale MySQLi'ye karşı önyargılı görünüyor. Sanırım PDO'ya karşı önyargılıyım. MySQLi üzerinden PDO'yu gerçekten çok seviyorum. Benim için doğru. API, programladığım diğer dillere çok daha yakın. OO Veritabanı arayüzleri daha iyi çalışıyor gibi görünüyor.

PDO aracılığıyla mevcut olmayan belirli bir MySQL özelliğine rastlamadım. Eğer yaparsam şaşırırdım.


3

PDO da çok yavaş ve API'si oldukça karmaşık. Aklı başında olan hiç kimse, taşınabilirlik bir endişe değilse bunu kullanmamalıdır. Ve yüzleşelim, tüm webapps'lerinin% 99'unda değil. Sadece MySQL veya PostrgreSQL ile ya da ne ile çalışıyorsanız kullanın.

PHP sorusu ve nelere dikkat edilmesi gerektiği. Bence erken optimizasyon tüm kötülüklerin köküdür. ;) Önce başvurunuzu yapın, programlama söz konusu olduğunda temiz tutmaya çalışın, biraz dokümantasyon yapın ve birim testleri yazın. Yukarıdakilerin tümü ile, zaman geldiğinde kodu yeniden düzenleme konusunda hiçbir sorun yaşamayacaksınız. Ama önce yapılması ve insanların buna nasıl tepki verdiğini görmek için dışarı itmek istiyorsunuz.


2

Tabii pdo güzel, ama orada gelmiştir olmuştur bazı artık sabit görünüyor olsa da, mysql ve mysqli karşı 's performansı hakkında tartışma.

Taşınabilirliği hayal ediyorsanız pdo kullanmalısınız, ancak değilse mysqli yol olmalıdır. Bir OO arayüzü, hazırlanmış ifadeler ve pdo'nun sunduğu şeylerin çoğuna sahiptir (taşınabilirlik hariç).

Ayrıca, performans gerçekten gerekliyse, daha iyi performans ve gelişmiş bellek kullanımı (ve performans ayarı istatistikleri) ile php ile çok daha sıkı bir şekilde entegre olacak PHP 5.3'te (yerli mysql) MysqLnd sürücüsüne hazırlanın .

Memcache kümelenmiş sunucuları (ve YouTube benzeri yük) varsa güzel, ama ben ilk önce APC denemek istiyorum .


2

Çok sayıda iyi yanıt verildi, ancak sizi XCache adlı alternatif bir opcode önbelleğine yönlendirmek istiyorum . Hafif bir katılımcı tarafından oluşturulur.

Ayrıca, gelecekte veritabanı sunucunuzu yük dengelemeye ihtiyacınız varsa, MySQL Proxy bunu başarmanıza çok iyi yardımcı olabilir.

Bu araçların her ikisi de mevcut bir uygulamaya kolayca bağlanmalıdır, bu nedenle bu optimizasyon ihtiyaç duyduğunuzda çok fazla uğraşmadan yapılabilir.


2

İlk soru gerçekten ne kadar büyük olmasını bekliyorsunuz? Ve altyapınıza ne kadar yatırım yapmayı planlıyorsunuz? Soruyu burada sormanız gerektiğini düşündüğünüz için, sınırlı bir bütçeyle küçük başlamayı beklediğinizi tahmin ediyorum.

Site yoksa performans önemsizdir. Kullanılabilirlik için yatay ölçeklendirmeye ihtiyacınız vardır. Makul bir şekilde kurtulabileceğiniz minimum, hem apache, php hem de mysql çalıştıran 2 sunucudur. Bir DBMS'yi diğerine bağımlı olarak ayarlayın. Herhangi bir nedenle okuduğunuz verileri tekrar okumanız gerekmiyorsa (master'ı kullanın), master'daki tüm yazmaları ve yerel veritabanındaki tüm okumaları yapın (ne olursa olsun). Köleyi otomatik olarak tanıtmak ve efendiyi çitlemek için makineleri kullandığınızdan emin olun. Bağımlı düğüme daha fazla benzeşim vermek için web sunucusu adresleri için yuvarlak devirli DNS kullanın.

Bu aşamada verilerinizi farklı veritabanı düğümleri arasında bölmek çok kötü bir fikirdir - ancak aynı sunucudaki farklı veritabanları arasında bölmeyi düşünebilirsiniz (bu, facebook'u geçtiğinizde düğümler arasında bölümlendirmeyi kolaylaştıracaktır).

Sitelerinizin performansını ölçmek ve darboğazları belirlemek için izleme ve veri analiz araçlarına sahip olduğunuzdan emin olun. Çoğu performans sorunu daha iyi SQL yazarak / veritabanı şemasını düzelterek düzeltilebilir.

Şablon önbelleğinizi veritabanında tutmak aptalca bir fikirdir - veritabanı yapılandırılmış veriler için merkezi bir ortak havuz olmalıdır. Şablon önbelleğinizi web sunucularınızın yerel dosya sisteminde tutun; daha hızlı kullanılabilir olacak ve veritabanı erişiminizi yavaşlatmayacaktır.

Bir op kodu önbellek kullanın.

Neden bu kadar yavaş gittiğini anlamak için sitenizi ve günlüklerini inceleyerek bolca zaman harcayın.

İstemciye mümkün olduğunca çok önbellek aktarın.

Yapabileceğiniz her şeyi sıkıştırmak için mod_gzip kullanın.

C.


2

İlk tavsiyem, bu konuyu düşünmek ve siteyi tasarlarken aklınızda bulundurmaktır ancak aşırıya kaçmayın . Yeni bir sitenin başarısını tahmin etmek genellikle zordur ve zamanınızı erken bitirmek ve daha sonra optimize etmek için daha iyi zaman harcayacağım.

Genel olarak, Simple hızlıdır . Şablonlar sizi yavaşlatır. Veritabanları sizi yavaşlatır. Karmaşık kütüphaneler sizi yavaşlatır. Şablonları birbirlerinden katmanlama ve bunları veritabanlarından alma ve karmaşık bir kütüphanede ayrıştırma -> zaman gecikmeleri birbiriyle çarpılır.

Temel siteyi kurduktan ve çabalarınızı nerede harcayacağınızı göstermek için testler yapın. Nereye hedefleneceğini görmek zor. Çoğu zaman işleri hızlandırmak için kodun karmaşıklığını çözmek zorunda kalacaksınız, bu da daha büyük ve bakımını zorlaştırıyor, bu yüzden sadece gerektiğinde yapmak istiyorsunuz.

Deneyimlerime göre veritabanı bağlantısı kurmak nispeten pahalıydı. Bundan kurtulabiliyorsanız, siteye ön sayfa gibi en çok trafik alan sayfalardaki genel ziyaretçiler için veritabanına bağlanmayın. Birden çok veritabanı bağlantısı oluşturmak çok az fayda sağlayan deliliktir.


1

@ Gary

MySQLi kullanmayın - PDO 'modern' OO veritabanı erişim katmanıdır. Kullanılacak en önemli özellik, sorgularınızdaki yer tutuculardır. Sizin için sunucu tarafı hazırlıkları ve diğer optimizasyonları kullanmak için yeterince akıllı.

Şu anda PDO üzerinde loking ve doğru gibi görünüyor - ancak MySQL PHP için MySQLd uzantısı geliştiriyor biliyorum - Ben ya MySQL veya MySQLi başarılı düşünüyorum - ne düşünüyorsun?


@ Ryan , Eric , tj9991

PHP'nin önbellek uzantıları hakkındaki öneri için teşekkürler - birini diğerinin üzerinde kullanma nedenlerini açıklayabilir misiniz? IRC aracılığıyla memcached hakkında harika şeyler duydum, ancak APC'yi hiç duymadım - onlar hakkında ne düşünüyorsunuz? Birden fazla önbellek sistemi kullanmanın oldukça ters etkili olduğunu varsayıyorum.

Kesinlikle bazı profilli test kullanıcılarını sıralayacağım - bunlarla ilgili önerileriniz için çok teşekkür ederim.


1

Kendimi MySQL'den yakında değiştirdiğimi görmüyorum - bu yüzden PDO'nun soyutlama özelliklerine ihtiyacım yok. Bu makaleler için teşekkürler DavidM, bana çok yardımcı oldular.


1

ASP.NET'te çıkış önbelleğine benzer şekilde Apache web sunucusu için bir çıkış önbelleği olan mod_cache'ye bakın .

Evet, hala deneysel olduğunu görebiliyorum ama bir gün kesin olacak.


1

Kimsenin bundan daha önce bahsetmediğine inanamıyorum: Modülerleşme ve Soyutlama. Sitenizin çok sayıda makineye büyümesi gerektiğini düşünüyorsanız , tasarlayabilmeniz için tasarlamanız ! Bu, veritabanının localhost üzerinde olduğunu varsaymayın gibi aptalca şeyler anlamına gelir. Aynı zamanda, bir veritabanı soyutlama katmanı yazmak gibi (PDO gibi, ama çok daha hafif olduğu için ilk başta rahatsız edici olacak şeyler anlamına gelir, çünkü sadece yapmanız gereken şeyi yapar).

Ve bu, bir çerçeveyle çalışmak gibi şeyler anlamına gelir. Daha sonra veri soyutlama katmanını yeniden düzenleyerek performans elde edebilmeniz için kodunuza katmanlara ihtiyacınız olacak, örneğin, bazı nesnelerin farklı bir veritabanında olduğunu ve kodun bilmek veya bakım yapmak zorunda olmadığını öğreterek .

Son olarak, bellek yoğun işlemlere, örneğin gereksiz dizgi kopyalamaya dikkat edin. PHP'nin bellek kullanımını düşük tutabiliyorsanız, web sunucunuzdan daha fazla performans elde edersiniz ve bu, yük dengeli bir çözüme gittiğinizde ölçeklenecek bir şeydir.


1

Çok miktarda veri ile çalışıyorsanız ve önbelleğe alma işlemi kesmiyorsa, Sfenks'e bakın. SphinxSearch'ü sadece daha iyi metin araması için değil, aynı zamanda daha büyük tablolarla uğraşırken MySQL için veri alma yedeği olarak kullanmakla harika sonuçlar elde ettik. SphinxSE (MySQL eklentisi) kullanıyorsanız, birkaç kez önbelleklemeden elde ettiğimiz performans kazancımızı aştı ve uygulama uygulaması bir sinch.


1

Önbellek ile ilgili noktalar açıktır; verimli bir uygulama oluşturmanın en az karmaşık ve en önemli parçasıdır. Memcached harika olsa da, uygulamanız tek bir sunucuda yaşıyorsa APC'nin yaklaşık beş kat daha hızlı olduğunu eklemek istiyorum.

MySQL performans blogundaki "Önbellek Performans Karşılaştırması" gönderisi bu konuda bazı ilginç ölçütlere sahiptir - http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/ .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.