Come scalare php5 + MySQL oltre 200 richieste / secondo?

Sto aggiustando la mia home page per le performance, attualmente gestisce circa 200 richieste / secondo su 3.14.what mangia 6 query SQL e 20 req / secondo su 3.14.by/forum che è forum phpBB.

Stranamente, i numbers sono quasi identici su alcuni VPS e dedicati al server Atom 330.

Il software del server è il seguente: Apache2 + mod_php prefork 4 bambini (qui provato diversi numbers), php5, APC, nginx, memcached per l'archiviazione delle sessioni PHP.

MySQL è configurato per mangiare circa il 30% della RAM disponibile (~ 150Mb su VPS, 700Mb su server dedicato)

Questo sembra che ci sia un collo di bottiglia da qualche parte che non mi permette di andare più in alto, di qualsiasi suggerimento? (vale a dire che facendo less di 6 SQL lo renderebbe più veloce, ma questo non sembra un fattore limitante, poiché gli sqld mangiano non più di pochi% in cima a causa delle query memorizzate nella cache)

Qualcuno ha testato che kicking preforked apache2 e lasciare solo nginx + php è molto più veloce?

Alcuni altri benchmark

Small 40-byte static file: 1484 r/s via nginx+apache2, 2452 if we talk to apache2 directly. Small "Hello world" php script: 458 r/s via ngin+apache2. 

Aggiornamento: sembra che il collo di bottiglia è la prestazione di MySQL sui dati memorizzati nella cache. La pagina con singoli SQL mostra 354req / sec, con 6 SQL – 180 req / sec. Cosa pensi che posso modificare qui? (Posso fork fuori 100-200Mb per MySQL)

 [client] port = 3306 socket = /var/run/mysqld/mysqld.sock [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] default-character-set=cp1251 collation-server=cp1251_general_cs skip-character-set-client-handshake user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock port = 3306 basedir = /usr datadir = /var/lib/mysql tmpdir = /tmp skip-external-locking bind-address = 127.0.0.1 key_buffer = 16M max_allowed_packet = 8M thread_stack = 64K thread_cache_size = 16 sort_buffer_size = 8M read_buffer_size = 1M myisam-recover = BACKUP max_connections = 650 table_cache = 256 thread_concurrency = 10 query_cache_limit = 1M query_cache_size = 16M expire_logs_days = 10 max_binlog_size = 100M [mysqldump] quick quote-names max_allowed_packet = 8M [mysql] [isamchk] key_buffer = 8M !includedir /etc/mysql/conf.d/ 

  • IDN e HTTP_HOST
  • Come permettere di modificare la versione php tramite .htaccess in Apache?
  • Apache apre selettivamente reverse-proxy richieste al nuovo server
  • Come faccio ad abilitare il supporto JPEG per PHP?
  • Installazione delle estensioni PHP su Linux
  • Apache sta inviando file php al mio browser invece di analizzare
  • Permessi di file Plesk - Apache / PHP in conflitto con account utente
  • sendmail su Snow Leopard
  • 8 Solutions collect form web for “Come scalare php5 + MySQL oltre 200 richieste / secondo?”

    Ovviamente, c'è molto da provare. La tua scommessa migliore sta inseguendo i tuoi registri per query che non utilizzano indici (abilita i registri per quelli) e altre query non ottimizzate. Ho compilato un enorme elenco di opzioni relative alle performance nel corso degli anni, quindi ho incluso qui un piccolo sottoinsieme per le tue informazioni – speriamo che aiuta. Ecco alcune note generali per le cose che puoi provare (se non l'hai già fatto):

    MySQL

    • query_cache_type = 1 – le query SQL cache sono attive. Se impostato su 2, le query vengono memorizzate nella cache solo se viene passato il suggerimento SQL_CACHE. Allo stesso modo, con il tipo 1, è ansible distriggersre la cache per una particolare query con il suggerimento SQL_NO_CACHE
    • key_buffer_size = 128M (predefinito: 8M) – buffer di memory per gli indici della tabella MyISAM. Su server dedicati, mirare a impostare il key_buffer_size su alless un quarto, ma non più della metà, della quantità totale di memory sul server
    • query_cache_size = 64M (default: 0) – dimensione della cache di query
    • back_log = 100 (default: 50, max: 65535) – La coda delle richieste di connessione in sospeso. Soltanto quando ci sono molti collegamenti in breve tempo
    • join_buffer_size = 1M (predefinito: 131072) – un buffer utilizzato quando si dispone di scansioni complete della tabella (senza indici)
    • table_cache = 2048 (default: 256) – deve essere max_user_connections moltiplicato per il numero massimo di JOIN che contiene la tua query più pesante SQL. Utilizza la variabile "open_tables" ai tempi di punta come guida. Guardate anche la variabile "open_tables" – dovrebbe essere vicino a "open_tables"
    • query_prealloc_size = 32K (predefinito: 8K) – memory persistente per l'analisi e l'esecuzione delle istruzioni. Aumenta se ha query complesse
    • sort_buffer_size = 16M (predefinito: 2M) – aiuta a ordinare (operazioni ORDER BY e GROUP BY)
    • read_buffer_size = 2M (predefinito: 128K) – Aiuta con scansioni sequenziali. Aumenta se ci sono molte scansioni sequenziali.
    • read_rnd_buffer_size = 4M – aiuta la tabella MyISAM a velocizzare la lettura dopo il sorting
    • max_length_for_sort_data – dimensione della row per memorizzare invece del puntatore di row nel file di sorting. Può evitare la lettura random della tabella
    • key_cache_age_threshold = 3000 (predefinito: 300) – tempo per mantenere la cache della chiave nella zona calda (prima di essere abbassata)
    • key_cache_division_limit = 50 (predefinito: 100) – consente un meccanismo più sfrenato di espulsione della cache (due livelli). Indica la percentuale da mantenere per il livello inferiore. delay_key_write = ALL – il buffer di chiavi non è spruzzato per la tabella di each aggiornamento dell'indice, ma solo quando la tabella è chiusa. Questo accelera scrive molto sui tasti, ma se si utilizza questa funzionalità, è necessario aggiungere il controllo automatico di tutte le tabelle MyISAM avviando il server con l'opzione –myisam-recover = BACKUP, FORCE
    • memlock = 1 – process di block in memory (per ridurre lo scambio in / out)

    Apache

    • modificare il metodo di spawning (ad esempio per mpm)
    • distriggersre i registri, se ansible
    • AllowOverride None – quando ansible disabilitare .htaccess. Arresta apache per la ricerca di file .htaccess se non vengono utilizzati in modo da salvare una richiesta di ricerca di file
    • SendBufferSize – Impostazione predefinita di OS. Su reti congestionate, è necessario impostare questo parametro vicino alla dimensione del file più grande normalmente scaricato
    • KeepAlive Off (impostazione predefinita triggers) – e installare lingerd per chiudere correttamente le connessioni di networking e è più veloce
    • DirectoryIndex index.php – Tenere l'elenco dei file come breve e assoluto ansible.
    • Opzioni FollowSymLinks – per semplificare il process di accesso ai file in Apache
    • Evitare di utilizzare mod_rewrite o alless regex complesse
    • ServerToken = prod

    PHP

    • variables_order = "GPCS" (se non è necessario modificare le variables di ambiente)
    • register_globals = Off – oltre ad essere un rischio per la sicurezza, ha anche un impatto sulle performance
    • Mantenere il path include_pare minima ansible (evita la ricerca di file system aggiuntivi)
    • display_errors = Distriggersto – Disabilita la visualizzazione degli errori. Fortemente raccomandato per tutti i server di produzione (non visualizza messaggi di errore in caso di problemi).
    • magic_quotes_gpc = Off
    • magic_quotes _ * = Off
    • output_buffering = On
    • Distriggers la logging se ansible
    • expose_php = Off
    • register_argc_argv = Off
    • always_populate_raw_post_data = Off
    • posiziona il file php.ini where php avrebbe cercato prima.
    • session.gc_divisor = 1000 o 10000
    • session.save_path = "N; / path" – per i siti più grandi considera l'utilizzo. Divide i file di session in sottodirectory

    Tweaks del sistema operativo

    • Montare i dischi rigidi utilizzati con l'opzione o noatime (nessun tempo di accesso). Aggiungi questa opzione anche a file / etc / fstab.
    • Modificare il / proc / sys / vm / swappiness (da 0 a 100) per vedere quali sono i migliori risultati
    • Utilizzare i dischi RAM – mount –bind -ttmpfs / tmp / tmp

    Se il collo di bottiglia non è CPU, allora il suo IO – networking o disco. Quindi .. devi vedere quanto sta succedendo. Non avrei pensato che fosse la networking (a less che non fossi in un collegamento a metà duplex di 10 MB, ma la sua validità è di controllare l'interruttore se il rilevamento automatico non sta facendo il proprio lavoro).

    Che lascia il disco IO, che può essere un fattore importnte soprattutto per i VPS. Utilizza sar o iostat per dare un'occhiata ai dischi, quindi google come trovare ulteriori dettagli se il disco è in uso pesantemente.

    Vorrei esaminare la memorizzazione con Nginx ( memcached ) o Varnish .

    Alless dovresti servire file statici con Nginx come ha detto SaveTheRbtz.

    Poiché il server non sembra essere un problema, forse è il generatore di carico. Provi ad eseguirlo su diverse macchine.

    Mi sembra che tu possa colpire la quantità massima di connessioni che Apache consente. Dai un'occhiata alla configuration di Apache. L'incremento del limite di server e dei client max dovrebbe aiutare se non siete già legati da altri limiti come I / O o memory. Osservare i valori presenti per mpm_prefork_module o mpm_worker_module e adattarsi di conseguenza per soddisfare le vostre esigenze.

     ServerLimit 512
     MaxClients 512
    

    Questo carico è generato da uno strumento o da un carico reale?

    Potresti voler controllare memcached. Ho visto problemi a elevati tassi di connessione causando latenza nell'applicazione.

    Se si utilizza un generatore di carico, cosa si ottiene quando si colpisce una piccola pagina statica?

    Durante i carichi, è ansible controllare lo stack di networking per le condizioni di TIME_WAIT. Forse stai riempiendo la coda di connessione.

    Ci sono circa un centinaio di ulteriori ragioni e oggetti che puoi guardare, ma senza ulteriori informazioni, sto solo buttando fuori indovinare a questo punto.

    Il 99% del numero di volte in questo modo verrà riportto al database. Assicurarsi che i tuoi indici di colpire prima di tutto. Se ciò non funziona, avviare la memorizzazione nella cache di tutto ciò che puoi.

    Ti raccommand di utilizzare (se ansible) un pooler di connessione per mantenere il database collegato alle applicazioni Web (non è necessario riconnettersi a each richiesta). Questo può fare una grande differenza di velocità.

    Inoltre, prova ad analizzare tutte le tue query con EXPLAIN (e perché non profilare le tue query con SHOW PROFILE?).

    Suggerimenti per Linux e Windows Server, quali Ubuntu, Centos, Apache, Nginx, Debian e argomenti di rete.