JavaでInfluxDBを使用する

JavaでInfluxDBを使用する

1. 概要

InfluxDB is a high-performance store for time-series data.SQLのようなクエリ言語を介したデータの挿入とリアルタイムクエリをサポートします。

この紹介記事では、InfluxDbサーバーに接続し、データベースを作成し、時系列情報を書き込んでから、データベースにクエリを実行する方法を示します。

2. セットアップ

データベースに接続するには、pom.xmlファイルにエントリを追加する必要があります。


    org.influxdb
    influxdb-java
    2.8

この依存関係の最新バージョンはMaven Centralにあります。

InfluxDBインスタンスも必要です。 downloading and installing a databaseの説明は、InfluxDataのWebサイトにあります。

3. サーバーへの接続

3.1. 接続の作成

データベース接続を作成するには、URLStringとユーザー資格情報を接続ファクトリに渡す必要があります。

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

3.2. 接続の確認

Communications with the database are performed over a RESTful APIなので、永続的ではありません。

APIは、接続が機能していることを確認するための専用の「ping」サービスを提供します。 接続が良好な場合、応答にはデータベースバージョンが含まれます。 そうでない場合は、“unknown”.が含まれます

そのため、接続を作成した後、以下を実行して確認できます。

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

3.3. データベースを作成する

InfluxDBデータベースの作成は、ほとんどのプラットフォームでデータベースを作成することに似ています。 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. CPUやメモリの統計などの時系列は、大きなデータセットに蓄積される傾向があります。

時系列データベースのサイズを制御するための一般的な戦略は、downsamplingです。 「生の」データは高速で保存され、要約され、短時間で削除されます。

Retention policies simplify this by associating a piece of data with an expiration time. InfluxDataのサイトにはin-depth explanationがあります。

データベースを作成した後、defaultPolicy.という名前の単一のポリシーを追加します。これにより、データが30日間保持されます。

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

保持ポリシーを作成するには、name,database,interval,areplication factor(単一インスタンスデータベースの場合は1)、およびbooleanはそれがデフォルトのポリシーであることを示します。

3.4. ロギングレベルの設定

内部的には、InfluxDB APIはRetrofitを使用し、logging interceptor.を介してRetrofitのロギング機能へのインターフェースを公開します

そのため、次を使用してログレベルを設定できます。

influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);

接続を開いてpingを実行すると、メッセージが表示されるようになりました。

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

使用可能なレベルは、BASICFULLHEADERS、およびNONE.です。

4. データの追加と取得

4.1. ポイント

これで、データの挿入と取得を開始する準備が整いました。

InfluxDBの情報の基本単位はPoint,であり、これは基本的にタイムスタンプとキーと値のマップです。

メモリ使用率データを保持するポイントを見てみましょう。

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

メモリ統計、ホスト名、タイムスタンプとして3つのLongsを含むエントリを作成しました。

これをデータベースに追加する方法を見てみましょう。

4.2. バッチの作成

Time series data tends to consist of many small points, and writing those records one at a time would be very inefficient.推奨される方法は、レコードをバッチに収集することです。

InfluxDB APIは、BatchPointオブジェクトを提供します。

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);

BatchPointを作成し、それにPointsを追加します。 タイムスタンプはプライマリインデックスであるため、2番目のエントリのタイムスタンプを過去の100ミリ秒に設定しました。 同じタイムスタンプで2つのポイントを送信すると、1つだけが保持されます。

BatchPointsをデータベースおよび保持ポリシーに関連付ける必要があることに注意してください。

4.3. 一度に1つずつ書く

一部のユースケースでは、バッチ処理は実用的ではない場合があります。

InfluxDB接続への1回の呼び出しでバッチモードを有効にしましょう。

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

私たちは、サーバーへの挿入のために100のバッチ処理を有効にするか、それは200ミリ秒ごとに持っているもの送ります。

バッチモードを有効にしても、一度に1つずつ書き込むことができます。 ただし、追加のセットアップが必要です。

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

さらに、個々のポイントを記述できるようになり、それらはバックグラウンドスレッドによってバッチで収集されています。

influxDB.write(point);

Before we enqueue individual points, we need to set a database(SQLのuseコマンドと同様)and set a default retention policy.したがって、複数の保持ポリシーを使用したダウンサンプリングを利用する場合は、バッチを作成することをお勧めします。

バッチモードは、個別のスレッドプールを利用します。 したがって、不要になったときに無効にすることをお勧めします。

influxDB.disableBatch();

接続を閉じると、スレッドプールもシャットダウンします。

influxDB.close();

4.4. クエリ結果のマッピング

クエリはQueryResultを返します。これは、POJOにマップできます。

クエリ構文を見る前に、メモリ統計を保持するクラスを作成しましょう。

@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;
}

クラスには、Pointsの作成に使用したPoint.measurement(“memory”)に対応する@Measurement(name = “memory”)の注釈が付けられています。

QueryResultの各フィールドに、対応するフィールドの名前を含む@Column(name = “XXX”)アノテーションを追加します。

QueryResultsInfluxDBResultMapper.でPOJOにマップされます

4.5. InfluxDBのクエリ

それでは、2ポイントバッチでデータベースに追加したポイントでPOJOを使用しましょう。

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());

クエリは、memoryという名前の測定値がselectからのPointsのテーブルとしてどのように格納されるかを示しています。

InfluxDBResultMapperは、QueryResultを含むMemoryPoint.classへの参照を受け入れ、ポイントのリストを返します。

結果をマッピングした後、クエリから受け取ったListの長さをチェックして、2つ受け取ったことを確認します。 次に、リストの最初のエントリを見て、挿入した2番目のポイントの空きメモリサイズを確認します。 The default ordering of query results from InfluxDB is ascending by timestamp.

それを変えましょう:

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());

order by time descを追加すると、結果の順序が逆になります。

InfluxDBクエリはSQLに非常によく似ています。 広範なリファレンスガイドon their siteがあります。

5. 結論

InfluxDBサーバーに接続し、保持ポリシーを使用してデータベースを作成し、サーバーにデータを挿入して取得しました。

例の完全なソースコードはover on GitHubです。