
Se si utilizza un database per le serie temporali (timeseries db, ) come principale archiviazione per un sito di statistiche, invece di risolvere il problema si possono ricevere molte complicazioni. Sto lavorando a un progetto che utilizza un tale database, e a volte InfluxDB, di cui parleremo, ha riservato sorprese inaspettate.
Avvertenza: i problemi citati si riferiscono alla versione InfluxDB 1.7.4.
Perché serie temporali?
Il progetto consiste nel monitorare le transazioni in vari blockchain e visualizzare statistiche. In particolare, osserviamo l'emissione e la cancellazione di stablecoin (). Sulla base di queste transazioni, è necessario costruire grafici e mostrare tabelle riassuntive.
Analizzando le transazioni, è emersa l'idea di utilizzare il database per le serie temporali InfluxDB come principale archiviazione. Le transazioni rappresentano punti nel tempo e si adattano bene al modello delle serie temporali.
Inoltre, le funzioni di aggregazione sembravano molto convenienti — ideali per l'elaborazione di grafici su un lungo periodo. L'utente ha bisogno di un grafico per l'anno, ma nel database ci sono set di dati con un time frame di cinque minuti. Inviare tutte e centomila informazioni sarebbe privo di senso — oltre a richiedere troppo tempo per l'elaborazione, non ci sarebbero nemmeno abbastanza spazio per visualizzarle. Si potrebbe scrivere una propria implementazione per aumentare il time frame o utilizzare le funzioni di aggregazione incorporate in Influx. Con esse, è possibile raggruppare i dati per giorno e inviare solo i 365 punti necessari.
Era un po' disorientante il fatto che di solito questi database sono utilizzati per raccogliere metriche. Monitoraggio dei server, dispositivi IoT, tutto ciò da cui "fluiscono" milioni di punti tipo: [ — ]. Ma se il database lavora bene con un grande flusso di dati, perché un volume ridotto dovrebbe causare problemi? Con questo pensiero, abbiamo deciso di utilizzare InfluxDB.
Cosa c'è di utile in InfluxDB
Oltre alle funzioni di aggregazione menzionate, c'è un'altra cosa straordinaria — continuous queries (). Questo è un pianificatore integrato nel database che può elaborare i dati secondo un programma. Ad esempio, è possibile raggruppare tutte le registrazioni del giorno ogni 24 ore, calcolare la media e registrare un nuovo punto in un'altra tabella senza dover scrivere implementazioni proprie.
C'è anche una retention policies () — configurazione per l'eliminazione dei dati dopo un certo periodo. Utile, per esempio, quando è necessario conservare il carico della CPU per una settimana con misurazioni ogni secondo, mentre su un periodo di alcuni mesi tale precisione non è necessaria. In questo caso, puoi procedere così:
- creare una continuous query per aggregare i dati in un'altra tabella;
- per la prima tabella, definire una politica di eliminazione delle metriche che superano quella settimana.
E Influx si occuperà autonomamente di ridurre la dimensione dei dati e di eliminare ciò che non è necessario.
Sui dati memorizzati
Non ci sono molti dati: circa 70.000 transazioni e un altro milione di punti con informazioni di mercato. L'aggiunta di nuove registrazioni non supera le 3000 punti al giorno. Ci sono anche metriche sul sito, ma i dati sono pochi e secondo la retention policy non vengono conservati oltre un mese.
Problemi
Durante lo sviluppo e i successivi test del servizio, sono emersi problemi sempre più critici nell'uso di InfluxDB.
1. Eliminazione dei dati
Esiste una serie di dati con transazioni:
SELECT time, amount, block, symbol FROM transactions WHERE symbol='USDT'Risultato:

Invio il comando per eliminare i dati:
DELETE FROM transactions WHERE symbol='USDT'Poi faccio una richiesta per ottenere dati già eliminati. E Influx, invece di un risposta vuota, restituisce parte dei dati che avrebbero dovuto essere eliminati.
Provo a eliminare completamente la tabella:
DROP MEASUREMENT transactionsControllo l’eliminazione della tabella:
SHOW MEASUREMENTSNon vedo la tabella nell'elenco, ma una nuova richiesta di dati continua a restituire lo stesso insieme di transazioni.
Questo problema si è presentato solo una volta, poiché il caso di eliminazione è un evento isolato. Ma questo comportamento del database chiaramente non rientra nei limiti di un funzionamento "corretto". Più tardi ho trovato su github un problema aperto di quasi un anno fa su questo argomento.
Di conseguenza, è stato utile eliminare e successivamente ripristinare l'intero database.
2. Numeri in virgola mobile
I calcoli matematici utilizzando le funzioni incorporate in InfluxDB danno errori di precisione. Non che sia qualcosa di insolito, ma è fastidioso.
Nel mio caso, i dati hanno una componente finanziaria e vorrei elaborarla con alta precisione. A causa di ciò, ho in programma di rinunciare alle continuous queries.
3. Le continuous queries non possono essere adattate a diversi fusi orari
Nel servizio c'è una tabella con statistiche giornaliere sulle transazioni. Per ogni giorno, è necessario raggruppare tutte le transazioni di quel giorno. Ma il giorno di ogni utente inizierà a orari diversi, e quindi anche il set di transazioni sarà diverso. Per UTC ci sono di fuso orario, per le quali è necessario aggregare i dati.
In InfluxDB, raggruppando per tempo, si può inoltre indicare uno spostamento, ad esempio per l'ora di Mosca (UTC+3):
SELECT MEAN("supply") FROM transactions GROUP BY symbol, time(1d, 3h) fill(previous)Tuttavia, il risultato della query sarà errato. Per qualche motivo, i dati raggruppati per giorni inizieranno addirittura nel 1677 (InfluxDB supporta ufficialmente un intervallo temporale a partire da quest'anno):

Per aggirare questo problema, il servizio è stato temporaneamente spostato su UTC+0.
4. Prestazioni
In rete ci sono molti benchmark che confrontano InfluxDB e altri database. All'inizio sembravano materiali di marketing, ma ora ritengo che ci sia una certa verità in essi.
Condividerò il mio caso.
Il servizio fornisce un metodo API che restituisce le statistiche delle ultime 24 ore. Nelle sue elaborazioni, il metodo interroga il database tre volte con queste query:
SELECT * FROM coins_info WHERE time <= NOW() GROUP BY symbol ORDER BY time DESC LIMIT 1SELECT * FROM dominance_info ORDER BY time DESC LIMIT 1SELECT * FROM transactions WHERE time >= NOW() - 24h ORDER BY time DESCSpiegazione:
- Nella prima query otteniamo gli ultimi punti per ciascuna moneta con i dati di mercato. Otto punti per otto monete nel mio caso.
- La seconda query ottiene un solo punto, il più recente.
- La terza richiede un elenco di transazioni delle ultime 24 ore, che possono essere alcune centinaia.
Preciso che InfluxDB costruisce automaticamente un indice sui tag e sul tempo, che accelera le query. Nella prima query symbol è un tag.
Ho condotto un test di stress per questo metodo API. A 25 RPS, il server mostrava un carico completo di sei CPU:

Inoltre, il processo NodeJs non comportava alcun carico.
La velocità di esecuzione è degradata già a 7-10 RPS: se un cliente poteva ricevere una risposta in 200 ms, 10 clienti dovevano aspettare un secondo. 25 RPS è il limite, oltre il quale la stabilità ne risente, e i clienti ricevevano errori 500.
Con tali prestazioni, utilizzare Influx nel nostro progetto è impossibile. Inoltre, in un progetto in cui il monitoraggio deve essere mostrato a molti clienti, possono sorgere problemi simili e il server delle metriche sarà sovraccarico.
Risultato
La più grande lezione appresa da quest'esperienza è che non si può introdurre nel progetto una tecnologia sconosciuta senza un'adeguata analisi. Una semplice verifica dei ticket aperti su GitHub avrebbe potuto fornire informazioni utili per non adottare InfluxDB come principale sistema di archiviazione dati.
InfluxDB sembrava adatta alle esigenze del mio progetto, ma come ha dimostrato la pratica, questo database non soddisfa le esigenze e presenta molti problemi.
Nel repository del progetto è già disponibile la versione 2.0.0-beta, e ci si augura che nella seconda versione ci saranno significativi miglioramenti. Nel frattempo, andrò a studiare la documentazione di TimescaleDB.
Fonte: habr.com
