Grand ensemble de données géospatiales (> 22 billions d'éléments) avec des performances de requête de lecture rapide (<1 s)


20

Je suis en train de concevoir un nouveau système pour un grand ensemble de données géospatiales qui nécessitera des performances de requête de lecture rapide. Par conséquent, je veux voir si quelqu'un pense que c'est possible ou a de l'expérience / des conseils sur les SGBD appropriés, la structure de données ou d'autres méthodes pour atteindre les performances requises dans la situation suivante:

Les données seront produites en continu à partir des données radar satellitaires traitées, qui auront une couverture mondiale. Sur la base de la résolution des satellites et de la couverture terrestre du globe, j'estime l'ensemble de données complet pour produire des valeurs à 75 milliards d'emplacements discrets sur le globe. Au cours de la durée de vie d'un seul satellite, la sortie produira jusqu'à 300 valeurs à chacun de ces emplacements (donc un ensemble de données total de> 22 billions de valeurs). C'est pour un satellite, et il y en a déjà un deuxième en orbite, avec deux autres prévus dans les nouvelles années. Il y aura donc beaucoup de données! Un seul élément de données est très simple et ne comprendra que (longitude, latitude, valeur), mais en raison du nombre d'éléments, j'estime qu'un seul satellite produira jusqu'à 100 To.

Les données écrites ne devraient jamais avoir besoin d'être mises à jour, car elles ne feront qu'augmenter à mesure que de nouvelles acquisitions de satellites seront traitées. Les performances d'écriture ne sont pas importantes, mais les performances de lecture sont cruciales. L'objectif de ce projet est de pouvoir visualiser les données via une interface simple telle qu'une couche sur google maps, où chaque point a une valeur colorée basée sur sa moyenne, son gradient ou une fonction dans le temps. (démo en fin de post).

À partir de ces exigences, la base de données doit être évolutive et nous sommes susceptibles de nous tourner vers des solutions cloud. Le système doit être capable de traiter des requêtes géospatiales telles que "points proches (lat, lon)" et "points dans (case)", et avoir des performances de lecture <1s pour localiser un seul point, et des polygones qui contiennent jusqu'à 50 000 points (bien que jusqu'à 200 000 points soient préférables).

Jusqu'à présent, j'ai un ensemble de données de test d'environ 750 millions d'éléments de données sur 111 millions d'emplacements. J'ai testé une instance postgres / postGIS, qui a bien fonctionné, mais sans possibilité de partitionnement, je ne le fais pas, cela pourra s'adapter à mesure que les données augmentent.J'ai également testé une instance mongoDB, qui semble à nouveau OK, donc loin, et avec le partage, il pourrait être suffisant de s'adapter au volume de données. J'ai récemment appris un peu sur elasticsearch, donc tout commentaire à ce sujet serait utile car c'est nouveau pour moi.

Voici une animation rapide de ce que nous voulons réaliser avec l'ensemble de données complet: Tileserver servant à la visualisation de 750 millions d'éléments de données.

Ce gif (de mon essai postgres) sert (6x3) des tuiles raster pré-calculées, chacune contenant ~ 200 000 points et prenant ~ 17s pour générer chacune. En cliquant sur un point, le graphique est créé en tirant toutes les valeurs historiques à l'emplacement le plus proche en <1 s.

Toutes mes excuses pour le long post, tous les commentaires / conseils sont les bienvenus.

Réponses:


4

Vous pouvez tailler par emplacement. Partitionnez le globe en une grille et disposez chaque carré de cette grille sur un serveur. Puisque vous avez mentionné le cloud, ce serait bien adapté au cloud. Bien sûr, vous devrez fusionner manuellement les résultats de plusieurs serveurs.

De cette façon, vous pouvez utiliser n'importe quelle solution de base de données comme vous le souhaitez. Il n'a pas besoin d'être évolutif en soi.

Les carrés individuels auront différentes quantités de données. Vous pouvez utiliser des machines de tailles différentes pour eux (car il s'agit du cloud), ou vous mettez plusieurs petits fragments sur la même machine.

Ce schéma de partage est idéal pour le type de requêtes que vous effectuez, car chaque requête ne devra toucher que très peu de fragments. Le partage temporel est pire car tous les fragments temporels doivent être touchés pour chaque requête. Le partage aléatoire a le même problème.

Dans l'ensemble, c'est un cas de partitionnement facile car le modèle de requête correspond si bien au schéma de partitionnement.

En fait, je me demande si vous avez besoin d'une base de données pour cela. Vous pouvez peut-être partitionner le globe en tuiles de 1 000 x 1 000 ou plus petites et avoir un fichier plat dans le stockage d'objets blob pour chaque tuile. Le stockage d'objets blob ne dérange pas du tout les objets blob 1M.

L'exécution d'une requête est conceptuellement très facile avec ce schéma de stockage. Vous pouvez également stocker les données de manière redondante dans plusieurs résolutions de grille.


Le partage par région est l'approche que j'ai envisagée avec MongoDB, et avec la publication opportune de MongoDB Atlas, je penche actuellement dans cette direction (en utilisant des valeurs agrégées précalculées). Pour le moment, je ne sais pas de combien de serveurs de répliques / fragments j'aurais besoin, donc le coût peut devenir un problème. Votre proposition d'utiliser le stockage BLOB est également intéressante et vous êtes la deuxième personne à la proposer. Cependant, l'utilisation des BLOB est complètement nouvelle pour moi, donc je dois y lire plus loin, des sources utiles que vous connaissez? Merci pour la réponse.
Azwok

Les blobs sont simples à utiliser. La complexité résultera de la nécessité d'implémenter des fonctionnalités de base de données telles que la sérialisation, les requêtes, les transactions, les sauvegardes, HA, DA. Tout cela est faisable mais peut-être pas sage. Vous pouvez peut-être stocker les blobs dans une table Postgres. Cela automatise tout cela, sauf la sérialisation et la requête. La performance pourrait être meilleure que le stockage d'objets blob et peut-être même moins cher. Les blobs et les machines virtuelles ne sont pas facturés par le coût, ils ont une belle marge (preuve: mon hébergeur local facture 3 à 5 fois moins pour la même puissance de calcul que le cloud. Cela implique des marges de cloud élevées).
usr

Notez que vous pouvez exécuter plusieurs fragments sur la même instance mongo. Vous pouvez "éclater". De cette façon, vous pouvez équilibrer les serveurs.
usr

1
Je ne suis pas sûr que vous ayez besoin de caractéristiques spatiales. Vous pouvez calculer tout cela dans l'application. Vous avez juste besoin de pouvoir interroger toutes les données pour un rectangle. Cela peut être fait en divisant manuellement le globe en une grille (ou en plusieurs grilles de résolution). Je pense que votre base de données n'a pas besoin de prendre en charge l'espace.
usr

8

Quelle doit être la mise à jour de vos requêtes de lecture?

Vous pouvez partitionner la base de données par le temps si la carte a juste besoin d'afficher la mesure la plus récente. Cela réduirait la charge de votre requête pour la carte.

Pour l'historique d'un point donné, vous pouvez tenir un deuxième magasin par x et y affichant l'historique. Cela pourrait être fait avec une actualisation / mise à jour nocturne car les données historiques ne changeront pas.

Vous pouvez ensuite pré-calculer des moyennes à des résolutions plus grossières pour les intégrer à des cartes à différents niveaux de zoom. Cela réduirait le nombre de points à récupérer pour les grandes zones de la carte (zoom arrière). Des résolutions plus fines seraient utilisées pour des cartes plus zoomées qui interrogeaient des zones plus petites. Si vous avez vraiment besoin d'accélérer cela, vous pouvez calculer les tuiles comme des blobs et les interpréter dans votre application.

Étant donné que cela impliquerait un recalcul des informations agrégées, il y aurait une certaine latence dans les résultats des requêtes. Selon la latence acceptable, vous pouvez utiliser ce type d'approche pour optimiser vos lectures.

OK, vos points doivent donc être calculés en moyenne dans le temps. Avec ce calcul, je suppose que vos requêtes réelles descendent beaucoup de 22 billions d'éléments, car les valeurs raster peuvent être pré-calculées pour les requêtes.


Les requêtes de lecture peuvent avoir un peu de retard (un jour ou deux), donc le traitement par lots est une option valide. À tout emplacement donné, une nouvelle valeur ne sera ajoutée que tous les 6 jours au plus vite (le prochain passage satellite). La sortie sur la carte n'est pas seulement la dernière valeur, elle est calculée sur la base de l'historique complet des valeurs à cet emplacement, par exemple, c'est la moyenne ou le gradient, ou une fonction personnalisée. Pour des niveaux plus dézoomés, je travaille déjà sur une structure de clustering / pyramide afin d'avoir une table / collection avec des valeurs moyennes afin qu'aucune tuile (requête) n'ait> 200 000 (ou 50 000) éléments d'emplacement.
Azwok

Je pense que le pré-calcul des agrégats est la clé - vos calculs temporels peuvent toujours être groupés. C'est ainsi que les systèmes OLAP obtiennent des performances de requête rapides et vous devrez probablement adopter ce type d'approche. Particulièrement pertinent si vous pouvez vivre avec des données vieilles d'un jour pour vos requêtes.
ConcernedOfTunbridgeWells

Si vous interrogez des valeurs moyennes calculées, à combien d'emplacements discrets prenez-vous des échantillons - c'est-à-dire quelle est la résolution du bitmap réel au plus haut niveau de zoom?
ConcernedOfTunbridgeWells

Je suis d'accord que les agrégats pré-calculés semblent très probablement la voie à suivre. Les moyennes calculées au zoom le plus élevé ne sont pas moyennées sur une zone, c'est la moyenne des valeurs dans le temps à 1 emplacement. Ce n'est que lors d'un zoom arrière que j'aurai des tables / collections distinctes qui feront la moyenne des zones pour s'assurer qu'aucune requête / tuile ne contient trop de points de localisation (max 50 000-200 000). La résolution maximale de n'importe quelle tuile est de 256x256 pixels.
Azwok

3

Il semble qu'il existe deux classes de requête - une pour comprendre quels emplacements se trouvent dans la fenêtre de vue actuelle et une seconde pour fournir les statistiques souhaitées pour ces points. Ma suggestion est d'utiliser des outils distincts et spécialisés pour chacun.

Je suppose que toutes les mesures se rapportent au même ensemble de points 75 milliards. Ces lat / longs, une fois établis, sont donc statiques. Ils peuvent être regroupés, agrégés et indexés à un coût unique. Par conséquent, je suggérerais un partage par région et niveau de zoom. La taille de chaque fragment dépendra des performances pouvant être obtenues à partir de chaque instance SIG.

Le SIG renverra un ensemble de points qui seront transmis à une base de données de séries chronologiques. Cela contient les valeurs mesurées et effectue des agrégats. KDB est celui que je connais. Il cible le trading de titres, qui aura moins de clés mais plus de points de données par clé que votre scénario.

Le transfert des valeurs clés du serveur SIG vers la base de données de la série temporelle entraînera un coût. Mon hypothèse est que ce coût sera remboursé par un traitement plus rapide dans la base de données de séries temporelles spécifiques aux tâches. D'après le libellé de la question, il semble qu'une seule instance ne pourra pas conserver toutes les données, de sorte qu'un trafic inter-serveurs semble inévitable. Compte tenu de la vitesse relative des composants, il semble probable que l'envoi d'un jeu de clés à un serveur distant dont les données sont mises en cache sera plus rapide que la lecture des données sur le disque local.

Si les parties de recherche de points et de calcul de valeur peuvent être locales les unes par rapport aux autres, je m'attends bien sûr à ce que la réponse soit plus rapide. Ma compréhension (limitée) est que trouver les N voisins les plus proches d'un point donné est une tâche non triviale. C'est pourquoi j'ai suggéré d'utiliser un logiciel spécifique pour l'exécuter. Si la recherche de points peut être réduite à

where latitude between x1 and x2
and logitude between y1 and y2

alors cette partie pourrait être gérée par le logiciel de stockage de valeur et le SIG éliminé de l'architecture.

Je n'ai pas mis en place un tel système. Je pense vraiment à haute voix ici. À l'échelle du pétaoctet, il n'y a pas de solutions standard. Il existe cependant de nombreux fournisseurs de données par satellite, de sorte que votre problème est traitable. Bonne chance.


D'accord, il y a deux classes. 1) faire une image des valeurs uniques de plusieurs emplacements, 2) obtenir toutes les valeurs historiques à un emplacement. Toutes les mesures sont liées aux mêmes milliards d'emplacements, le seul changement sera le nombre de valeurs historiques à chaque point. Le partage par région est l'approche que j'envisage d'adopter, pour les raisons que vous avez indiquées. Je n'avais pas envisagé de passer les valeurs renvoyées dans une base de données temporelle distincte. J'aurais pensé que la sélection et le transfert dans une base de données chronologiques ajouteraient trop de temps pour en faire une option viable, sauf si j'ai mal compris votre proposition.
Azwok
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.