InfluxDB

Siehe auch

Verwandte Artikel
Offizielle Dokumentation
Linuxfabrik

Die Time-Series-Datenbank (Zeitreihendatenbank) InfluxDB speichert mit Zeitstempel versehene Messwerte und ist auf hohe Schreibraten sowie Abfragen über Zeiträume optimiert. Sie hört per HTTP API auf Port 8086. Es gibt eine Open-Source- (OSS) und eine Enterprise-Edition; letztere bietet zusätzlich einen HA-Modus, die Verwaltung lokaler Benutzer, Anbindung an LDAP oder OAuth sowie Scale-out-Features.

Eine verteilte InfluxDB mit synchronisierten Daten lässt sich auch mit der OSS-Variante erreichen, indem Telegraf die gesammelten Werte in mehrere InfluxDB-Instanzen schreibt. Schreibanfragen gehen dann allerdings an Telegraf statt an InfluxDB.

Begriffe
  • Bucket: Datenbank bzw. Named Location mit einer Retention Policy

  • Field: nicht-indizierte Spalte einer Tabelle

  • Measurement: entspricht einer Tabelle in einer SQL-Datenbank; bei Icinga erhält jedes Plugin sein eigenes Measurement, z.B. cmd-check-swap

  • Series: Kombination aus Retention Policy, Measurement und Tag Set

  • Tag: indizierte Spalte einer Tabelle; Tag Key ist der Spaltenname, Tag Value der Inhalt

  • Tag Set: Menge von Tag-Key/Tag-Value-Paaren, z.B. hostname=myhost,service=Swap

Installation und Konfiguration

cat > /etc/yum.repos.d/influxdb.repo << 'EOF'
[influxdb]
name = InfluxDB Repository - RHEL $releasever
baseurl = https://repos.influxdata.com/stable/$basearch/main
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdata-archive.key
EOF
dnf -y install influxdb
/etc/influxdb/influxdb.conf
# Once every 24 hours InfluxDB will report usage data to usage.influxdata.com
reporting-disabled = true
systemctl enable --now influxdb

Backup und Restore

Benutzer und deren Rechte können nicht wiederhergestellt werden. Siehe https://github.com/influxdata/influxdb/issues/9685.

Backup:

# full dump
influxd backup -portable /path/to/influxdb-dump
influxd backup
    [ -database <db_name> ]
    [ -portable ]
    [ -host <host:port> ]
    [ -retention <rp_name> ] | [ -shard <shard_ID> -retention <rp_name> ]
    [ -start <timestamp> [ -end <timestamp> ] | -since <timestamp> ]
    <path-to-backup>

Timestamps sind im RFC3339-Format anzugeben, also zum Beispiel als 2015-12-24T08:12:23Z.

Restore:

Vor dem Restore müssen existierende Datenbanken per influx -execute 'DROP DATABASE mydb' gelöscht werden. Nach dem Restore müssen User und User-Rechte von Hand nachgezogen werden.

influxd restore -portable /path/to/influxdb-dump

# restore a specific database with a new name
influxd restore -db old_db -newdb new_db -portable /path/to/influxdb-dump

# but only one retention policy
influxd restore -db old_db -newdb new_db -rp old_rp -newrp new_rp -portable /mnt/influxdb-dump

Query

InfluxDB hat über die Major-Versionen mehrere Abfragesprachen durchlaufen:

  • InfluxDB 1.x: InfluxQL (SQL-ähnlich) ist die primäre Sprache; Flux kam mit 1.8 als funktionale Alternative dazu.

  • InfluxDB 2.x: Flux ist die primäre Sprache, InfluxQL läuft über eine Kompatibilitäts-API weiter.

  • InfluxDB 3.x: SQL ist primär, InfluxQL bleibt nativ unterstützt. Flux wird hier nicht mehr unterstützt (nur noch Maintenance-Modus); bestehende Flux-Abfragen müssen nach SQL oder InfluxQL migriert werden.

InfluxQL und Flux sind nicht gleichwertig. Flux ist mächtiger: Joins, Berechnungen über mehrere Measurements hinweg, Abfragen externer Quellen (CSV, PostgreSQL, MySQL, …), Pivot und erweiterte Sortierung gehen nur mit Flux. InfluxQL kennt keine Joins, sortiert nur nach Zeit und fragt ausschliesslich InfluxDB ab. Ab InfluxDB 3.x übernimmt SQL diese komplexen Analysen, InfluxQL bleibt für einfache, vertraute Abfragen. InfluxQL hat damit über alle Generationen Bestand, Flux nicht.

Die Beispiele hier beziehen sich auf InfluxDB 1.x.

InfluxQL

Umgang mit der DB:

# interactive
influx -host 'localhost' -username 'influxdb-user' -password ''

# non-interactive
influx -host 'localhost' -username 'influxdb-user' -password '' -execute 'My InfluxQL Query'

Beispiele für gebräuchliche Influx-Queries:

Informationen abfragen
SHOW STATS

SHOW DATABASES
USE icinga2

SHOW MEASUREMENTS
SHOW SERIES
SHOW RETENTION POLICIES
SHOW TAG KEYS FROM "cmd-check-about-me"
DDL
CREATE DATABASE measure
USE measure

INSERT temp inside=24.2,outside=10.1
# INSERT with two tags to enhance search speed
INSERT temp,room=bad,building=ferienhaus inside=24.2,outside=10.1

SELECT * FROM "temp"
SELECT * FROM temp WHERE "room" = 'bad'
SHOW TAG VALUES FROM "cmd-check-disk-usage" WITH KEY = "metric" WHERE "hostname" =~ /^myhost.*/ AND "service" = 'Disk Usage'
Löschen
USE icinga2

# might take some time:
DROP MEASUREMENT "cmd-check-users"

# DROP SERIES FROM <measurement_name[,measurement_name]> WHERE <tag_key>='<tag_value>'
DROP SERIES FROM "cmd-check-cpu-usage" WHERE hostname='myhost'
DROP SERIES FROM "cmd-check-diskio"
# drop series for all measurements:
DROP SERIES WHERE hostname='myhost'

# Drop a subscription
DROP SUBSCRIPTION "icinga-replication" ON "icinga"."autogen"
Retention Times
USE icinga2

SELECT * FROM "cmd-check-disk-usage" LIMIT 10
SELECT metric, value FROM "cmd-check-about-me" WHERE ("hostname" =~ /^myhost\.linuxfabrik\.ch$/ AND "service" = 'About me') AND time >= now() - 30d GROUP BY "metric" limit 2;

# Show Retention Policies
SHOW RETENTION POLICIES ON icinga_influxdb

# Add Retention Policy
CREATE RETENTION POLICY "lf_retention_policy" ON icinga_influxdb DURATION 4320h REPLICATION 1 DEFAULT

# Alter Retention Policy
ALTER RETENTION POLICY "lf_retention_policy" ON icinga_influxdb DURATION 4320h REPLICATION 1 DEFAULT'

# Delete Retention Policy
DROP RETENTION POLICY "lf_retention_policy" ON icinga_influxdb

Bemerkung

Flux

Flux ist seit InfluxDB 1.8 verfügbar und eine funktionale Alternative zu InfluxQL, mit den oben genannten Mehr-Möglichkeiten (Joins, Berechnungen über verschiedene Measurements, Abfrage mehrerer Data Sources). In InfluxDB 2.x ist Flux die primäre Sprache. Ab InfluxDB 3.x wird Flux nicht mehr unterstützt.

HTTP API

INSERTs etc. lassen sich wie oben mit dem CLI erledigen, meist ist das InfluxDB HTTP API aber dafür besser geeignet.

curl --include --request POST --data-binary 'mymeasure,mytag=1 myfield=90 1463683075' "http://influxdb1:8086/write?db=measure&precision=s"

Sync

Es existieren verschiedene Ansätze, von denen die meisten nur die Enterprise-Version beherrscht. Siehe auch https://www.influxdata.com/blog/multiple-data-center-replication-influxdb/. Alternativ:

Per rsync

Data-Verzeichnisse von InfluxDB1 auf InfluxDB2 syncen.

  1. InfluxDB auf beiden Maschinen stoppen: systemctl stop influxdb

  2. Auf InfluxDB2: rm -rf /var/lib/influxdb/*

  3. Auf InfluxDB1: rsync --archive /var/lib/influxdb/ influxdb2:/var/lib/influxdb/ (Trailing-Slash, kein * - sonst werden versteckte Dateien nicht mitgesynct)

  4. InfluxDB auf der zweiten Maschine starten, dann auf der ersten: systemctl start influxdb

Per Backup und Restore

Siehe oben.

Clients

InfluxDB Workbench

Für Linux, Mac und Windows. Schon älter, aber funktioniert Stand 2023-04 einwandfrei: https://github.com/JorgeMaker/InfluxDBWorkBench

InfluxDB und Icinga

Icinga erzeugt in InfluxDB eine Tabelle/ein Measurement pro Check-Command. Jedes Measurement weist mindestens diese Spalten/Fields/Tags auf:

  • acknowledgement::field (integer, z.B. 0.0)

  • current_attempt::field (integer, z.B. 1.0)

  • downtime_depth::field (integer, z.B. 0.0)

  • execution_time::field (float, z.B. 0.09958)

  • hostname::tag (string, z.B. host.example.com)

  • latency::field (float, z.B. 5.51e-4)

  • max_check_attempts::field (integer, z.B. 5.0)

  • metric::tag (string, z.B. cpu-usage)

  • min::field (float, z.B. 0)

  • reachable::field (boolean, z.B. true)

  • service::tag (string, z.B. CPU Usage)

  • state::field (integer, z.B. 0.0)

  • state_type::field (integer, z.B. 1.0)

  • unit::field (string, z.B. seconds)

  • value::field (float, z.B. 0.031)

Hinzu kommen die pro Check individuellen Perfdata-Werte. Der Tag „time“ mit einem Inhalt wie „1999-12-31T13:59:59Z“ ist logischerweise immer vorhanden.

InfluxDB hinter einem eigenen Paket-Mirror

Wer Pakete nicht direkt von InfluxData, sondern über einen eigenen Paket-Mirror bezieht (etwa in Umgebungen ohne direkten Internetzugang oder mit kontrollierten Paketversionen), muss ein Detail beachten. Das mit InfluxDB installierte Paket influxdata-archive-keyring aktiviert den Dienst influxdata-keyring.service, der bei einem Systemupgrade automatisch ein zusätzliches Repository (influxdata) einrichtet.

Das stört den Mirror-Betrieb: Das externe Repository liefert in der Regel neuere Paketversionen als der interne Mirror und übersteuert so die eigenen, kontrollierten Paketquellen. Der Timer legt das Repository zudem nach manueller Entfernung erneut an. Auf Servern ohne Internetanbindung kann das Upgrades ganz verhindern, weil der Paketmanager das nicht erreichbare externe Repository anzusprechen versucht.

Abhilfe: in der /etc/yum.repos.d/influxdb.repo (siehe oben) exclude = influxdata-archive-keyring setzen, damit das Keyring-Paket gar nicht erst installiert wird.

Troubleshooting

Disk läuft mit Daten in der Influx-DB voll? Nur - mit welchen? Was tun?

Zunächst einmal die Disk-Usage pro Measurement anzeigen lassen:

# influxdb v1:
influx_inspect report-disk -detailed /var/lib/influxdb/data/

# influxdb v2+:
influxd inspect report-db --db-path /var/lib/influxdb

Der Output ist recht mühsam lesbar. Den JSON-Teil aus obiger Ausgabe kann man in eine separate Datei packen und mit folgendem Python-Skript lesbarer darstellen (benötigt die Linuxfabrik Python Libraries):

influx-inspect-hr
#!/usr/bin/env python3

import json
import sys

import lib.human

if len(sys.argv) != 2:
    print(f"Usage: {sys.argv} <influxdb_inspect file>")

with open(sys.argv[1], 'rb') as input_file:
    data = json.load(input_file)

    for measurement in sorted(data['Measurement'], key=lambda v: v['size']):
        print(f"{lib.human.bytes2human(measurement['size'])} {measurement['db']} {measurement['measurement']}")

Aufruf dann mit ./influx-inspect-hr /tmp/influx-usage.json. Aus

"Measurement": [
    {"db": "icinga_influxdb", "rp": "lf_retention_policy", "measurement": "cmd-check-about-me", "size": 759341},

wird so:

741.5KiB icinga_influxdb cmd-check-about-me

Hat man die „schuldigen“ Tabellen gefunden, und man benötigt die historischen Daten nicht mehr, kann man sie entfernen. Beispiel:

2.1GiB icinga_influxdb icinga
3.9GiB icinga_influxdb cmd-check-journald-query
4.1GiB icinga_influxdb cmd-check-network-io
12.3GiB icinga_influxdb cmd-check-disk-io

Aufräumen:

influx -username 'influxdb-admin' -password ''
show databases

use icinga_influxdb

drop measurement "cmd-check-disk-io"
drop measurement "cmd-check-network-io"
drop measurement "cmd-check-journald-query"
drop measurement "icinga"