The difficult solution of simple problems HighLoad WEB-services
The key task of high-loaded WEB-systems is the ability to process a large number of requests. This problem can be solved in different ways. In this article, I propose to consider an unusual method for optimizing requests to the backend via the content-range (range) technology. Namely - to reduce their number without losing the quality of the system through effective caching.
To begin with, I propose to study the article , where the technology preamble with an example for S2S is very succinctly and clearly stated. Further, it is advisable to get acquainted with my first article on the use of this technology for optimizing work with the market-data on a crypto-exchange project.
In this article, I want to show that this technology can be used more widely than the first article demonstrated. Let me remind you that there trading information ( candles ) is obtained by range-requests to static files that are prepared in advance by a special service. Now, I want to consider requests for a full backend on the example of the same market-data, and for the same candles, without losing key profits.
So, what is planned to achieve:
- Optimize requests to the backend (reduce their number);
- Increase the speed of content delivery to the end user;
- Optimize traffic.
Once again, I emphasize that range technology is a standard ( RFC 2616 ). It is natively supported by browsers and they are able to cache the received chunks of data. Therefore, the next request from the browser, in the presence of the actual cache of the requested portion, is implemented on the client, without disturbing your servers.
If you add a CDN between the client and servers , you can get another, powerful cache layer. And if in the first case, caching will occur for a specific, final client, then paired with a CDN, you get the opportunity to cache data already for a group of end customers.
Thus, in order for a real request to the server to take place, the request needs to overcome two echelons of caching, each of which reduces the volume of requests to the target server. Of course, the final “redoubt”, in the path of the request, can be your server with its cache.
Of the features of the use of technology range, you need to consider that it works with portions of bytes. Those. with binary data. And we can request exactly the intervals of bytes. Must respond, respectively - a binary block.
I think introductory enough. Let's move on to a special case, and by an example we will figure out how we can use all this “happiness” in a particular task - a request for candles for a given interval with a given exposure.
To begin with, because we have to work with binary structures, let's encode our candle. To do this, take, for example, the following structure:
moment: int32// Момент времени min: float64// Минимальная цена max: float64// Максимальная цена open: float64// Цена открытияclose: float64// Цена закрытия volume: float64// Объем average: float64// Средняя цена
Thus, our structure will take 52 bytes. Let's accept it as a quantum - the minimum binary block.
Next, we will implement a controller that will receive GET requests and parse the range header. In this case, we will translate the requested interval into quanta by simple division without remainder, i.e. for example, a request with an interval: We
must be interpreted in the dimension of our quantum as:
In essence, this will be the offset and limit of our query to the database.
With the definition of exposure is quite simple, we can put it in the url. For example:
Ie we will request candles with an exposure of 7 minutes. Naturally, we assume that this parameter can be changed at will frontend.
Now, knowing the required exposure, the number of the first candle and the number of the last candle requested by the frontend, we can execute the corresponding query to the database.
In general, it is very similar to the classical problem with pagination.
Little things left. Each line of the query result is converted into a binary structure (the same quantum) and the resulting binary array is output as a result of the query, and content-range is sent to the response header:
Content-Range: [запрошенный интервал] / [[количество записей в БД] * [размер кванта]]
Stop. But how can the front be able to request the desired time interval, and even in the byte interval? How does he know any numbers of candles? Here, too, everything is invented. Range supports relative offset, for example,
Will request 52 bytes from the end. Those. last candle Now, knowing the last time point of the last candle, knowing from the response, the total size of the “file”, you can calculate the total number of candles, and from here you can determine the byte interval for requesting the desired time exposure.
If you suddenly wanted to ask a question - why is it so difficult? Please return to the goals. This technology has “masked” analytical database queries into binary files for CDN and browser. This allows most of the repeated requests to pass on to the CDN and the end client.
Perhaps another question arises - why not use simple GET requests caching? Good. Let's figure it out. If we execute such a query in the classic REST:
We will get a unique cache for this query. By running the following query:
We will get another unique cache .... although note, the second request asks for the data included in the response of the first.
So, in the case of the above proposed implementation (range), the second request does not form a separate cache, but uses the data already received from the first request. And do not climb to the server. And this, saving the size of caches and reducing the number of calls to the server.
Are there any disadvantages of this technology? Yes. They are obvious:
- This technology is poorly suited for data changing over time, because based on total caching.
- CDN CloudFlare only caches files entirely. This means that if the end client requests an interval, say, from 1 to 100 bytes, then CloudFlare will actually request the entire file from the server. Those. in our case, it will load all the candles with a certain exposure. He will put it in his place and will be giving it out himself. It could even be considered a plus, if it were not for restrictions on the site. And if you can form “heavy” answers, and many parameters, then ... In general, it is clear that the place will end. Perhaps we could not properly configure it. But while the result is as follows.
- It is required to manage caches wisely. There are sufficient mechanisms for this, but they require tuning.
- Frontend should be able to parse binary data and have something ala dataset on board to work with range requests.
I would formulate the expediency of implementing this strategy in the following way: when you need it, you will understand. If there is any doubt, it is useful to know about her, but do not bother.