PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment pgBouncer aide à accélérer Django

En plus d'économiser la surcharge de connexion et de déconnexion là où cela se fait autrement à chaque demande, un pool de connexions peut canaliser un grand nombre de connexions client vers un petit nombre de connexions réelles à la base de données. Dans PostgreSQL, le nombre optimal de connexions actives à la base de données se situe généralement autour de ((2 * core_count) + effective_spindle_count) . Au-dessus de ce nombre, le débit et la latence se détériorent.

Parfois, les gens diront "Je veux prendre en charge 2000 utilisateurs, avec un temps de réponse rapide." Il est à peu près garanti que si vous essayez de le faire avec 2000 connexions réelles à la base de données, les performances seront horribles. Si vous disposez d'une machine dotée de quatre processeurs quadricœurs et que l'ensemble de données actif est entièrement mis en cache, vous constaterez de bien meilleures performances pour ces 2 000 utilisateurs en acheminant les requêtes via environ 35 connexions à la base de données.

Pour comprendre pourquoi cela est vrai, cette expérience de pensée devrait vous aider. Considérez une machine de serveur de base de données hypothétique avec une seule ressource à partager - un seul cœur. Ce noyau répartira le temps de manière égale entre toutes les demandes simultanées sans surcharge. Disons que 100 requêtes arrivent toutes au même moment, chacune nécessitant une seconde de temps CPU. Le noyau travaille sur chacun d'eux, en les découpant dans le temps jusqu'à ce qu'ils finissent tous 100 secondes plus tard. Considérez maintenant ce qui se passe si vous placez un pool de connexions devant qui acceptera 100 connexions client mais n'enverra qu'une seule demande à la fois au serveur de base de données, en plaçant toutes les demandes qui arrivent alors que la connexion est occupée dans une file d'attente. Désormais, lorsque 100 requêtes arrivent en même temps, un client obtient une réponse en 1 seconde; un autre reçoit une réponse en 2 secondes et le dernier client reçoit une réponse en 100 secondes. Personne n'a eu à attendre plus longtemps pour obtenir une réponse, le débit est le même, mais la latence moyenne est de 50,5 secondes au lieu de 100 secondes.

Un vrai serveur de base de données a plus de ressources qui peuvent être utilisées en parallèle, mais le même principe s'applique, une fois qu'elles sont saturées, vous ne faites que nuire aux choses en ajoutant plus de requêtes de base de données simultanées. C'est en fait pire que l'exemple, car avec plus de tâches, vous avez plus de commutateurs de tâches, une augmentation des conflits pour les verrous et le cache, des conflits de lignes de cache L2 et L3 et de nombreux autres problèmes qui réduisent à la fois le débit et la latence. En plus de cela, alors qu'un haut work_mem le paramètre peut aider une requête de plusieurs façons, ce paramètre est la limite par nœud de plan pour chaque connexion , donc avec un grand nombre de connexions, vous devez le laisser très petit pour éviter de vider le cache ou même de conduire à un échange, ce qui entraînerait des plans plus lents ou des choses telles que des tables de hachage se déversant sur le disque.

Certains produits de base de données créent effectivement un pool de connexions dans le serveur, mais la communauté PostgreSQL a adopté la position selon laquelle, puisque le meilleur regroupement de connexions est effectué plus près du logiciel client, ils laisseront aux utilisateurs le soin de gérer cela. La plupart des poolers auront un moyen de limiter les connexions à la base de données à un nombre fixe, tout en autorisant plus de requêtes client simultanées que cela, en les mettant en file d'attente si nécessaire. C'est ce que vous voulez, et cela devrait être fait de manière transactionnelle base, pas par déclaration ou connexion.