Lindorm Time Series Database (TSDB) SDK を使用して、時系列データに対するクエリを構築・実行します。本ドキュメントでは、同期クエリおよび非同期クエリ、結果の並べ替え、および時系列における最新データポイントの取得方法について説明します。
基本概念
| 概念 | クラス | 説明 |
|---|---|---|
| クエリ | Query | 最上位のクエリオブジェクトです。時間範囲と 1 つ以上のサブクエリを保持します。 |
| サブクエリ | SubQuery | 取得するデータの内容を定義します:メトリック、集約関数、任意のダウンサンプリング、およびタグフィルターです。1 つの Query には複数のサブクエリを含めることができます。 |
| アグリゲーター | Aggregator | 集約関数の列挙型です。一般的な値: AVG、SUM、NONE。 |
クエリの構築
ビルダーパターンを使用して Query オブジェクトを作成します。最低限、時間範囲と少なくとも 1 つのサブクエリを指定する必要があります。
Query query = Query
.timeRange(startTime, endTime) // データをクエリする対象の時間範囲を指定します。
.sub(SubQuery.metric("hello").aggregator(Aggregator.AVG).tag("tagk1", "tagv1").build())
.sub(SubQuery.metric("world").aggregator(Aggregator.SUM).tag("tagk2", "tagv2").build())
.build();サブクエリのパラメーター
各 SubQuery は以下のパラメーターを受け付けます:
| パラメーター | 型 | 説明 | 例 |
|---|---|---|---|
metric | String | クエリ対象のメトリック名です。 | "cpu.usage" |
aggregator | Aggregator | 適用する集約関数です。 | Aggregator.AVG |
downsample | String | 再サンプリングによるデータ密度の低減を行います。形式: <間隔><単位>-<集約関数>。たとえば、60m-avg は 60 分ごとの平均値を 1 つ生成します。 | "60m-avg" |
tag | String, String | 特定のタグキーと値のペアに一致する結果のみをフィルターします。複数回呼び出して、複数のフィルターを追加できます。 | "region"、"us-west" |
すべてのパラメーターを指定したサブクエリの例:
SubQuery subQuery = SubQuery
.metric("test-metric")
.aggregator(Aggregator.AVG)
.downsample("60m-avg") // 60 分ごとの平均値
.tag("tagk1", "tagv1")
.tag("tagk2", "tagv2")
.build();同期クエリの実行
スレッド同期モードでクエリを実行するには、tsdb.query(query) を呼び出します。このメソッドは、結果が返されるまでブロックされます。
List<QueryResult> result = tsdb.query(query);
System.out.println("返された結果:" + result);非同期クエリの実行
非同期でクエリを実行するには、QueryCallback を tsdb.query() に渡します。SDK は結果が利用可能になると、response() を呼び出します。
QueryCallback cb = new QueryCallback() {
@Override
public void response(Query input, List<QueryResult> result) {
System.out.println("クエリパラメーター:" + input);
System.out.println("返された結果:" + result);
}
};
tsdb.query(query, cb);クエリ結果の構造
tsdb.query() は List<QueryResult> を返します。各 QueryResult は 1 つのサブクエリに対応します。
getDps() を QueryResult オブジェクトに対して呼び出すことで、データポイントを取得できます。
タイムスタンプによるクエリ結果の並べ替え
デフォルトでは、getDps() は順序のないマップでデータポイントを返します。getOrderDps() を使用すると、タイムスタンプで並べられたコレクションを取得できます:
| メソッド | 並べ替え順 |
|---|---|
getDps() | 順序なし |
getOrderDps() | 昇順(古いものから) |
getOrderDps(true) | 降順(新しいものから) |
以下の例では、同一のデータポイントを 3 種類の並べ替え順で取得しています:
Query query = Query
.timeRange(current - 1000, start + 1000)
.sub(SubQuery.metric(metric).aggregator(Aggregator.NONE).tag(tags).build())
.build();
try {
List<QueryResult> result = tsdb.query(query);
for (QueryResult queryResult : result) {
// 順序なしのデータポイント
System.out.println(queryResult.getDps());
System.out.println("-------------");
// タイムスタンプ昇順(古いものから)
System.out.println(queryResult.getOrderDps());
System.out.println("-------------");
// タイムスタンプ降順(新しいものから)
System.out.println(queryResult.getOrderDps(true));
}
} catch (HttpUnknowStatusException e) {
e.printStackTrace();
}最新データポイントのクエリ実行
tsdb.queryLast() は、各時系列に対して 1 つの LastDataValue を返します。これは、指定されたタイムスタンプより前に記録された最も新しいデータポイントです。
クエリ対象の時系列を特定する方法は以下の 2 通りです:
| 方法 | 使用タイミング |
|---|---|
| メトリックおよびタグによる特定 | 初回クエリ時、または TSUID をまだ取得していない場合 |
| TSUID による | 同一の時系列に対する後続のクエリ時 |
推奨ワークフロー: 最初にメトリックおよびタグでクエリを実行し、その結果から得られた TSUID を保存して、後続のクエリで使用します。
メトリックおよびタグによる特定
LastPointSubQuery にメトリック名およびタグフィルターを指定します:
// タグフィルターの定義
Map<String, String> tags = new HashMap<String, String>();
tags.put("uid", "1");
tags.put("id", "6");
String metric = "test.1";
// クエリの構築および実行
LastPointQuery query = LastPointQuery.builder()
.timestamp(1537520409729l) // このタイムスタンプより前の最新ポイントをクエリ
.msResolution(true) // タイムスタンプをミリ秒単位として解釈
.sub(LastPointSubQuery.builder(metric, tags).build())
.build();
List<LastDataValue> lastDataValues = tsdb.queryLast(query);
System.out.println(lastDataValues);結果には、各一致した時系列の TSUID が含まれます。これらの TSUID を保存し、後続のクエリで使用してください。
TSUID による
以前のクエリから既に TSUID を取得済みの場合は、それらを直接渡します。
// 以前の queryLast() 呼び出しで取得した TSUID
List<String> tsuids = new ArrayList<String>();
tsuids.add("10000B7C000095000081****FF00006F");
LastPointQuery query = LastPointQuery.builder()
.timestamp(1537520409729l)
.msResolution(true)
.sub(LastPointSubQuery.builder(tsuids).build())
.build();
List<LastDataValue> lastDataValues = tsdb.queryLast(query);
System.out.println(lastDataValues);