Une solution complexe aux problèmes simples des services WEB HighLoad



Une tâche clé des systèmes WEB très chargés est la capacité de traiter un grand nombre de demandes. Ce problème peut être résolu de différentes manières. Dans cet article, je propose d'envisager une méthode inhabituelle pour optimiser les requêtes backend via la technologie content-range (range). À savoir, pour réduire leur nombre sans perdre la qualité du système grâce à une mise en cache efficace.

Pour commencer, je propose d'étudier un article où le préambule technologique avec un exemple pour S2S est présenté de manière très concise et intelligible. De plus, il est conseillé de se familiariser avec mon premier article sur l'utilisation de cette technologie pour optimiser le travail avec les données de marché sur un projet d'échange de crypto-monnaie.

Dans cet article, je veux montrer que cette technologie peut être utilisée plus largement que le premier article l'a démontré. Permettez-moi de vous rappeler que les informations de trading ( bougies ) sont obtenues par des demandes de plage de fichiers statiques, qui sont préparées à l'avance par un service spécial. Maintenant, je veux considérer les demandes pour un backend complet en utilisant les mêmes données de marché comme exemple, et pour les mêmes bougies, sans perdre de bénéfices clés.

Alors, qu'est-ce qui est prévu de réaliser:

  1. Optimiser les requêtes backend (réduire leur nombre);
  2. Augmentez la vitesse de livraison du contenu à l'utilisateur final;
  3. Optimiser le trafic.

Encore une fois, j'insiste sur le fait que la technologie de portée est un standard ( RFC 2616 ). Il est pris en charge nativement par les navigateurs et ils sont capables de mettre en cache les parties de données reçues. Par conséquent, la prochaine requête du navigateur, s'il existe un cache réel de la partie demandée, est implémentée sur le client sans déranger vos serveurs.

Si vous ajoutez CDN entre le client et les serveurs, vous pouvez obtenir une autre couche puissante de mise en cache. Et si dans le premier cas, la mise en cache se produit pour un client final spécifique, puis associée à un CDN, vous avez la possibilité de mettre en cache des données déjà pour un groupe de clients finaux.

Ainsi, afin de faire une vraie demande au serveur, la demande doit surmonter deux niveaux de mise en cache, chacun réduisant le volume de demandes au serveur de destination. Bien sûr, la «redoute» finale, sur le chemin de requête, peut être votre serveur avec son cache.

Parmi les fonctionnalités de l'utilisation de la technologie de plage, vous devez considérer qu'elle fonctionne avec des portions d'octets. C'est-à-dire avec des données binaires. Et nous pouvons demander des intervalles d'octets exactement. Ils doivent répondre, respectivement - avec un bloc binaire.

Je pense assez introductif. Passons à un cas particulier, et déjà à titre d'exemple, nous découvrirons comment utiliser tout ce «bonheur» dans un problème particulier - demander des bougies pour un intervalle donné avec une exposition donnée.

Pour commencer, comme nous devons travailler avec des structures binaires, encodons notre bougie. Pour cela nous prenons, par exemple, la structure suivante:

moment: int32 //   min: float64 //   max: float64 //   open: float64 //   close: float64 //   volume: float64 //  average: float64 //   

Ainsi, notre structure occupera 52 octets. Nous le prenons comme un quantum - le bloc binaire minimum.

Ensuite, nous implémentons un contrôleur qui acceptera les requêtes GET et analysera l'en-tête de plage. Dans ce cas, nous traduirons l'intervalle demandé en quanta par simple division sans reste, c'est-à-dire par exemple, une demande d'intervalle:

Range: 5200-52000

Nous devons interpréter dans la dimension de notre quantum comme:

Range: 100-1000

En substance, ce sera l'offset et la limite de notre requête de base de données.

La définition de l'exposition étant très simple, on peut la mettre dans l'url. Par exemple:

/api/v1/candles/7m

C'est-à-dire nous demanderons des bougies d'une exposition de 7 minutes. Naturellement, nous supposons que ce paramètre peut être modifié à la demande du frontend.

Maintenant, connaissant l'exposition requise, le numéro de la première bougie et le numéro de la dernière bougie que le frontend demande, nous pouvons exécuter la requête correspondante dans la base de données.

En général, cela fait très penser au problème de pagination classique.

Il reste peu de choses. Chaque ligne du résultat de la requête est convertie en une structure binaire (le même quantum) et le tableau binaire résultant est affiché comme résultat de la requête, et la plage de contenu est renvoyée à l'en-tête de réponse:

Content-Range: [ ] / [[ ] * [ ]]

Arrêter Mais comment le front peut-il demander l'intervalle de temps souhaité, et même dans l'intervalle d'octets? Comment sait-il des nombres de bougies là-bas? Ici aussi, tout a été inventé. La plage prend en charge le décalage relatif, par exemple

Range: -52

Demandez 52 octets à la fin. C'est-à-dire la dernière bougie. Maintenant, connaissant le dernier instant de la dernière bougie, connaissant, à partir de la réponse, la taille totale du «fichier», vous pouvez calculer le nombre total de bougies, et à partir de là déterminer l'intervalle d'octets pour demander l'exposition de temps souhaitée.

Si vous avez soudainement voulu poser une question - pourquoi de telles difficultés? Veuillez revenir à vos objectifs. Cette technologie a «masqué» les requêtes analytiques vers la base de données en fichiers binaires pour le CDN et le navigateur. Cela vous permet de transférer la plupart des demandes répétées vers le CDN et le client final.

Peut-être qu'une autre question se pose - pourquoi ne pas utiliser la simple mise en cache des requêtes GET? Bon. Faisons les choses correctement. Si nous exécutons une telle demande en REST classique:

GET /api/v1/candles/7m?from=01-03-2018&to=31-03-2018

Nous obtiendrons un cache unique pour cette demande. En exécutant la requête suivante:

GET /api/v1/candles/7m?from=15-03-2018&to=20-03-2018

Nous aurons un autre cache unique .... bien que, notez, la deuxième demande demande les données incluses dans la réponse de la première.

Ainsi, dans le cas de la mise en œuvre proposée ci-dessus (plage), la deuxième demande ne formera pas un cache séparé, mais utilisera les données déjà reçues de la première demande. Et il n'entrera pas sur le serveur. Et cela, en économisant la taille des caches et en réduisant le nombre d'appels au serveur.

Y a-t-il des inconvénients à cette technologie? Oui Ils sont évidents:

  1. Cette technologie n'est pas adaptée à l'évolution des données dans le temps, car basé sur la mise en cache totale.
  2. CDN CloudFlare ne met en cache que les fichiers complètement. Cela signifie que si le client final demande un intervalle de, disons, 1 à 100 octets, CloudFlare demandera en fait l'intégralité du fichier au serveur. C'est-à-dire dans notre cas, il chargera toutes les bougies avec une certaine exposition. Il le mettra seul et le distribuera déjà lui-même. Cela pourrait même être considéré comme un avantage, sinon pour les restrictions sur l'endroit. Et si vous pouvez former des réponses "lourdes", et beaucoup de paramètres, alors ... En général, il est clair que l'endroit prendra fin. Peut-être n'avons-nous pas pu le configurer correctement. Mais jusqu'à présent, le résultat est le suivant.
  3. Il est nécessaire de gérer judicieusement les caches. Il existe des mécanismes suffisants pour cela, mais ils nécessitent un réglage.
  4. Le frontend devrait être capable d'analyser les données binaires et d'avoir quelque chose comme un jeu de données à bord pour travailler avec les demandes de plage.

Je formulerais la faisabilité de la mise en œuvre de cette stratégie comme suit - lorsque vous en aurez besoin, vous comprendrez. S'il y a maintenant des doutes, il est utile de la connaître, mais ne vous embêtez pas.

Source: https://habr.com/ru/post/fr424415/


All Articles