Bonjour à toutes et à tous,
Ce coup-ci l’article sera en anglais car c’est une publication d’un white paper rédigé à l’origine par NBS System sur les performances de Magento quand on y couple Zend server. Les tests & benchmarks sont fait entre les versions 1.2, 1.3 et 1.3 avec le flat catalog d’activé puis avec Zend Server et enfin avec Zend server incluant le page cache (version payante).
Ce white paper est en licence Creative commons paternity no commercial use, vous pouvez donc le télécharger, le modifier, le diffuser à votre convenance, sauf pour usage commercial. Celui-ci est uniquement autorisé aux sociétés NBS System, Zend et Varien. (NBS System peut autoriser explicitement l’usage commercial de ce contenu sur demande)
Vous pouvez le télécharger dans sa version PDF intégrale ici.
Magento & Zend Benchmarks
Version 1.2, 1.3 (with & without Flat Catalogs)
Magento is a PHP/Zend application which intensively uses the CPU. Since version 1.1.6, each new version includes some mechanisms aimed to improve the performances. The goal is to use fewer resources for a given e-shop, which mainly means less CPU, in order to host more users with the same hardware.
One key to achieve better performances is how to optimize PHP pages generation and service. "LAMP" servers are well known and usually run Apache server with mod-php, eventually in fast_cgi mod.
Zend, the PHP Company, made a specific server (Zend Server), which includes a web application stack that (among other things) improves application performances through page caching and opcode reorganization & acceleration.
Apache and Zend Server is an alternative to the usual Apache and mod-php to run Magento, the goal of theses studies & tests is to qualify and estimate the performances added by the use of this software.
Many thanks to Yoav Kutner (Varien's CTO) for providing us with prefilled catalogs for 1.2 and 1.3 version of Magento. Thanks goes as well to Zend labs for providing help in configuration and tweaking of the Zend Server as well as explaining the in depth mechanism of the solution.
2. Methods & tools used
The benchmarks were done using siege (2.66-2), with different numbers of simultaneous threads (5, 10, 20 and 40). Each thread opens a connection to the web server, request a page, and start again as soon as the page is fetched.
Tests were run over 5 minutes each; average pages retrieved was counted for this benchmark.
Two kinds of tests were done: the first one is the simplest; we only load the main page in loop, as fast as possible.
The second test is based on logs produced by a visit, loading all the data the browser collected (including css, js, images ...). As loading a single page would usually load multiple elements, the number displayed is much higher than the number of pages that would be actually seen by visitors.
(18 pages viewed by the user, for 91 items downloaded, a ratio around 5)
All results were obtained on the same hardware and operating system, for testing purposes, no reverse proxy was active during the benchmarks but APC code cache was running. This was a "standard", default environment with no special performance tweaks installed.
Dual Quad-Core AMD Opteron(tm) Processor 2376 (2.3GHz), 8GB Ram, 15K SAS disks. (Dell PE M605)
Operating system: Linux (188.8.131.52-grsec) on a Debian (lenny)
Web Server: Apache2 (2.2.9-10+lenny2)
PHP (mod-php): mod-php5 (5.2.6.dfsg.1-1+lenny3) / php-apc (3.0.19-2)
PHP (Zend Server): zend-pe (1.0.0-1+b47) / mod-php5-zend-pe (5.2.9+b75)
deb http://ftp.fr.debian.org/debian/ lenny main
deb http://security.debian.org/ lenny/updates main
deb http://volatile.debian.org/debian-volatile lenny/volatile main
deb http://repos.zend.com/deb/pe pe non-free
3. Magento Versions benchmarks
Those tests were realized on an 80 000 (later called 80 k) products catalog.
Graphs represent the average number of requests successfully loaded from the server per second during the 5 minutes test.
Loading the homepage
Magento 1.3 is much faster than 1.2 showing the main page. Flat Catalogs do not help much displaying this homepage, and seems to even slow down a little under heavy loads. The performance between 1.2 and 1.3 is doubled for low charges and is still 33% higher under heavy load.
For a standard value, under a "standard" load, we can consider that +40% is a reasonable value when running a 1.3 version instead of a 1.2, at least for the homepage.
Full visit cycle
The graph shows a slightly smaller increase with 1.3 compared to 1.2 and the flat catalog mechanism give an overall benefit which greatly increases the performances.
For the records, we can reasonably choose to keep theses values in mind:
Version 1.2 -> 1.3 : +66%
Version 1.3 -> 1.3+Flat Catalog : +20%
4. Apache + mod-php VS Apache + Zend Server
Zend Server (sometimes refered as ZS later on) comes with several built-in technologies for enhancing application performance:
- Zend Optimizer+ performs byte-code optimization and caching. This speeds up PHP applications by eliminating the process of reading scripts from disk and compiling them. Zend Optimizer+ runs automatically, and installing your application on top of Zend Server (ZS) is all you need to do in order to enjoy its benefits. During the test with ZS, APC Code cache is deactivated as Zend optimizer+ is doing the same job.
- Zend Page Cache allows caching of complete PHP pages. Page Caching greatly improves the performance of web applications while maintaining dynamic capabilities through an elaborate system of caching rules that could be based on request parameters and user session data. Page Caching also has the benefit of not requiring any code changes, and can be set up from the Zend Server UI. Only the "pro" version contains this precise piece of software which definitely makes a difference as we will see in a minute.
- Zend Data Cache is a set of API functions enabling a developer to store and manage data items (PHP strings, arrays and other data) and even output elements in either disk-based cache or shared memory cache. Zend Data Cache allows for precision-guided caching when Page Caching is not an option. The provided API is easy-to-use on existing code, and in many cases a developer can skip existing code sections by simply wrapping them with caching APIs. This precise piece of software would benefit from a little remastering of the code by Varien to really achieve a full support of this functionality. If done, we can imagine selectively flushing the cache when changing some pages on the servers and not destroying the whole Magento cache thus doing a "cold cache start" after a new functionality is put online.
Note: Zend Optimizer+ and Zend Data Cache are available in the free, community version of Zend Server, while Zend Page Cache requires a licensed Zend Server (full comparison of Zend Server and Zend Server Community Edition is located at http://www.zend.com/fr/products/server/editions).
Zend Server Configuration for Magento
In the benchmark, two caching rules have been defined:
This simple rule results in a very substantial improvement to response times.
The second rule caches all web pages accessed by users who have nothing in their shopping carts or history (when the shopping cart is not empty or when the user history is saved, there is no point in page caching). As you can see in the screen capture below, this is accomplished by looking at $_SESSION variables and by splitting according to $_SERVER['REQUEST_URI'] in addition to the QUERY_STRING.
Finally, Zend Optimizer+ has been enabled for optimizing and caching the PHP byte-code.
As you can see, Zend Page Cache seems a very powerful feature. It needs fine tuning and better configuration, but let's see results :
Homepage / 80 000 products catalog
Load on main page doesn't prove very constructive, although, on heavy load (40 concurrent requests), Zend Server (with or without page cage) is slightly better than basic mod-php, but almost no real improvements on this test. A 5% or less win is not to be taken seriously as it is the error margin of the tests.
Full visit / 80k products
Full visit graphic speaks for itself, whatever the load, Zend Server with Page Cache and Flat Catalog make a big difference.
Comparing a 1.3 with flat catalog with a the same configuration but with a Zend Community installed instead of just APC, our server yield up to 15% more performances, just using a free edition of ZS.
If we use a full Zend server (the licensed one including the page cache) on this 1.3 flat catalog, our server goes up to 30% more performances!
Mod PHP + APC -> ZS: +15%
Mod PHP + APC -> ZS licensed edition: +30%
5. Response time
Homepage / 80k products
This graph show response time on the homepage measured during a load. No match on this test, under a good load, ZS, community or licensed edition, gives up a 35% boost in the load time, good to take.
Full visit / 80k products
Page Cache provides a better response time over a full visit of the site, even under very heavy load. As the difference remains thin, I would conclude it to be identical in that condition. However, the benefits of the page cache under a standard load remains a must have. Once again, a 35% win is to be considered as a reference value under a good load whether you are using a community or licensed version.
Under medium or light load, the page cache is giving a lot more power than the community edition can do. This strange result is probably mainly due to the page cache mechanism which prove to be not that efficient under heavy load because the system is using its resource in a different way.
We didn't had time to check if it was a False cache sharing effect on L2 or L3 processor cache or a Linux or ZS issue but the test has been runned several times yielding the same results.
So keep in mind that the benefits of the ZS Page cache mechanism is going to be less and less active as the server load gets high. Under a usual load, a reasonable load lets say, the Page Cache algorithm gives a nice boost to the loading time, driving it down for ~40%.
6. Additional technical details about the tests
All tests were run with generated sample data (provided by Varien)
|Category * product associations||24690||202743|
Description of the tests
Main page test
Each concurrent thread loads the main page, without storing the cookies to simulate simultaneous users.
Full visit test
We have a list requests based on a visit done with a real browser. Each concurrent thread loads each item one after another as fast as possible, and restarts after deleting all its cookies. This simulates simultaneous users, except that simultaneous.
List of requested pages for the 80k database (with POST information when it applies):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
<span style="font-size: xx-small;">http://test80k/ http://test80k/skin/frontend/default/default/favicon.ico</span> <span style="font-size: xx-small;">http://test80k/js/index.php?c=auto&f=,prototype/prototype.js,prototype/validation.js,scriptaculous/builder.js,scriptaculous/effects.js,scriptaculous/dragdrop.js,scriptaculous/controls.js,scriptaculous/slider.js,varien/js.js,varien/form.js,varien/menu.js,mage/translate.js,mage/cookies.js http://test80k/skin/frontend/default/default/css/reset.css http://test80k/skin/frontend/default/default/css/menu.css http://test80k/skin/frontend/default/default/css/print.css http://test80k/skin/frontend/default/default/css/clears.css http://test80k/skin/frontend/default/default/css/boxes.css http://test80k/skin/frontend/default/default/images/body_bg.gif http://test80k/skin/frontend/default/default/images/logo.gif http://test80k/skin/frontend/default/default/images/btn_mini_search.gif http://test80k/skin/frontend/default/default/images/mini_search_bg.gif http://test80k/skin/frontend/default/default/images/nav_bg.jpg http://test80k/skin/frontend/default/default/images/nav_divider.gif http://test80k/skin/frontend/default/default/images/main_container_bg.gif http://test80k/skin/frontend/default/default/images/shop_access_pipe.gif http://test80k/skin/frontend/default/default/images/base_mini_head_bg.gif http://test80k/skin/frontend/default/default/images/media/col_left_callout.jpg http://test80k/skin/frontend/default/default/images/header_top_container_bg.jpg http://test80k/skin/frontend/default/default/images/icon_table.gif http://test80k/skin/frontend/default/default/images/icon_newspaper.gif http://test80k/skin/frontend/default/default/images/icon_tag_green.gif http://test80k/skin/frontend/default/default/images/icon_basket.gif http://test80k/skin/frontend/default/default/images/media/col_right_callout.jpg http://test80k/skin/frontend/default/default/images/footer_info_separator.gif http://test80k/skin/frontend/default/default/images/main_bg.gif http://test80k/category-736 http://test80k/skin/frontend/default/default/images/layered_nav_head_bg.gif http://test80k/skin/frontend/default/default/images/layered_nav_narrowed_category_heading.gif http://test80k/skin/frontend/default/default/images/narrow_by_set.gif http://test80k/skin/frontend/default/default/images/narrow_by_dd_bg.gif http://test80k/skin/frontend/default/default/images/pager_arrow_right.gif http://test80k/skin/frontend/default/default/images/sort_asc_arrow.gif http://test80k/media/catalog/product/cache/1small_image/135x135/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/small_image.jpg http://test80k/skin/frontend/default/default/images/pager_bg.gif http://test80k/category-736?attribute_864=306 http://test80k/skin/frontend/default/default/images/list_remove_btn.gif http://test80k/skin/frontend/default/default/images/narrow_category_bg.gif http://test80k/skin/frontend/default/default/images/narrow_by_li_by.gif http://test80k/category-736?attribute_864=306&price=3%2C100 http://test80k/category-736?attribute_864=306&price=3%2C100&p=2 http://test80k/skin/frontend/default/default/images/pager_arrow_left.gif http://test80k/category-736?attribute_864=306&price=3%2C100&p=3 http://test80k/category-736/gtx14049.html http://test80k/js/index.php?c=auto&f=,prototype/prototype.js,prototype/validation.js,scriptaculous/builder.js,scriptaculous/effects.js,scriptaculous/dragdrop.js,scriptaculous/controls.js,scriptaculous/slider.js,varien/js.js,varien/form.js,varien/menu.js,mage/translate.js,mage/cookies.js,varien/product.js,calendar/calendar.js,calendar/lang/calendar-en.js,calendar/calendar-setup.js http://test80k/js/calendar/calendar-win2k-1.css http://test80k/media/catalog/product/cache/1/image/265x/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/image.jpg http://test80k/skin/frontend/default/default/images/product_essential_bg.gif http://test80k/skin/frontend/default/default/images/product_collateral_bg.gif http://test80k/skin/frontend/default/default/images/dotted_divider.gif http://test80k/skin/frontend/default/default/images/icon_tag_add.gif http://test80k/checkout/cart/add/uenc/aHR0cDovL3Rlc3RtMTIudGVzdC5uYnMtc3lzdGVtLmNvbS9jYXRlZ29yeS03MzYvZ3R4MTQwNDkuaHRtbD9fX19TSUQ9VQ,,/product/67952/ POST product=67952&related_product=&qty= http://test80k/checkout/cart/ http://test80k/js/index.php?c=auto&f=,prototype/prototype.js,prototype/validation.js,scriptaculous/builder.js,scriptaculous/effects.js,scriptaculous/dragdrop.js,scriptaculous/controls.js,scriptaculous/slider.js,varien/js.js,varien/form.js,varien/menu.js,mage/translate.js,mage/cookies.js,varien/weee.js http://test80k/skin/frontend/default/default/images/btn_proceed_to_checkout.gif http://test80k/skin/frontend/default/default/images/btn_trash.gif http://test80k/media/catalog/product/cache/1/thumbnail/75x/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/thumbnail.jpg http://test80k/skin/frontend/default/default/images/success_msg_icon.gif http://test80k/skin/frontend/default/default/images/icon_asterick.gif http://test80k/skin/frontend/default/default/images/icon_lorry.gif http://test80k/skin/frontend/default/default/images/data_table_th_bg.gif http://test80k/skin/frontend/default/default/images/base_mini_actions_bg.gif http://test80k/category-736/gtx14049.html http://test80k/media/catalog/product/cache/1/thumbnail/50x50/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/thumbnail.jpg http://test80k/category-1497 http://test80k/media/catalog/product/cache/1/small_image/135x135/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/small_image.jpg http://test80k/category-1497?attribute_864=305 http://test80k/category-1497/npt25-a.html http://test80k/media/catalog/product/cache/1/image/265x/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/image.jpg http://test80k/checkout/cart/add/uenc/aHR0cDovL3Rlc3RtMTIudGVzdC5uYnMtc3lzdGVtLmNvbS9jYXRlZ29yeS0xNDk3L25wdDI1LWEuaHRtbD9fX19TSUQ9VQ,,/product/25870/ POST product=25870&related_product=&qty= http://test80k/checkout/cart/ http://test80k/media/catalog/product/cache/1/thumbnail/75x/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/thumbnail.jpg http://test80k/category-3 http://test80k/media/catalog/product/cache/1/thumbnail/50x50/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/thumbnail.jpg http://test80k/category-3?price=4%2C1000 http://test80k/checkout/cart/add/uenc/aHR0cDovL3Rlc3RtMTIudGVzdC5uYnMtc3lzdGVtLmNvbS9jYXRlZ29yeS0zP3ByaWNlPTQlMkMxMDAwJmNhdD0zNyZfX19TSUQ9VQ,,/product/4642/ http://test80k/checkout/cart/ http://test80k/checkout/onepage/ http://test80k/js/varien/accordion.js http://test80k/skin/frontend/default/default/js/opcheckout.js http://test80k/skin/frontend/default/default/images/opc_off_head_bg.gif http://test80k/skin/frontend/default/default/images/opc-ajax-loader.gif http://test80k/skin/frontend/default/default/images/btn_window_close.gif http://test80k/skin/frontend/default/default/images/cvv.gif http://test80k/skin/frontend/default/default/images/multi_address_box_bg.gif http://test80k/skin/frontend/default/default/images/btn_place_order.gif http://test80k/catalogsearch/ajax/suggest/ POST q=45 http://test80k/catalogsearch/ajax/suggest/ POST q=456 http://test80k/catalogsearch/result/?q=456&x=17&y=8 http://test80k/media/catalog/product/cache/1/small_image/135x135/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/small_image.jpg http://test80k/media/catalog/product/cache/1/thumbnail/50x50/5e06319eda06f020e43594a9c230972d/images/catalog/product/placeholder/thumbnail.jpg</span>
7. Things to test in the next benchmark campaign
When running all those tests, 184.108.40.206 version including the Mage optimizer was about to be released and an immediate 220.127.116.11 version followed and we didn't had time to include some tests around this precise point. Let's just consider the fact that this mechanism is mainly made to lower I/O jobs by "compiling" the libraries files all in one or two includes only. If your servers were already using mainly their RAM to work, the performances increase will not be that valuable. But if your servers where low on RAM or using mainly their disks, you should feel confident with using this option which can do great good to your performances!
We didn't had the required time to consolidate the results involving Nginx + PHP tests. This solution ranked almost every time between Magento 1.3 + FC and Magento 1.3 + Zend server (without Page cache). So this combination yield average performances, not as sharp as a Magento 1.3 + Zend server or any more advanced combination.
More "customed" visits
We have used a scenario involving each time a research in the search bar of the website and some "standard" behaviors. A more precise test can be run replaying some real traffic pumped up from apache log on a real site, the customer's behaviors being more realistic even if our scenario was as logical as possible.
First, let me say that no electrons were armed or injured during these benchmarks. Perhaps one or two CTO were put under constraint and continuous coffee perfusions but all of this was intend for the greater good of E-commerce!
If you wish a more professional conclusion, let's say that using ZS community edition will only do you good and really can replace APC.
If using the licensed version, the Page cache is very efficient (under reasonable load of the servers) and can help using ~25% less machines to achieve similar hosting capacities. If your servers are billed in a "managed hosting" way, having one or two less servers billed per month can make a good difference in the budget.
About Zend Server : this software has many other great functionalities and this paper is only consider the "performances" issues, just pay a visit to Zend Website for a far more complete overview of the product.
Last but not least, creating a server with all optimizations and best practices, based on an a dual AMD 2376 with 8 Go of RAM and using ZS and page cache, you can try to reach up to ~40 000 unique visitors a day corresponding to ~2 500 Magento simultaneous session at maximum load. (if database is separated on a different server and you activate a reverse proxy like Squid or Varnish above your front web servers)
This estimation is deeply linked to the website complexity and user standard behavior but these figures are given for a "standard" site and use, you can usually also expect a ~2 seconds loading time on the homepage.
© June 2009, NBS Team,
René Amirkhanian, Adrien Urban, Philippe Humeau,
you can visit us here: www.nbs-system.com
and reach us at: email@example.com for any comments or corrections (and yes, we do hosting [superemotions file="icon_biggrin.gif" title="Big Grin"])
9. Creative Commons
This document is released under the creative common license "Attribution-Noncommercial-Share Alike 3.0". Only three companies (NBS System, Zend and Varien) are allowed to use it for commercial purposes.