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

4,284 views

Published on

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

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,284
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
15
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

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

  1. 1. ElePHPants on speed RunningTYPO3 Flow on HipHopVM Inspiring Conference, March 28th 2014 Martin Helmich, Mittwald CM Service m.helmich@mittwald.de Photo: George Lamson, CC BY-NC-SA http://www.flickr.com/photos/lamsongf/6415913075/
  2. 2. YOUR SPEAKER Martin Helmich Software architect at Mittwald TYPO3 addicted since 2004 Caffeine addicted since 2007
  3. 3. Sebastian Bergmann, CC BY-SA http://www.flickr.com/photos/sebastian_bergmann/2337231691/
  4. 4. Lexing Parsing Compilation Execution PHP execution, traditional
  5. 5. <?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 Compilat Executio
  6. 6. T_OPEN_TAG T_VARIABLE T_LNUMBER T_DOUBLE_ ARROW T_CONSTANT_ENCAPSED_STRING T_IF T_ELSE T_ECHO T_STRING Lexing Parsing Compilat Executio <?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";
  7. 7. Lexing Parsing Compilat Executio 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";
  8. 8. Lexing Parsing Compilat Executio compiled vars: !0 = $locations, !1 = $currentLocationId, !2 = $currentLocationName, !3 = $greetingTemplate line # * 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 !
  9. 9. Lexing Parsing Compilat Executio
  10. 10. Lexing Parsing Compilation Execution PHP execution, traditional
  11. 11. Lexing Parsing Compilation Execution Opcode Cache PHP opcodes PHP execution, opcode cache opcodes executed by PHP interpreter
  12. 12. Lexing Parsing Compilation Execution HipHop bytecode JIT compiler HipHop intermediate representation Code repository x86-64/arm machine code PHP execution, HipHopVM 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
  13. 13. $whatAmI = "Dynamic typization is great!"; ! if ($whatAmI > 0) { $whatAmI = [ "But in many PHP programs,", "this is not excessively used." ]; } else { $whatAmI = FALSE; }
  14. 14. <?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 Integer String
  15. 15. 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.list sudo apt-get update sudo apt-get install hhvm https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Debian-7
  16. 16. RunningTYPO3 Flow on HHVM
  17. 17. One does not simply runTYPO3 Flow on HHVM. Flore Allemandou, CC BY-NC-SA http://www.flickr.com/photos/flore_frmoz/5031037626/
  18. 18. 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
  19. 19. 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 %
  20. 20. 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 }
  21. 21. 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 } }
  22. 22. 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/
  23. 23. 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)
  24. 24. Start it > FLOW_CONTEXT=PRODUCTION hhvm -m server -c Configuration/Production.hdf
  25. 25. 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
  26. 26. 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
  27. 27. 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
  28. 28. Don't forget! Always enable production mode!
  29. 29. > composer create-project mittwald-typo3/neos-hhvm-distribution > composer create-project mittwald-typo3/flow-hhvm-distribution Contribute: https://github.com/mittwald/flow-hhvm
  30. 30. > composer create-project mittwald-typo3/neos-hhvm-distribution Apply compatibility patches Adjust configuration Create appropriate HDF configuration file What does it do?
  31. 31. HHVM FastCGI Static files nginx
  32. 32. 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
  33. 33. 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
  34. 34. Tobias Schlitt, CC-BY-NC-SA http://www.flickr.com/photos/tobiasschlitt/2644905363/
  35. 35. Duncan

×