I bring to your attention a translation of the article Spryker Performance and Scalability Concepts .Spryker is an e-commerce framework, the result of more than 100 individual e-commerce projects. It provides two of the most important architectural qualities out of the box - high performance and scalability. This article describes the basic concepts for achieving them.
Why is performance and scalability so important?
Everyone knows that low server performance is a real conversion killer. Without a doubt, a fast website is pleasant to use, but there are other reasons to fight for reducing the response time of the server.
You may remember the difficulties of working with a slow application under high load. At Spryker, we want to make sure that the online store will never become a “bottleneck” in any marketing campaign, be it TV advertising, mass mailing or SEM campaigns.
')
Good application performance has a positive effect on the productivity of the IT team. Developers do not need to spend time that has no business value on the introduction of complex database replication mechanisms or expensive server configuration.
For obvious reasons, we also want to avoid full-page caching .
Another advantage of a fast application is the ability to run a store on small (and cheap) servers in the cloud, both for testing and for production. In general, the complexity of server hardware can be greatly simplified if you do not need to spend time optimizing and setting up the hardware.
Architectural goals
Under normal load, a typical Spryker Store should have an average response time of about 50 ms. Even such costly requests, such as adding a product to the cart, must be completed in less than 150 ms. If these numbers do not tell you anything, you can compare them with the (unofficial)
Magento performance tests , which were published by
Dmitry Soroka . Dmitry is a former lead architect of Magento, so it can be assumed that his numbers are not very different from reality. He compared the old, but still famous, Magento 1 with the new Magento 2:
On the Magento 1 product page, the server response was 250 ms or less in 90% of cases. For Magento 2, less than 25% of requests could be within 250 ms. As shown in the graph below, most requests were executed 600 ms or more.
Compared to these results, Spryker is 5 times faster than Magento 1 and 5-12 times faster than Magento 2. As a first acquaintance with our results, we give below a graph of the response time of the home page of the Spryker store (its behavior is similar to the product page). Testing was conducted on a single Heroku server with a load of 3000 requests per minute, there is no full page caching.
3k RPM / Heroku 1 Performance L Dyno / PHP7In addition to faster response, both at low and high loads, at the maximum load of equipment, scalable systems show a slower increase in response time. A bad system simply stops responding, often when the SQL database starts to accumulate requests in the queue or the I / O wait time is too long.
We also try to reduce the amount of consumed memory, it allows you to perform a large number of parallel requests without having to buy more expensive server memory
Finally, we want to be able to easily scale horizontally, without bottlenecks or cold caches.
Actual performance in a particular project depends on many factors, such as the specific setting of the hosting, the structure of the site, the number of products, interaction with other services and, of course, the performance of the developed solution. For high-load projects, we always recommend a specialized load test simulating real user traffic. Our customers do not need to make significant efforts to optimize or complex server configuration, as Spryker provides a fast PHP framework framework.
Optimized software design
To achieve the above goals, we decided to divide the store application into two parts: Yves and Zed. Yves - client front-end. This is a small PHP application based on the
Silex microframe from SensioLabs . Zed is a “heavy” server application containing all business logic.
Yves provides most of its speed with a simplified design without unnecessary architectural layers and an easy loading process. Another important concept of Yves is the way to access data. Instead of costly SQL queries to a relational database with many connections and conditions, Yves reads data from a very fast key-value data repository (Redis by default). The speed of full-text and faceted search for Yves is due to the powerful Elasticsearch. The relational database, which often becomes a bottleneck for scalability, is not directly accessible from Yves. Instead, Zed collects all changes to the data and puts them in a prepared form in Redis and Elasticsearch.

Yves performance
To evaluate the performance of Yves, consider the sequence of its actions. A typical Yves query is as follows:
(1) Parsing URL
(2) Get all data from Redis and / or Elasticsearch
(3) Add this data to precompiled
Twig templates.
Obviously, there are not so many actions for PHP code, fast because of the simplified architecture. In terms of performance, the most critical part begins in the second step, when Yves receives data from Redis and / or Elasticsearch. All product data, CMS pages and translations are stored in Redis. On the other hand, the normalized relational database PostgreSQL or MySQL information about each product is distributed among several tables: stocks, prices, taxes, etc .; All this is hydrogenated into a single data set, which is stored in Redis. Instead of several costly queries, Yves simply executes Redis :: get () to get all the necessary data at once.
Each page requires multiple data sets. Redis is very fast, even with large amounts of data and a large number of connections. In the case of installing Redis on the same server with Spryker, one Redis :: get () request takes only 0.1 ms. In the event that you run Spryker in a cloud service, which makes 90% of our customers, network latency manifests itself. Instead of a quick in-memory search for local Redis, a slow network significantly increases execution time. For this reason, Yves automatically merges data into a single Redis :: mget () request instead of dozens of Redis :: get (). This allows to level the conceptual limitations of cloud services and get the maximum performance from Redis.
Unlike Redis, Elasticsearch is used only for the directory. We execute only one request, but this request is much slower than Redis :: get (). To prevent slow queries, we optimized the index population, in which data is prepared for a quick search. We will talk about this in detail in another article.
And finally, I would like to say a few words about scalability. To prepare Spryker for scalability in cloud services, we strictly adhere to the
methodology of twelve factors . The most important part of it is that “application processes do not store their internal state (stateless) and do not have shared data (share-nothing)”. All parts of Yves can be scaled independently of other parts of the application. You can add more instances of Yves, or additional resources for Redis or Elasticsearch. All this is possible without downtime, you do not even need to deploy the application. More, this issue will be consecrated in future articles.
We will be happy if you learn about the Spryker project. It will easily
run on your computer , since all settings are prepared in the basic virtual machine for VirtualBox. Important: Opcache is disabled in this image.