PnX-SI / gn_mobile_occtax

Application mobile pour la saisie dans le module Occtax de GeoNature
GNU General Public License v3.0
13 stars 2 forks source link

[2.7-RC] Lenteur de synchronisation des taxons #247

Closed TheoLechemia closed 3 months ago

TheoLechemia commented 4 months ago

On vient de tester la synchronisation des taxons sur la 2.7, voici quelques retours. La première synchronisation s'est arrêté au bout de 200 000 taxons synchronisé (on a pas sur déterminé si le problème venait du serveur ou du téléphone) On a lancé une deuxième synchronisation en suivant de plus près les logs du serveurs. Occtax-mobile récupère/intègre 10 000 taxons par minutes (les données retournées font environ 7Mb). Quand on interroge la route directement, celle-ci met environ 3 secondes à répondre. La lenteur est donc à priori côté Occtax-mobile. Côté serveur on ne remarque aucune surcharge. Il utilise un 1Go de RAM et TaxHub utilise seulement 8% de la RAM. En l'état la synchronisation va mettre plus d'une heure et demi. Est-ce qu'il y aurait des pistes d'amélioration ?

TheoLechemia commented 4 months ago

Petit update suite à un autre test ce matin : On a mis à jour Taxref sur le serveur de démo, le mobile a bien détecté ce changement et relancé un téléchargement de taxref. Début de la synchro à 10h45 : 10:45:11.725 INFO: [fr.geonature.datasync.api.ClientKt] <-- 200 OK https://demo.geonature.fr/taxhub/api/taxref/?limit=10000&page=1 (3229ms, 7902077-byte body)

à 11h20 il a téléchargé 290 000 taxons, la synchronisation s'arrête là et il se met à synchroniser les utilisateurs, datasets etc ...

11:17:08.907 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] taxa to update: 270000
11:17:08.909 INFO: [fr.geonature.datasync.api.ClientKt] --> GET https://demo.geonature.fr/taxhub/api/taxref?limit=10000&page=28
11:17:14.003 INFO: [fr.geonature.datasync.api.ClientKt] <-- 200 OK https://demo.geonature.fr/taxhub/api/taxref/?limit=10000&page=28 (5090ms, 8218800-byte body)
11:17:53.812 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] taxa to update: 280000
11:17:53.813 INFO: [fr.geonature.datasync.api.ClientKt] --> GET https://demo.geonature.fr/taxhub/api/taxref?limit=10000&page=29
11:17:58.240 INFO: [fr.geonature.datasync.api.ClientKt] <-- 200 OK https://demo.geonature.fr/taxhub/api/taxref/?limit=10000&page=29 (4426ms, 7495852-byte body)
11:20:50.687 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] taxa to update: 290000
11:20:50.691 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] starting local data synchronization from 'https://demo.geonature.fr/geonature' (with additional data: true)...
11:20:50.693 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] synchronize dataset...
11:20:50.696 INFO: [fr.geonature.datasync.api.ClientKt] --> POST https://demo.geonature.fr/geonature/api/meta/datasets (19-byte body)
11:20:52.222 INFO: [fr.geonature.datasync.api.ClientKt] <-- 200 OK https://demo.geonature.fr/geonature/api/meta/datasets (1524ms, 496774-byte body)
11:20:54.406 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] dataset to update: 194
11:20:54.411 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] synchronize users...
11:20:54.413 INFO: [fr.geonature.datasync.api.ClientKt] --> GET https://demo.geonature.fr/geonature/api/users/menu/1
11:20:55.176 INFO: [fr.geonature.datasync.api.ClientKt] <-- 200 OK https://demo.geonature.fr/geonature/api/users/menu/1 (760ms, 20884-byte body)

puis il se remet à télécharger taxref depuis le début :

11:21:09.834 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] taxa last synchronization date from remote: 2024-02-28T10:35:34Z
11:21:09.865 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] synchronize taxa...
11:21:13.063 INFO: [fr.geonature.datasync.api.ClientKt] --> GET https://demo.geonature.fr/taxhub/api/taxref?limit=10000&page=1
11:21:16.411 INFO: [fr.geonature.datasync.packageinfo.worker.CheckInputsToSynchronizeWorker] available inputs to synchronize: 0
11:21:17.821 INFO: [fr.geonature.datasync.api.ClientKt] <-- 200 OK https://demo.geonature.fr/taxhub/api/taxref/?limit=10000&page=1 (4754ms, 7495593-byte body)
11:21:21.429 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] taxa to update: 10000
11:21:21.431 INFO: [fr.geonature.datasync.api.ClientKt] --> GET https://demo.geonature.fr/taxhub/api/taxref?limit=10000&page=2
11:21:24.680 INFO: [fr.geonature.datasync.api.ClientKt] <-- 200 OK https://demo.geonature.fr/taxhub/api/taxref/?limit=10000&page=2 (3248ms, 7498886-byte body)
11:21:35.267 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] taxa to update: 20000
11:21:35.268 INFO: [fr.geonature.datasync.api.ClientKt] --> GET https://demo.geonature.fr/taxhub/api/taxref?limit=10000&page=3
11:21:38.189 INFO: [fr.geonature.datasync.api.ClientKt] <-- 200 OK https://demo.geonature.fr/taxhub/api/taxref/?limit=10000&page=3 (2919ms, 7571857-byte body)
11:21:50.244 INFO: [fr.geonature.datasync.sync.usecase.DataSyncUseCase] taxa to update: 30000

à 11h54 : -11:54:27.150 INFO: [fr.geonature.datasync.api.ClientKt] <-- HTTP FAILED: InternalServerException(message=INTERNAL SERVER ERROR, response=Response{protocol=http/1.1, code=500, message=INTERNAL SERVER ERROR, url=https://demo.geonature.fr/taxhub/api/taxref/?limit=10000&page=31}, cause=null) la synchro echoue et recommence depuis la début.

Côté GeoNature on a cette erreur :


[SQL: SELECT taxonomie.vm_taxref_list_forautocomplete.gid AS taxonomie_vm_taxref_list_forautocomplete_gid, taxonomie.vm_taxref_list_forautocomplete.cd_nom AS taxonomie_vm_taxref_list_forautocomplete_cd_nom, taxonomie.vm_taxref_list_forautocomplete.search_name AS taxonomie_vm_taxref_list_forautocomplete_search_name, taxonomie.vm_taxref_list_forautocomplete.unaccent_search_name AS taxonomie_vm_taxref_list_forautocomplete_unaccent_search__1, taxonomie.vm_taxref_list_forautocomplete.cd_ref AS taxonomie_vm_taxref_list_forautocomplete_cd_ref, taxonomie.vm_taxref_list_forautocomplete.nom_valide AS taxonomie_vm_taxref_list_forautocomplete_nom_valide, taxonomie.vm_taxref_list_forautocomplete.lb_nom AS taxonomie_vm_taxref_list_forautocomplete_lb_nom, taxonomie.vm_taxref_list_forautocomplete.nom_vern AS taxonomie_vm_taxref_list_forautocomplete_nom_vern, taxonomie.vm_taxref_list_forautocomplete.regne AS taxonomie_vm_taxref_list_forautocomplete_regne, taxonomie.vm_taxref_list_forautocomplete.group2_inpn AS taxonomie_vm_taxref_list_forautocomplete_group2_inpn, taxonomie.vm_taxref_list_forautocomplete.group3_inpn AS taxonomie_vm_taxref_list_forautocomplete_group3_inpn, similarity(taxonomie.vm_taxref_list_forautocomplete.unaccent_search_name, %(similarity_1)s) AS idx_trgm 
FROM taxonomie.vm_taxref_list_forautocomplete JOIN taxonomie.bib_noms ON taxonomie.bib_noms.cd_nom = taxonomie.vm_taxref_list_forautocomplete.cd_nom JOIN taxonomie.cor_nom_liste ON taxonomie.cor_nom_liste.id_nom = taxonomie.bib_noms.id_nom AND taxonomie.cor_nom_liste.id_liste = %(id_liste_1)s 
WHERE taxonomie.vm_taxref_list_forautocomplete.unaccent_search_name ILIKE unaccent(%(unaccent_1)s) ORDER BY idx_trgm DESC, taxonomie.vm_taxref_list_forautocomplete.cd_nom = taxonomie.vm_taxref_list_forautocomplete.cd_ref DESC 
 LIMIT %(param_1)s OFFSET %(param_2)s]
[parameters: {'similarity_1': 'chir', 'id_liste_1': 100, 'unaccent_1': '%chir%', 'param_1': 20, 'param_2': 0}]
(Background on this error at: https://sqlalche.me/e/14/e3q8)
[2024-02-28 11:54:23,802] ERROR in app: Exception on /api/taxref/ [GET]
Traceback (most recent call last):
  File "/home/demo/TaxHub/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1910, in _execute_context
    self.dialect.do_execute(
  File "/home/demo/TaxHub/venv/lib/python3.11/site-packages/sqlalchemy/engine/default.py", line 736, in do_execute
    cursor.execute(statement, parameters)
psycopg2.OperationalError: SSL SYSCALL error: EOF detected
sgrimault commented 4 months ago

Bonjour,

En cours d'analyse de mon coté. L'appel à l'API reste assez rapide (<2s) pour une pagination de 10000 entrées (coté taxons), le souci viendrait plutôt de la partie contrôle et insertion en base, surtout de l'insertion en base...

Je vous tiens au courant de la suite.

camillemonchicourt commented 4 months ago

Selon moi, l'application mobile devrait insérer les données fournies tel quel, sans les contrôler ni les traîter. L'API se charge déjà d'envoyer de données contrôlées par ailleurs.

sgrimault commented 4 months ago

Oui je suis bien d'accord. Le seul contrôle qui est fait est de s'assurer que chaque taxon est bien rattaché à un rang taxonomique. J'ai eu par le passé des cas où ce n'est pas forcément garantie. Coté application, un taxon doit obligatoirement avoir un rang taxonomique.

gildeluermoz commented 4 months ago

Le seul contrôle qui est fait est de s'assurer que chaque taxon est bien rattaché à un rang taxonomique.

Est-ce que c'est fait ligne par ligne ? Sinon est-ce que ce contrôle, potentiellement chronophage, peut être fait via une requête sql après le chargement de tous les taxons (sans contrôle) ? Ou éventuellement coté serveur, en amont de ce que sert l'API ?

camillemonchicourt commented 4 months ago

En effet, si une telle vérification est nécessaire, il me semble qu'il faut d'abord tout insérer, puis éventuellement identifier globalement les taxons sans rang taxonomique.

Mais, tous les taxons de Taxref ont bien un rang taxonomique. Ce qui peut arriver est que certains administrateurs aient ajouté des taxons dans leur référentiel taxonomique et les ai pas complètement renseigné, donc en omettant de leur associer un règne et autres rangs taxonomiques.

Ce cas rare et non souhaitable ne devrait pas ralentir tous les autres cas classiques.

De plus, on peut s'interroger pourquoi un taxon sans rang taxonomique poserait soucis. Cela ne devrait pas empêcher de l'utiliser et de saisir des observations sur celui-ci tant qu'il a un nom et un cd_nom... La seule conséquence devrait être que l'on ne remonte pas ce taxon si on filtre sur un rang taxonomique.

Mais selon moi on ne devrait pas contrôler les rangs taxonomiques des taxons ni les exclure de la saisie, seulement ne pas les renvoyer lors des filtres.

sgrimault commented 4 months ago

Le rang taxonomique reste obligatoire coté application car il sert notamment à filtrer les valeurs possibles dans les listes des champs de type nomenclature (utilisé sur la partie Information et Dénombrement). Je ne pense pas que ce petit contrôle (filtre) soit coûteux, mes premiers tests montrent surtout qu'il y a un souci lors de l'insertion en base. On ne s'est pas vraiment rendu compte auparavant car la liste restait relativement petite, donc avec un temps de traitement acceptable on va dire. Mais là c'est plus flagrant avec potentiellement des centaines de milliers de taxons à synchroniser... Pour information, toute la synchronisation fonctionne dans un contexte transactionnel et la partie insertion en base des éléments paginés (taxons et "couleurs" des taxons) se fait en mode "batch" (bulk insert) dans un contexte transactionnel aussi.

sgrimault commented 4 months ago

Après une analyse plus fine, la base de données n'est pas en cause (et c'est une bonne nouvelle :tada:). C'est donc bien le contrôle qui a une complexité linéaire en fonction du nombre de taxons car il faut aussi tenir compte des listes des taxons (dernière petite nouveauté apportée par la version 2.7 en plus de la partie "couleur" des taxons)...

Suite à vos retours et sur le fait que je suis d'accord comme vous qu'idéalement l'API devrait (doit) fournir des données propres et cohérentes et que l'application se contente de les prendre en faisant confiance à ce que fourni l'API. Donc pour cela j'ai fais un test en simplifiant tout ça et pour les taxons n'ayant pas de rang taxonomique de renseigné, ils auront simplement la valeur par défaut (ANY:ANY, une sorte de "wildcard" sur les rangs taxonomique). Et là je me retrouve avec un temps de traitement constant par page où c'est l'appel à l'API qui prend le plus de temps. Exemple lors du 32e appel (GET -> /taxhub/api/taxref/?limit=10000&page=32), 10000 taxons à traiter :

La synchronisation au total a demandé environ 3 minutes et 20s ce qui est beaucoup mieux :slightly_smiling_face:

camillemonchicourt commented 4 months ago

OK super. Et c'est idéal de ne pas exclure les taxons sans rang taxonomique mais de leur appliquer ANY. Merci beaucoup.

amandine-sahl commented 4 months ago

A terme on pourrait rajouter une contrainte au niveau de la base de taxref pour éviter que les rangs soit null et éviter ce traitement

camillemonchicourt commented 3 months ago

Synchro sans les contrôles bien plus rapide dans la 2.7.0-rc7.