GithubHelp home page GithubHelp logo

apache / incubator-horaedb-client-java Goto Github PK

View Code? Open in Web Editor NEW
21.0 9.0 12.0 843 KB

Apache HoraeDB (Incubating) Java Client.

Home Page: https://horaedb.apache.org/

License: Apache License 2.0

Java 99.97% Shell 0.03% Makefile 0.01%
java cloud-native database distributed-database horaedb iot-database sql timeseries-analysis timeseries-database tsdb

incubator-horaedb-client-java's Introduction

Apache HoraeDB (Incubating) Java Client

License

中文

Introduction

Java client for Apache HoraeDB (Incubating).

Important

Apache HoraeDB (incubating) is an effort undergoing incubation at the Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC.

Please read the DISCLAIMER and a full explanation of "incubating".

Features

  • With the well-designed SPI, the network transport layer is extensible. And we provide the default implementation which uses the gRPC framework.
  • The client provides high-performance async streaming write API.
  • The client also collects lots of performance metrics by default. These metrics can be configured to write to local file.
  • We can take memory snapshots that contains the status of critical objects. The snapshots can also be configured to write to local file, which helps a lot when we diagnose complex problems.

Data ingestion process

                   ┌─────────────────────┐  
                   │   HoraeDBClient     │  
                   └─────────────────────┘  
                              │  
                              ▼  
                   ┌─────────────────────┐  
                   │     WriteClient     │───┐  
                   └─────────────────────┘   │  
                              │     Async to retry and merge responses  
                              │              │  
                 ┌────Split requests         │  
                 │                           │  
                 │  ┌─────────────────────┐  │   ┌─────────────────────┐       ┌─────────────────────┐
                 └─▶│    RouterClient     │◀─┴──▶│     RouterCache     │◀─────▶│      RouterFor      │
                    └─────────────────────┘      └─────────────────────┘       └─────────────────────┘
                               ▲                                                          │  
                               │                                                          │  
                               ▼                                                          │  
                    ┌─────────────────────┐                                               │  
                    │      RpcClient      │◀──────────────────────────────────────────────┘  
                    └─────────────────────┘  
                               ▲  
                               │  
                               ▼  
                    ┌─────────────────────┐  
                    │  Default gRPC impl  │  
                    └─────────────────────┘  
                               ▲  
                               │  
           ┌───────────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐  
           │                            │  
           ▼                            ▼                            ▼  
┌─────────────────────┐      ┌─────────────────────┐      ┌─────────────────────┐  
│   HoraeDB Node1     │      │   HoraeDB Node2     │      │         ...         │  
└─────────────────────┘      └─────────────────────┘      └─────────────────────┘  

Data query process

                   ┌─────────────────────┐  
                   │   HoraeDBClient     │  
                   └─────────────────────┘  
                              │  
                              ▼  
                   ┌─────────────────────┐  
                   │     QueryClient     │───┐  
                   └─────────────────────┘   │  
                              │              │Async to retry  
                              │              │  
                 ┌────────────┘              │  
                 │                           │  
                 │  ┌─────────────────────┐  │   ┌─────────────────────┐       ┌─────────────────────┐
                 └─▶│    RouterClient     │◀─┴──▶│     RouterCache     │◀─────▶│      RouterFor      │
                    └─────────────────────┘      └─────────────────────┘       └─────────────────────┘
                               ▲                                                          │  
                               │                                                          │  
                               ▼                                                          │  
                    ┌─────────────────────┐                                               │  
                    │      RpcClient      │◀──────────────────────────────────────────────┘  
                    └─────────────────────┘  
                               ▲  
                               │  
                               ▼  
                    ┌─────────────────────┐  
                    │  Default gRPC impl  │  
                    └─────────────────────┘  
                               ▲  
                               │  
           ┌───────────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐  
           │                            │  
           ▼                            ▼                            ▼  
┌─────────────────────┐      ┌─────────────────────┐      ┌─────────────────────┐  
│   HoraeDB Node1     │      │   HoraeDB Node2     │      │         ...         │  
└─────────────────────┘      └─────────────────────┘      └─────────────────────┘  

Requirements

  • Java 8 or later is required for compilation

Import

<dependency>
  <groupId>io.ceresdb</groupId>
  <artifactId>horaedb-all</artifactId>
  <version>1.0.0-alpha</version>
</dependency>

Init HoraeDB client

final HoraeDBOptions opts = HoraeBOptions.newBuilder("127.0.0.1", 8831, DIRECT) // HoraeDB default grpc port 8831,use DIRECT RouteMode
        .database("public") // use database for client, can be overridden by the RequestContext in request
        // maximum retry times when write fails
        // (only some error codes will be retried, such as the routing table failure)
        .writeMaxRetries(1)
        // maximum retry times when read fails
        // (only some error codes will be retried, such as the routing table failure)
        .readMaxRetries(1).build();

final HoraeDBClient client = new HoraeDBClient();
if (!client.init(opts)) {
        throw new IllegalStateException("Fail to start HoraeDBClient");
}

For more configuration options, see configuration

Create table example

HoraeDB is a Schema-less time-series database, so creating table schema ahead of data ingestion is not required (HoraeDB will create a default schema according to the very first data you write into it). Of course, you can also manually create a schema for fine grained management purposes (eg. managing index).

The following table creation statement(using the SQL API included in SDK )shows all field types supported by HoraeDB:

// Create table manually, creating table schema ahead of data ingestion is not required
String createTableSql = "CREATE TABLE IF NOT EXISTS machine_table(" +                                                                                              "ts TIMESTAMP NOT NULL," + //
        "ts TIMESTAMP NOT NULL," +
        "city STRING TAG NOT NULL," +
        "ip STRING TAG NOT NULL," +
        "cpu DOUBLE NULL," +
        "mem DOUBLE NULL," +
        "TIMESTAMP KEY(ts)" + // timestamp column must be specified
        ") ENGINE=Analytic";

Result<SqlQueryOk, Err> createResult = client.sqlQuery(new SqlQueryRequest(createTableSql)).get();
if (!createResult.isOk()) {
        throw new IllegalStateException("Fail to create table");
}

How to build write data

final Point point = Point.newPointBuilder("machine_table")
        .setTimestamp(t0)
        .addTag("city", "Singapore")
        .addTag("ip", "10.0.0.1")
        .addField("cpu", Value.withDouble(0.23))
        .addField("mem", Value.withDouble(0.55))
        .build();

Write data example

final CompletableFuture<Result<WriteOk, Err>> wf = client.write(new WriteRequest(pointList));
// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API
final Result<WriteOk, Err> writeResult = wf.get();
Assert.assertTrue(writeResult.isOk());
// `Result` class referenced the Rust language practice, provides rich functions (such as mapXXX, andThen) transforming the result value to improve programming efficiency. You can refer to the API docs for detail usage.
Assert.assertEquals(3, writeResult.getOk().getSuccess());
Assert.assertEquals(3, writeResult.mapOr(0, WriteOk::getSuccess).intValue());
Assert.assertEquals(0, writeResult.mapOr(-1, WriteOk::getFailed).intValue());

See write

Query data example

final SqlQueryRequest queryRequest = SqlQueryRequest.newBuilder()
        .forTables("machine_table") // table name is optional. If not provided, SQL parser will parse the `sql` to get the table name and do the routing automaticly
        .sql("select * from machine_table where ts = %d", t0) //
        .build();
final CompletableFuture<Result<SqlQueryOk, Err>> qf = client.sqlQuery(queryRequest);
// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API
final Result<SqlQueryOk, Err> queryResult = qf.get();

Assert.assertTrue(queryResult.isOk());

final SqlQueryOk queryOk = queryResult.getOk();
Assert.assertEquals(1, queryOk.getRowCount());

// get rows as list
final List<Row> rows = queryOk.getRowList();

// get rows as stream
final Stream<Row> rowStream = queryOk.stream();
rowStream.forEach(row -> System.out.println(row.toString()));

See read

stream write/read Example

HoraeDB support streaming writing and reading,suitable for large-scale data reading and writing。

final StreamWriteBuf<Point, WriteOk> writeBuf = client.streamWrite("machine_table");
for (int i = 0; i < 1000; i++) {
    final Point point = Point.newPointBuilder("machine_table")
        .setTimestamp(timestamp)
        .addTag("city", "Beijing")
        .addTag("ip", "10.0.0.3")
        .addField("cpu", Value.withDouble(0.42))
        .addField("mem", Value.withDouble(0.67))
        .build();
        writeBuf.writeAndFlush(Arrays.asList(point));
        timestamp = timestamp+1;
}

final CompletableFuture<WriteOk> writeOk = writeBuf.completed();

See streaming

Licensing

Under Apache License 2.0.

Community and support

  • Join the user group on DingTalk: 44602802

incubator-horaedb-client-java's People

Contributors

archerny avatar baojinri avatar chunshao90 avatar dependabot[bot] avatar fengjiachun avatar jiacai2050 avatar michaelleehz avatar tanruixiang avatar tisonkun avatar zuliangwang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

incubator-horaedb-client-java's Issues

Empty query response

Describe this problem

Steps to reproduce

  1. Create table
curl --location --request POST 'http://127.0.0.1:5440/sql' --data-raw '
CREATE TABLE `demo` (
    `name` string TAG,
    `value` double NOT NULL,
    `t` timestamp NOT NULL,
    `t2` timestamp NOT NULL,
    timestamp KEY (t))
ENGINE=Analytic
  with
(enable_ttl="false")
  1. Insert a row
curl --location --request POST 'http://127.0.0.1:5440/sql' --data-raw '
INSERT INTO demo (t, t2, name, value)
    VALUES (1651737067000, 1651737067009, "ceresdb", 100)
'
  1. Query by http interface
curl --location --request POST 'http://127.0.0.1:5440/sql' --data-raw '
SELECT t, avg(value) FROM `demo` group by t
'

response:

{"rows":[{"t":1651737067000,"AVG(demo.value)":100.0}]}
  1. Query by Java SDK
        CeresDBClient client = getClient();
        String query = "SELECT t, avg(value) FROM `demo` group by t";
        SqlQueryRequest request = new SqlQueryRequest(query);
        CompletableFuture<Result<SqlQueryOk, Err>> future = client.sqlQuery(request);
        Result<SqlQueryOk, Err> result = future.get();
        System.out.println(result);

The response's rowCount is 0.

Expected behavior

Additional Information

garbled characters

Describe this problem
Using the image of ceresdb:v1.0.0 and the sdk of version 1.0.1, when the query data contains Chinese characters, some servers have garbled characters

Steps to reproduce
By setting JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=US-ASCII"

Expected behavior
Chinese characters are not garbled

Additional Information

bug: Query failed when aliasing a table name in sql

Describe this problem

It occurs Table not found when aliasing a table name in sql

Steps to reproduce

Run this sql with sdk

select * from `SPM_2197803522_INFLUENCE_DEFAULT` t1 
WHERE 
t1.`period` between '2023-03-22 11:09:00' and  '2023-03-22 11:09:59'
limit 10

Expected behavior

No error happened

Additional Information

support eclipse dev environment

Eclipse will produce some config file, should be ignored
image

Eclipse m2e errors, such as:

  • Plugin execution not covered by lifecycle configuration: com.googlecode.maven-java-formatter-plugin:maven-java-formatter-plugin:0.4:format (execution: default, phase: process-sources)

Report NPE for table error while creating table

Describe this problem

ceresdb server is running as single mode, image: ceresdb/ceresdb-server: nightly-20230223-ce9fa87

Report NPE for table error while creating table

Steps to reproduce

Expected behavior

Additional Information

Remove the protos and generated codes inside this project.

Description

The proto files and generated code should be managed in a single repo, rather than scatter them everywhere. It will be more maintainable that other projects depend on one single proto repo.

Proposal

Since ceresdb-client-java is a pure Java written project, we can add ceresdb-proto-internal as a dependency to the pom. And then remove the protos and related codes maintained inside this project.

Additional context

no

code formatter settings does not work sometimes.

Describe this problem

When there are lambda expressions in the code files, code formatter does not work.

Steps to reproduce

use maven -X to see the debug log

Expected behavior

All java codes, except the generated files should be formatted.

Additional Information

Memory leak for java SDK

Describe this problem

Memory leak for sdk 1.0.0

Steps to reproduce

Expected behavior

Additional Information

It's time to make a first formal release

Description
Current client APIs are stable and have passed many tests in different scenarios. It's time to make a first formal release.

Proposal

Release 0.1.0

Additional context
No.

Feat: Support refresh table routing info in Client

Description

I found table routeCache will not refresh when routeCache size is too small.

   if (this.routeCache.size() < this.opts.getMaxCachedSize() * CLEAN_CACHE_THRESHOLD) {
            LOG.info("Now that the number of cached entries is {}.", this.routeCache.size());
            return times;
        }

The problem is:
Request will be routed to wrong server after table is recreated.

Proposal

Support refresh table routing info in Client periodly

Additional context

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.