Gniew, targowanie się i depresja podczas pracy z InfluxDB

Gniew, targowanie się i depresja podczas pracy z InfluxDB

Jeżeli używasz bazy danych szeregów czasowych (timeseries db, wiki) jako głównego magazynu dla strony ze statystykami, to zamiast rozwiązania problemu możesz natknąć się na wiele bólu głowy. Pracuję nad projektem, w którym wykorzystuje się taką bazę, a czasami InfluxDB, o której za chwilę mowa, zaskakuje zupełnie nieoczekiwanymi niespodziankami.

Zrzeczenie się odpowiedzialności: przedstawione problemy dotyczą wersji InfluxDB 1.7.4.

Dlaczego szereg czasowy?

Projekt polega na śledzeniu transakcji w różnych blockchainach i wyświetlaniu statystyk. Konkretnie - przyglądamy się emisji i spalaniu stablecoinów (wiki). Na podstawie tych transakcji należy budować wykresy i przedstawiać tabele podsumowujące.

Podczas analizy transakcji pojawił się pomysł: użyć bazy danych szeregów czasowych InfluxDB jako głównego magazynu. Transakcje są punktami w czasie i dobrze wpasowują się w model szeregów czasowych.

Dodatkowo funkcje agregacji wyglądały bardzo wygodnie - doskonale nadają się do przetwarzania wykresów z dużym okresem. Użytkownik potrzebuje wykresu za rok, a w bazie znajduje się zbiór danych z interwałem pięciu minut. Wysyłanie wszystkich stu tysięcy punktów jest bez sensu - oprócz długiego przetwarzania, nie zmieszczą się też na ekranie. Można napisać własną implementację zwiększenia interwału lub skorzystać z wbudowanych w Influx funkcji agregacji. Dzięki nim można pogrupować dane według dni i wysłać potrzebne 365 punktów.

Nieco niepokoiło to, że zazwyczaj takie bazy używa się w celu zbierania metryk. Monitorowanie serwerów, urządzenia IoT, wszystko, z czego „spływają” miliony punktów w postaci: [<czas> - <wartość metryki>]. Ale jeśli baza dobrze działa z dużym przepływem danych, to dlaczego mały wolumen miałby stwarzać problemy? Z tym przemyśleniem wzięliśmy InfluxDB do pracy.

Co jeszcze jest wygodne w InfluxDB

Oprócz wspomnianych funkcji agregacji istnieje jeszcze jedna wspaniała rzecz - zapytania ciągłe (doc). To wbudowany w bazie planer, który może przetwarzać dane według harmonogramu. Na przykład, można co 24 godziny grupować wszystkie rekordy za dzień, obliczać średnią i zapisywać jeden nowy punkt w innej tabeli bez pisania własnych rozwiązań.

Jest także polityki retencji (doc) — ustawienie usuwania danych po pewnym okresie. Przydatne, gdy na przykład trzeba przechować obciążenie CPU za tydzień z pomiarami co sekundę, a na odległości kilku miesięcy taka precyzja nie jest konieczna. W takiej sytuacji można zrobić tak:

  1. utworzyć zapytanie ciągłe do agregacji danych w innej tabeli;
  2. dla pierwszej tabeli określić politykę usuwania metryk, które są starsze niż ten tydzień.

I Influx samodzielnie będzie zmniejszać rozmiar danych i usuwać zbędne.

O przechowywanych danych

Danych nie ma wiele: około 70 tysięcy transakcji oraz kolejny milion punktów z informacjami rynkowymi. Dodawanie nowych rekordów — nie więcej niż 3000 punktów dziennie. Są też metryki dotyczące strony, ale tam danych jest mało i według polityki retencji przechowują się one nie dłużej niż miesiąc.

Problemy

Podczas rozwoju i późniejszych testów usługi pojawiały się coraz bardziej krytyczne problemy przy eksploatacji InfluxDB.

1. Usuwanie danych

Jest seria danych z transakcjami:

SELECT time, amount, block, symbol FROM transactions WHERE symbol='USDT'

Wynik:

Gniew, targowanie się i depresja podczas pracy z InfluxDB

Wysyłam komendę do usunięcia danych:

DELETE FROM transactions WHERE symbol='USDT'

Następnie wykonuję zapytanie o już usunięte dane. I Influx zamiast pustej odpowiedzi zwraca część danych, które powinny być usunięte.

Próbuję usunąć tabelę całkowicie:

DROP MEASUREMENT transactions

Sprawdzam usunięcie tabeli:

SHOW MEASUREMENTS

Nie widzę tabeli na liście, ale nowe zapytanie danych nadal zwraca ten sam zestaw transakcji.

Problem pojawił się u mnie tylko raz, ponieważ przypadek usunięcia — to jednostkowy przypadek. Ale takie zachowanie bazy ewidentnie nie wpisuje się w ramy “poprawnej” pracy. Później na githubie znalazłem otwarty ticket prawie roczny na ten temat.

W rezultacie, pomogło usunięcie i późniejsze przywrócenie całej bazy.

2. Liczby zmiennoprzecinkowe

Obliczenia matematyczne przy użyciu wbudowanych funkcji InfluxDB dają błędy dokładności. Nie jest to nic niezwykłego, ale jest nieprzyjemne.

W moim przypadku dane mają aspekt finansowy i chciałbym je przetwarzać z wysoką dokładnością. Z powodu tego planuję zrezygnować z zapytań ciągłych.

3. Zapytania ciągłe nie mogą być dostosowywane do różnych stref czasowych

Na serwisie znajduje się tabela dziennej statystyki transakcji. Dla każdego dnia należy pogrupować wszystkie transakcje z tych 24 godzin. Jednak dzień dla każdego użytkownika zaczyna się o różnym czasie, co oznacza, że zestaw transakcji również będzie inny. Według UTC jest 37 wariantów przesunięcia, dla których należy agregować dane.

W InfluxDB podczas grupowania według czasu można dodatkowo wskazać przesunięcie, na przykład dla czasu moskiewskiego (UTC+3):

SELECT MEAN("supply") FROM transactions GROUP BY symbol, time(1d, 3h) fill(previous)

Jednak wynik zapytania będzie niepoprawny. Z jakiegoś powodu dane pogrupowane według dni będą zaczynały się aż w 1677 roku (InfluxDB oficjalnie wspiera przedział czasowy od tego roku):

Gniew, targowanie się i depresja podczas pracy z InfluxDB

Aby obejść ten problem, tymczasowo przestawiliśmy serwis na UTC+0.

4. Wydajność

W internecie jest wiele benchmarków porównujących InfluxDB i inne bazy danych. Podczas pierwszej lektury wyglądały one na materiały marketingowe, ale teraz uważam, że jest w nich trochę prawdy.

Podzielę się swoim przypadkiem.

Serwis udostępnia metodę API, która zwraca statystyki za ostatnie 24 godziny. Przy obliczeniach metoda wykonuje trzy zapytania do bazy danych:

SELECT * FROM coins_info WHERE time <= NOW() GROUP BY symbol ORDER BY time DESC LIMIT 1

SELECT * FROM dominance_info ORDER BY time DESC LIMIT 1

SELECT * FROM transactions WHERE time >= NOW() - 24h ORDER BY time DESC

Wyjaśnienie:

  1. W pierwszym zapytaniu otrzymujemy ostatnie punkty dla każdej monety z danymi rynkowymi. W moim przypadku osiem punktów dla ośmiu monet.
  2. Drugie zapytanie pobiera jeden najnowszy punkt.
  3. Trzecie zapytanie żąda listy transakcji za ostatnie 24 godziny, może ich być kilka setek.

Uzupełnię, że w InfluxDB indeks automatycznie buduje się według tagów i czasu, co przyspiesza zapytania. W pierwszym zapytaniu symbol — to tag.

Przeprowadziłem test obciążeniowy tego metody API. Przy 25 RPS serwer wykazywał pełne obciążenie sześciu CPU:

Gniew, targowanie się i depresja podczas pracy z InfluxDB

Przy czym proces NodeJS wcale nie obciążał serwera.

Prędkość wykonania zaczęła spadać już przy 7-10 RPS: jeśli jeden klient mógł otrzymać odpowiedź w 200 ms, to 10 klientów musiało czekać po sekundzie. 25 RPS — to granica, przy której stabilność zaczynała cierpieć, klienci otrzymywali błędy 500.

Przy takiej wydajności użycie Influx w naszym projekcie jest niemożliwe. Co więcej: w projekcie, gdzie monitoring musi być pokazany wielu klientom — mogą wystąpić podobne problemy i serwer metryk będzie przeciążony.

Wnioski

Najważniejszym wnioskiem z uzyskanego doświadczenia jest to, że nie można wprowadzać do projektu nieznanej technologii bez odpowiedniej analizy. Proste przeszukanie otwartych zgłoszeń na GitHubie mogło dostarczyć informacji, które pomogłyby zrezygnować z InfluxDB jako głównego magazynu danych.

InfluxDB wydawała się dobrze pasować do zadań mojego projektu, ale jak pokazała praktyka, ta baza danych nie spełnia wymagań i wiele rzeczy nie działa poprawnie.

W repozytorium projektu można już znaleźć wersję 2.0.0-beta, pozostaje mieć nadzieję, że w drugiej wersji pojawią się istotne ulepszenia. A ja tymczasem zajmę się dokumentacją TimescaleDB.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster