Przy okazji wykonywania kilku drobnych optymalizacji swojej stronki natknąłem się na eAccelerator’a. Ciekawy projekt, który w sposobie działania przypomina Zend Optimizer’a ale ma jedną zasadniczą zaletę - jest darmowy 😃

Niestety nie ma go w repozytoriach Debiana, więc trzeba go sobie skompilować - cały proces jest dość prosty. Zaczynamy od pobrania najświeższej paczki, obecnie jest to wersja 0.9.5.3:

Pobierz eAcceleratorexternal link  (ostatnio miałem problem z tym linkiem więc proponuję pogooglać)

Pobieramy i rozpakowujemy pliki:

tar xvfj eaccelerator-0.9.5.3.tar.bz2
cd eaccelerator-0.9.5.3

Do kompilacji eAccelerator’a potrzebujemy paru paczek, które możemy zainstalować tak:

apt-get install build-essential php5-dev

W katalogu ze źródłami klepiemy (prawie standardowo):

phpize
./configure
make
make install

No i eAccelerator jest już zainstalowany w naszym systemie. Pozostało wygenerowanie konfiguracji PHP aby moduł był automatycznie ładowany oraz ustawienie podstawowych parametrów konfiguracyjnych.
W przypadku Debiana domyślna konfiguracja modułów PHP przechowywana jest w katalogu/etc/php5/conf.d tam też zapiszemy naszą konfigurację jako eaccelerator.ini. Tworzymy plik naszym ulubionym edytorem:

vim /etc/php5/conf.d/eaccelerator.ini

W pliku wpisujemy:

extension="eaccelerator.so"
eaccelerator.shm_size="128"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"

extension - określa plik modułu, czasami może być konieczne podanie pełnej ścieżki,
eaccelerator.shm_size - określa ilość pamięci współdzielonej, którą eAccelerator rezerwuje do przechowywani skompilowanych skryptów. Ja dałem 128MB bo mój serwerek ma 2GB RAM-u, ale przypuszczam że dla mniej obciążonych maszyn wystarczy 16~32MB. Nadając temu parametrowi wartość 0 ufamy programistom 😉
eaccelerator.cache_dir - ustawiamy katalog, w którym będzie zapisywane to co nie będzie się już mieścić w pamięci współdzielonej. Ja mam akurat sporą osobną partycję na /tmp, ale równie dobrze nadaje się /var/cache/eaccelerator czy /var/tmp/eaccelerator - ustawiamy jak nam wygodnie,

Skoro już piszę o katalogu na skrypty to warto go utworzyć i przypisać mu odpowiednie uprawnienia (ja ustawiam je tak aby tylko Apache miał dostęp):

mkdir /tmp/eaccelerator
chown -R www-data:www-data /tmp/eaccelerator
chmod 0770 /tmp/eaccelerator

No to jeszcze restart Apache’a i możemy sprawdzać jak działa:

invoke-rc.d apache2 restart

Najszybszym sposobem sprawdzenia czy moduł się ładuje jest sprawdzenie wyniku poleceniaphp -v - powinno to wyglądać jak poniżej:

php -v

Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
    with eAccelerator v0.9.5.3, Copyright (c) 2004-2006 eAccelerator, \
    by eAccelerator

Podobny wynik można uzyskać z pomocą funkcji phpinfo() i prostego skryput PHP do jej wywołania.

Czy warto?

Na koniec trochę benchmarków aby sprawdzić czy cała zabawa jest warta świeczki 😃
Wykorzystam standardowe narzędzie dostępne z Apache’m: ab (Apache benchmark):

ab -n 1000 -c 10 http://mojastrona.pl/

U mnie dało to następujące wyniki - z wyłączonym eAccelerator’em:

Concurrency Level:      10
Time taken for tests:   8.648 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      12836000 bytes
HTML transferred:       12612000 bytes
Requests per second:    115.64 [#/sec] (mean)
Time per request:       86.477 [ms] (mean)
Time per request:       8.648 [ms] (mean, across all concurrent requests)
Transfer rate:          1449.54 [Kbytes/sec] received

Oraz z włączonym:

Concurrency Level:      10
Time taken for tests:   3.663 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      12840344 bytes
HTML transferred:       12616120 bytes
Requests per second:    272.97 [#/sec] (mean)
Time per request:       36.634 [ms] (mean)
Time per request:       3.663 [ms] (mean, across all concurrent requests)
Transfer rate:          3422.90 [Kbytes/sec] received

Wynik jest całkiem niezły, ponad dwa razy szybciej. A w niektórych przypadkach udaje się wyciągnąć więcej (nawet 5~10 krotnie). Tak, czy siak - warto!