InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

40
ElePHPants on speed Running TYPO3 Flow on HipHop VM Inspiring Conference, March 28th 2014 Martin Helmich, Mittwald CM Service [email protected] Photo: George Lamson, CC BY-NC-SA http://www.flickr.com/photos/lamsongf/6415913075/

description

Slides of my presentation at the Inspiring Conference (http://www.inspiring-conference.com) in Kolbermoor on March 28th, 2014.

Transcript of InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Page 1: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

ElePHPants on speed Running TYPO3 Flow on HipHop VM Inspiring Conference, March 28th 2014

Martin Helmich, Mittwald CM Service [email protected]

Photo: George Lamson, CC BY-NC-SA http://www.flickr.com/photos/lamsongf/6415913075/

Page 2: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

YOUR SPEAKER

Martin Helmich Software architect at Mittwald

TYPO3 addicted since 2004 Caffeine addicted since 2007

Page 3: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Sebastian Bergmann, CC BY-SA http://www.flickr.com/photos/sebastian_bergmann/2337231691/

Page 4: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Lexing

Parsing

Compilation

Execution

PHP execution, traditional

Page 5: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

<?php!$locations = [ 0 => "Kolbermoor", 1 => "Espelkamp", 2 => "Las Vegas"];!$currentLoc = 0;$currentLocName = $locations[$currentLoc];!if ($currentLoc === 2) { $greeting = "%s, baby!";} else { $greeting = "Hello %s!";}!echo sprintf($greeting, $currentLocName) . "\n";

Lexing

Parsing

Compilation

Execution

Page 6: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

T_OPEN_TAG

T_VARIABLE

T_LNUMBER

T_DOUBLE_ ARROW

T_CONSTANT_ENCAPSED_STRING

T_IF

T_ELSE

T_ECHO

T_STRING

Lexing

Parsing

Compilation

Execution

<?php!$locations = [ 0 => "Kolbermoor", 1 => "Espelkamp", 2 => "Las Vegas"];!$currentLoc = 0;$currentLocName = $locations[$currentLoc];!if ($currentLoc === 2) { $greeting = "%s, baby!";} else { $greeting = "Hello %s!";}!echo sprintf($greeting, $currentLocName) . "\n";

Page 7: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Lexing

Parsing

Compilation

Execution

Variable assignment

Array constructor

Array accessor

Constant

Conditional statement

Boolean expression

Function call

Print statement

<?php!$locations = [ 0 => "Kolbermoor", 1 => "Espelkamp", 2 => "Las Vegas"];!$currentLoc = 0;$currentLocName = $locations[$currentLoc];!if ($currentLoc === 2) { $greeting = "%s, baby!";} else { $greeting = "Hello %s!";}!echo sprintf($greeting, $currentLocName) . "\n";

Page 8: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Lexing

Parsing

Compilation

Execution

compiled vars: !0 = $locations, !1 = $currentLocationId, !2 = $currentLocationName, !3 = $greetingTemplateline # * op fetch ext return operands---------------------------------------------------------------- 4 0 > EXT_STMT 1 INIT_ARRAY ~0 'Kolbermoor', 0 5 2 ADD_ARRAY_ELEMENT ~0 'Espelkamp', 1 7 3 ADD_ARRAY_ELEMENT ~0 'Las+Vegas', 2 4 ASSIGN !0, ~0 9 5 EXT_STMT 6 ASSIGN !1, 0 10 7 EXT_STMT 8 FETCH_DIM_R $3 !0, !1 9 ASSIGN !2, $3 12 10 EXT_STMT 11 IS_IDENTICAL ~5 !1, 2 12 > JMPZ ~5, ->16 13 13 > EXT_STMT 14 ASSIGN !3, '%25s%2C+baby%21' 14 15 > JMP ->18 15 16 > EXT_STMT 17 ASSIGN !3, 'Hello+%25s%21' 18 18 > EXT_STMT 19 EXT_FCALL_BEGIN 20 SEND_VAR !3 21 SEND_VAR !2 22 DO_FCALL 2 $8 'sprintf' 23 EXT_FCALL_END 24 CONCAT ~9 $8, '%0A' 25 ECHO ~9 19 26 > RETURN 1!

Page 9: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Lexing

Parsing

Compilation

Execution

Page 10: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Lexing

Parsing

Compilation

Execution

PHP execution, traditional

Page 11: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Lexing

Parsing

Compilation

Execution

Opcode Cache

PHP opcodesPHP execution,

opcode cacheopcodes executed by PHP interpreter

Page 12: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Lexing

Parsing

Compilation

Execution

HipHop bytecode

JIT compiler

HipHop intermediate

representation

Code repository

x86-64/arm machine code

PHP execution, HipHop VM

executed as native machine code

AST

https://www.facebook.com/notes/facebook-engineering/the-hiphop-virtual-machine/10150415177928920 http://www.hhvm.com/blog/2027/faster-and-cheaper-the-evolution-of-the-hhvm-jit

Page 13: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

$whatAmI = "Dynamic typization is great!";!if ($whatAmI > 0) { $whatAmI = [ "But in many PHP programs,", "this is not excessively used." ];} else { $whatAmI = FALSE;}

Page 14: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

<?php!$locations = [ 0 => "Kolbermoor", 1 => "Espelkamp", 2 => "Las Vegas"];!$currentLoc = 0;$currentLocName = $locations[$currentLoc];!if ($currentLoc === 2) { $greeting = "%s, baby!";} else { $greeting = "Hello %s!";}!echo sprintf($greeting, $currentLocName) . "\n";

Array of strings

IntegerString

Page 15: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

How to install

wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | apt-key add -echo deb http://dl.hhvm.com/debian wheezy main | tee /etc/apt/sources.list.d/hhvm.listsudo apt-get updatesudo apt-get install hhvm

https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Debian-7

Page 16: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM
Page 17: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Running TYPO3 Flow on HHVM

Page 18: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

One does not simply run TYPO3 Flow on HHVM.

Flore Allemandou, CC BY-NC-SA http://www.flickr.com/photos/flore_frmoz/5031037626/

Page 19: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM
Page 20: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM
Page 21: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

TYPO3.Flow/Classes/.../Core/Bootstrap.php ---|+++++++ TYPO3.Flow/Classes/.../Error/ErrorHandler.php -|+ TYPO3.Flow/Classes/.../Http/Headers.php |+++++ TYPO3.Flow/Classes/.../Mvc/Routing/ObjectPathMappingRepository.php -----|++++ TYPO3.Flow/Classes/.../Object/Configuration/ConfigurationArgument.php --|++++++++ TYPO3.Flow/Classes/.../Object/Configuration/ConfigurationProperty.php --|++++++++ TYPO3.Flow/Classes/.../Package/Package.php -|+ TYPO3.Flow/Classes/.../Security/AccountRepository.php -----|++++ TYPO3.Flow/Classes/.../Security/Policy/Role.php -|+++++ TYPO3.Flow/Classes/.../Security/Policy/RoleRepository.php -----|+++++++ TYPO3.Flow/Classes/.../Utility/Unicode/TextIterator.php -|+++++ TYPO3.Party/Classes/TYPO3/Party/Domain/Repository/PartyRepository.php -|+++ doctrine/dbal/lib/.../Driver/PDOConnection.php |+++++++++++++++++++++++++++++++++++++++++++++++ doctrine/dbal/lib/.../Driver/PDOStatement.php -|+++++++++++++++++++++++++++++++++++++++

Web/index.php |++ TYPO3.Media/Classes/.../Domain/Model/Image.php -|++++ TYPO3.Media/Classes/.../Domain/Model/ImageVariant.php -|++++ TYPO3.Setup/Classes/.../Core/BasicRequirements.php -| TYPO3.Setup/Classes/.../Core/RequestHandler.php |+++ TYPO3.TYPO3CR/Classes/.../Migration/Command/NodeCommandController.php -|+++++imagine/imagine/lib/.../Filter/Basic/Resize.php --|++ imagine/imagine/lib/.../Filter/Basic/Thumbnail.php --|++

Doctrine issue #372 (https://github.com/doctrine/dbal/pull/373), backported to 2.3

Hacks around various HHVM glitches

Page 22: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

TYPO3 Flow 2.1

Unit tests, PHP 5.5

Tests: 4186, Assertions: 10145, Failures: 1, Incomplete: 1, Skipped: 95

Unit tests, HHVM (with compatibility patches)

Tests: 4186, Assertions: 10057, Failures: 14, Errors: 21, Incomplete: 1, Skipped: 95

99,98 %

99,14 %

Page 23: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Configuration/Production.hdf

Server { SourceRoot = /var/www/my-flow-site/Web DefaultDocument = index.php Port = 9000 ThreadCount = 100} Eval { Jit = true}!VirtualHost { my-flow-site { Pattern = .* ServerVariables { FLOW_REWRITEURLS = 1 FLOW_CONTEXT = Production } RewriteRules {

Page 24: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Server { SourceRoot = /var/www/my-flow-site/Web DefaultDocument = index.php Port = 9000 ThreadCount = 100} Eval { Jit = true}!VirtualHost { my-flow-site { Pattern = .* ServerVariables { FLOW_REWRITEURLS = 1 FLOW_CONTEXT = Production } RewriteRules { persistentresources { pattern = ^/?(_Resources/Persistent/.{40})/.+(\..+) to = $1$2 }! index { pattern = ^(.*) to = index.php/$1 qsa = true } } }}!StaticFile { Extensions { css = text/css js = text/javascript png = image/png jpg = image/jpeg }}

Page 25: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

TYPO3: Flow: core: phpBinaryPathAndFilename: /usr/bin/hhvm subRequestPhpIniPathAndFilename: false

Configuration/Settings.yaml (configured for speed)

Use HHVM on sub-requests, too for even more performance.

Nico Kaiser, CC BY http://www.flickr.com/photos/nicokaiser/6070496071/

Page 26: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

TYPO3: Flow: core: phpBinaryPathAndFilename: /usr/bin/php subRequestPhpIniPathAndFilename: /etc/php5/cli/php.ini

Always specify a php.ini or “false”. Automatic detection will fail.

Configuration/Settings.yaml (configured conservatively)

Page 27: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Start it> FLOW_CONTEXT=PRODUCTION hhvm -m server -c Configuration/Production.hdf

Page 28: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM
Page 29: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

0

20

40

60

80

Concurrency

50 100 150 200 250 300 350 400 450 500

PHP (Apache+opcache) HHVM (standalone)HHVM (FCGI+Apache) HHVM (FCGI+nginx)

Requests per second TYPO3 Neos 1.0.2, production mode, with HHVM patches

Page 30: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

0

4

8

12

16

Concurrency

50 100 150 200 250 300 350 400 450 500

PHP (Apache+opcache) HHVM (standalone)HHVM (FCGI+Apache) HHVM (FCGI+nginx)

Response times TYPO3 Neos 1.0.2, production mode, with HHVM patches

Page 31: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

91 %

93,25 %

95,5 %

97,75 %

100 %

Concurrency

50 100 150 200 250 300 350 400 450 500

PHP (Apache+opcache) HHVM (standalone)HHVM (FCGI+Apache) HHVM (FCGI+nginx)

Availability TYPO3 Neos 1.0.2, production mode, with HHVM patches

Page 32: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Don't forget! Always enable production mode!

Page 33: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

> composer create-project \ mittwald-typo3/neos-hhvm-distribution

> composer create-project \ mittwald-typo3/flow-hhvm-distribution

Contribute: https://github.com/mittwald/flow-hhvm

Page 34: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

> composer create-project \ mittwald-typo3/neos-hhvm-distribution

Apply compatibility patches Adjust configuration

Create appropriate HDF configuration file

What does it do?

Page 35: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

HHVM

FastCGI

Static files

nginx

Page 36: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Use HHVM as FastCGI backend

Server { Type = fastcgi FileSocket = /var/run/hhvm.sock SourceRoot = /var/www/my-flow-site/Web DefaultDocument = index.php ThreadCount = 100}

configuration.hdf

Page 37: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Use HHVM as FastCGI backend

ProxyPassMatch ^/_Resources !ProxyPass / fcgi://127.0.0.1:9000/var/www/flow/Web/

Apache configuration

location /_Resources { try_files $uri;}!location / { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/flow/Web/$fastcgi_script_name; include fastcgi_params;}

Nginx configuration

Page 38: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Tobias Schlitt, CC-BY-NC-SA http://www.flickr.com/photos/tobiasschlitt/2644905363/

Page 39: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Duncan����������� ������������������  Hull,����������� ������������������  CC����������� ������������������  BY����������� ������������������  http://www.flickr.com/photos/dullhunk/202872717/

Page 40: InspiringCon14: ElePHPants on speed: Running TYPO3 Flow on HipHop VM

Reading

The HipHop virtual machine https://www.facebook.com/notes/facebook-engineering/the-hiphop-virtual-machine/10150415177928920 !Faster and cheaper: The evolution of the HHVM JIT http://www.hhvm.com/blog/2027/faster-and-cheaper-the-evolution-of-the-hhvm-jit !HHVM runtime options https://github.com/facebook/hhvm/wiki/Runtime-options !Running HHVM as FastCGI server https://github.com/facebook/hhvm/wiki/FastCGI !HipHop bytecode specification https://github.com/facebook/hhvm/blob/master/hphp/doc/bytecode.specification !HipHop intermediate representation specification https://github.com/facebook/hhvm/blob/master/hphp/doc/ir.specification !HHVM compatibility package for TYPO3 Flow and Neos https://github.com/mittwald/flow-hhvm !Alla breve: Serverlasten halbieren mit dem PHP-zu-C++-Konverter HipHop c't, 23/2010, p. 180