El SDK de LindormTSDB ofrece tres categorías de interfaces: interfaces de gestión para operaciones DDL (lenguaje de definición de datos) y DCL (lenguaje de control de datos), interfaces de escritura para la ingesta de registros de series temporales y una interfaz de consulta para recuperar datos mediante SQL.
Interfaces de gestión
Las interfaces de gestión ejecutan sentencias SQL en LindormTSDB. Hay dos métodos sobrecargados disponibles:
|
Firma del método |
Descripción |
|
|
Ejecuta una sentencia SQL en la base de datos predeterminada |
|
|
Ejecuta una sentencia SQL en la base de datos especificada |
El objeto Result contiene la salida de la ejecución:
|
Campo |
Tipo |
Descripción |
|
|
|
Nombres de las columnas en los resultados devueltos |
|
|
|
Tipos de datos de las columnas |
|
|
|
Resultados devueltos fila por fila |
Gestionar bases de datos y tablas
Utilice sentencias DDL para crear, describir y eliminar bases de datos o tablas. El siguiente ejemplo muestra un ciclo de vida completo de creación y eliminación:
// 1. List existing databases.
String showDatabase = "show databases";
Result result = lindormTSDBClient.execute(showDatabase);
System.out.println("before create, db list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
// 2. Create a database named "demo".
String createDatabase = "create database demo";
result = lindormTSDBClient.execute(createDatabase);
System.out.println("create database:" + result.isSuccessful());
// 3. Verify the database was created.
result = lindormTSDBClient.execute(showDatabase);
System.out.println("after create, db list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
String database = "demo";
// 4. List existing tables in the database.
String showTables = "show tables";
result = lindormTSDBClient.execute(database, showTables);
System.out.println("before create, table list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
// 5. Create a table.
String createTable = "CREATE TABLE sensor (device_id VARCHAR TAG, region VARCHAR TAG, " +
"time BIGINT, temperature DOUBLE, humidity DOUBLE, PRIMARY KEY(device_id))";
result = lindormTSDBClient.execute(database, createTable);
System.out.println("create table: " + result.isSuccessful());
// 6. Verify the table was created.
result = lindormTSDBClient.execute(database, showTables);
System.out.println("after create, table list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
// 7. Describe the table schema.
String describeTable = "describe table sensor";
result = lindormTSDBClient.execute(database, describeTable);
System.out.println("------------ describe table -------------------");
List<String> columns = result.getColumns();
System.out.println("columns: " + columns);
List<String> metadata = result.getMetadata();
System.out.println("metadata: " + metadata);
List<List<Object>> rows = result.getRows();
for (int i = 0, size = rows.size(); i < size; i++) {
List<Object> row = rows.get(i);
System.out.println("column #" + i + " : " + row);
}
System.out.println("------------ describe table -------------------");
// 8. Drop the table.
String dropTable = "drop table sensor";
result = lindormTSDBClient.execute(database, dropTable);
System.out.println("drop table: " + result.isSuccessful());
// 9. Verify the table was dropped.
result = lindormTSDBClient.execute(database, showTables);
System.out.println("after drop, table list: " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
// 10. Drop the database.
String dropDatabase = "drop database demo";
result = lindormTSDBClient.execute(dropDatabase);
System.out.println("drop database:" + result.isSuccessful());
// 11. Verify the database was dropped.
result = lindormTSDBClient.execute(showDatabase);
System.out.println("after drop, db list : " +
result.getRows().stream().map(e -> (String) e.get(0)).collect(Collectors.toList()));
Salida esperada:
before create, db list: [default]
create database:true
after create, db list: [default, demo]
before create, table list: []
create table: true
after create, table list: [sensor]
------------ describe table -------------------
columns: [columnName, typeName, columnKind]
metadata: [VARCHAR, VARCHAR, VARCHAR]
column #0 : [device_id, VARCHAR, TAG]
column #1 : [region, VARCHAR, TAG]
column #2 : [time, TIMESTAMP, TIMESTAMP]
column #3 : [temperature, DOUBLE, FIELD]
column #4 : [humidity, DOUBLE, FIELD]
------------ describe table -------------------
drop table: true
after drop, table list: []
drop database:true
after drop, db list : [default]
Las operaciones DDL para consultas continuas no se cubren en esta sección. Para consultar la sintaxis SQL completa compatible con LindormTSDB, consulte SQL syntax.
Interfaces de escritura
De forma predeterminada, el SDK de LindormTSDB escribe datos de manera asíncrona para maximizar el rendimiento. Las interfaces de escritura admiten:
Escrituras de registro único y por lotes (se recomiendan las escrituras por lotes porque reducen la contención de bloqueos en la cola asíncrona)
Dos patrones de manejo de resultados:
CompletableFuture<WriteResult>para procesamiento en línea yCallbackpara manejo basado en eventosEscrituras síncronas al invocar
.join()en el objetoCompletableFuturedevuelto
Construir un registro de escritura
Un objeto Record almacena una sola fila para escribir. Especifique el nombre de la tabla, la marca de tiempo, las etiquetas y los valores de los campos:
Record record = Record
.table("sensor") // Table name
.time(currentTime) // Timestamp in milliseconds
.tag("device_id", "F07A1260") // Tag: indexed key-value dimension
.tag("region", "north-cn")
.addField("temperature", 12.1) // Field: non-indexed metric value
.addField("humidity", 45.0)
.build();
De forma predeterminada, el SDK valida la validez de los caracteres al construir un objeto Record. Pase false a build() para omitir la validación.
Escritura con CompletableFuture
Todas las sobrecargas devuelven un objeto CompletableFuture<WriteResult>. Utilice escrituras por lotes para reducir la contención de bloqueos en la cola asíncrona.
|
Firma del método |
Descripción |
|
|
Escribe un solo registro en la base de datos predeterminada |
|
|
Escribe un solo registro en la base de datos especificada |
|
|
Escribe un lote de registros en la base de datos predeterminada (recomendado) |
|
|
Escribe un lote de registros en la base de datos especificada (recomendado) |
Registro único:
// Default database
CompletableFuture<WriteResult> future = lindormTSDBClient.write(record);
// Specified database
String database = "demo";
CompletableFuture<WriteResult> future = lindormTSDBClient.write(database, record);
Escritura por lotes (recomendado):
List<Record> records;
// Default database
CompletableFuture<WriteResult> future = lindormTSDBClient.write(records);
// Specified database
String database = "demo";
CompletableFuture<WriteResult> future = lindormTSDBClient.write(database, records);
Manejar el resultado:
CompletableFuture<WriteResult> future = lindormTSDBClient.write(records);
future.whenComplete((r, ex) -> {
if (ex != null) {
// Write submission failed.
System.out.println("Failed to write.");
Throwable throwable = ExceptionUtils.getRootCause(ex);
if (throwable instanceof LindormTSDBException) {
LindormTSDBException e = (LindormTSDBException) throwable;
System.out.println("Error code: " + e.getCode());
System.out.println("SQL state: " + e.getSqlstate());
System.out.println("Error message: " + e.getMessage());
} else {
throwable.printStackTrace();
}
} else {
// Write completed.
if (r.isSuccessful()) {
System.out.println("Write successfully.");
} else {
System.out.println("Write failure.");
}
}
});
No realice cálculos complejos o que consuman mucho tiempo dentro de whenComplete. Delegue este trabajo a un pool de hilos independiente. Para obtener detalles sobre los códigos de error, consulte Common error codes.
Escritura con callback
Pase un objeto Callback al método write(). El método onCompletion recibe el resultado de la escritura, los registros correspondientes y cualquier excepción.
public interface Callback {
void onCompletion(WriteResult result, List<Record> records, Throwable e);
}
|
Firma del método |
Descripción |
|
|
Escribe un solo registro en la base de datos predeterminada con un callback |
|
|
Escribe un solo registro en la base de datos especificada con un callback |
|
|
Escribe un lote de registros en la base de datos predeterminada con un callback (recomendado) |
|
|
Escribe un lote de registros en la base de datos especificada con un callback (recomendado) |
Implementar y pasar el callback:
Callback callback = new Callback() {
@Override
public void onCompletion(WriteResult result, List<Record> list, Throwable throwable) {
if (throwable != null) {
// Write failed.
if (throwable instanceof LindormTSDBException) {
LindormTSDBException ex = (LindormTSDBException) throwable;
System.out.println("errorCode: " + ex.getCode());
System.out.println("sqlstate: " + ex.getSqlstate());
System.out.println("message: " + ex.getMessage());
} else {
throwable.printStackTrace();
}
} else {
if (result.isSuccessful()) {
System.out.println("Write successfully.");
} else {
System.out.println("Write failure.");
}
}
}
};
// Batch write — recommended
List<Record> records;
lindormTSDBClient.write(records, callback);
// Single record
lindormTSDBClient.write(record, callback);
No realice cálculos complejos o que consuman mucho tiempo dentro de onCompletion. Delegue este trabajo a un pool de hilos independiente. Para obtener detalles sobre los códigos de error, consulte Common error codes.
Interfaz de consulta
La interfaz de consulta ejecuta sentencias SQL y transmite los resultados en fragmentos. Todas las sobrecargas devuelven un objeto ResultSet.
|
Firma del método |
Descripción |
|
|
Consulta la base de datos predeterminada; devuelve hasta 1,000 filas por fragmento |
|
|
Consulta la base de datos especificada; devuelve hasta 1,000 filas por fragmento |
|
|
Consulta la base de datos especificada con un tamaño de fragmento personalizado |
Parámetros:
|
Parámetro |
Tipo |
Descripción |
|
|
|
Nombre de la base de datos que se va a consultar |
|
|
|
Sentencia SQL que se va a ejecutar. Para conocer la sintaxis compatible, consulte Sintaxis SQL. |
|
|
|
Número de filas devueltas por lote. Valor predeterminado: 1,000. |
Procesar resultados de consulta
Itere sobre el objeto ResultSet con next() hasta que devuelva null; luego cierre el conjunto de resultados para liberar recursos de E/S:
public interface ResultSet extends Closeable {
QueryResult next();
void close();
}
Cada objeto QueryResult contiene:
|
Campo |
Tipo |
Descripción |
|
|
|
Nombres de las columnas en los resultados de la consulta |
|
|
|
Tipos de datos de las columnas. Consulte Data types. |
|
|
|
Resultados de la consulta devueltos fila por fila |
Ejemplo:
String sql = "select * from sensor";
int chunkSize = 100;
ResultSet resultSet = lindormTSDBClient.query("demo", sql, chunkSize);
try {
QueryResult result = null;
// Iterate until next() returns null — all results have been retrieved.
while ((result = resultSet.next()) != null) {
List<String> columns = result.getColumns();
System.out.println("columns: " + columns);
List<String> metadata = result.getMetadata();
System.out.println("metadata: " + metadata);
List<List<Object>> rows = result.getRows();
for (int i = 0, size = rows.size(); i < size; i++) {
List<Object> row = rows.get(i);
System.out.println("row #" + i + " : " + row);
}
}
} finally {
// Always close ResultSet after the query — whether it succeeds or fails.
resultSet.close();
}
Siempre invoque resultSet.close() después de que finalice la consulta, independientemente de si se completó correctamente o con errores. Si no lo hace, se producirá una fuga de conexiones.