Duży (> 22 tryliony elementów) zbiór danych geoprzestrzennych z szybką (<1s) wydajnością zapytania do odczytu

20

Jestem w trakcie projektowania nowego systemu dla dużego zestawu danych geoprzestrzennych, który będzie wymagał szybkiego wykonania zapytania dotyczącego odczytu. Dlatego chcę sprawdzić, czy ktoś uważa, że ​​jest to możliwe, lub ma doświadczenie / porady dotyczące odpowiednich DBMS, struktury danych lub alternatywnych metod, aby osiągnąć wymaganą wydajność w następującej sytuacji:

Dane będą nieprzerwanie wytwarzane z przetworzonych danych radaru satelitarnego, które będą miały zasięg globalny. Na podstawie rozdzielczości satelitarnej i zasięgu lądowego globu szacuję pełny zestaw danych, aby uzyskać wartości w 75 miliardach dyskretnych lokalizacji na kuli ziemskiej. W ciągu całego życia pojedynczego satelity dane wyjściowe będą generować do 300 wartości w każdej z tych lokalizacji (więc całkowity zestaw danych> 22 bilionów wartości). Dotyczy to jednego satelity, a na orbicie jest już drugi, a kolejne dwa planowane są na kilka kolejnych lat. Będzie więc dużo danych! Pojedynczy element danych jest bardzo prosty i będzie się składał tylko (długość, szerokość geograficzna, wartość), ale ze względu na liczbę elementów oceniam, że pojedynczy satelita może wyprodukować do 100 TB.

Zapisane dane nigdy nie powinny wymagać aktualizacji, ponieważ będą rosły tylko w miarę przetwarzania nowych akwizycji satelitarnych. Wydajność zapisu nie jest ważna, ale wydajność odczytu ma kluczowe znaczenie. Celem tego projektu jest możliwość wizualizacji danych za pomocą prostego interfejsu, takiego jak warstwa nad mapami Google, gdzie każdy punkt ma kolorową wartość na podstawie jego średniej, gradientu lub funkcji w czasie. (demo na końcu postu).

Z tych wymagań baza danych musi być skalowalna i prawdopodobnie będziemy szukać rozwiązań w chmurze. System musi być w stanie poradzić sobie z zapytaniami geoprzestrzennymi, takimi jak „punkty w pobliżu (lat, lon)” i „punkty w (box)”, i mieć wydajność odczytu <1s dla lokalizacji pojedynczego punktu oraz wielokątów zawierających do 50 000 punktów (choć preferowane byłoby do 200 000 punktów).

Do tej pory mam zestaw danych testowych ~ 750 milionów danych w 111 milionach lokalizacji. Przetestowałem instancję postgres / postGIS, która działała OK, ale bez możliwości dzielenia nie robię tego, to będzie w stanie poradzić sobie w miarę wzrostu danych. Przetestowałem również instancję mongoDB, która znów wydaje się OK, więc daleko, a przy dzieleniu na fragmenty może być wystarczające skalowanie z woluminem danych. Niedawno nauczyłem się trochę o elasticsearch, więc wszelkie komentarze na ten temat byłyby pomocne, ponieważ są dla mnie nowe.

Oto szybka animacja tego, co chcemy osiągnąć przy użyciu pełnego zestawu danych: Tileserver służący do wizualizacji 750 milionów danych.

Ten gif (z mojej postgresowej wersji próbnej) podaje (6x3) wstępnie obliczone płytki rastrowe, z których każda zawiera ~ 200 000 punktów i zajmuje około 17 sekund na wygenerowanie każdego. Kliknięcie punktu powoduje utworzenie wykresu poprzez wyciągnięcie wszystkich wartości historycznych z najbliższej lokalizacji w <1s.

Przepraszamy za długi post, wszelkie komentarze / porady są mile widziane.

Azwok
źródło

Odpowiedzi:

4

Możesz odłamek według lokalizacji. Podziel glob na siatkę i umieść każdy kwadrat w tej siatce na jednym serwerze. Ponieważ wspomniałeś o chmurze, byłoby to dobrze dostosowane do chmury. Oczywiście będziesz musiał ręcznie scalić wyniki z wielu serwerów.

W ten sposób możesz użyć dowolnego rozwiązania bazodanowego. Sam nie musi być skalowalny.

Poszczególne kwadraty będą miały różne ilości danych. Możesz używać dla nich maszyn o różnych rozmiarach (ponieważ jest to chmura) lub umieszczać wiele małych odłamków na tym samym komputerze.

Ten schemat dzielenia jest świetny dla tego rodzaju zapytań, które wykonujesz, ponieważ każde zapytanie musi dotykać tylko bardzo niewielu odłamków. Odłamki czasu są gorsze, ponieważ dla każdego zapytania należy dotknąć wszystkich odłamków czasu. Losowe dzielenie ma ten sam problem.

Podsumowując, jest to łatwy przypadek dzielenia, ponieważ wzorzec zapytania tak dobrze pasuje do schematu dzielenia.

Właściwie zastanawiam się, czy w ogóle potrzebujesz do tego bazy danych. Być może możesz podzielić glob na kafelki 1000 x 1000 lub mniejsze i mieć jeden płaski plik w magazynie obiektów blob dla każdego kafelka. Przechowywanie obiektów blob w ogóle nie przeszkadza w przypadku obiektów blob 1M.

Wykonanie zapytania jest koncepcyjnie bardzo łatwe w tym schemacie przechowywania. Możesz przechowywać dane nadmiarowo również w wielu rozdzielczościach siatki.

usr
źródło
Podział na regiony to podejście, na które patrzyłem w MongoDB, a wraz z terminową wersją MongoDB Atlas, obecnie skłaniam się w tym kierunku (używając wcześniej obliczonych wartości zagregowanych). W tej chwili nie jestem pewien, ile serwerów repliki / odłamków potrzebowałbym, więc kosztowanie może stać się problemem. Twoja propozycja użycia magazynu BLOB jest również interesująca i jesteś drugą osobą, która ją zaproponowała. Jednak korzystanie z BLOBów jest dla mnie zupełnie nowe, więc muszę dalej w nich czytać, jakieś przydatne źródła, które znasz? Dzięki za odpowiedzi.
Azwok,
Obiekty BLOB są łatwe w użyciu. Złożoność będzie wynikać z konieczności wdrożenia funkcji bazy danych, takich jak serializacja, zapytania, transakcje, kopie zapasowe, HA, DA. To wszystko jest wykonalne, ale może nie mądre. Może możesz przechowywać obiekty BLOB w tabeli Postgres. Automatyzuje to wszystko oprócz serializacji i zapytań. Perf może być lepszy niż przechowywanie kropli i może nawet jest tańszy. Obiekty BLOB i maszyny wirtualne nie są obciążane kosztami, mają ładny margines (dowód: mój lokalny webhoster pobiera 3-5x mniej za tę samą moc obliczeniową niż chmura. Oznacza to wysokie marginesy chmury).
usr
Pamiętaj, że możesz uruchomić wiele odłamków w tej samej instancji mongo. Możesz „overshard”. W ten sposób możesz zrównoważyć serwery.
usr
1
Nie jestem pewien, czy w ogóle potrzebujesz jakichkolwiek funkcji przestrzennych. Możesz to wszystko obliczyć w aplikacji. Potrzebujesz tylko możliwości zapytania wszystkich danych o prostokąt. Można tego dokonać ręcznie dzieląc kulę ziemską na siatkę (lub siatki o wielu rozdzielczościach). Myślę, że twoja baza danych nie musi obsługiwać przestrzeni.
usr
8

Jak aktualne muszą być Twoje zapytania dotyczące odczytu?

Możesz podzielić bazę danych na partycje według czasu, jeśli mapa musi tylko pokazywać ostatni pomiar. Zmniejszy to obciążenie zapytania mapą.

W przypadku historii danego punktu można przechowywać drugi sklep przez xiy pokazujące historię. Można to zrobić za pomocą nocnego odświeżania / aktualizacji, ponieważ dane historyczne nie ulegną zmianie.

Następnie możesz wstępnie obliczyć średnie przy bardziej zgrubnych rozdzielczościach do integracji z mapami przy różnych poziomach powiększenia. Zmniejszyłoby to liczbę punktów do pobrania dla dużych obszarów mapy (oddalenie). Lepsze rozdzielczości byłyby stosowane do bardziej powiększonych map, które sprawdzały mniejsze obszary. Jeśli naprawdę chcesz to przyspieszyć, możesz obliczyć kafelki jako obiekty BLOB i zinterpretować je w swojej aplikacji.

Ponieważ wiązałoby się to z ponownym obliczeniem danych zagregowanych, pojawiłoby się pewne opóźnienie w wynikach zapytań. W zależności od dopuszczalnego opóźnienia można zastosować takie podejście do optymalizacji odczytów.

OK, więc twoje punkty muszą być obliczane średnie w czasie. Z tego obliczenia wydaje mi się, że twoje rzeczywiste zapytania sprowadzają się dość często z 22 bilionów przedmiotów, ponieważ wartości rastrowe można wstępnie obliczyć dla zapytań.

ConcernedOfTunbridgeWells
źródło
Zapytania dotyczące odczytu mogą mieć nieco opóźnienie (dzień lub dwa), więc przetwarzanie wsadowe jest prawidłową opcją. W dowolnej lokalizacji nowa wartość będzie dodawana najszybciej co 6 dni (kolejna przepustka satelitarna). Dane wyjściowe na mapie nie są tylko najnowszymi wartościami, są obliczane na podstawie całej historii wartości w tej lokalizacji, np. Wartości średniej, gradientu lub funkcji niestandardowej. Aby uzyskać więcej pomniejszonych poziomów, pracuję już nad strukturą klastrowania / piramidy, dzięki czemu będę mieć tabelę / kolekcję ze uśrednionymi wartościami, tak aby żadne kafelki (zapytanie) nie miały> 200 000 (lub 50 000) elementów lokalizacji.
Azwok,
Myślę, że kluczem są agregaty do obliczeń wstępnych - nadal można zestawiać obliczenia czasowe. W ten sposób systemy OLAP uzyskują szybką wydajność zapytań i prawdopodobnie będziesz musiał zastosować takie podejście. Jest to szczególnie istotne, jeśli możesz żyć z danymi, które są od dawna używane w zapytaniach.
ConcernedOfTunbridgeWells
Jeśli pytasz o obliczone wartości średnie, w ilu dyskretnych lokalizacjach pobierasz próbki - tj. Jaka jest rozdzielczość rzeczywistej mapy bitowej przy najwyższym poziomie powiększenia?
ConcernedOfTunbridgeWells
Zgadzam się, że wstępnie obliczone dane zagregowane są bardzo prawdopodobne. Obliczone średnie dla największego powiększenia nie są uśredniane dla obszaru, jest to średnia wartości w czasie w 1 lokalizacji. Tylko w miarę pomniejszania będę miał osobne tabele / kolekcje, które uśrednią obszary, aby upewnić się, że żadne zapytanie / kafelek nie ma w sobie zbyt wielu punktów lokalizacji (maksymalnie 50 000-200 000). Maksymalna rozdzielczość dowolnego kafelka wynosi 256 x 256 pikseli.
Azwok,
3

Wygląda na to, że istnieją dwie klasy zapytań - jedna dla zrozumienia, które lokalizacje mieszczą się w bieżącym oknie widoku, a druga dla dostarczenia pożądanej statystyki dla tych punktów. Sugeruję, aby dla każdego użyć osobnych, specjalistycznych narzędzi.

Zakładam, że wszystkie pomiary odnoszą się do tego samego zestawu 75 miliardów punktów. Te długości / długości, po ustaleniu, są zatem statyczne. Można je grupować, agregować i indeksować jednorazowo. Dlatego sugerowałbym dzielenie na fragmenty według regionu i poziomu powiększenia. Rozmiar każdego fragmentu będzie zależał od wydajności, którą można uzyskać z każdej instancji GIS.

GIS zwróci zestaw punktów, które są przekazywane do bazy danych szeregów czasowych. Przechowuje zmierzone wartości i wykonuje agregacje. KDB jest tym, którego jestem świadomy. Jego celem jest handel papierami wartościowymi, które będą miały mniej kluczy, ale więcej punktów danych na klucz niż Twój scenariusz.

Przeniesienie kluczowych wartości z serwera GIS do bazy danych timeseries będzie kosztowało. Moja hipoteza jest taka, że ​​koszt ten zostanie zwrócony dzięki szybszemu przetwarzaniu w DB szeregów czasowych specyficznych dla zadania. Z treści pytania wynika, że ​​pojedyncze wystąpienie nie będzie w stanie pomieścić wszystkich danych, więc ruch na wielu serwerach wydaje się nieunikniony. Biorąc pod uwagę względną szybkość komponentów, wydaje się prawdopodobne, że wysłanie zestawu kluczy do zdalnego serwera, który ma buforowane dane, będzie szybsze niż odczyt danych z dysku lokalnego.

Jeśli części służące do ustalania punktów i obliczania wartości mogą być względem siebie lokalne, to oczywiście oczekiwałbym szybszej reakcji. Moje (ograniczone) zrozumienie jest takie, że znalezienie N najbliższych sąsiadów w danym punkcie jest nietrywialnym zadaniem. Dlatego zasugerowałem użycie specjalnego oprogramowania do jego wykonania. Jeśli ustalenie punktu można zredukować do

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

wtedy ta część mogłaby być obsługiwana przez oprogramowanie przechowujące wartości, a GIS wyeliminowany z architektury.

Nie wdrożyłem takiego systemu. Naprawdę po prostu myślę tutaj głośno. W skali petabajtów nie ma gotowych rozwiązań. Istnieje jednak wielu dostawców danych satelitarnych, więc problem można rozwiązać. Powodzenia.

Michael Green
źródło
Uzgodnione, istnieją dwie klasy. 1) zrób zdjęcie pojedynczych wartości z wielu lokalizacji, 2) zbierz wszystkie wartości historyczne z jednego miejsca. Wszystkie pomiary dotyczą tych samych miliardów lokalizacji, jedyną zmianą będzie liczba wartości historycznych w każdym punkcie. Z podanych przez ciebie powodów dzielenie według regionów to podejście, które zamierzam przyjąć. Nie zastanawiałem się nad przekazaniem zwróconych wartości do osobnego DB szeregów czasowych. Sądziłbym, że wybór i przeniesienie do bazy danych szeregów czasowych wydłużyłoby zbyt wiele czasu, aby uczynić tę wykonalną opcję, chyba że źle zrozumiałem waszą propozycję.
Azwok,