Przechowywanie danych szeregów czasowych, relacyjnych czy nie?

185

Tworzę system, który sonduje urządzenia w poszukiwaniu danych o różnych parametrach, takich jak wykorzystanie procesora, wykorzystanie dysku, temperatura itp. W (prawdopodobnie) 5-minutowych odstępach przy użyciu SNMP. Ostatecznym celem jest zapewnienie wizualizacji użytkownikowi systemu w postaci wykresów szeregów czasowych.

W przeszłości patrzyłem na używanie RRDTool, ale odrzuciłem go, ponieważ przechowywanie przechwyconych danych w nieskończoność jest ważne dla mojego projektu i chcę wyższego poziomu i bardziej elastycznego dostępu do przechwyconych danych. Tak więc moje pytanie brzmi:

Co więcej, relacyjna baza danych (taka jak MySQL lub PostgreSQL) lub nierelacyjna lub NoSQL (taka jak MongoDB lub Redis) w odniesieniu do wydajności podczas wysyłania zapytań o dane do wykresów.

Relacyjny

Biorąc pod uwagę relacyjną bazę danych, użyłbym data_instancestabeli, w której zapisano by każde wystąpienie danych przechwyconych dla każdej metryki mierzonej dla wszystkich urządzeń, z następującymi polami:

Pola: id fk_to_device fk_to_metric metric_value timestamp

Kiedy chcę narysować wykres dla konkretnej metryki na określonym urządzeniu, muszę wykonać zapytanie do tej pojedynczej tabeli, odfiltrowując inne urządzenia i inne metryki analizowane dla tego urządzenia:

SELECT metric_value, timestamp FROM data_instances
    WHERE fk_to_device=1 AND fk_to_metric=2

Liczba wierszy w tej tabeli wynosiłaby:

d * m_d * f * t

gdzie djest liczbą urządzeń , m_doznacza łączną liczbę metryk rejestrowanych dla wszystkich urządzeń, fjest to częstotliwość, z jaką dane są odpytywane i tjest to całkowity czas, przez który system zbiera dane.

Dla użytkownika rejestrującego 10 wskaźników dla 3 urządzeń co 5 minut przez rok, mielibyśmy nieco mniej niż 5 milionów rekordów.

Indeksy

Bez indeksowania fk_to_devicei fk_to_metricskanowania ta ciągle rozwijana tabela zajęłaby zbyt wiele czasu. Zatem indeksowanie wyżej wymienionych pól, a także timestamp(do tworzenia wykresów ze zlokalizowanymi okresami) jest wymagane.

Nierelacyjny (NoSQL)

MongoDB ma koncepcję kolekcji , w przeciwieństwie do tabel, które można tworzyć programowo bez instalacji. Dzięki nim mogłem podzielić pamięć na dane dla każdego urządzenia, a nawet każdą metrykę zarejestrowaną dla każdego urządzenia.

Nie mam doświadczenia z NoSQL i nie wiem, czy zapewniają one funkcje zwiększające wydajność zapytań, takie jak indeksowanie, jednak w poprzednim akapicie zaproponowano wykonanie większości tradycyjnych relacyjnych zapytań w strukturze, w której dane są przechowywane w NoSQL.

Niezdecydowany

Czy rozwiązanie relacyjne z poprawnym indeksowaniem zredukuje się do indeksowania w ciągu roku? Czy też oparta na zbiorze struktura metod NoSQL (która pasuje do mojego modelu mentalnego przechowywanych danych) zapewnia zauważalną korzyść?

Marcus Whybrow
źródło
1
Bardzo ważne pytanie, zastanawiałem się nad tym, czy relacyjna baza danych jest właściwym sposobem przechowywania struktury danych, która jest w rzeczywistości hierarchiczna (struktura SNMP). Czasami, gdy piszę zapytanie, aby pobrać nawet trywialne dane, zapytanie jest nadmiernie skomplikowane, czułem, że dane musiały zostać zniekształcone do postaci, która nie jest jego własną. Na przykład dopasowanie ifnames i ich indeksów jest rzekomo trywialnym zadaniem, ponieważ oba są dziećmi tego samego nadrzędnego identyfikatora. Ale sposób, w jaki jest przechowywany w relacyjnej bazie danych, nie odnosi się do jego oryginalnej struktury i uważam, że bardziej efektywne jest przechowywanie go w sposób hierarchiczny.
Benny,
„Dla użytkownika rejestrującego 10 danych dla 3 urządzeń co 5 minut przez rok, mielibyśmy prawie 5 milionów rekordów”. Czy 10 * 3 * 365 * 24 * 12 nie jest w przybliżeniu równe 3 milionom, czyli nie mniej niż 5 milionów?
Mathieu Borderé,

Odpowiedzi:

152

Zdecydowanie relacyjny. Nieograniczona elastyczność i ekspansja.

Dwie poprawki, zarówno w koncepcji, jak i zastosowaniu, a następnie rzędna.

Korekta

  1. Nie „odfiltrowuje niepotrzebnych danych”; jest wybranie tylko potrzebne dane. Tak, oczywiście, jeśli masz indeks do obsługi kolumn określonych w klauzuli WHERE, jest on bardzo szybki, a zapytanie nie zależy od wielkości tabeli (pobieranie 1000 wierszy z tabeli o wartości 16 miliardów jest natychmiastowe) .

  2. Twój stół ma jedną poważną przeszkodę. Biorąc pod uwagę twój opis, rzeczywisty PK to (Urządzenie, Metryka, Data i godzina). (Proszę nie nazywać go TimeStamp, co oznacza coś innego, ale jest to drobny problem.) Wyjątkowość wiersza jest identyfikowana przez:

       (Device, Metric, DateTime)
    
    • IdKolumna nic nie robi, to jest całkowicie i zupełnie zbędne.

      • IdKolumna nie jest klucz (zduplikowane wiersze, które są zakazane w relacyjnej bazie danych, należy zapobiegać za pomocą innych środków).
      • IdKolumna wymaga dodatkowego Index, co oczywiście utrudnia szybkość INSERT/DELETEi dodaje do przestrzeni dyskowej używany.

      • Możesz się go pozbyć. Proszę.

Podniesienie

  1. Teraz, gdy usunąłeś przeszkodę, być może jej nie rozpoznałeś, ale twój stół jest w szóstej normalnej formie. Bardzo duża prędkość, z jednym indeksem na PK. Aby zrozumieć, przeczytaj tę odpowiedź z Co to jest szósta normalna forma? zmierzamy dalej.

    • (Mam tylko jeden indeks, a nie trzy; w Non-SQLs możesz potrzebować trzech indeksów).

    • Mam dokładnie ten sam stół ( Idoczywiście bez „klucza”). Mam dodatkową kolumnę Server. Zdalnie wspieram wielu klientów.

      (Server, Device, Metric, DateTime)

    Tabeli można użyć do przestawienia danych (tj. U Devicesgóry i na Metricsdole strony lub przestawnego ) przy użyciu dokładnie tego samego kodu SQL (tak, przełącz komórki). Używam tej tabeli do tworzenia nieograniczonej różnorodności grafów i wykresów dla klientów dotyczących wydajności ich serwerów.

    • Monitoruj model danych statystycznych .
      (Zbyt duży, by wstawić; niektóre przeglądarki nie mogą załadować się w treści; kliknij link. Jest to również przestarzała wersja demo, z oczywistych powodów, nie mogę pokazać ci komercyjnego produktu DM)

    • Pozwala mi to tworzyć takie wykresy , sześć naciśnięć klawiszy po otrzymaniu nieprzetworzonego pliku statystyk monitorowania od klienta za pomocą jednego polecenia SELECT . Zwróć uwagę na mix-and-match; System operacyjny i serwer na tym samym wykresie; różnorodne elementy przestawne. Oczywiście nie ma ograniczenia liczby macierzy statystyk, a tym samym wykresów. (Używane za uprzejmą zgodą klienta.)

    • Czytelnicy niezaznajomieni ze standardem modelowania relacyjnych baz danych mogą uznać notację IDEF1X za przydatną.

Jeszcze jedna rzecz

Wreszcie, SQL jest standardem IEC / ISO / ANSI. Freeware w rzeczywistości nie jest SQL; użycie wyrażenia SQL jest niezgodne z prawem, jeśli nie zapewniają standardu. Mogą zapewniać „dodatki”, ale nie mają podstaw.

PerformanceDBA
źródło
1
@PerformanceDBA czy użyłbyś sugerowanego schematu do konfiguracji, która musi obsługiwać ~ 3 miliony pomiarów z częstotliwością 1 minuty? Jak zamówiłbyś PK na taki stół? Czy Device, Metric, DateTime nie tworzy fragmentacji i nie wymusza na RDBMS wielu podziałów stron? Zamiast tego umieszczenie DateTime na pierwszym miejscu zmniejszyłoby fragmentację (zakładam, że czas wstawia wstawki), ale pogorszy odczyt.
marcob
1
@Buchi. Używam Sybase ASE. Ale to nie jest problem z platformą (jasne, wysokie platformy zapewniają wydajność, która jest o rząd wielkości lepsza niż dolny koniec; trzy rzędy wielkości lepsza niż Oracle, ale nie o to chodzi), montaż wykresu z tabeli „ działa „na dowolnej platformie. Użyj odpowiedniego narzędzia do pracy. RDBMS jest narzędziem bazodanowym, a nie narzędziem graficznym. gnuplot, Apple Numbers (lub jeśli lubisz płacić dziesięć razy więcej, za połowę MS Excel) to narzędzia do tworzenia wykresów, a nie narzędzia do baz danych. W dzisiejszych czasach używamy warstw narzędzi, aby uzyskać wynik, monolit to dinozaur.
PerformanceDBA
1
@marcob. Twoje pytanie jest dobre, ale nie można na nie odpowiedzieć poprawnie w komentarzach. Jeśli otworzysz nowe pytanie i wyślesz do mnie wiadomość e-mail (przejdź do profilu), odpowiem na nie. Szybka odpowiedź tutaj. (1) ~ 3 miliony wskaźników. Świetnie, im bardziej wesoło, pięknie rozprowadza punkty INSERT, twój gwarantowałby konflikty na ostatniej stronie. Serwer jest wielowątkowy, tak? Podziel stół na partycje. Użyj FILLFACTOR i pozostaw miejsce na wstawki, a tym samym unikaj podziału strony. (2) ~ 3 Mill wskazuje, że Metryki nie są znormalizowane, jeśli to naprawisz, będzie jeszcze szybciej.
PerformanceDBA
1
@marcob. (3) Używam podanego indeksu właśnie do rozłożenia płytek pod obciążeniem, co zapewnia brak konfliktów. (4) Dlatego moja metoda uzyskuje obie wstawki bez konfliktów i wysoką wydajność na SELECT.
PerformanceDBA
2
@Loic. Dlaczego, u licha, każdy, kto ma inwestycję (dane; kod) w platformę SQL, która z łatwością obsługuje dane szeregów czasowych i ma bardzo wysoką wydajność (jak wyszczególniono w odpowiedzi), migruje do TSDB bez SQL; nieznana prędkość dla czegokolwiek poza danymi szeregów czasowych? Dlaczego ktokolwiek, kto ma wymaganie przekraczające tylko dane szeregów czasowych, nie korzysta z platformy SQL? Umysł drży. TSDB jest szybszy niż relacyjny tylko w smutnym przypadku, gdy dane są przechowywane w db, ale nie są znormalizowane relacyjnie. Na przykład. gdy Idużywane są kolumny, jako „klucze”. Zgodnie z zaleceniami „teoretyków”.
PerformanceDBA
21

Znalazłem bardzo interesujące powyższe odpowiedzi. Próbuję dodać tutaj kilka dodatkowych uwag.

1) Starzenie się danych

Zarządzanie szeregami czasowymi zwykle musi tworzyć polityki dotyczące starzenia się. Typowy scenariusz (np. Procesor serwera monitorującego) wymaga przechowywania:

  • 1-sekundowe surowe próbki przez krótki okres (np. Przez 24 godziny)

  • 5-minutowe szczegółowe próbki zbiorcze przez średni okres (np. 1 tydzień)

  • 1-godzinny szczegół (np. Do 1 roku)

Chociaż modele relacyjne umożliwiają to na pewno (moja firma wdrożyła masowe scentralizowane bazy danych dla niektórych dużych klientów z dziesiątkami tysięcy serii danych) w celu odpowiedniego zarządzania nimi, nowa rasa magazynów danych dodaje ciekawe funkcje, które można zbadać, takie jak:

  • automatyczne czyszczenie danych (patrz polecenie Redis EXPIRE)

  • agregacje wielowymiarowe (np. zadania zmniejszania mapy a-la-Splunk)

2) Kolekcja w czasie rzeczywistym

Co ważniejsze, niektóre nierelacyjne magazyny danych są z natury rozproszone i pozwalają na znacznie bardziej wydajne zbieranie danych w czasie rzeczywistym (lub prawie w czasie rzeczywistym), co może stanowić problem z RDBMS z powodu tworzenia hotspotów (zarządzanie indeksowaniem podczas wstawiania w pojedynczy stół). Ten problem w przestrzeni RDBMS zazwyczaj rozwiązuje się, powracając do procedur importowania wsadowego (w przeszłości zarządzaliśmy w ten sposób), podczas gdy technologiom no-sql udało się masowo gromadzić i agregować w czasie rzeczywistym (patrz na przykład Splunk, wspomniany w poprzednich odpowiedziach) .

Paolo Bozzola
źródło
7

Twoja tabela zawiera dane w jednej tabeli. Tak więc relacja kontra relacja nie jest pytaniem. Zasadniczo musisz odczytać wiele danych sekwencyjnych. Teraz, jeśli masz wystarczającą ilość pamięci RAM do przechowywania danych wartych lat, nic nie przypomina korzystania z Redis / MongoDB itp.

Przeważnie bazy danych NoSQL przechowują dane w tej samej lokalizacji na dysku oraz w formie skompresowanej, aby uniknąć dostępu do wielu dysków.

NoSQL robi to samo, co tworzenie indeksu na identyfikator urządzenia i identyfikator metryki, ale na swój własny sposób. Z bazą danych, nawet jeśli to zrobisz, indeks i dane mogą znajdować się w różnych miejscach i byłoby dużo dyskowych operacji we / wy.

Narzędzia takie jak Splunk używają backendów NoSQL do przechowywania danych szeregów czasowych, a następnie używają map redukuj do tworzenia agregatów (co może być tym, czego później chcesz). Moim zdaniem użycie NoSQL jest opcją, ponieważ ludzie już go wypróbowali dla podobnych przypadków użycia. Ale milion wierszy sprowadzi bazę danych do indeksowania (może nie, z przyzwoitym sprzętem i odpowiednimi konfiguracjami).

Ravindra
źródło
1
Czy możesz wyjaśnić, w jaki sposób tabela jest „zdenormalizowana”? Marcus ma błąd w tabeli, ale nie jest to błąd normalizacji.
PerformanceDBA
poprawię się, tabele są znormalizowane w tradycyjnym sensie. Miałem na myśli zdenormalizowany w tym sensie, że przypadek użycia zawiera wszystkie dane w jednej tabeli.
Ravindra
4

Utwórz plik, nadaj mu nazwę 1_2.data. pomysł na zużyty? co dostałeś:

  • Oszczędzasz do 50% miejsca, ponieważ nie musisz powtarzać wartości fk_to_device i fk_to_metric dla każdego punktu danych.
  • Oszczędzasz jeszcze więcej miejsca, ponieważ nie potrzebujesz żadnych indeksów.
  • Zapisz pary (datownik, wartość_metryka) do pliku, dołączając dane, aby otrzymać zamówienie według datownika za darmo. (zakładając, że Twoje źródła nie wysyłają danych poza kolejnością dla urządzenia)

=> Zapytania według znacznika czasu działają niezwykle szybko, ponieważ można użyć wyszukiwania binarnego, aby znaleźć odpowiednie miejsce w pliku do odczytu.

jeśli ci się podoba, jeszcze bardziej zoptymalizowany, zacznij myśleć o takim dzieleniu plików;

  • 1_2_ stycznia2014.data
  • 1_2_ lutego 2014 r. Dane
  • 1_2_march2014.data

lub użyj kdb + ze strony http://kx.com, ponieważ robią to wszystko za Ciebie :) orientacja na kolumnie może ci pomóc.

Pojawia się oparte na chmurze rozwiązanie zorientowane na kolumny, więc możesz rzucić okiem na: http://timeseries.guru

hellomichibye
źródło
Napisałem post na blogu na ten temat. z tłumaczeniem google może okazać się pomocne: blog.michaelwittig.info/die-spaltenorientierte-datenbank-kdb
hellomichibye
3

Jeśli patrzysz na pakiety GPL, RRDTool jest dobrym rozwiązaniem. Jest to dobre narzędzie do przechowywania, wyodrębniania i tworzenia wykresów danych szeregów czasowych. Twój przypadek użycia wygląda dokładnie jak dane szeregów czasowych.

sunil
źródło
2

Jest to problem, który musieliśmy rozwiązać w ApiAxle. Mamy pisał się na blogu o tym, jak zrobiliśmy to za pomocą Redis. Nie było tam bardzo długo, ale okazało się skuteczne.

Użyłem również RRDTool do innego projektu, który był doskonały.

Phil Jackson
źródło
2

Myślę, że odpowiedź na tego rodzaju pytania powinna dotyczyć głównie sposobu wykorzystania pamięci przez bazę danych. Niektóre serwery baz danych używają pamięci RAM i dysku, niektóre używają tylko pamięci RAM (opcjonalnie dysku w celu zachowania trwałości) itp. Najpopularniejsze rozwiązania bazy danych SQL wykorzystują pamięć + pamięć dyskową i zapisują dane w układzie wierszowym (każdy wstawiony plik raw jest zapisywany w tym samym lokalizacja fizyczna). W sklepach z timeseries w większości przypadków obciążenie jest podobne: Relatywnie niski przedział ogromnej ilości wstawek, podczas gdy odczyty są oparte na kolumnach (w większości przypadków chcesz odczytać zakres danych z określonej kolumny, reprezentujący metrykę)

Znalazłem Kolumnowe bazy danych (google, znajdziesz MonetDB, InfoBright, parAccel itp.) Wykonują wspaniałą pracę dla szeregów czasowych.

Jeśli chodzi o twoje pytanie, które osobiście uważam za nieco nieważne (ponieważ wszystkie dyskusje z użyciem błędu NoSQL - IMO): możesz użyć serwera bazy danych, który potrafi mówić SQL z jednej strony, dzięki czemu twoje życie jest bardzo łatwe, ponieważ wszyscy znają SQL dla wielu lata, a ten język był ciągle doskonalony pod kątem zapytań o dane; ale nadal wykorzystujesz pamięć RAM, pamięć podręczną procesora i dysk w sposób zorientowany na kolumny, dzięki czemu Twoje rozwiązanie najlepiej pasuje do szeregów czasowych

Shay
źródło
2

5 milionów wierszy to nic dla dzisiejszych ulewnych danych. Spodziewaj się, że dane znajdą się w TB lub PB za kilka miesięcy. W tym momencie RDBMS nie skaluje się do zadania i potrzebujemy liniowej skalowalności baz danych NoSql. Wydajność zostanie osiągnięta dla partycji kolumnowej używanej do przechowywania danych, dodając więcej kolumn i mniej koncepcji wierszy w celu zwiększenia wydajności. Wykorzystaj pracę Open TSDB wykonaną na HBASE lub MapR_DB itp.

Juan Asenjo
źródło
„RDBMS nie skaluje się do zadania” - dlaczego by nie miał? code.facebook.com/posts/190251048047090/…
Zathrus Writer
1

Regularnie spotykam się z podobnymi wymaganiami i ostatnio zacząłem używać Zabbix do gromadzenia i przechowywania tego rodzaju danych. Zabbix ma własną funkcję graficzną, ale łatwo jest wydobyć dane z bazy danych Zabbix i przetworzyć je w dowolny sposób. Jeśli jeszcze nie sprawdziłeś Zabbix, być może warto poświęcić temu czas.

monch1962
źródło
Tak, Zabbix jest fajny i już integruje się z monitorowaniem SNMP. Zabbix może używać MySQL lub PostgreSQL i działa mniej więcej od razu na Ubuntu.
Dirk Eddelbuettel
Dzięki, mam wiedzę na temat Zabbix i wielu innych narzędzi SNMP. Jednak rozwijam ten projekt jako proces edukacyjny w omawianym tutaj temacie i wielu innych aspektach. Dobra uwaga!
Marcus Whybrow
0

Powinieneś zajrzeć do bazy danych szeregów czasowych . Został stworzony w tym celu.

Baza danych szeregów czasowych (TSDB) to system oprogramowania zoptymalizowany do obsługi danych szeregów czasowych, tablic liczb indeksowanych według czasu (przedział czasu lub przedział czasu).

Popularny przykład bazy danych szeregów czasowych InfluxDB

Adam
źródło
dodaj teraz
timescaledb