Google App Engine makes it easy to create applications that work reliably even under heavy loads and with large amounts of data. But it is even easier to create a software monster that will work very slowly or not at all, constantly returning an HTTP 500 error.
How to write fast and well-scalable applications - this will be discussed in this article.
All of the following applies primarily to applications written in Java, but for the most part should be true for applications written in the Python language.
')
One second
Google App Engine allows each application to serve up to 500 requests per second, but only if the execution of each request takes on average no more than one second. Otherwise, the application, as ineffective, will be limited, and already at a relatively small load, some requests will start to end with an HTTP 500 error.
Unfortunately, Google does not disclose the method for calculating the average query execution time, therefore, to ensure that the application does not “fall into disfavor”, it is necessary to ensure that all requests to the application are executed in less than one second.
If it is not possible to do completely without the “long” requests, it is necessary to minimize the frequency of their appearance - “smear” among the quick requests - and then experimentally make sure that the application did not fall under the restrictions. It should be remembered that the restrictions are imposed and removed by the system gradually.
Thirty seconds
Data storage in App Engine allows applications to work effectively with a huge amount of data due to its distributed architecture, but because of it, on average, 1 out of 3000 operations with storage ends up with a timeout. Such operations are automatically repeated, but if after several repetitions the operation was not completed, a DatastoreTimeoutException is generated, in the absence of which handler the application will end with an HTTP 500 error.
For quick requests that take less than a second to process, automatic retries reduce the frequency of DatastoreTimeoutException. During the execution of “long” queries that intensively work with the repository, the probability of generating an exception is much higher. Often, such requests are terminated at all by DeadlineExceededException, because if you repeatedly repeat the unsuccessful “heavy” access to the repository, the application may run out of the 30-second timeout allotted for processing the request.
An application can intercept and process both exceptions, but still the best solution would be to get rid of “heavy” requests in general, for example, by breaking each such request into slightly easier ones. Completely from exceptions, this does not save, but will make their appearance a very rare event.
Ten times per second
All objects in the repository belong to an entity group. To each group belong the objects between which the dependency relationship is defined. An object that is independent of other objects belongs to a group consisting of itself. Groups of objects help App Engine keep related objects together in a distributed repository.
Distributed storage architecture allows you to parallelize operations with objects, but only if they belong to different groups. For objects that are part of a group, no more than 10 write operations per second are supported.
If two requests to an application simultaneously attempt to modify the same object or objects belonging to the same group of objects, then at least one of the write operations will fail, since
there will be a collision. The failed operation will repeat automatically. But if after several repeated attempts the collision is still present, the application will be interrupted by a DatastoreTimeoutException.
When designing an application, you need to clearly understand how the objects will be combined into groups, and how often each of them will be modified, including taking into account the growth in the number of users of the application. In order for the application to scale well, you need to stick to small groups of objects, and for frequently updated data use sharding techniques.
Summary
Google App Engine makes it easy to create applications that work reliably even under heavy loads and with large amounts of data, but only if the requests to the application are executed quickly, the data is exchanged with the storage in small portions, and the data itself is organized into small groups of objects.
The article is written by Alexander, who is not yet present at Habré.Alexander on Habré -
windicted