Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gérer le moissonnage de gros catalogues via DCAT (CSW-DCAT ou XSLT) #1046

Closed
maudetes opened this issue Feb 6, 2023 · 3 comments · Fixed by opendatateam/udata#2980
Closed
Labels
💙 Back Les tickets de back Code quality Indique qu'il s'agit d'une amélioration de la qualité du code (au sens très large) Moissonnage Indique que le sujet touche au moissonnage

Comments

@maudetes
Copy link
Contributor

maudetes commented Feb 6, 2023

Ce point est à traiter dans l'éventualité du choix de la solution d'un moissonneur CSW-DCAT et d'une reproduction du problème sur des catalogues effectivement moissonnés.

Suite aux tests de moissonneurs de portails CSW-DCAT, Geo2France a testé de modifier leur point de moissonnage en CSW sur demo.data.gouv.fr (https://www.geo2france.fr/geonetwork/srv/eng/csw).
Il se trouve que ce moissonnage échoue à l'étape d'initialisation à cause de la taille du graphe qui dépasse la limite Mongo (16MB) pour un document. Voir l'erreur Sentry. Le catalogue cible contient en tout 4330 JDDs.

pymongo.errors.DocumentTooLarge: 'update' command document too large

Ce problème n'a pas encore été rencontré sur du moissonnage DCAT standard, probablement car le graphe n'est pas aussi grand (seules certaines métadonnées sont renseignées sur les gros catalogues du geocatalogue par exemple). Mais il est possible que ce problème apparaisse aussi sur du moissonnage DCAT standard.

Quelques pistes de résolutions envisagées, si ce point devient bloquant :

  • enregistrer les différents graphes (un par page) dans des objets différents plutôt que dans une unique liste job.data['graphs'] ;
  • compresser le graphe (qui est une string) pour limiter sa taille -> à voir les possibilités avec notre version Mongo ;
  • jouer sur la taille de pagination, pour essayer de limiter la redondance entre toutes les pages du graphe ;
  • filtrer les noeuds du graphe pour ne garder que ceux qui seront ensuite utilisés lors de la conversion à udata. Attention, cela signifie qu'on filtre à priori, et en l'absence de profile DCAT clair, cela répartie la charge de la transformation avant initialization. Par contre, si un profile DCAT est définit, ne garder que les noeuds reconnus dans ce schéma semble cohérent.

En autre considération importante, le stockage de 50MB de graphe par job, avec un historique de 30 jours de HarvestJob pèserait donc 50 * 30 = 1,5GB.

@maudetes maudetes added Moissonnage Indique que le sujet touche au moissonnage Code quality Indique qu'il s'agit d'une amélioration de la qualité du code (au sens très large) 💙 Back Les tickets de back labels Feb 6, 2023
@agarrone
Copy link
Contributor

En attende de savoir la priorisation CSW DCAT vs DCAT

@landryb
Copy link

landryb commented Feb 2, 2024

soucis aussi vu sur https://demo.data.gouv.fr en moissonnant https://demo.georchestra.org/geonetwork/srv/eng/csw en CSW-DCAT, le catalogue contient un peu moins de 20k records.

@maudetes maudetes changed the title Gérer le moissonnage de gros catalogues via CSW-DCAT Gérer le moissonnage de gros catalogues via DCAT (CSW-DCAT ou XSLT) Feb 22, 2024
@ThibaudDauce
Copy link

ThibaudDauce commented Feb 26, 2024

Quelques remarques après avoir exploré ce code. J'écris ça à chaud, il y a peut-être (sans doute) pleins de choses auxquelles je n'ai pas pensé mais c'est pour laisser une trace de ma réflexion afin de pouvoir avoir tous les éléments / questions que je me pose quelque part.

Est-ce que nous avons vraiment besoin de traiter chaque item dans un job séparé ?

Si nous avons assez de moissonneurs, il est peu probable qu'un worker serait plus long que les autres. De plus il est possible je pense simplement de stocker dans les infos du moissonneur le nombre d'item collectés lors du dernier moissonnage et donc de faire un simple tri pour répartir les graphes les plus importants au début du moissonnage sur tous les workers disponibles et donc ainsi répartir la charge et éviter de traiter https://demo.georchestra.org/geonetwork/srv/eng/csw en dernier par exemple où il serait sur un seul worker à travailler avec tous les autres workers qui n'auraient plus de travail à faire.

Peut-être un petit schéma pour être plus clair ? 😄 (xxxx un moissonneur avec 4 datasets, x un item à traiter, -> sépare les jobs)

worker 1: xxxxxxx -> xxx -> xxx -> xx -> x
worker 2: xxxxx -> xx -> x -> x -> x -> x

Avantages de cette solution :

  • Supprimer la partie sérialisation/dé-sérialisation du graphe qui doit quand même coûter cher.
  • Elle me semble plus simple niveau code et je pense qu'elle apporterait une réduction de la complexité du système (pas de cache intermédiaire)
  • Plus de stockage du graphe dans MongoDB (donc une taille de base de données plus petite)

Inconvénients :

  • On aurait des jobs qui durent un temps très long. Mais à voir si dans la pratique ce temps long est un vrai problème ? A-t-on des limites à ce niveau ?
  • Plus de stockage (donc on perd de l'information si l'on a besoin de voir le graph chargé pour ce moissonnage). Est-ce que c'est réellement un problème ? Qui utilise actuellement ces graphes ? Il est même possible de stocker les petits graphes dans la base mais pas les gros vu qu'on en aurait plus besoin pour le traitement qui serait fait à la suite. (on perd un peu du gain car l'on doit sérialiser le graphe mais nous n'avons pas besoin de le dé-sérialiser)
Est-il possible d'utiliser MinIO pour stocker les grands graphes ? (@geoffreyaldebert peut-être ?)

Une autre solution assez simple à mettre en place (en fonction de la maturité du stockage S3/MinIO) serait de simplement dans le cas des graphes de taille importante de stocker le JSON dans MinIO plutôt que dans MongoDB (et de stocker uniquement l'URL dans le MongoDB). Cette solution à l'avantage de conserver le fonctionnement actuel et ne demande que des changements minimes. Elle continue la sérialisation / dé-sérialisation qui semble sous-optimale et elle rajoute la latence MinIO (si MinIO est plus lent que MongoDB mais ça me semble probable). C'est également plus compliqué de gérer l'archivage / le nettoyage des données dans un système externe comme MinIO plutôt que dans la base MongoDB.

À propos des solutions proposées par @maudetes

enregistrer les différents graphes (un par page) dans des objets différents plutôt que dans une unique liste job.data['graphs'] ;

Ça me semble rajouter encore plus de complexité (il faudrait un document par item avec des références) afin de garder absolument le fonctionnement actuel. Si c'est l'unique solution elle devrait fonctionner mais pas sûr que ça soit la meilleure…

compresser le graphe (qui est une string) pour limiter sa taille -> à voir les possibilités avec notre version Mongo ;

Le graphe devrait bien se compresser, il faudrait faire des tests. Mais ça pourrait être une solution facile et rapide. Pour l'implémenter il faudrait que le gain soit très important car si l'on passe de 50Mo à 14Mo, on sait que dans le futur le problème reviendra dès que l'on aura un graphe de 60Mo qui passera, même compressé, au dessus des 16Mo limite de MongoDB.

jouer sur la taille de pagination, pour essayer de limiter la redondance entre toutes les pages du graphe ;

Peut donner des gains mais pas sûr que ça soit une solution pérenne (si les graphes grossissent dans le futur le problème pourrait réapparaître)

filtrer les noeuds du graphe pour ne garder que ceux qui seront ensuite utilisés lors de la conversion à udata. Attention, cela signifie qu'on filtre à priori, et en l'absence de profile DCAT clair, cela répartie la charge de la transformation avant initialization. Par contre, si un profile DCAT est définit, ne garder que les noeuds reconnus dans ce schéma semble cohérent.

Compliqué à mettre en place et comme tu le dis ensuite ça peut poser beaucoup de problèmes / duplication de code / oublis / bugs… Effectivement si on avait un système simple qui permettait de « normaliser » un DCAT en gardant uniquement les champs « officiels » ça pourrait se faire mais ça semble être un gros travail (et peut-être empêcherait d'améliorer le moissonnage en supportant des choses moyennement officielles en attendant des améliorations des moissonnés)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💙 Back Les tickets de back Code quality Indique qu'il s'agit d'une amélioration de la qualité du code (au sens très large) Moissonnage Indique que le sujet touche au moissonnage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants