Sie sind auf Seite 1von 7

Apache2/PHP/MySQL Optimierung

Patrick Schneider 1. November 2008

Inhaltsverzeichnis

1

1

Vorwort

In der heutigen Zeit finden sich viele Server die auf der Komibnation Apache/PHP/- MySQL (LAMP, XAMP Installation) aufsetzen. Oft werden die einzelnen Komponenten aber nicht weiter beobachtet und optimiert. Zwar reicht es fur¨ kleine Webservices, aber wer einmal gr¨oßere Seiten betreibt, welche statischen und dynamischen Inhalt bieten, werden schnell die Grenzen erreicht. Daher soll dieser kleine Bericht einige Optimierungstipps bieten, die der Leser bei Bedarf einsetzen kann. Dieses Dokument bezieht sich auf eine OpenSUSE 10.3 Installation mit Apache 2.0.24, PHP 5.2.4 und MySQL 5.0.45.

2 Optimierungsbereiche

Durch den Einsatz von verschiedenen Komponenten, bedarf es eine genauen Analyse um eine gezielte Steigerung zu erhalten. Hierbei muss jede Komponente w¨ahrend der Laufzeit gepruft¨ und optimiert werden. Fur¨ Apache2/PHP kommt das Dienstprogramm ApacheBench2 zum Einsatz. Es simuliert den Zugriff beliebig vieler Benutzer mit beliebig vielen Zugriffen auf eine Seite. Dafur¨ wurde eine einfache Testseite mit PHP verwendet (siehe Anhang - Listing 1). Fur¨ die Optimierung der MySQL Datenbank verwenden wir die Dienstprogramme:

ApacheBench2

tuning-primer.sh (http://www.day32.com/MySQL/)

Das Skript tuning-primer.sh liefert nach einer Laufzeit von 48 Stunden (der Datenbank) Optimierungshinweise. Zusammen mit ApacheBench2 kann damit eine Konfiguration erstellt werden, die auch hohe Belastungen standh¨alt. Fur¨ die PHP Optimierung mittels eAccelerator empfiehlt sich auch der Einsatz einer Ramdisk. Diese kann ab Kernel 2.6 mithilfe des tmpfs eingerichtet werden (Anhang - Listing 2).

3 Apache

Um Apache2 performant zu betreiben, bedarf es einiger Anpassungen. Als erstes pas- sen wir das MPM Modell ang. Dieses beeinflusst das Verhalten der Child Prozesse von Apache. Hier wird Standardm¨aßig das prefork Modell verwendet. Es bietet fur¨ kleine Zugriffszahlen eine Ausgeglichene Performance, allerdings erstellt Apache teilweise zu viele Prozesse die enorme Rechenleistung beanspruchen. Da die prefork Prozesse wei- tere Child Prozesse separat starten wird hier schnell eine hohe Auslastung des Systems erreicht. Ersetzen werden wir es durch das worker Modell. Hier werden alle Kind Pro- zesse unterhalb des Hauptprozesses gestartet. Verliert so ein Prozess seine Gultigkeit,¨ werden gleichzeitig alle anderen Kind Prozesse beendet. Dadurch kann bei hohen Zu- griffszahlen eine schnellere Erreichbarkeit gew¨ahrleistet werden (falls ein Prozess h¨angt,

2

wird der Hauptprozess beendet und die Ressourcen sind sofort wieder frei). Durch diese

¨

Anderung muss auch das FastCGI Modul verwendet werden. Hier wird PHP nicht mehr intern uber¨ Apache aufgerufen, sondern uber¨ die CGI Schnittstelle. Hier kann durch eine Optimierung der PHP Prozesses eine h¨ohere Performance und ein besserer Lastenaus- gleich erzielt werden (Multiprozessoren).

4 PHP

Fur¨ PHP wurde, speziell im FastCGI Bereich, einiges optimiert. Dies umfasst die max. Dauer und Wartezeit auf die Skripte. Hier liegt Standardm¨aßig eine Zeitspanne von 30 Sek. Fur¨ die Ausfuhrungszeit¨ und 60 Sek. fur¨ die Wartezeit. Beide werden auf 70 Sek. angepasst. Des Weiteren kann, falls vorhanden, der Zend Optimizer eingesetzt werden. Zend bietet verschiedene Optimierungsstufen an, welche die PHP Abl¨aufe beschleunigen. Hierbei wird der normale PHP Code kompiliert und dadurch schneller ausgefuhrt,¨ da dieser nun im Speicher ausgefuhrt¨ wird. Fur¨ die n¨otigen Einstellungen, schauen Sie im Anhang nach (Listing 3). Um den st¨andigen Zugriff auf die Datenbank einzuschr¨anken, kommt das PHP Modul eAccelerator zum Einsatz. Es cached die PHP Seiten und kann diese bei wiederholten Zugriff (Startseite, alle statischen Seiten) direkt darstellen ohne eine Datenbank Abfrage zu starten. Diese Cache Dateien liegen in einer 512 MB großen Ram Disk um eine sehr schnelle Zugriffszeit zu erreichen. Durch das Zwischenspeichern der Daten erreichen wir bei oft besuchten Seiten eine erh¨ohte Geschwindigkeit, da diese nur noch aus dem Speicher gelesen werden mussen.¨ Hier gilt zu beachten, eine richtige Einstellung zu finden. Auf hochgradig Dynamischen Seiten (AJAX lastig oder st¨andige Aktualisierend) bringt der Einsatz von eAccelerator keinen Vorteil mehr.

5 MySQL

Im Datenbank Bereich k¨onnen die meisten Optimierungen durchgefuhrt¨ werden. Hier stellt sich die Frage, welche Anwendung zum Einsatz kommt. Bei komplexen CMS Programmen, wie zum Beispiel Typo3 oder Joomla empfiehlt sich der Einsatz des Da- tenbanktyps InnoDB. Dieser bietet mit der ACID Sicherheit (atomicity, consistency, isolation and durability) eine Gew¨ahrleistung fur¨ konsistente Daten. Zwar sind die Abfragen etwas langsamer, allerdings kann durch Transaktionen dieser Nachteil wieder ausgeglichen werden. Haben Sie noch keine Datenbank angelegt, verwenden Sie gleich den InnoDB Typ (siehe MySQL Beschreibung). Existiert bereits eine Datenbank, kann diese leicht konvertiert werden.

mysqldump −−u s e r=p a t r i c k −−password=s q l −−a l l dropd a t ab a se \ −−noautocommit −−databases=u n s e r t e s t > datenbank . s q l

sed

mysql −−u s e r=p a t r i c k −−password=s q l < datenbankinnodb . s q l

’ s /ENGINE=MyISAM/ENGINE=INNODB/ g ’ datenbank . s q l > datenbankinnodb . s q l

3

Anhand von mysqldump erstellen wir ein komplettes Abbild der Datenbank. Der Pa- rameter –all-drop-database bewirkt das bei einem Import die alte Datenbank gel¨oscht wird. Fur¨ eine InnoDB ist der weitere Parameter –no-autocommit sehr wichtig. Er be- wirkt das die Datenbank erst nach kompletten Abarbeiten des Dumps eingelesen wird. Ansonsten wird bei jedem Befehl ein Commit ausgefuhrt,¨ bei dem der Import einer 100MB Datei bis zu 2 Stunden beanspruchen kann.

von langen Datenbankab-

fragen zustande kommt, setzen wir diese Dauer auf 7 Sekunden. So hat jede Abfrage

Um einer Uberlastung vorzubeugen, die durch Ausfuhrung¨

¨

¨

7 Sekunden Zeit. Uberschreitet es diese Zeit, wird sie abgebrochen und erneut durch- gefuhrt.¨ Hier ist wichtig, das man selbst mittels des Datenbankskriptes misst, wie viele solcher Abfragen im Echtbetrieb stattfinden. Werden zuviele Abfragen abgebrochen, en- steht ein Teufelskreis welcher nach 10 Versuchen einen Seitenfehler ausgibt (nach 70 sekunden bricht PHP die Bearbeitung des Skriptes ab!!!). Auch im Bereich des Cachings wird gezielt optimiert. Erh¨ohen Sie das worker threads caching um eine bessere Auslastung der einzelnen Pro- zesse zu erreichen. Auch der table cache sollte angepasst werden. Setzen Sie ihn als Anfangswert fur¨ ein CMS auf 200 und beobachten Sie die Auslastung mithilfe des Datenbankskriptes. Je nach Einsatzzweck (CMS, normale Webseite mit gelegentlicher Abfrage) k¨onnen die key buffer size und der query cache verringert werden. Je nach Datentypen werden die- se unterschiedlich ausgelastet. Setzen Sie einen Anfangswert von 16M und prufen¨ Sie mit Hilfe des Skriptes die Auslastung. Je nach Beansprichung des Servers, sollten Sie die max connections anpassen. Bedenken Sie, das jede Abfrage eine Verbindung darstellt. Setzen Sie bspw. bei einem durchschnitt- lichen Zugriff von 50 Benutzern die Verbindungen auf 250.

6 Nachwort

Im Anhang finden Sie die Anpassungen und Optionen des Textes. Setzen Sie diese mit Vorbehalt ein. Gerade im MySQL Bereich empfiehlt sich der Einsatz des tuning-primer Skriptes. Es gibt gute Statistiken aus, anhand derer Sie die Anpassungen vornehmen k¨onnen. Bitte bedenken Sie auch, dass dieses Dokument nur ein Leitfaden ist und zur Anregung dienen soll und keinesfalls einen optimalen Zustand eines Webservers darstellt.

4

7 Anhang

7.1 PHP-Testcode

Listing 1: Test.php

<?php

For ( $x=0; $x <5000; $x++) {

Echo ”Nummer: ”

.

$x

}

?>

7.2 Linux Optimierungen

tmpfs

/ tmp cache

7.3 MySQL

Listing 2: /etc/fstab

tmpfs

d e f a ul t s , s i z e =512MB

Listing 3: /etc/my.cnf

# Uncomment t h e

f o l l o w i n g

i f

you are

u s i n g InnoDB

innodb data home dir = /var/ li b /mysql/

i n n o d b

innodb log group home dir = /var/ lib /mysql/ innodb log arch dir = /var/ lib /mysql/

d a t a

f i l e

p a t h

=

i b d a t a 1 : 1 0 0M: au t oex tend

t a b l e s

0

0

# You can

# o f RAM b u t beware

s e t

b u f f e r

o f

.

.

p o o l

s e t t i n g

s i z e

up memory u s age

t o

50

80 %

t o o

h i g h

i n n o d b

b u f f e r

p o o l

s i z e

= 16M

i n n o d b

a d di ti o n al

m em p o ol

si z e

=

2M

#

Set

.

.

l o g

f i l e

s i z e

to

25 %

of

buf fer

pool

s i z e

i f i l e

n n o d b

l o g

s i z e

=

5M

 

i b u f f e r

n n o d b

l o g

s i z e

=

8M

innodb flush log at trx commit = 1 innodb lock wait timeout = 50

l

o n g

q u e r y

tim e=7

t h r e a d

max connections =250

s i z e=5

c a c h e

k

e y

b u f f e r

s i z e =16M

q

u e r y

c a c h e

s i z e =16M

t

a b l e

c a c h e =107

m a x

h e a p

t a bl e

si z e =64M

t

m p

t a b l e

s i z e =128M

l

o w

p r i o r i t y

u p d a t e s=1

5

7.4

PHP

Listing 4: /etc/php5/fastcgi/php.ini

[

eaccelerator ]

 

z

e n d

e x t e n si o n=” / u s r

/ l i b /php5/ e x t e n si o n s

/

e a c c e l e r a t o r . s o ”

e

a c c e l e r a t o r

.

s hm si z e=” 32 ”

 

e

a c c e l e r a t o r

.

c a c h e

d i r=” / tmp cache ”

e

a c c e l e r a t o r

.

e n a bl e=” 1 ”

 

e

a c c e l e r a t o r

. o p timi z e r=” 1 ”

e

a c c e l e r a t o r . check mtime=” 1”

e

a c c e l e r a t o r

. debug=”0 ”

e

a c c e l e r a t o r

. f i l t e r=” ”

e

a c c e l e r a t o r

. shm max=” 0 ”

e

a c c e l e r a t o r

.

s hm

t tl=” 0 ”

e

a c c e l e r a t o r

.

shm

p rune pe ri od=”0 ”

e

a c c e l e r a t o r

.

shm only=” 0 ”

 

e

a c c e l e r a t o r . compress=” 1 ”

e

a c c e l e r a t o r

.

c o m p r e s s

l e v e l=” 9 ”

[

zend ]

report zend debug = 0

z

e n d

e x t e n si o n

m a n a g e r

.

o p timi z e r=/u s r / l o c a l /Zend/ l i b / Optimizer 3. 3. 0

e n d zend

z

e x t e n si o n

m a n a g e r

.

o p t i m i z e r

t s=/u s r /

l o c a l /Zend/ l i b / Optimizer

TS 3. 3. 0

optimizer . version =3.3.0a

 

z

e n d

e x t e n si o n=/u s r / l o c a l /Zend/ l i b / ZendExtensionManager . s o

z

e n d e x t e n s i o n t s=/u s r / l o c a l /Zend/ l i b / ZendExtensionManager TS . s o

z

e n d

o p timi z e r . o p t i m i z a t i o n

l e v e l =15

m a x m ax

e x e c u ti o n tim e

inpu t time

=

60

=

60

; ; Maximum amount o f time each

Maximum e x e c u ti o n

time o f each

s c r i p t

s c r i p t , may spend

i n

s e c o n p a r si n

c g i . f i x

p a t h i n f o =0

7.5 Apache

Listing 5: /etc/apache2/conf.d/mod fcgi.conf ” \. php$”>

. php

<FilesMatch

AddHandler fcgid s c r i p t

FCGIWrapper ” / s r v /www/ c gi bin /php5”

. php

Options +ExecCGI

</FilesMatch>

ShareMemPath / var / l i b / apache2 / fcgid shm

6

7.6 OpenSUSE Pakete

apache2-worker

apache2-mod fastcgi

php5-fastcgi

readline-devel

libxml2-devel

pcre-devel

eaccelerator (http://eaccelerator.net)