Forum PHP - 2014

60 millions de visiteurs uniques par mois ...
Qu'est qu'un cache d'opcode ?
Script PHP
<?php
$end = time() + 60 * 60 * 24 * 365;
echo strftime("Expire le %m/%d/%Y\n", $end);
Noeuds
| 0 | T_OPEN_TAG | |
| 1 | T_VARIABLE | $end |
| 2 | T_WHITESPACE | |
| 3 | = | |
| 4 | T_WHITESPACE | |
| 5 | T_STRING | time |
| 6 | ( | |
| 7 | ) | |
| 8 | T_WHITESPACE | |
| 9 | + | |
| 10 | T_WHITESPACE | |
| 11 | ( | |
| 12 | T_LNUMBER | 60 |
| 13 | T_WHITESPACE | |
| 14 | * | |
| 15 | T_WHITESPACE | |
| 16 | T_LNUMBER | 60 |
| 17 | T_WHITESPACE | |
| 18 | * | |
| 19 | T_WHITESPACE | |
| 20 | T_LNUMBER | 24 |
| 21 | T_WHITESPACE | |
| 22 | * | |
| 23 | T_WHITESPACE | |
| 24 | T_LNUMBER | 365 |
| 25 | ) | |
| 26 | ; | |
| 27 | T_WHITESPACE | |
| 28 | T_ECHO | echo |
| 29 | T_WHITESPACE | |
| 30 | T_STRING | strftime |
| 31 | ( | |
| 32 | T_CONSTANT_ENCAPSED_STRING | "Expire le %m/%d/%Y\n" |
| 33 | , | |
| 34 | T_WHITESPACE | |
| 35 | T_VARIABLE | $end |
| 36 | ) | |
| 37 | ; | |
| 38 | T_WHITESPACE |
Opcodes
0 EXT_STMT 1 ASSIGN !0, 1 2 EXT_STMT 3 BOOL_NOT ~1 !0 4 JMPZ ~1, ->7 5 EXIT 6 JMP ->7 7 RETURN 1
Script PHP

Noeuds

Opcodes


Script PHP

Opcodes

Les caches d'opcode
Avant 2007, règne de Turck MMCache et d'eAccelerator
Zend en observateur des premiers jours
A partir de 2007 : APC monte sur le trône
Début 2013, Zend libère Optimizer+
En mars 2013, RFC pour intégrer Optimizer+ dans PHP 5.5
Depuis, désaffection pour APC
Mais quid des autres solutions ?
NuSphere et ionCube ?
Bonne question !
XCache fait de la résistance
Raison du règne d'APC ?
apc_store()
Naissance d'APCu
Opcache est donc un simple cache d'opcodes ?
Script PHP

Noeuds

Opcodes

Opcodes


<?php
echo 60 * 60 * 24 * 365;
?>
line # * op ext return operands
------------------------------------------------
2 0 > EXT_STMT
1 MUL ~0 60, 60
2 MUL ~1 ~0, 24
3 MUL ~2 ~1, 365
4 ECHO ~2
4 5 > RETURN 1
line # * op ext return operands
------------------------------------------------
2 0 > EXT_STMT
1 ECHO 31536000
4 2 > RETURN 1
<?php
$x = 1;
if (!$x) exit;
?>
line # * op ext return operands
------------------------------------------------
2 0 > EXT_STMT
1 ASSIGN !0, 1
3 2 EXT_STMT
3 BOOL_NOT ~1 !0
4 > JMPZ ~1, ->7
5 > > EXIT
6* JMP ->7
7 > > RETURN 1
line # * op ext return operands
------------------------------------------------
2 0 > EXT_STMT
1 ASSIGN !0, 1
3 2 EXT_STMT
3 > JMPNZ !0, ->5
4 > > EXIT
5 > > RETURN 1
<?php
if (true) echo 'ok';
?>
---- Pas optim ------ 0 EXT_STMT 1 JMPZ true, ->4 2 ECHO 'ok' 3 JMP ->4 4 RETURN 1 -- Optim bit 1 ------ 0 EXT_STMT 1 NOP 2 ECHO 'ok' 3 JMP ->4 4 RETURN 1 -- Optim bit 2 ------ 0 EXT_STMT 1 JMPZ true, ->4 2 ECHO 'ok' 3 NOP 4 RETURN 1 ----- Optim --------- 0 EXT_STMT 1 ECHO 'ok' 2 RETURN 1
Optimisation mémoire : interned strings
<?php
function test()
{
return 'test';
}
$test = test();
echo $test;
?>
Cinq chaînes

Un seul emplacement mémoire
cache d'opcode + optimisation
=
gros gain de performance ?
Pas tout à fait !
cache : temps de réponse -50%
optimisation : temps de réponse -10%
OPCache : un outil magique ?
Pas tout à fait !
Un besoin de configuration important
26 paramètres de configuration
Dont 15 impactant la performance ou la mise en cache
Les stratégies d'invalidation
revalidate_freq 2
validate_timestamps 1
revalidate_path 0
| Répertoire courant | Chemin d'inclusion | Fichier inclus | |
|---|---|---|---|
|
|
|
monFichier.php |
|
|
||
|
|
||
1 fichier en cache mais 3 clés pour y accéder.
Attention !
APC et OPCache ne se comportent pas de la même manière
Structure de répertoire avec capistrano :
|-current -> releases / 1
|
|-releases
|--1/
|---index.php (inode: 80)
|-current -> releases / 2
|
|-releases
|--1/
|---index.php (inode: 80)
|--2/
|---index.php (inode: 250)
max_wasted_percentage 5
Les stratégies de stockage
memory_consumption 64Mo
max_accelerated_files 2000
interned_strings_buffer 4Mo
save_comments 1
load_comments 1
Les filtres sur les fichiers
file_update_protection 2
max_file_size 0
blacklist_filename ""
Les stratégies d'optimisation
fast_shutdown 0
enable_file_override 0
optimization_level 0xffffffff
enable_cli 0
Quelle configuration pour quel environnement ?
Dév
Test
Prod
Activer :
Désactiver :
Flush obligatoire
Surveiller OPCache
opcache_get_status();
Suivre la consommation mémoire n'est pas suffisante !
Suivre les clefs de cache
Exemple, pour opcache.max_accelerated_files = 7 963
num_cached_scripts : 1 946 num_cached_keys : 7 963
opcache.log_verbosity_level = 4 (max)
Fri Oct 10 15:07:44 2014 (14926): Debug No more entries in hash table!
Suivre les interned strings
interned_strings_usage.free_memory : 0
Et mes données utilisateurs ?
Il n'y a pas qu'APC dans la vie !
Pensez à shmop ou aux ramdisks !
Sinon, il y a toujours APCu ...
Pour stocker quoi d'ailleurs ?
$content = '<?php return ' . var_export($configuration, true) . ';';
file_put_contents('/tmp/cache/configuration.php', $configuration);
if (file_exists('/tmp/cache/config.php')) {
$configuration = include('/tmp/cache/config.php');
} else {
// ... génération
}
Attention à file_update_protection
... ce n'est pas une révolution
Attention à la configuration par défaut
joind.in : https://joind.in/11960
Slides : http://tech.ccmbg.com/forumphp-2014/
@FredBouchery - @Beoneself
Dév : dev/opcache.ini
Test : test/opcache.ini
Prod : prod/opcache.ini