InfluxDB

Die Time-Series-Datenbank (Zeitreihendatenbank) InfluxDB gibt es in einer Open Source- (OSS) und einer Enterprise-Edition. Die Enterprise-Edition bietet zusätzlich:

  • einen HA-Modus

  • Verwaltung lokaler Benutzer

  • Anbindung an LDAP oder OAuth

  • Scale out Features

Eine verteilte InfluxDB mit synchronisierten Daten lässt sich mit der Open Source-Variante erreichen, indem man Telegraf die gesammelten Werte in mehrere InfluxDB-Instanzen schreiben lässt. Bedeutet aber auch, dass Schreibanfragen an Telegraf statt InfluxDB gerichtet werden müssen.

InfluxDB hört auf

  • HTTP API: Port 8086

Begriffe:

  • Bucket: Datenbank/Named Location mit einer Retention Policy

  • Measurement: Entspricht einer „Table“ in einer SQL-Datenbank. Bei Icinga erhält jedes Plugin sein Measurement, beispielsweise cmd-check-swap.

    SHOW MEASUREMENTS ON icinga2
    
    name: measurements
    name
    ----
    cmd-check-about-me
    cmd-check-apache-httpd-status
    cmd-check-apache-httpd-version
    cmd-check-cpu-usage
    ...
    
  • Field: Nicht-indizierte Spalte einer Tabelle

  • Tag: Indizierte Spalte einer Tabelle

    • Tag Key: Spaltenname

    • Tag Value: der Inhalt

  • Tag Set: „tag key“=“tag value“,“tag key“=“tag value“, …

  • Series: Eine Serie besteht aus einer Retention Policy, einem Measurement und einem Tag Set. Series sehen so aus, im Beispiel aus einer Icinga-Datenbank:

    SHOW SERIES ON icinga2
    
    # measurement, "tag key"="tag value","tag key"="tag value", ...
    cmd-check-swap,hostname=myhost,      metric=free,          service=Swap
    cmd-check-swap,hostname=myhost,      metric=swap-usage,    service=Swap
    cmd-check-swap,hostname=myhost,      metric=used,          service=Swap
    cmd-check-swap,hostname=myhost,                            service=Swap
    

Connect und Execute:

# ask for password
influx -username 'influxdb-user' -password ''

# execute statement
influx -username 'influxdb-user' -password 'password' -execute 'SHOW RETENTION POLICIES ON icinga_influxdb'
Links:

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_compat.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

InfluxQL Query Language

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 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 Query Language

Flux ist ab InfluxDB v1.8 verfügbar, und eine Alternative zur SQL-ähnlichen InfluxQL-Abfragesprache. Flux verwendet funktionale Sprachmuster, die im Vergleich zu InfluxQL neue Möglichkeiten bietet, beispielsweise Berechnungen über verschiedene Measurements oder die Abfrage mehrerer Data Sources.

HTTP API

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

curl -i -XPOST --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/

  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-31 T13:59:59Z“ ist logischerweise immer vorhanden.

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:

influx_inspect report-disk -detailed /var/lib/influxdb/data/

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"

Built on 2024-02-26