Optimisations d'Overpass API pour éviter les lags ?
publié le , mis à jourSuite à #811 je crée une issue spécifique pour discuter d'Overpass API.
Aujourd'hui les requêtes sont générées côté client et envoyées à overpass-api.de/api. Ce serveur est limité à 4 requêtes simultanées, avec qq secondes d'attente entre chaque (et cette durée augmente si on a généré des requêtes qui ont pris du temps).
Pour peu que l'utilisateur ait chargé trop de catégories sur la carte et scrolle trop vite, il atteint vite cette limite. Ca peut créer des gros lags, voire cette erreur ?
J'ai cherché dans la console des retours du genre "no more slot avaible" comme ceux qui m'ont posé pb sur playguide à une époque mais je n'en ai pas trouvé (pourtant cette erreur apparait, je ne sais pas d'où elle vient). J'ai plutôt l'impression que les requêtes successives sont mises en attente, d'où des lags très longs parfois.
D'autres retours d'utilisateurs sur le sujet ?
Dans #811 j'avais proposé de mettre les réponses en cache mais c'est débile, ça impliquerait de générer les requêtes côté serveur et il serait immédiatement bloqué. Il n'y a pas de débat, ça doit rester côté client. Mais n'empêche, l'utilisateur peut générer trop de requêtes, on aurait intérêt à minimiser au maximum le nb de requêtes générées pour éviter les lenteurs.
Optimisations imaginées, mais toutes pas évidentes à mettre en place (voire impossibles ou aberrantes, dites moi !) :
- quand des catégories sont affichées, ne pas relancer une requête quand l'utilisateur zoome dans la carte (plus précisément si la nouvelle bbox est incluse dans la précédente)
- quand plusieurs catégories sont affichées, lancer 1 seule requête incluant les différentes catégories sélectionnées plutôt que 1 par catégorie (ça implique de déconvoluer la réponse...)
- lancer des requêtes sur des bbox plus grandes que nécessaires pour éviter de relancer une requête lors d'un petit scroll sur la carte (ça implique de bien standardiser les frontières des bbox possibles.. et faut vérifier si une bbox plus grande ne génère pas un temps d'attente plus long avant la requête suivante)
- éviter de relancer les requêtes quand la carte se recentre automatiquement quand le volet s'agrandit
- annuler une requête si elle est déjà caduque (si l'utilisateur a déjà scrollé plus loin avant que la réponse ne soit reçue)
- au clic sur un POI chargé via les catégories, ne pas relancer une requête pour ce POI vu que ses tags sont déjà dans la requête par bbox qui a permis de l'afficher sur la carte
- déployer une instance overpass interne (ou chez osm fr?), au moins pour les requêtes par bbox des POI des catégories (en limitant l'instance à des données là pour qu'elle soit légère et rapide)
- précharger chaque nuit dans une base interne les infos des POIs par catégories pour utiliser pour les bbox une requête sur cette base interne plutôt qu'overpass
Et n'hésitez pas à proposer d'autres idées !
laem
ça impliquerait de générer les requêtes côté serveur et il serait immédiatement bloqué. Il n'y a pas de débat, ça doit rester côté client.
D'autant plus qu'il y a déjà des requêtes côté serveur, pour préparer les fiches lieu. Les données des fiches lieus sont maintenant aussi téléchargées depuis Overpass, car on n'a pas droit d'utiliser en lecture l'API officielle.
laem
Tu pourras observer que chez Google ils ont le même problème : un bouton "relancer la recherche ici" apparait. J'ai toujours trouvé ça relou à utiliser, d'où l'implémentation plus gourmande actuelle.
déployer une instance overpass interne (ou chez osm fr?), au moins pour les requêtes par bbox des POI des catégories (en limitant l'instance à des données là pour qu'elle soit légère et rapide)
Oui on pourrait déployer une instance chez nous, qui se concentrerait sur la France et on redirigerait les requêtes hors France sur la .De.
Ça demande un peu de boulot, et faut voir quel est le cout en charge serveur et en temps d'initialiser Overpass et surtout de le maintenir à jour. Car Overpass c'est le seul truc ultra à jour sur cartes.app aujourd'hui. Nos tuiles sont regénérées toutes les semaines et Photon à la main :/
Je créée #841
etienneJr
Tu pourras observer que chez Google ils ont le même problème : un bouton "relancer la recherche ici" apparait. J'ai toujours trouvé ça relou à utiliser, d'où l'implémentation plus gourmande actuelle.
Ah oui j'avais oublié ça, c'est une solution radicale mais très efficace pour diminuer le nb de requêtes !
etienneJr
Une autre idée (mais pas sûr que ça soit réalisable) tant qu'on ne veut pas une instance générique mais "juste" remplacer les requêtes pour les bbox par catégorie : à partir d'un .osm à jour, on crée 1 fichier de tuiles pour chaque catégorie. Quand l'utilisateur active la catégorie, on affiche les tuiles correspondantes. Plus besoin de requêtes Overpass dès que l'utilisateur scrolle.
laem
Oui c'est astucieux bête, mais la puissance d'Overpass me semble quand même importante à garder. Avec une instance d'Overpass performante, on pourrait faire beaucoup de choses assez dingues je pense. Si les tuiles vectorielles sont une API rest, Overpass est une API graphql : à l'appel d'API, on demande ce qu'on veut et on obtient ce qu'on veut.
Générer des tuiles par contre c'est bien plus efficace pour les choses très demandées, car cachable 👍
Mais en tout cas ça ne résoud pas le pb de la perf de notre principal usage d'Overpass : le chargement des données OSM d'un lieu.
etienneJr
J'ai regardé comment installer une instance locale d'overpass. C'est assez bien documenté ici, j'ai pu l'installer, remplir une base de données avec la Bretagne, et faire des requêtes en ligne de commande. Je n'ai pas tenté de démarrer une api web en localhost car j'ai eu l'impression que c'était corrélé au lancement des mises à jour automatiques ?!?
Mais le truc qui m'inquiète le plus c'est le hardware nécessaire :
- espace disque : les différents tuto annoncent qu'il faut entre 500 Go et 1 To pour charger OSM en entier, selon la profondeur de l'historique et des méta-données. C'est déjà pas mal. Pourtant dans mon essai, le fichier bretagne.osm.pbf de 300Mo est devenu 33 Go une fois décompressé sur mon disque, soit x100. Sachant que planet.osm.pbf fait 80 Go, il faudrait carrément 8 To ? J'avoue que je ne comprends pas une telle différence.
- RAM : l'instance .de dispose de 32 Go de RAM. J'y connais rien en infra, mais ça me parait énorme ? ça va coûter cher en frais de serveurs, non ?
Si on veut une instance légère car focalisée, on pourrait filtrer les tags dont on a besoin (shop, amenity, etc en étant assez large quand même) avec osmosis pour créer une DB overpass qui ne contient que ceux là.
etienneJr
Mais en tout cas ça ne résoud pas le pb de la perf de notre principal usage d'Overpass : le chargement des données OSM d'un lieu.
Je pense que si, car si on trouve une solution pour gérer nous même les requêtes gourmandes (typiquement l'affichage des catégories) alors les 4 slots de l'instance .de seront tout à fait disponibles pour les requêtes faciles
tags d'un élément OSM
. D'autant que ce sont des requêtes que l'utilisateur génère manuellement en cliquant, donc à fréquence moins rapide qu'un scroll sur la carte, je serais surpris que l'utilisateur arrive à saturer ses 4 slots avec ça. A moins que j'ai raté une subtilité entre les requêtes overpass côté client et celles côté serveur ?etienneJr
Mes notes sur le test d'une base locale osm2pgsql sont dans le wiki, page osm2pgsql Voir en particulier la section "combien pèse chaque tag ?"
etienneJr
@laem bilan de mes tests pour l'import de la France dans une base avec
osm2pgsql
(cf cette section de mes notes) :- une base contenant les tags présents aujourd'hui dans nos catégories pèse 1,5 Go
- en rajoutant des tags présents dans le layer POI des tuiles (et qq autres intéressants et pas trop lourds), on passe à 3,7 Go
- j'avais encore d'autres idées, mais ça fait passer la base à 10Go (et besoin de 25 Go pour le calcul)
Et si la France est représentative de l'Europe, alors il faut faire x7 pour couvrir l'Europe.
Dis moi si cet ordre de grandeur de taille (disons 10-30 Go) te parait gérable à stocker sur le serveur actuel ? Si oui, je continuerai en regardant comment gérer la synchro, et comment utiliser
underpass
.etienneJr
Si je comprends bien il faudrait donc prévoir 100-200 go pour l'Europe
30-60 Go (au final) devrait déjà permettre de stocker la grosse majorité de ce qui nous intéresse (les 2 premiers points des 3 listés plus haut). Attention pour l'instant je n'ai pas les tables nécessaires à la gestion de la synchro, il faut que je teste pour voir à quel point c'est plus gros. [edit] j'avais pas pris les metadata non plus, faut que je teste ça aussi.
10Go (et besoin de 25 Go pour le calcul)
J'imagine qu'il sera possible de remplir la base en plusieurs fois pour éviter ce pic, sinon il y aura besoin de plus au moment du remplissage initial.
etienneJr
[edit] j'avais pas pris les metadata non plus, faut que je teste ça aussi.
Sur un essai spot, ajouter les metadata augmente la taille de +30%.
etienneJr
J'ai tenté Underpass-API mais je crois que j'atteins les limites de mes compétences : https://github.com/teritorio/Underpass-API/issues/1
laem
J'ai tenté Underpass-API mais je crois que j'atteins les limites de mes compétences : https://github.com/teritorio/Underpass-API/issues/1
Haha pour info, je n'ai pas non plus bcp bossé sur des bases SQL. À découvrir progressivement :)
etienneJr
Haha pour info, je n'ai pas non plus bcp bossé sur des bases SQL. À découvrir progressivement :)
Ah zut je comptais sur toi pour écrire les requêtes sql 😂
laem
J'utilise beaucoup Le Chat de mistral pour ça. C'est super fort.