InfluxDB v.2

InfluxDB e' un Database Open Source NoSQL ed e' considerato IL Time Series Database (TSDB) per diffusione e completezza.

InfluxDB, prodotto da InfluxData, e' costituito da un solo eseguibile che contiene tutte le funzionalita' per raccogliere, mantenere ed analizzare i dati su serie temporali. Interessa? Se volte saperne di piu'... continuate a leggere!

Il documento si riferisce alla versione 2.0 di InfluxDB rilasciato di recente [NdA 2020-11] e versioni successive ma in realta' i contenuti valgono anche per altre versioni.
Questo documento presenta diversi aspetti di InfluxDB: Introduzione, Installazione, Architettura, Primi passi, Query temporali, Cenni sulle prestazioni, Versioni ed aggiornamenti, ... con un approccio pratico con molti esempi di comandi.

Introduzione

DB Ranking - TSDB I Time Series Database (TSDB) sono una tecnologia emergente di questi ultimi anni spinta dalla grande richiesta di memorizzazione delle informazioni per l'IoT (Internet of Things) [NdA immagine da db-engines.com].
Tra i piu' famosi TSDB e' possibile ricordare: Graphite, Prometheus, KairosDB, TimescaleDB, ... e naturalmente InfluxDB che e' di gran lunga il piu' noto!

InfluxDB e' un database NoSQL ed utilizza concetti differenti rispetto agli altri database, relazionali o non.
I dati vengono raccolti in misure (measurement), ogni evento e' un punto (point) che ha sempre un timestamp. Possono essere raccolte ulteriori informazioni in campi (field) o etichette (tag). I tag sono indicizzati e le ricerche su di loro sono molto piu' efficienti ma sono solo di tipo stringa.

Per fare un parallelo con un DB relazionale le measurement sono tabelle, i point sono righe, il timestamp e' sempre la chiave primaria, i field sono le colonne ed i tag sono le colonne indicizzate. Per interrogare i dati si utilizza l'InfluxQL, un query language di 4 generazione. Naturalmente gli accessi per indice sono molto piu' efficienti mentre una ricerca su un field richiede un FULL SCAN.
Le analogie con i relazionali pero' finiscono qui... Non e' necessario creare le tabelle o definire le colonne: quando vengono introdotti i dati vengono create automaticamente tutte le strutture necessarie. Non esistono join tra misure o altri oggetti ed eventuali correlazioni vanno implementate applicativamente. Non esistono operazioni CRUD almeno nel senso normale: solo l'inserimento di point nelle measurement. Non sono presenti transazioni: ogni punto viene inserito immediatamente, in pratica l'unica operazione atomica e' l'INSERT.

Ulteriori funzionalita' di InfluxDB, fondamentali per le prestazioni, sono le CQ (continuous query) e le RP (retention policy).
Le CQ consentono di aggregare i dati in modo effiente mentre le RP cancellano automaticamente i dati quando non sono piu' necessari [NB in v.2 i task sono l'evoluzione delle CQ].

Con la versione 2 di InfluxDB l'architettura si e' evoluta integrando i diverse componenti in un unico eseguibile senza dipendenze dall'esterno [NdA terribilmente semplice da installare: basta 1 file] programmabile con il linguaggio di interrograzione e scripting Flux. Gia' presente nelle versioni precedenti, nella versione 2 il linguaggio Flux e' ancora piu' potente ed e' disponibile in ogni componente.
Altre novita' della 2.0 sono i bucket che riuniscono il concetto di database e periodo di ritenzione e le organization che sono in pratica gruppi di utenti a cui abilitare le dashboard ed i bucket.

Installazione

L'installazione di InfluxDB v.2 e' semplice...

(cfr. https://docs.influxdata.com/influxdb/v2.0/get-started/) #Docker Image docker run --name influxdb -p 8086:8086 influxdb:2.0.4 # Red Hat/CentOS/Fedora wget https://dl.influxdata.com/influxdb/releases/influxdb2-2.x.x-xxx.rpm sudo yum localinstall influxdb2_2.x.x_xxx.deb.rpm # Ubuntu/Debian wget https://dl.influxdata.com/influxdb/releases/influxdb2-2.x.x-xxx.deb sudo dpkg -i influxdb2_2.x.x_xxx.deb # Mac OS X (NB occorre abilitare l'esecuzione in Open System Preferences, Security & Privacy) https://dl.influxdata.com/influxdb/releases/influxdb2-2.0.4-darwin-amd64.tar.gz tar zxvf influxdb_2.0.0-alpha.17_darwin_amd64.tar.gz # Mac OS X (NB con Homebrew) brew install influxdb

Ora e' necessario avviarlo (demone influxd).
Terminata l'installazione serve una semplice configurazione per impostare l'organizzazione e l'utente amministrativo [NdA in v.1 per default l'autenticazione non e' attiva]:

$ influx setup Welcome to InfluxDB 2.0! Please type your primary username: admin Please type your password: Please type your password again: Please type your primary organization name: my_org Please type your primary bucket name: my_bucket Please type your retention period in hours. Or press ENTER for infinite.: 840

Per vedere la console di InfluxDB basta accedere:

 http://localhost:8086

Ovviamente le versioni possono cambiare con le ultime updates [NdA ad esempio la 2.0.4 e' disponibile su MacOS con Homebrew dalla primavera: 2021-03-21].

Architettura

I componenti della piattaforma TICK tipica di InfluxDB v.1 erano:

  • Telegraf: Time-Series Data Collector
  • InfluxDB: Time-Series Data Storage
  • Chronograf: Time-Series Data Visualization
  • Kapacitor: Time-Series Data Processing

    In realta' il componente piu' importante era appunto InfluxDB mentre gli altri venivano spesso sostituiti da altri prodotti Open Source o realizzati direttamente nelle applicazioni. In pratica nella versione 2 i componenti InfluxDB, Chronograf e Kapacitor sono confluiti in InfluxDB 2.0.
    L'architettura di InfluxDB v.2 prevede un unico binario eseguibile realizzato in Go.

    Altro componente fondamentale della v.2 e' il potente linguaggio Flux che permette di inserire velocemente i dati, analizzarli facilmente e gestirne il monitoraggio.

    InfluxDB utilizza la porta TCP 8086 per la comunicazione client-server con l'InfluxDB HTTP API v.2 [NdA nelle prime versioni 2.x prima dell'uscita in produzione era usata la porta 9999]. Il protocollo utilizzato e' al tempo stesso semplice (basato sull'HTTP) ed efficiente.

    Quando vengono inseriti nuovi point questi vengono immediatamente registrati nei WAL (Write-Ahead-Log) e mantenuti in cache. I WAL sono in pratica dei file di log in cui si procede accodando i dati e sono molto efficienti per le scritture (ma non per le ricerche). Quindi i dati vengono compressi e memorizzati nei file TSM (Time-Structured Merge Tree) che sono invece ottimizzati per le ricerche. Periodicamente i file TSM vengono ricompressi per mantenersi sempre il piu' efficienti possibile.
    Il path tipico dei WAL e' var\lib\influxdb\wal mentre i file .tsm vengono posti nell directory /data.

    A seconda delle RP (retention policy) impostate i dati vengono automaticamente cancellati quando non piu' necessari. Questo mantiene la base dati limitata nelle dimensioni e sempre efficiente.

    Le scelte tecniche nell'implementazione di InfluxDB lo rendono particolarmente veloce nell'ingestion dei dati ed efficiente nelle query temporali.

    Primi passi

    L'inserimento dei dati (point) avviene con il line protocol che e' oggettivamente molto semplice:

    mem,host=host1 used_percent=23.69 1556892726997397000
    cpu,host=host1 usage_user=5.8234,usage_system=4.23874 1556892726997397000
    mem,host=host2 used_percent=41.83 1556892726999397000
    

    Nell'ordine si riconoscono: measurement,tag=valore field=valore timestamp. Se inseriti da linea di comando basta anteporre la clausola INSERT.

    La measurement e' unica. I tag possono essere nessuno o piu' e sono quelli che identificano a chi corrispondono i field indicati. I timestamp sono precisi al nanosecondo.
    InfluxDB identifica in modo univico un point per misura, insieme di tag e per timestamp, non importa se i valori dei field sono inseriti con un solo comando o con piu' comandi: il point e' unico per chiave ed i valori mantenuti sono gli ultimi arrivati nel caso in cui ci siano sovrapposizioni.

    I dati possono essere direttamente trattati con le API in HTTP:

    curl -i -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE mydb" curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load,host=server01,region=us-west value=0.64 1556892756999397000'

    Utilizzare InfluxDB per interrogare i dati basta e' semplice anche con il client...

    $ influx > SHOW DATABASES > USE mydb > SHOW MEASUREMENTS > SHOW TAG KEYS FROM cpu > SHOW FIELD KEYS FROM cpu > HELP ... > INSERT foodships,planet=Saturn type="Apples",quantity=69 > SELECT * FROM "foodships" WHERE "planet" = 'Saturn' > SELECT * FROM "foodships" WHERE "planet" = 'Saturn' AND time > '2015-04-16 12:00:01' > SELECT * FROM "foodships" WHERE time > now() - 1h > SELECT * FROM /.*/ LIMIT 1 > exit

    Come si e' visto il linguaggio InfluxQL e' molto semplice e simile all'SQL anche se contiene diverse funzioni utili per i dati temporali. Per esempio per indicare la scala temporale e' sufficiente una lettera: ns nanoseconds, u microseconds, ms milliseconds, s seconds, m minutes, h hours, d days, w weeks (lo so, avete ragione: due lettere per i nanosecondi ed i microsecondi ;-)

    I comandi di USE e SHOW sono simili a quelli MySQL ma in realta' le anaologie si fermano qui: vediamo l'InfluxQL!

    Query temporali

    Un grande vantaggio di InfluxDB e' quello di estrarre in modo agevole i dati per serie temporali.

    Nel seguito vediamo gli aspetti piu' interessanti di InfluxDB con esempi pratici:

    > SELECT * FROM "foodships" WHERE "planet" <> 'Saturn' AND (sugar < -0.50 OR sugar > 0.95) LIMIT 10 > SELECT count(*) FROM "foodships" GROUP BY "planet" > SELECT count(*) FROM "foodships" GROUP BY time(15m) > SELECT count(*) FROM "foodships" GROUP BY time(12m) ORDER BY time DESC > SELECT "calorie" FROM "h2o_feet" GROUP BY * LIMIT 3 SLIMIT 1
    > SELECT * FROM "foodships" WHERE "planet" = "Saturn" > SELECT * FROM "foodships" WHERE "planet" = Saturn > SELECT * FROM "birthday" WHERE time = '1963-12-19T17:07:00Z' OR time = '2018-12-19T08:15:00Z'

    Le SELECT possono avere condizioni complesse sui field o sui tag. Naturalmente le condizioni sui tag sono piu' efficienti perche' evitano un fullscan per essere verificate.
    E' possibile utilizzare la clausola GROUP BY sui tag oppure su un intervallo temporale. Sono disponibili molteplici funzioni aggregate: COUNT() DISTINCT() INTEGRAL() MEAN() MEDIAN() MODE() SPREAD() STDDEV() SUM() BOTTOM() FIRST() LAST() MAX() MIN() PERCENTILE() SAMPLE() TOP(), matematiche, di analisi statistica (eg. EXPONENTIAL_MOVING_AVERAGE() KAUFMANS_ADAPTIVE_MOVING_AVERAGE() TRIPLE_EXPONENTIAL_DERIVATIVE()), ...
    Possono essere richiesti ordinamenti (ORDER BY) per tag o sul tempo, puo' essere indicato il numero massimo di record restituiti (LIMIT) ed il numero di serie restituite (SLIMIT).

    E' evidente che InfluxQL non e' SQL e ci sono alcune importanti differenze. In rosso sono segnate alcune query che non si comportano come ci si aspetterebbe...
    Perche'? Perche' gli apici sono importanti (e sono diversi per gli oggetti e le stringhe), perche' non si possono mettere in alternativa due periodi temporali, ... e naturalmente perche' non ci sono join!

    Flux vs InfluxQL

    Anche se InfluxQL e' di semplice utilizzo sono presenti una serie di limiti che vengono superati da linguaggio Flux. Il linguaggio Flux era gia' stato introdotto nella versione 1, esteso nella 1.8 ma e' con la v.2 che diventa il linguaggio principale per la gestione dei dati ed e' disponibile su ogni componente della piattaforma.

    Tra le funzionalita' presenti in Flux e non disponibili in InfluxQL ricordiamo: Join, Math tra measurement, ordinamenti per tag, Group by per ogni colonna, operare data source differenti, UNION, HAVING, ...

    from(bucket:"telegraf/autogen") |> range(start:-1h) |> filter(fn:(r) => r._measurement == "cpu" and r.cpu == "cpu-total" ) |> aggregateWindow(every: 1m, fn: mean)

    Ulteriori esempi sono riportati nella documentazione ufficiale.

    Telegraf

    Telegraf e' il componente di data collection dello stack InfluxDB ma e' puo' anche essere utilizzato anche separatamente.

    Un grosso vantaggio di Telegraf e' la sua semplice configurazione che prevede la compilazione di sezioni separate nel file di configurazione.
    Sono disponibili oltre 150 Input Plugin molto completi e costantemente aggiornati.

    Ad esempio compilando la sezione [[inputs.postgresql]] del file /etc/telegraf/telegraf.conf verranno raccolte, con l'intervallo desiderato, le statistiche prestazionali dalle viste di sistema PostgreSQL pg_stat_database, pg_stat_bgwriter ed inserite in InfluxDB nella metrica "telegraf"."autogen"."postgresql". Ulteriori statistiche PostgreSQL possono essere raccolte con il plugin [[inputs.postgresql_extensible]]. Si tratta solo di un esempio... le statistiche raccolte per MySQL sono ancora piu' dettagliate!

    Telegraf nei plugin di output parla in modo nativo con il line protocol ed inserisce direttamente i dati in InfluxDB.
    I dati raccolti con gli input plugin vengono inviati sugli output plugin configurati. Tra questi il piu' semplice e' [[outputs.influxdb]] perche' necessita solo dell'URL di InfluxDB su cui inserire i dati. I dati vengono inviati con il line protocol che Telegraf usa in modo nativo.
    Naturalmente con [[outputs.influxdb_v2]] vanno indicati anche l'organization ed il bucket come previsto nella v.2.

    Data la semplicita' di configurazione telegraf e' molto utilizzato anche con output plugin differenti da InfluxDB.

    Cenni sulle prestazioni

    Una volta installato InfluxDB puo' essere utilizzato immediatamente. Ma perche' le prestazioni siano ottimali e' opportuno utilizzare delle best pratices.

    InfluxDB e' uno schemaless database. Si possono aggiungere nuove measurement, tag, and field in qualsiasi momento. L'unico limite e' che non possono essere variati i data type (eg. su un field utilizzato inizialmente come intero non e' possibile inserire una stringa).
    Questo pero' non vuol dire che non sia opportuno progettare la base dati raggruppando o meno i campi nelle stesse misure e scegliendo opportunamente i tag di ricerca.

    Oltre ad un corretto disegno della base dati, sono molto importanti le politiche di retention che definiscono la durata temporale dei dati.

    Altra funzionalita' importante per le prestazioni e' la possibilita' di creare CONTINUOUS QUERY, in pratica viste precalcolate mantenute aggiornate in modo continuo.
    Vediamo qualche semplice esempio:

    -- CREATE RETENTION POLICY retention_policy_name ON database_name DURATION duration REPLICATION n [SHARD DURATION duration] [DEFAULT]
    
    > CREATE RETENTION POLICY "h4" ON "iot_db" DURATION 4h REPLICATION 1 DEFAULT
    > CREATE RETENTION POLICY "y1" ON "iot_db" DURATION 52w REPLICATION 1
    > CREATE CONTINUOUS QUERY "cq_1h" ON "iot_db" BEGIN
      SELECT mean("temp") AS "mean_temperature", sum("bytes") AS "sum_bytes"
      INTO "a_year"."data_h1"
      FROM "raw_data"
      GROUP BY time(60m)
    END
    

    Cenni sull'amministrazione

    Una volta installato InfluxDB e' possibile utilizzarlo immediatamente!

    Tuttavia per un'installazione di produzione e' consigliata un'adeguata configurazione anche se molto semplice.
    La configurazione si effettua nel file /etc/influxdb/influxdb.conf che e' diviso in sezioni.

    Per default InfluxDB v.1 non utilizza autenticazione. E' possibile configurarla con:

    [http]  
    enabled = true  
    bind-address = ":8086" 
    auth-enabled = true  
    

    Le utenze vengono quindi definite in modo simile a quello usato nei DB relazionali:

    $ influx Connected to http://localhost:8086 version 2.0 > CREATE DATABASE iot_db > CREATE USER admin WITH PASSWORD 'xxx' WITH ALL PRIVILEGES > CREATE USER iot_own WITH PASSWORD 'xxx' > CREATE USER grafana WITH PASSWORD 'xxx' > GRANT ALL ON iot_db TO iot_own > GRANT READ ON iot_db TO grafana > EXIT

    Nella versione 1.x erano presenti due tipi di utenti (admin ed utenti normali) e sugli utenti normali venivano definiti semplicemente gli accessi in READ e WRITE (ALL entrambe) per i database. Tutto qui!

    Dalla versione 2 la configurazione e' molto piu' flessibile, comprende anche l'accesso ad altri componenti (eg. dashboard) e puo' essere definita in modo gerarchico per organizzazione.

    Versioni ed upgrade

    Mantenersi aggiornati con le versioni e' sempre importante [NdE: serve a rimanere giovani e tutto e' piu' veloce :-] ... naturalmente questo vale anche per InfluxDB!
    La versione piu' recente di InfluxDB e' la 2.0 [NdA 2020-11] che ha modifica in modo significativo l'architettura presentanto tutti i componenti dello stack TICK in un unico eseguibile ed introducento un nuovo ampio insieme di funzionalita' (eg. API v2, security, ...).

    Le versioni di InfluxDB sono disponibili in linea su Git. Nel documento Your Server Stinks sono mantenute apposite sezioni aggiornate anche per InfluxDB.

    (Sources: Official site Github )

    Version
    Status
    Features
    Last release
    Date (from)
    Date (last)
    Notes
    2 Production Whole TICK stack in a component, FLUX for everything. 2.0.42020-112021-02
    1 Production (1.7 2018-11): Flux language support, Time Series Index (TSI), performance improvements
    (1.8 2020-07): InfluxDB 2.0 API forward compatibility, Flux 0.65
    1.8.42016-112021-02
    0 EOL High performance datastore for time series data. Single binary written in Go. Simple HTTP(S) APIs. Plugins support for data ingestion protocols: Graphite, collectd, and OpenTSDB. 0.132013-102016-05

    Gli upgrade sono molto semplici: basta spegnere il servizio, aggiornare il software e riavviare. Un poco piu' impegnativi possono essere i cambi di versione... ma per il passaggio alla 2.0 e' stato introdotto nella 1.8 la compatibilita' delle API.

    Varie ed eventuali

    InfluxDB e' supportato da moltissimi strumenti di interrogazione ed ha un ampio ecosistema. Tra i molti anche Grafana fin dalle prime versioni: InfluxDB query in Grafana

    La versione community di InfluxDB opera su un server singolo mentre InfluxDB Enterprise puo' essere installata in cluster. E' anche disponibile il servizio InfluxDB Cloud AWS gestito da InfluxData (cfr. Sito ufficiale).


    Titolo: InfluxDB v.2
    Livello: Medio (2/5)
    Data: 1 Aprile 2019
    Versione: 1.0.1 - 14 Febbraio 2021 ❤️
    Autore: mail [AT] meo.bogliolo.name