Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Dans son exposé, Andrey Borodin vous expliquera comment ils ont pris en compte l'expérience de la mise à l'échelle de PgBouncer lors de la conception d'un pooler de connexions Odyssey, comment ils l'ont déployé en production. De plus, nous discuterons des fonctions du pooler que nous aimerions voir dans les nouvelles versions : il est important pour nous non seulement de couvrir nos besoins, mais de développer la communauté des utilisateurs Одиссея.

Vidéo:

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Salut tout le monde! Mon nom est Andrew.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Chez Yandex, je développe des bases de données open source. Et aujourd'hui, nous avons un sujet sur les connexions du pool de connexions.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Si vous savez comment appeler le pooler de connexion en russe, dites-le moi. Je veux vraiment trouver un bon terme technique qui devrait être établi dans la littérature technique.

Le sujet est assez compliqué, car dans de nombreuses bases de données, le pooler de connexions est intégré et vous n'avez même pas besoin de le savoir. Certains paramètres, bien sûr, sont partout, mais dans Postgres cela ne fonctionne pas. Et en parallèle (à HighLoad++ 2019) il y a un rapport de Nikolai Samokhvalov sur la mise en place des requêtes dans Postgres. Et je comprends que des gens sont venus ici qui ont déjà parfaitement configuré les requêtes, et ce sont des gens qui sont confrontés à des problèmes système plus rares liés au réseau, à l'utilisation des ressources. Et dans certains endroits, cela peut être assez difficile dans le sens où les problèmes ne sont pas évidents.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Yandex a Postgres. De nombreux services Yandex vivent dans Yandex.Cloud. Et nous avons plusieurs pétaoctets de données qui génèrent au moins un million de requêtes par seconde dans Postgres.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et nous fournissons un cluster assez typique pour tous les services - c'est le nœud principal principal du nœud, les deux répliques habituelles (synchrone et asynchrone), la sauvegarde, la mise à l'échelle des demandes de lecture sur la réplique.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Chaque nœud de cluster est Postgres, sur lequel, en plus de Postgres et des systèmes de surveillance, un pooler de connexion est également installé. Le pooler de connexion est utilisé pour les clôtures et pour son objectif principal.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Quel est l'objectif principal d'un pooler de connexion ?

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Postgres adopte un modèle de processus pour travailler avec une base de données. Cela signifie qu'une connexion est un processus, un backend Postgres. Et il y a beaucoup de caches différents dans ce backend, qui sont assez coûteux à rendre différents pour différentes connexions.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

En outre, il existe un tableau dans le code Postgres appelé procArray. Il contient des données de base sur les connexions réseau. Et presque tous les algorithmes de traitement procArray ont une complexité linéaire, ils parcourent l'ensemble du réseau de connexions réseau. C'est un cycle assez rapide, mais avec plus de connexions réseau entrantes, les choses deviennent un peu plus chères. Et lorsque les choses deviennent un peu plus chères, vous finissez par payer un prix très élevé pour un grand nombre de connexions réseau.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Il existe 3 approches possibles :

  • Du côté des applications.
  • Côté base de données.
  • Et entre, c'est-à-dire toutes les combinaisons possibles.

Malheureusement, le pooler intégré est actuellement en cours de développement. Les amis de PostgreSQL Professional le font principalement. Il est difficile de prévoir quand il apparaîtra. Et de fait, nous avons deux solutions pour le choix d'un architecte. Il s'agit du pool côté application et du pool proxy.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Le pool côté application est le moyen le plus simple. Et presque tous les pilotes clients vous proposent un moyen : représenter des millions de vos connexions dans le code sous la forme de quelques dizaines de connexions à la base de données.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Il y a un problème avec le fait qu'à un certain moment, vous voulez faire évoluer le backend, vous voulez le déployer sur de nombreuses machines virtuelles.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Ensuite, vous réalisez toujours que vous avez plusieurs autres zones de disponibilité, plusieurs centres de données. Et l'approche de mutualisation côté client conduit à de gros chiffres. Les grands comptent environ 10 000 connexions. C'est un avantage qui peut bien fonctionner.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Si nous parlons de poolers proxy, alors il y a deux poolers qui peuvent faire beaucoup de choses. Ils ne sont pas que des poolers. Ce sont des poolers + des fonctionnalités plus cool. Ce pgpool и Proxy croustillant.

Mais, malheureusement, tout le monde n'a pas besoin de cette fonctionnalité supplémentaire. Et cela conduit au fait que les poolers ne prennent en charge que le pooling de sessions, c'est-à-dire un client entrant, un client sortant vers la base de données.

Ce n'est pas très adapté à nos tâches, nous utilisons donc PgBouncer, qui implémente le regroupement des transactions, c'est-à-dire que les connexions serveur sont mappées aux connexions client uniquement pendant la durée de la transaction.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et sur notre charge - c'est vrai. Mais il y a plusieurs problèmes.Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Les problèmes commencent lorsque vous souhaitez diagnostiquer une session, car toutes les connexions entrantes sont locales. Tout le monde est venu avec un bouclage et d'une manière ou d'une autre, il devient difficile de retracer la session.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Bien sûr, vous pouvez utiliser application_name_add_host. C'est le côté Bouncer pour ajouter une adresse IP au nom de l'application. Mais application_name est défini par une connexion supplémentaire.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Sur ce graphique, où la ligne jaune correspond aux demandes réelles et où la ligne bleue correspond aux demandes qui arrivent dans la base de données. Et cette différence est précisément le paramètre de application_name, qui n'est nécessaire que pour le traçage, mais ce n'est pas du tout gratuit.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

De plus, Bouncer ne peut pas limiter un pool, c'est-à-dire le nombre de connexions à la base de données par utilisateur, par base de données.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

À quoi cela mène-t-il ? Vous avez un service chargé écrit en C ++ et quelque part à proximité un petit service sur un nœud qui ne fait rien de mal avec la base, mais son pilote devient fou. Il ouvre 20 000 connexions et tout le reste attendra. Même ton code est correct.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Bien sûr, nous avons écrit un petit patch pour Bouncer qui a ajouté ce paramètre, c'est-à-dire en limitant les clients au pool.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Il serait possible de le faire côté Postgres, c'est-à-dire de limiter les rôles dans la base de données au nombre de connexions.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Mais alors vous perdez la capacité de comprendre pourquoi vous n'avez aucune connexion au serveur. PgBouncer ne génère pas d'erreur de connexion, il renvoie toujours les mêmes informations. Et vous ne pouvez pas comprendre : peut-être que votre mot de passe a changé, peut-être que la base de données vient de tomber en panne, peut-être que quelque chose ne va pas. Mais il n'y a pas de diagnostic. Si la session ne peut pas être établie, vous ne saurez pas pourquoi cela ne peut pas être fait.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

À un certain moment, vous regardez les graphiques de l'application et constatez que l'application ne fonctionne pas.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Regardez en haut et voyez que Bouncer est monothread. C'est un tournant dans la vie du service. Vous comprenez que vous vous prépariez à faire évoluer la base de données dans un an et demi et que vous devez faire évoluer le pooler.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Nous sommes arrivés à la conclusion que nous avons besoin de plus de PgBouncers.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

https://lwn.net/Articles/542629/

Bouncer a été légèrement patché.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et ils ont fait en sorte que plusieurs Bouncers puissent être déclenchés avec la réutilisation du port TCP. Et déjà le système d'exploitation transfère automatiquement les connexions TCP entrantes entre eux par round-robin'om.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Ceci est transparent pour les clients, c'est-à-dire qu'il semble que vous ayez un Bouncer, mais vous avez une fragmentation des connexions inactives entre les Bouncer en cours d'exécution.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et à un moment donné, vous remarquerez peut-être que ces 3 Bouncers mangent chacun leur noyau à 100%. Vous avez besoin de plusieurs videurs. Pourquoi?

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Parce que vous avez TLS. Vous avez une connexion cryptée. Et si vous évaluez Postgres avec et sans TLS, vous constaterez que le nombre de connexions établies diminue de près de deux ordres de grandeur avec le chiffrement activé, car la poignée de main TLS consomme des ressources CPU.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et en haut, vous pouvez voir pas mal de fonctions cryptographiques qui sont exécutées lors d'une vague de connexions entrantes. Étant donné que notre principal peut basculer entre les zones de disponibilité, une vague de connexions entrantes est une situation assez typique. Autrement dit, pour une raison quelconque, l'ancien primaire n'était pas disponible, la totalité de la charge a été envoyée à un autre centre de données. Ils viendront tous dire bonjour à TLS en même temps.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et un grand nombre de poignées de main TLS peuvent ne pas déjà saluer Bouncer, mais lui serrer la gorge. Une vague de connexions entrantes peut devenir non amortie en raison du délai d'attente. Si vous avez une nouvelle tentative à la base sans un backoff exponentiel, ils ne reviendront pas encore et encore dans une vague cohérente.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Voici un exemple de 16 PgBouncers qui chargent 16 cœurs à 100%.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Nous sommes arrivés au PgBouncer en cascade. C'est la meilleure configuration que nous pouvons réaliser sur notre charge Bouncer. Nos videurs externes servent à la poignée de main TCP, et les videurs internes servent à la mise en commun réelle, afin de ne pas trop fragmenter les connexions externes.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Dans cette configuration, un redémarrage progressif est possible. Vous pouvez redémarrer tous ces 18 videurs un par un. Mais maintenir une telle configuration est assez difficile. Les administrateurs système, DevOps et les personnes réellement responsables de ce serveur ne seront pas très satisfaits de ce schéma.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Il semblerait que toutes nos améliorations puissent être promues en open source, mais Bouncer ne le supporte pas très bien. Par exemple, la possibilité d'exécuter plusieurs PgBouncers sur le même port a été validée il y a un mois. Une pull request avec cette fonctionnalité remonte à quelques années.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

https://www.postgresql.org/docs/current/libpq-cancel.html

https://github.com/pgbouncer/pgbouncer/pull/79

Ou encore un exemple. Dans Postgres, vous pouvez annuler une requête en cours d'exécution en envoyant le secret à une autre connexion sans authentification supplémentaire. Mais certains clients envoient simplement une réinitialisation TCP, c'est-à-dire qu'ils rompent la connexion réseau. Que va faire Bouncer avec ça ? Il ne fera rien. Il continuera à exécuter la requête. Si vous avez reçu un grand nombre de connexions qui ont jeté les bases de petites requêtes, il ne suffira pas de déconnecter simplement la connexion de Bouncer, vous devez toujours compléter les requêtes en cours d'exécution dans la base de données.

Cela a été corrigé et le problème n'est toujours pas fusionné avec l'amont de Bouncer.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et nous sommes donc arrivés à la conclusion que nous avions besoin de notre propre pooler de connexions, qui sera développé, patché, dans lequel il sera possible de résoudre rapidement les problèmes et qui, bien sûr, doit être multi-thread.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Nous définissons le multithreading comme tâche principale. Nous devons être capables de bien gérer la vague de connexions TLS entrantes.

Pour ce faire, nous avons dû développer une bibliothèque distincte appelée Machinarium, conçue pour décrire les états machine d'une connexion réseau sous la forme d'un code série. Si vous regardez le code source de libpq, vous verrez des appels assez complexes qui peuvent vous renvoyer un résultat et dire : « Appelle-moi un peu plus tard. En ce moment j'ai IO pour l'instant, mais quand l'IO passe, j'ai une charge sur le processeur. Et c'est un schéma à plusieurs niveaux. L'interaction réseau est généralement décrite par une machine à états. Beaucoup de règles comme "Si j'ai déjà reçu un en-tête de paquet de taille N, alors maintenant j'attends N octets", "Si j'ai envoyé un paquet SYNC, alors maintenant j'attends un paquet avec des métadonnées de résultat". Il s'avère un code contre-intuitif plutôt difficile, comme si le labyrinthe était converti en un balayage de ligne. Nous avons fait en sorte qu'au lieu d'une machine à états, le programmeur décrive le chemin d'interaction principal sous la forme d'un code impératif ordinaire. Juste dans ce code impératif, vous devez insérer des endroits où la séquence d'exécution doit être interrompue en attendant des données du réseau, en passant le contexte d'exécution à une autre coroutine (fil vert). Cette approche est similaire au fait que nous écrivons le chemin le plus attendu dans le labyrinthe d'affilée, puis y ajoutons des branches.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

En conséquence, nous avons un thread qui permet à un TCP d'accepter et de transmettre à tour de rôle une connexion TPC à de nombreux travailleurs.

Dans ce cas, chaque connexion client s'exécute toujours sur un processeur. Et cela vous permet de le rendre compatible avec le cache.

De plus, nous avons légèrement amélioré la collecte de petits paquets en un seul gros paquet afin de décharger la pile TCP du système.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

De plus, nous avons amélioré le pooling transactionnel dans le sens où Odyssey, lorsqu'il est configuré, peut envoyer CANCEL et ROLLBACK en cas d'échec de la connexion réseau, c'est-à-dire que si personne n'attend la requête, Odyssey dira à la base de données de ne pas essayer de répondre la demande qui peut gaspiller des ressources précieuses.

Et dans la mesure du possible, nous gardons les connexions au même client. Cela évite d'avoir à réinstaller application_name_add_host. Si possible, nous n'avons pas de réinitialisation supplémentaire des paramètres nécessaires au diagnostic.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Nous travaillons dans l'intérêt de Yandex.Cloud. Et si vous utilisez PostgreSQL managé et que vous avez installé un pooler de connexion, vous pouvez créer une réplication logique vers l'extérieur, c'est-à-dire nous laisser si vous le souhaitez, en utilisant la réplication logique. Bouncer en dehors du flux de réplication logique ne donnera pas.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Il s'agit d'un exemple de configuration de la réplication logique.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

De plus, nous prenons en charge la réplication physique vers l'extérieur. Dans le Cloud, bien sûr, c'est impossible, car alors le cluster vous donnera trop d'informations sur lui-même. Mais dans vos installations, si vous avez besoin de réplication physique via un pooler de connexion dans Odyssey, c'est possible.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Odyssey a une surveillance entièrement compatible avec PgBouncer. Nous avons la même console qui exécute presque toutes les mêmes commandes. S'il manque quelque chose, envoyez une demande d'extraction, ou au moins un problème sur GitHub, nous compléterons les commandes nécessaires. Mais nous avons déjà la fonctionnalité principale de la console PgBouncer.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et bien sûr, nous avons le transfert d'erreur. Nous retournerons l'erreur signalée par la base. Vous obtiendrez des informations sur la raison pour laquelle vous n'êtes pas dans la base, pas seulement sur le fait que vous n'y êtes pas.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Cette fonctionnalité est désactivée au cas où vous auriez besoin d'une compatibilité à 100 % avec PgBouncer. On peut se comporter comme Bouncer, juste au cas où.

Développement

Quelques mots sur le code source d'Odyssey.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

https://github.com/yandex/odyssey/pull/66

Par exemple, il existe des commandes "Pause / Reprendre". Ils sont généralement utilisés pour mettre à jour la base de données. Si vous avez besoin de mettre à niveau Postgres, vous pouvez le mettre en pause dans le pooler de connexion, faire un pg_upgrade, puis reprendre. Et du côté client, il semblera que la base de données ralentisse. Cette fonctionnalité nous a été apportée par des personnes de la communauté. Elle n'est pas encore morte, mais bientôt tout le sera. (déjà mort)

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

https://github.com/yandex/odyssey/pull/73 - déjà mort

De plus, l'une des nouvelles fonctionnalités de PgBouncer est la prise en charge de l'authentification SCRAM, qui nous a également été apportée par une personne qui ne travaille pas dans Yandex.Cloud. Les deux sont des fonctionnalités complexes et importantes.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Par conséquent, je voudrais vous dire de quoi est fait Odyssey, au cas où vous souhaiteriez également écrire du code maintenant.

Vous avez la base originale d'Odyssey, qui s'appuie sur deux bibliothèques principales. La bibliothèque Kiwi est une implémentation du protocole de message Postgres. C'est-à-dire que le proto 3 natif de Postgres est constitué de messages standard que les frontends et les backends peuvent échanger. Ils sont implémentés dans la bibliothèque Kiwi.

La bibliothèque Machinarium est une bibliothèque d'implémentation de threads. Un petit fragment de ce Machinarium est écrit en assembleur. Mais ne vous inquiétez pas, il n'y a que 15 lignes.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Architecture Odyssée. Il y a une machine principale exécutant des coroutines. Cette machine implémente l'acceptation des connexions TCP entrantes et la distribution entre les travailleurs.

Au sein d'un travailleur, un gestionnaire pour plusieurs clients peut travailler. Et aussi dans le thread principal, la console et le traitement des tâches crone pour supprimer les connexions qui ne sont plus nécessaires dans le pool tournent.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Odyssey est testé à l'aide de la suite de tests Postgres standard. Nous exécutons simplement install-check via Bouncer et via Odyssey, nous obtenons une div nulle. Il existe plusieurs tests liés au formatage de la date qui échouent exactement de la même manière dans Bouncer et Odyssey.

De plus, il existe de nombreux pilotes qui ont leurs propres tests. Et nous utilisons leurs tests pour tester Odyssey.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

De plus, en raison de notre configuration en cascade, nous devons tester différents bundles : Postgres + Odyssey, PgBouncer + Odyssey, Odyssey + Odyssey afin d'être sûrs que si Odyssey est dans l'une des parties de la cascade, il fonctionne également comme prévu. .

Râteau

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Nous utilisons Odyssey en production. Et ce ne serait pas juste si je disais que tout fonctionne. Non, c'est-à-dire oui, mais pas toujours. Par exemple, en production, tout fonctionnait, puis nos amis de PostgreSQL Professional sont venus et ont dit que nous avions une fuite de mémoire. Ils l'étaient vraiment, nous les avons réparés. Mais c'était simple.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Ensuite, nous avons constaté que le pooleur de connexions avait des connexions TLS entrantes et des connexions TLS sortantes. Et les connexions ont besoin de certificats client et de certificats serveur.

Les certificats de serveur Bouncer et Odyssey sont relus par pcache, mais les certificats clients n'ont pas besoin d'être relus depuis pcache, car notre Odyssey évolutif repose finalement sur les performances du système de lecture de ce certificat. Cela nous a surpris, car il ne s'est pas reposé immédiatement. Au début, il évoluait de manière linéaire et après 20 000 connexions simultanées entrantes, ce problème s'est manifesté.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

La méthode d'authentification enfichable est la possibilité de s'authentifier avec les outils lunux intégrés. Dans PgBouncer, il est implémenté de telle sorte qu'il y ait un thread séparé attendant une réponse de PAM et il y a un thread principal PgBouncer qui dessert la connexion actuelle et peut leur demander de vivre dans le thread PAM.

Nous ne l'avons pas mis en œuvre pour une raison simple. Nous avons de nombreux flux. Pourquoi en avons-nous besoin?

Par conséquent, cela peut créer des problèmes dans la mesure où si vous avez une authentification PAM et une authentification non-PAM, une grande vague d'authentification PAM peut retarder considérablement l'authentification non-PAM. C'est une de ces choses que nous n'avons pas corrigées. Mais si vous voulez le réparer, vous pouvez le faire.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Un autre râteau était avec le fait que nous avons un thread qui accepte toutes les connexions entrantes. Et puis ils sont transférés vers le pool de nœuds de calcul, où la poignée de main TLS aura lieu.

Par conséquent, si vous avez une vague cohérente de 20 000 connexions réseau, elles seront toutes acceptées. Et côté client, libpq commencera à signaler les délais d'attente. Par défaut, c'est comme 3 secondes là-bas.

S'ils ne peuvent pas tous entrer dans la base en même temps, alors ils ne peuvent pas entrer dans la base, car tout cela peut être couvert par une nouvelle tentative non exponentielle.

Nous avons fini par copier le schéma PgBouncer ici afin de limiter le nombre de connexions TCP que nous acceptons.

Si nous constatons que nous acceptons des connexions, mais qu'elles n'ont pas le temps de serrer la main à la fin, nous les mettons dans une file d'attente afin qu'elles ne consomment pas de ressources CPU. Cela conduit au fait qu'une poignée de main simultanée peut ne pas être effectuée pour toutes les connexions qui sont arrivées. Mais au moins quelqu'un entrera dans la base de données, même si la charge est suffisamment forte.

Feuille de route

Qu'aimeriez-vous voir à l'avenir dans Odyssey ? Que sommes-nous prêts à développer nous-mêmes et qu'attendons-nous de la communauté ?

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Pour août 2019.

Voici à quoi ressemblait la feuille de route Odyssey en août :

  • Nous voulions une authentification SCRAM et PAM.
  • Nous voulions transférer les demandes de lecture en veille.
  • Je voudrais redémarrer en ligne.
  • Et la possibilité de faire une pause sur le serveur.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

La moitié de cette feuille de route est faite, et pas par nous. Et c'est bien. Discutons donc de ce qui reste et ajoutons-en plus.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Concernant le transfert des requêtes en lecture seule vers la veille? Nous avons des répliques qui, sans répondre aux demandes, chaufferont simplement l'air. Nous en avons besoin pour assurer le basculement et le basculement. En cas de problème dans l'un des centres de données, je voudrais les occuper avec un travail utile. Parce qu'on ne peut pas configurer différemment les mêmes processeurs centraux, la même mémoire, parce que la réplication ne fonctionnera pas autrement.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

En principe, dans Postgres, à partir de 10, il est possible de spécifier session_attrs lors de la connexion. Vous pouvez répertorier tous les hôtes de base de données dans la connexion et dire pourquoi vous accédez à la base de données : écriture ou lecture seule. Et le pilote lui-même choisira le premier hôte de la liste qu'il préfère, qui répond aux exigences de session_attrs.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Mais le problème avec cette approche est qu'elle ne contrôle pas le décalage de réplication. Vous pouvez avoir une sorte de réplique qui est en retard d'un temps inacceptable pour votre service. Afin de rendre l'exécution complète des demandes de lecture sur une réplique, en fait, nous devons prendre en charge dans Odyssey la possibilité de ne pas fonctionner lorsqu'il est impossible de lire.

Odyssey doit se rendre de temps en temps dans la base de données et demander la distance de réplication par rapport au primaire. Et s'il a atteint la limite, ne laissez pas de nouvelles requêtes entrer dans la base de données, dites au client que vous devez réinitialiser les connexions et, éventuellement, sélectionnez un autre hôte pour exécuter les requêtes. Cela permettra à la base de données de restaurer rapidement le décalage de réplication et de revenir à nouveau pour répondre avec une requête.

Il est difficile de nommer les dates de mise en œuvre, car il est open source. Mais, j'espère, pas 2,5 ans comme les collègues de PgBouncer. C'est la fonctionnalité que j'aimerais voir dans Odyssey.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Dans la communauté, les gens ont posé des questions sur le soutien des déclarations préparées. Vous pouvez maintenant créer une instruction préparée de deux manières. Tout d'abord, vous pouvez exécuter une commande SQL, à savoir "préparé". Afin de comprendre cette commande SQL, nous devons apprendre à comprendre SQL du côté Bouncer. Ce serait exagéré parce que c'est exagéré puisque nous avons besoin de l'analyseur complet. Nous ne pouvons pas analyser chaque commande SQL.

Mais il existe une instruction préparée au niveau du protocole de message sur proto3. Et c'est là que l'information selon laquelle la déclaration préparée est en cours de création se présente sous une forme structurée. Et nous pourrions soutenir la compréhension que sur une connexion serveur, le client a demandé de créer des déclarations préparées. Et même si la transaction est fermée, nous devons toujours garder le serveur et le client connectés.

Mais ici, une divergence apparaît dans le dialogue, car quelqu'un dit que vous devez comprendre quelles déclarations préparées le client a créées et partager la connexion au serveur entre tous les clients qui ont créé cette connexion au serveur, c'est-à-dire qui a créé une telle déclaration préparée.

Andres Freund a déclaré que si un client venait à vous qui avait déjà créé une telle déclaration préparée dans une autre connexion au serveur, créez-la pour lui. Mais il semble un peu faux d'exécuter des requêtes dans la base de données au lieu du client, mais du point de vue du développeur qui écrit le protocole d'interaction avec la base de données, ce serait pratique s'il recevait simplement une connexion réseau qui a une telle demande préparée.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

Et une autre fonctionnalité que nous devons implémenter. Nous avons maintenant une surveillance compatible avec PgBouncer. Nous pouvons retourner le temps d'exécution moyen de la requête. Mais le temps moyen est la température moyenne à l'hôpital : quelqu'un a froid, quelqu'un a chaud - en moyenne, tout le monde est en bonne santé. Ce n'est pas vrai.

Nous devons implémenter la prise en charge des centiles, ce qui indiquerait qu'il y a des requêtes lentes qui consomment des ressources et rendrait la surveillance plus acceptable.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

La chose la plus importante est que je veux la version 1.0 (la version 1.1 est déjà sortie). Le fait est que maintenant Odyssey est en version 1.0rc, c'est-à-dire en release candidate. Et tout le rake que j'ai listé a été corrigé exactement avec la même version, à l'exception de la fuite de mémoire.

Que signifiera la version 1.0 pour nous ? Nous déployons l'Odyssey dans nos bases. Il est déjà en cours d'exécution sur nos bases de données, mais lorsqu'il atteint le point de 1 000 000 requêtes par seconde, alors nous pouvons dire qu'il s'agit d'une version finale et c'est une version qui peut être appelée 1.0.

Plusieurs personnes de la communauté ont demandé plus de pause et de SCRAM dans la version 1.0. Mais cela signifiera que nous devrons déployer la prochaine version en production, car ni SCRAM ni la pause n'ont encore été fusionnés. Mais, très probablement, ce problème sera résolu assez rapidement.

Feuille de route Odyssey : que voulons-nous d'autre d'un pooler de connexion ? Andreï Borodine (2019)

J'attends votre pull request. Et j'aimerais aussi savoir quels problèmes vous rencontrez avec Bouncer. Discutons-en. Peut-être pouvons-nous implémenter certaines fonctions dont vous avez besoin.

Ceci conclut ma partie, j'aimerais avoir de vos nouvelles. Merci!

des questions

Si je mets mon propre application_name, sera-t-il correctement lancé, y compris dans le pooling des transactions dans Odyssey ?

Odyssey ou Bouncer ?

Dans Odyssée. Le videur est lancé.

Nous ferons un ensemble.

Et si ma connexion réelle saute sur d'autres connexions, sera-t-elle transmise ?

Nous allons faire un ensemble de tous les paramètres qui sont listés. Je ne peux pas dire si application_name est dans cette liste. Il semble qu'il l'y ait vu. Nous fixerons tous les mêmes paramètres. Avec une seule requête, l'ensemble fera tout ce qui a été installé par le client lors du démarrage.

Merci Andrey pour le rapport! Bon rapport ! Je suis heureux qu'Odyssey se développe de plus en plus vite à chaque minute. J'aimerais continuer la même chose. Nous vous avons déjà demandé d'avoir une connexion multi-sources de données afin qu'Odyssey puisse se connecter à différentes bases de données en même temps, c'est-à-dire le maître esclave, puis se connecter automatiquement au nouveau maître après un basculement.

Oui, je crois me souvenir de cette discussion. Maintenant, il y a plusieurs stockages. Mais il n'y a pas de commutation entre eux. De notre côté, nous devons interroger le serveur qu'il est toujours vivant et comprendre qu'un basculement a eu lieu, qui appellera pg_recovery. J'ai une manière standard de comprendre que nous ne sommes pas venus au maître. Et nous devons comprendre en quelque sorte des erreurs ou comment? C'est-à-dire que l'idée est intéressante, elle est en discussion. Écrivez plus de commentaires. Si vous avez des mains de travail qui connaissent C, alors c'est généralement merveilleux.

La question de la mise à l'échelle entre les répliques nous intéresse également, car nous voulons rendre l'adoption de clusters répliqués aussi simple que possible pour les développeurs d'applications. Mais ici, je voudrais plus de commentaires, c'est-à-dire comment le faire, comment le faire bien.

La question porte aussi sur les répliques. Il s'avère que vous avez un maître et plusieurs répliques. Et il est clair qu'ils vont moins souvent vers la réplique que vers le maître pour les connexions, car ils peuvent avoir une différence. Vous avez dit que la différence de données peut être telle que votre entreprise ne vous satisfera pas et que vous n'irez pas jusqu'à ce qu'elle soit répliquée. Dans le même temps, si vous n'y êtes pas allé pendant longtemps, puis que vous avez commencé à y aller, les données dont vous avez besoin ne seront pas immédiatement disponibles. Autrement dit, si nous allons constamment au maître, le cache y est réchauffé et le cache est un peu en retard dans la réplique.

Oui c'est vrai. Il n'y aura pas de blocs de données dans pcache que vous voulez, dans le cache réel, il n'y aura pas d'informations sur les tables que vous voulez, il n'y aura pas de requêtes analysées dans les plans, rien du tout.

Et lorsque vous avez une sorte de cluster et que vous y ajoutez une nouvelle réplique, alors pendant qu'il démarre, tout est mauvais dedans, c'est-à-dire qu'il agrandit son cache.

J'ai eu l'idée. L'approche correcte consisterait à exécuter d'abord un petit pourcentage de requêtes sur le réplica, ce qui réchaufferait le cache. En gros, nous avons une condition selon laquelle nous ne devons pas être à plus de 10 secondes derrière le maître. Et cette condition ne devrait pas être incluse dans une seule vague, mais en douceur pour certains clients.

Oui, augmenter le poids.

C'est une bonne idée. Mais vous devez d'abord mettre en œuvre cet arrêt. Nous devons d'abord éteindre, puis nous réfléchirons à la façon d'allumer. C'est une excellente fonctionnalité à activer en douceur.

nginx a cette option slowly start dans le cluster pour le serveur. Et il accumule progressivement la charge.

Oui, excellente idée, nous essaierons quand nous y arriverons.

Source: habr.com

Ajouter un commentaire