InfluxDB mit Java verwenden

InfluxDB mit Java verwenden

1. Überblick

InfluxDB is a high-performance store for time-series data. Es unterstützt das Einfügen und Abfragen von Daten in Echtzeit über eine SQL-ähnliche Abfragesprache.

In diesem Einführungsartikel wird gezeigt, wie Sie eine Verbindung zu einem InfluxDb-Server herstellen, eine Datenbank erstellen, Zeitreiheninformationen schreiben und dann die Datenbank abfragen.

2. Konfiguration

Um eine Verbindung zur Datenbank herzustellen, müssen wir unsererpom.xml-Datei einen Eintrag hinzufügen:


    org.influxdb
    influxdb-java
    2.8

Die neueste Version dieser Abhängigkeit befindet sich inMaven Central.

Wir benötigen außerdem eine InfluxDB-Instanz. Anweisungen fürdownloading and installing a database finden Sie auf der Website vonInfluxData.

3. Verbindung zu einem Server herstellen

3.1. Verbindung herstellen

Zum Erstellen einer Datenbankverbindung müssen eine URLString und Benutzeranmeldeinformationen an eine Verbindungsfactory übergeben werden:

InfluxDB influxDB = InfluxDBFactory.connect(databaseURL, userName, password);

3.2. Überprüfen der Verbindung

Communications with the database are performed over a RESTful API, daher sind sie nicht persistent.

Die API bietet einen dedizierten "Ping" -Dienst, um zu bestätigen, dass die Verbindung funktioniert. Wenn die Verbindung hergestellt ist, enthält die Antwort eine Datenbankversion. Wenn nicht, enthält es“unknown”.

Nachdem Sie eine Verbindung hergestellt haben, können Sie diese folgendermaßen überprüfen:

Pong response = this.influxDB.ping();
if (response.getVersion().equalsIgnoreCase("unknown")) {
    log.error("Error pinging server.");
    return;
}

3.3. Eine Datenbank erstellen

Das Erstellen einer InfluxDB-Datenbank ähnelt dem Erstellen einer Datenbank auf den meisten Plattformen. But we need to create at least one retention policy before using it.

A retention policy tells the database how long a piece of data should be stored. Zeitreihen wie CPU- oder Speicherstatistiken häufen sich in großen Datenmengen an.

Eine typische Strategie zur Steuerung der Größe von Zeitreihendatenbanken istdownsampling. „Rohdaten“ werden mit hoher Geschwindigkeit gespeichert, zusammengefasst und nach kurzer Zeit wieder entfernt.

Retention policies simplify this by associating a piece of data with an expiration time. InfluxData hat einin-depth explanation auf ihrer Site.

Nach dem Erstellen der Datenbank fügen wir eine einzelne Richtlinie mit dem NamendefaultPolicy. hinzu. Die Daten werden einfach 30 Tage lang gespeichert:

influxDB.createDatabase("example");
influxDB.createRetentionPolicy(
  "defaultPolicy", "example", "30d", 1, true);

Um eine Aufbewahrungsrichtlinie zu erstellen, benötigen wirname,database,interval,areplication factor (für eine Datenbank mit einer Instanz sollte 1 sein) undboolean zeigt an, dass es sich um eine Standardrichtlinie handelt.

3.4. Festlegen einer Protokollierungsstufe

Intern verwendet die InfluxDB-APIRetrofit und stellt überlogging interceptor. eine Schnittstelle zur Protokollierungsfunktion von Retrofit bereit

So können wir die Protokollierungsstufe festlegen:

influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);

Und jetzt können wir Nachrichten sehen, wenn wir eine Verbindung öffnen und sie anpingen:

Dec 20, 2017 5:38:10 PM okhttp3.internal.platform.Platform log
INFO: --> GET http://127.0.0.1:8086/ping

Die verfügbaren Werte sindBASIC,FULL,HEADERS undNONE.

4. Hinzufügen und Abrufen von Daten

4.1. Punkte

Jetzt können wir mit dem Einfügen und Abrufen von Daten beginnen.

Die grundlegende Informationseinheit in InfluxDB istPoint,, was im Wesentlichen ein Zeitstempel und eine Schlüsselwertzuordnung ist.

Werfen wir einen Blick auf einen Punkt, an dem Speicherauslastungsdaten gespeichert sind:

Point point = Point.measurement("memory")
  .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
  .addField("name", "server1")
  .addField("free", 4743656L)
  .addField("used", 1015096L)
  .addField("buffer", 1010467L)
  .build();

Wir haben einen Eintrag erstellt, der dreiLongs als Speicherstatistik, einen Hostnamen und einen Zeitstempel enthält.

Mal sehen, wie man dies zur Datenbank hinzufügt.

4.2. Stapel schreiben

Time series data tends to consist of many small points, and writing those records one at a time would be very inefficient. Die bevorzugte Methode besteht darin, Datensätze in Stapeln zu sammeln.

Die InfluxDB-API stellt einBatchPoint-Objekt bereit:

BatchPoints batchPoints = BatchPoints
  .database(dbName)
  .retentionPolicy("defaultPolicy")
  .build();

Point point1 = Point.measurement("memory")
  .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
  .addField("name", "server1")
  .addField("free", 4743656L)
  .addField("used", 1015096L)
  .addField("buffer", 1010467L)
  .build();

Point point2 = Point.measurement("memory")
  .time(System.currentTimeMillis() - 100, TimeUnit.MILLISECONDS)
  .addField("name", "server1")
  .addField("free", 4743696L)
  .addField("used", 1016096L)
  .addField("buffer", 1008467L)
  .build();

batchPoints.point(point1);
batchPoints.point(point2);
influxDB.write(batchPoints);

Wir erstellen einBatchPoint und fügen dannPoints hinzu. Wir haben den Zeitstempel für unseren zweiten Eintrag in der Vergangenheit auf 100 Millisekunden festgelegt, da die Zeitstempel ein primärer Index sind. Wenn wir zwei Punkte mit demselben Zeitstempel senden, wird nur einer beibehalten.

Beachten Sie, dass wirBatchPoints einer Datenbank und einer Aufbewahrungsrichtlinie zuordnen müssen.

4.3. Einer nach dem anderen schreiben

In einigen Anwendungsfällen kann die Stapelverarbeitung unpraktisch sein.

Aktivieren Sie den Batch-Modus mit einem einzigen Aufruf einer InfluxDB-Verbindung:

influxDB.enableBatch(100, 200, TimeUnit.MILLISECONDS);

Wir haben die Stapelverarbeitung von 100 aktiviert, um sie in den Server einzufügen oder alle 200 Millisekunden zu senden.

Wenn der Batch-Modus aktiviert ist, können wir immer noch einen nach dem anderen schreiben. Es sind jedoch einige zusätzliche Einstellungen erforderlich:

influxDB.setRetentionPolicy("defaultPolicy");
influxDB.setDatabase(dbName);

Außerdem können wir jetzt einzelne Punkte schreiben und sie werden in Stapeln von einem Hintergrund-Thread gesammelt:

influxDB.write(point);

Before we enqueue individual points, we need to set a database (ähnlich dem Befehluse in SQL)and set a default retention policy. Wenn Sie also das Downsampling mit mehreren Aufbewahrungsrichtlinien nutzen möchten, ist das Erstellen von Stapeln der richtige Weg.

Der Stapelmodus verwendet einen separaten Thread-Pool. Es ist daher eine gute Idee, es zu deaktivieren, wenn es nicht mehr benötigt wird:

influxDB.disableBatch();

Durch das Schließen der Verbindung wird auch der Thread-Pool heruntergefahren:

influxDB.close();

4.4. Abfrageergebnisse zuordnen

Abfragen geben einQueryResult zurück, das wir POJOs zuordnen können.

Bevor wir uns die Abfragesyntax ansehen, erstellen wir eine Klasse für unsere Speicherstatistik:

@Measurement(name = "memory")
public class MemoryPoint {

    @Column(name = "time")
    private Instant time;

    @Column(name = "name")
    private String name;

    @Column(name = "free")
    private Long free;

    @Column(name = "used")
    private Long used;

    @Column(name = "buffer")
    private Long buffer;
}

Die Klasse ist mit@Measurement(name = “memory”) versehen, entsprechend denPoint.measurement(“memory”), mit denen wir unserePoints erstellt haben.

Für jedes Feld in unserenQueryResult fügen wir die Annotation@Column(name = “XXX”) mit dem Namen des entsprechenden Felds hinzu.

QueryResults werden POJOs mitInfluxDBResultMapper. zugeordnet

4.5. InfluxDB abfragen

Verwenden wir also unser POJO mit den Punkten, die wir in unserem Zwei-Punkte-Stapel zur Datenbank hinzugefügt haben:

QueryResult queryResult = connection
  .performQuery("Select * from memory", "example");

InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
List memoryPointList = resultMapper
  .toPOJO(queryResult, MemoryPoint.class);

assertEquals(2, memoryPointList.size());
assertTrue(4743696L == memoryPointList.get(0).getFree());

Die Abfrage zeigt, wie unsere Messung mit dem Namenmemory als Tabelle mitPoints gespeichert wird, aus der wirselect ableiten können.

InfluxDBResultMapper akzeptiert einen Verweis aufMemoryPoint.class mitQueryResult und gibt eine Liste von Punkten zurück.

Nachdem wir die Ergebnisse zugeordnet haben, überprüfen wir, ob wir zwei erhalten haben, indem wir die Länge derList überprüfen, die wir von der Abfrage erhalten haben. Dann schauen wir uns den ersten Eintrag in der Liste an und sehen die freie Speichergröße des zweiten Punktes, den wir eingefügt haben. The default ordering of query results from InfluxDB is ascending by timestamp.

Ändern wir das:

queryResult = connection.performQuery(
  "Select * from memory order by time desc", "example");
memoryPointList = resultMapper
  .toPOJO(queryResult, MemoryPoint.class);

assertEquals(2, memoryPointList.size());
assertTrue(4743656L == memoryPointList.get(0).getFree());

Das Hinzufügen vonorder by time desc kehrt die Reihenfolge unserer Ergebnisse um.

InfluxDB-Abfragen sehen SQL sehr ähnlich. Es gibt eine ausführliche Referenzon their site.

5. Fazit

Wir haben eine Verbindung zu einem InfluxDB-Server hergestellt, eine Datenbank mit einer Aufbewahrungsrichtlinie erstellt und dann Daten vom Server eingefügt und abgerufen.

Der vollständige Quellcode der Beispiele lautetover on GitHub.