Project

General

Profile

Development #71441

Passer les nonces dans la base de données

Added by Pierre Ducroquet 3 months ago. Updated 26 days ago.

Status:
Solution déployée
Priority:
Normal
Target version:
-
Start date:
18 November 2022
Due date:
% Done:

0%

Estimated time:
Patch proposed:
No
Planning:
No

Description

Aujourd'hui, les nonces sont représentés par des fichiers dans les dossiers nonces des tenants.
Cette solution fonctionne, mais a un défaut majeur : elle va générer un nombre important d'entrées dans le dossier.
Certes, les fichiers sont supprimés ultérieurement, mais cela a des conséquences en fonction du système de fichiers, et ext4, que l'on utilise présentement, gère "mal" ce cas.

pducroquet@node1.prod:/srv/drbd0/lib/wcs$ du -shc */nonces
1,5G    total

C'est beaucoup pour 50000 fichiers de 0 octets, et ça semble à l'origine de gros pics d'iowait la nuit lors de l'exécution des crons de nettoyage.

Démo du problème :

$ mkdir demo-huge-dir
$ cd demo-huge-dir
$ for i in `seq 0 50000`; do touch $i ; done
$ rm *
$ ls -hal .. | grep "demo-huge-dir" 
drwxr-xr-x  2 pierre pierre 384K Nov 18 08:21 demo-huge-dir
$ for i in `seq 0 50000`; do touch $i ; done
$ rm *
$ ls -hal .. | grep "demo-huge-dir" 
drwxr-xr-x  2 pierre pierre 1.1M Nov 18 08:21 demo-huge-dir

En fait, ext4 n'est pas capable de réindexer à chaud un dossier. Il existe une solution pour forcer la réindexation, mais il s'agit de démonter le système de fichiers et forcer un fsck avec l'option -D.
Du coup, contrairement à ce qu'on pourrait imaginer, il n'est pas inutile de considérer une migration des nonces dans la base de données.
PG sera largement capable d'optimiser ça, à la limite en augmentant l'aggressivité de l'autovacuum sur cette nouvelle table.

La table pourrait être de la forme

CREATE TABLE nonces (
  id uuid primary key,
  expiration timestamp with time zone not null
);

Vu que l'expiration est faite dans un cron, et qu'on a rarement beaucoup d'éléments, inutile d'envisager un index sur cette colonne.
La conversion des formats existants en uuid est transparente (et a l'avantage de considérablement accélérer l'indexation et la recherche)

test=> insert into nonces (id) values ('d408b86c9282548e15f210b810dc1a7f') returning *;
                  id                  |          expiration           
--------------------------------------+-------------------------------
 d408b86c-9282-548e-15f2-10b810dc1a7f | 2022-11-18 08:35:03.052132+01
(1 row)

INSERT 0 1
test=> select * from nonces where id = 'd408b86c9282548e15f210b810dc1a7e';
                  id                  |          expiration           
--------------------------------------+-------------------------------
 d408b86c-9282-548e-15f2-10b810dc1a7e | 2022-11-18 08:33:48.556903+01
(1 row)

Si le format UUID pose problème en python, on peut passer outre avec :

In [18]: cur.execute("select uuid_send(id) from nonces limit 1")

In [19]: cur.fetchone()[0].hex()
Out[19]: 'd408b86c9282548e15f210b810dc1a7e'


Related issues

Related to w.c.s. - Development #71455: Passer les form_tokens dans la base de donnéesSolution déployée18 November 2022

Actions

Associated revisions

Revision f7a70b4c (diff)
Added by Frédéric Péters 26 days ago

misc: save received nonces in token table (#71441)

History

#1

Updated by Frédéric Péters 3 months ago

ça semble à l'origine de gros pics d'iowait la nuit lors de l'exécution des crons de nettoyage

cls.register_cronjob(CronJob(cls.clean_nonces, minutes=range(0, 60, 5), name='clean_nonces'))

Le job de nettoyage des nonces est programmé pour tourner toutes les cinq minutes, je pense qu'il y a erreur dans l'analyse.

#2

Updated by Pierre Ducroquet 3 months ago

Je me suis fait avoir par le nom de l'autre cron qui tournait et qui pour moi était déjà en base. Clean_sessions nettoie en fait les form_tokens qui ont exactement le même fonctionnement et le même problème que les nonces.
Donc il y aura le même ticket à faire, mais pour form_tokens. Je suis d'avis de commencer par nonces parce que ça me semble plus facile à faire et donnera un premier aperçu de l'évolution.

#3

Updated by Benjamin Dauvergne 3 months ago

Pierre Ducroquet a écrit :

Je me suis fait avoir par le nom de l'autre cron qui tournait et qui pour moi était déjà en base. Clean_sessions nettoie en fait les form_tokens qui ont exactement le même fonctionnement et le même problème que les nonces.
Donc il y aura le même ticket à faire, mais pour form_tokens. Je suis d'avis de commencer par nonces parce que ça me semble plus facile à faire et donnera un premier aperçu de l'évolution.

Tu peux ouvrir un ticket spécifique pour les form_tokens ? Parce que pour les form_tokens la situation est particulière, ils sont sensés être liés à une session1 et qu'il y a déjà un moyen de déporter le stockage en table principale des sessions via sql.TransientData utilisé actuellement pour les magictokens.

Est-ce que ce ne serait pas plus simple d'utiliser memcache (rendu cohérent pour l'occasion) pour les nonces ? L'expiration n'est qu'à 30 secondes et on peut se permette de ne pas être totalement ACID et éventuellement consistent sur un système qui limite le rejeu (ce que je dirai qu'on est déjà via NFS).

1 ce qui n'est plus vrai dans l'implémentation via le filesystem actuelle, vu que le chemin ne contient que l'identifiant du token et pas celui de la session dans laquelle on l'a créé, mais passons, ça se corrigera tout seul si on change le mode de stockage.

#4

Updated by Pierre Ducroquet 3 months ago

Benjamin Dauvergne a écrit :

Pierre Ducroquet a écrit :

Je me suis fait avoir par le nom de l'autre cron qui tournait et qui pour moi était déjà en base. Clean_sessions nettoie en fait les form_tokens qui ont exactement le même fonctionnement et le même problème que les nonces.
Donc il y aura le même ticket à faire, mais pour form_tokens. Je suis d'avis de commencer par nonces parce que ça me semble plus facile à faire et donnera un premier aperçu de l'évolution.

Tu peux ouvrir un ticket spécifique pour les form_tokens ? Parce que pour les form_tokens la situation est particulière, ils sont sensés être liés à une session1 et qu'il y a déjà un moyen de déporter le stockage en table principale des sessions via sql.TransientData utilisé actuellement pour les magictokens.

Yep, c'est prévu, je regarde un peu le code pour réfléchir au truc avant de faire le ticket.

Est-ce que ce ne serait pas plus simple d'utiliser memcache (rendu cohérent pour l'occasion) pour les nonces ? L'expiration n'est qu'à 30 secondes et on peut se permette de ne pas être totalement ACID et éventuellement consistent sur un système qui limite le rejeu (ce que je dirai qu'on est déjà via NFS).

Rendu cohérent pour l'occasion, en voilà une phrase qu'elle est belle :)
Oui ça serait sûrement plus simple, mais je n'ai pas connaissance de l'utilisation de memcache au sein de wcs, et je n'ai jamais regardé comment rendre le memcache "cohérent" entre les nœuds.

1 ce qui n'est plus vrai dans l'implémentation via le filesystem actuelle, vu que le chemin ne contient que l'identifiant du token et pas celui de la session dans laquelle on l'a créé, mais passons, ça se corrigera tout seul si on change le mode de stockage.

C'est effectivement ce qu'il me semble aussi de ce que j'ai commencé à lire (mais ça posera la question de la migration)

#5

Updated by Pierre Ducroquet 3 months ago

#6

Updated by Benjamin Dauvergne 3 months ago

Pierre Ducroquet a écrit :

Rendu cohérent pour l'occasion, en voilà une phrase qu'elle est belle :)
Oui ça serait sûrement plus simple, mais je n'ai pas connaissance de l'utilisation de memcache au sein de wcs, et je n'ai jamais regardé comment rendre le memcache "cohérent" entre les nœuds.

En général ça veut dire n'en avoir qu'un et le partager.

#7

Updated by Frédéric Péters 28 days ago

  • Status changed from Nouveau to En cours
  • Assignee changed from Pierre Ducroquet to Frédéric Péters

Je prends dans la suite de #71455 et pareil ici on peut réutiliser une table existante (token, qui gère déjà l'expiration).

#8

Updated by Gitea (Bot) Gitea 28 days ago

  • Status changed from En cours to Solution proposée

Frédéric Péters (fpeters) a ouvert une pull request sur Gitea concernant cette demande :

#9

Updated by Gitea (Bot) Gitea 28 days ago

  • Status changed from Solution proposée to Solution validée

Lauréline Guérin (lguerin) a approuvé une pull request sur Gitea concernant cette demande :

N/A

#10

Updated by Gitea (Bot) Gitea 26 days ago

  • Status changed from Solution validée to Résolu (à déployer)

Frédéric Péters (fpeters) a mergé une pull request sur Gitea concernant cette demande :

#11

Updated by Transition automatique 26 days ago

  • Status changed from Résolu (à déployer) to Solution déployée

Also available in: Atom PDF