From ff447680096a18348e1db5487459260a91e477d7 Mon Sep 17 00:00:00 2001 From: Arthur Chern Date: Mon, 20 Jun 2022 14:54:12 +0800 Subject: [PATCH 1/4] docs: update readme --- README.md | 190 +++++++++++++++++++++++++++++++++++++++++++++- docs/README.md | 75 +++++++++--------- docs/README_CN.md | 187 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 416 insertions(+), 36 deletions(-) create mode 100644 docs/README_CN.md diff --git a/README.md b/README.md index 065e074..bc033a3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,188 @@ -# ceresdb-java-client -Java client for CeresDB +# CeresDB Java Client +[中文](./docs/README_CN.md) + +## Introduction +CeresDBxClient is a high-performance Java client for CeresDB. CeresDB is a high-performance, distributed, schema-less, cloud native time-series database that can handle both time-series and analytics workloads. + +## 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 + +``` + ┌─────────────────────┐ + │ CeresDBxClient │ + └─────────────────────┘ + │ + ▼ + ┌─────────────────────┐ + │ WriteClient │───┐ + └─────────────────────┘ │ + │ Async to retry and merge responses + │ │ + ┌────Split requests │ + │ │ + │ ┌─────────────────────┐ │ ┌─────────────────────┐ ┌─────────────────────┐ + └─▶│ RouterClient │◀─┴──▶│ RouterCache │◀─────▶│ RouterFor │ + └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ + ▲ │ + │ │ + ▼ │ + ┌─────────────────────┐ │ + │ RpcClient │◀──────────────────────────────────────────────┘ + └─────────────────────┘ + ▲ + │ + ▼ + ┌─────────────────────┐ + │ Default gRPC impl │ + └─────────────────────┘ + ▲ + │ + ┌───────────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ + │ │ + ▼ ▼ ▼ +┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ +│ CeresDBx Node1 │ │ CeresDBx Node2 │ │ ... │ +└─────────────────────┘ └─────────────────────┘ └─────────────────────┘ +``` + +## Data query process +``` + ┌─────────────────────┐ + │ CeresDBxClient │ + └─────────────────────┘ + │ + ▼ + ┌─────────────────────┐ + │ QueryClient │───┐ + └─────────────────────┘ │ + │ │Async to retry + │ │ + ┌────────────┘ │ + │ │ + │ ┌─────────────────────┐ │ ┌─────────────────────┐ ┌─────────────────────┐ + └─▶│ RouterClient │◀─┴──▶│ RouterCache │◀─────▶│ RouterFor │ + └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ + ▲ │ + │ │ + ▼ │ + ┌─────────────────────┐ │ + │ RpcClient │◀──────────────────────────────────────────────┘ + └─────────────────────┘ + ▲ + │ + ▼ + ┌─────────────────────┐ + │ Default gRPC impl │ + └─────────────────────┘ + ▲ + │ + ┌───────────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ + │ │ + ▼ ▼ ▼ +┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ +│ CeresDBx Node1 │ │ CeresDBx Node2 │ │ ... │ +└─────────────────────┘ └─────────────────────┘ └─────────────────────┘ +``` + +## Requirements +- Java 8 or later is required for compilation + + +## Create table +CeresDB is a Schema-less time-series database, so creating table schema ahead of data ingestion is not required (CeresDB 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 CeresDB: + +```java +SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" + + "ts TIMESTAMP NOT NULL," + + "c1 STRING TAG NOT NULL," + + "c2 STRING TAG NOT NULL," + + "c3 DOUBLE NULL," + + "c4 STRING NULL," + + "c5 INT64 NULL," + + "c6 FLOAT NULL," + + "c7 INT32 NULL," + + "c8 INT16 NULL," + + "c9 INT8 NULL," + + "c10 BOOLEAN NULL," + "c11 UINT64 NULL," + "c12 UINT32 NULL," + "c13 UINT16 NULL," + "c14 UINT8 NULL," + "c15 TIMESTAMP NULL," + "c16 VARBINARY NULL," + "TIMESTAMP KEY(ts)) ENGINE=Analytic" +); +``` + +For more examples of table creation statements, see the detail docs [here](./table.md) + + +## Data ingestion example +```java +// CeresDBx options +final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8081) // + .tenant("test", "sub_test", "test_token") // tenant info + .writeMaxRetries(1) // maximum retry times when write fails (only some error codes will be retried, such as the routing table failure) + .readMaxRetries(1) // maximum retry times when read fails (only some error codes will be retried, such as the routing table failure) + .build(); + +final CeresDBxClient client = new CeresDBxClient(); +if (!client.init(this.opts)) { + throw new IllegalStateException("Fail to start CeresDBxClient"); +} + +final long t0 = System.currentTimeMillis(); +final long t1 = t0 + 1000; +final long t2 = t1 + 1000; +final Rows data = Series.newBuilder("machine_metric") + .tag("city", "Singapore") + .tag("ip", "127.0.01") + .toRowsBuilder() + // codes below organizes 3 lines data (3 timestamps) for the `cpu` and `mem` column, this will just transport once through network. CeresDB encourage practices like this, because the SDK could use efficient compression algorithm to reduce network overhead and also be friedly to the sever side. + .field(t0, "cpu", FieldValue.withDouble(0.23)) // first row, first column + .field(t0, "mem", FieldValue.withDouble(0.55)) // first row, second column + .field(t1, "cpu", FieldValue.withDouble(0.25)) // second row, first column + .field(t1, "mem", FieldValue.withDouble(0.56)) // second row, second column + .field(t2, "cpu", FieldValue.withDouble(0.21)) // third row, first column + .field(t2, "mem", FieldValue.withDouble(0.52)) // third row, second column + .build(); + +final CompletableFuture> wf = client.write(data); +// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API +final Result wr = wf.get(); + +Assert.assertTrue(wr.isOk()); +Assert.assertEquals(3, wr.getOk().getSuccess()); +// `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, wr.mapOr(0, WriteOk::getSuccess())); +Assert.assertEquals(0, wr.getOk().getFailed()); +Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed)); + +final QueryRequest queryRequest = QueryRequest.newBuilder() + .forMetrics("machine_metric") // table name is optional. If not provided, SQL parser will parse the `ql` to get the table name and do the routing automaticly + .ql("select timestamp, cpu, mem from machine_metric") // + .build(); +final CompletableFuture> qf = client.query(queryRequest); +// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API +final Result qr = qf.get(); + +Assert.assertTrue(qr.isOk()); + +final QueryOk queryOk = qr.getOk(); + +final List records = queryOk.mapToRecord().collect(Collectors.toList()) +``` +## Licensing +CeresDB and its Java client is under [Apache License 2.0](./LICENSE). + +## Community and support +- Join the user group on [Slack](https://join.slack.com/t/ceresdbcommunity/shared_invite/zt-1au1ihbdy-5huC9J9s2462yBMIWmerTw) +- Join the use group on WeChat [WeChat QR code](https://github.com/CeresDB/assets/blob/main/WeChatQRCode.jpg) +- Join the user group on DingTalk: 44602802 \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 959fe84..7d3edda 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,13 +1,15 @@ -# CeresDB client -CeresDBxClient 是 CeresDB 的高性能 Java 版客户端,CeresDB 定位高性能的、分布式的、Schema-less 的 HTAP (Hybrid Timeseries/Analytic Processing) 型时间序列数据库。 +# CeresDB Java Client -## 功能特性 -- 通信层基于 SPI 可扩展,默认提供 gRPC 的实现 -- 提供纯异步的流式高性能写入 API -- 默认提供丰富的性能指标采集,可输指标统计到本地文件 -- 支持关键对象内存状态快照或配置输出到本地文件以协助排查问题 +## Introduction +CeresDBxClient is a high-performance Java client for CeresDB. CeresDB is a high-performance, distributed, schema-less, cloud native time-series database that can handle both time-series and analytics workloads. -## 写入流程图 +## 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 ``` ┌─────────────────────┐ @@ -47,7 +49,7 @@ CeresDBxClient 是 CeresDB 的高性能 Java 版客户端,CeresDB 定位高性 └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ ``` -## 查询流程 +## Data query process ``` ┌─────────────────────┐ │ CeresDBxClient │ @@ -86,14 +88,14 @@ CeresDBxClient 是 CeresDB 的高性能 Java 版客户端,CeresDB 定位高性 └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ ``` -## 需要 -编译需要 Java8 及以上 +## Requirements +- Java 8 or later is required for compilation + -## 建表 -CeresDB 是一个 Schema-less 的时序数据引擎,你可以不必创建 schema 就立刻写入数据(CeresDB 会根据你的第一次写入帮你创建一个默认的 schema)。 -当然你也可以自行创建一个 schema 来更精细化的管理的表(比如索引等) +## Create table +CeresDB is a Schema-less time-series database, so creating table schema ahead of data ingestion is not required (CeresDB 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). -下面的建表语句(使用 SDK 的 SQL API)包含了 CeresDB 支持的所有字段类型: +The following table creation statement(using the SQL API included in SDK )shows all field types supported by CeresDB: ```java SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" + @@ -118,15 +120,16 @@ SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" ); ``` -更多建表语句例子见 [这里](./table.md) +For more examples of table creation statements, see the detail docs [here](./table.md) + -## 写入 Example +## Data ingestion example ```java // CeresDBx options final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8081) // - .tenant("test", "sub_test", "test_token") // 租户信息 - .writeMaxRetries(1) // 写入失败重试次数上限(只有部分错误 code 才会重试,比如路由表失效) - .readMaxRetries(1) // 查询失败重试次数上限(只有部分错误 code 才会重试,比如路由表失效) + .tenant("test", "sub_test", "test_token") // tenant info + .writeMaxRetries(1) // maximum retry times when write fails (only some error codes will be retried, such as the routing table failure) + .readMaxRetries(1) // maximum retry times when read fails (only some error codes will be retried, such as the routing table failure) .build(); final CeresDBxClient client = new CeresDBxClient(); @@ -138,35 +141,35 @@ final long t0 = System.currentTimeMillis(); final long t1 = t0 + 1000; final long t2 = t1 + 1000; final Rows data = Series.newBuilder("machine_metric") - .tag("city", "Hangzhou") + .tag("city", "Singapore") .tag("ip", "127.0.01") .toRowsBuilder() - // 下面针对 cpu、mem 两列,一次写入了三行数据(3 个时间戳),CeresDB 鼓励这种实践,SDK 可以通过高效的压缩来减少网络传输,并且对 server 端写入非常友好 - .field(t0, "cpu", FieldValue.withDouble(0.23)) // 第 1 行第 1 列 - .field(t0, "mem", FieldValue.withDouble(0.55)) // 第 1 行第 2 列 - .field(t1, "cpu", FieldValue.withDouble(0.25)) // 第 2 行第 1 列 - .field(t1, "mem", FieldValue.withDouble(0.56)) // 第 2 行第 2 列 - .field(t2, "cpu", FieldValue.withDouble(0.21)) // 第 3 行第 1 列 - .field(t2, "mem", FieldValue.withDouble(0.52)) // 第 3 行第 2 列 + // codes below organizes 3 lines data (3 timestamps) for the `cpu` and `mem` column, this will just transport once through network. CeresDB encourage practices like this, because the SDK could use efficient compression algorithm to reduce network overhead and also be friedly to the sever side. + .field(t0, "cpu", FieldValue.withDouble(0.23)) // first row, first column + .field(t0, "mem", FieldValue.withDouble(0.55)) // first row, second column + .field(t1, "cpu", FieldValue.withDouble(0.25)) // second row, first column + .field(t1, "mem", FieldValue.withDouble(0.56)) // second row, second column + .field(t2, "cpu", FieldValue.withDouble(0.21)) // third row, first column + .field(t2, "mem", FieldValue.withDouble(0.52)) // third row, second column .build(); final CompletableFuture> wf = client.write(data); -// 这里用 `future.get` 只是方便演示,推荐借助 CompletableFuture 强大的 API 实现异步编程 +// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API final Result wr = wf.get(); Assert.assertTrue(wr.isOk()); Assert.assertEquals(3, wr.getOk().getSuccess()); -// `Result` 类参考了 Rust 语言,提供了丰富的 mapXXX、andThen 类 function 方便对结果值进行转换,提高编程效率,欢迎参考 API 文档使用 +// `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, wr.mapOr(0, WriteOk::getSuccess())); Assert.assertEquals(0, wr.getOk().getFailed()); Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed)); final QueryRequest queryRequest = QueryRequest.newBuilder() - .forMetrics("machine_metric") // 表名可选填,不填的话 SQL Parser 会自动解析 ql 涉及到的表名并完成自动路由 + .forMetrics("machine_metric") // table name is optional. If not provided, SQL parser will parse the `ql` to get the table name and do the routing automaticly .ql("select timestamp, cpu, mem from machine_metric") // .build(); final CompletableFuture> qf = client.query(queryRequest); -// 这里用 `future.get` 只是方便演示,推荐借助 CompletableFuture 强大的 API 实现异步编程 +// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API final Result qr = qf.get(); Assert.assertTrue(qr.isOk()); @@ -175,6 +178,10 @@ final QueryOk queryOk = qr.getOk(); final List records = queryOk.mapToRecord().collect(Collectors.toList()) ``` +## Licensing +CeresDB and its Java client is under [Apache License 2.0](./LICENSE). -## 技术支持 -- 顾客是上帝钉钉群:21983792 +## Community and support +- Join the user group on [Slack](https://join.slack.com/t/ceresdbcommunity/shared_invite/zt-1au1ihbdy-5huC9J9s2462yBMIWmerTw) +- Join the use group on WeChat [WeChat QR code](https://github.com/CeresDB/assets/blob/main/WeChatQRCode.jpg) +- Join the user group on DingTalk: 44602802 \ No newline at end of file diff --git a/docs/README_CN.md b/docs/README_CN.md new file mode 100644 index 0000000..65ed8bb --- /dev/null +++ b/docs/README_CN.md @@ -0,0 +1,187 @@ +# CeresDB Java Client + +## 介绍 +CeresDBxClient 是 CeresDB 的高性能 Java 版客户端。CeresDB 是定位为高性能的、分布式的、Schema-less 的云原生时序数据库。它可以同时支持时间序列和数据分析型的工作负载。 + +## 功能特性 +- 通信层基于 SPI 可扩展,默认提供 gRPC 的实现 +- 提供纯异步的流式高性能写入 API +- 默认提供丰富的性能指标采集,可输指标统计到本地文件 +- 支持关键对象内存状态快照或配置输出到本地文件以协助排查问题 + +## 写入流程图 + +``` + ┌─────────────────────┐ + │ CeresDBxClient │ + └─────────────────────┘ + │ + ▼ + ┌─────────────────────┐ + │ WriteClient │───┐ + └─────────────────────┘ │ + │ Async to retry and merge responses + │ │ + ┌────Split requests │ + │ │ + │ ┌─────────────────────┐ │ ┌─────────────────────┐ ┌─────────────────────┐ + └─▶│ RouterClient │◀─┴──▶│ RouterCache │◀─────▶│ RouterFor │ + └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ + ▲ │ + │ │ + ▼ │ + ┌─────────────────────┐ │ + │ RpcClient │◀──────────────────────────────────────────────┘ + └─────────────────────┘ + ▲ + │ + ▼ + ┌─────────────────────┐ + │ Default gRPC impl │ + └─────────────────────┘ + ▲ + │ + ┌───────────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ + │ │ + ▼ ▼ ▼ +┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ +│ CeresDBx Node1 │ │ CeresDBx Node2 │ │ ... │ +└─────────────────────┘ └─────────────────────┘ └─────────────────────┘ +``` + +## 查询流程 +``` + ┌─────────────────────┐ + │ CeresDBxClient │ + └─────────────────────┘ + │ + ▼ + ┌─────────────────────┐ + │ QueryClient │───┐ + └─────────────────────┘ │ + │ │Async to retry + │ │ + ┌────────────┘ │ + │ │ + │ ┌─────────────────────┐ │ ┌─────────────────────┐ ┌─────────────────────┐ + └─▶│ RouterClient │◀─┴──▶│ RouterCache │◀─────▶│ RouterFor │ + └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ + ▲ │ + │ │ + ▼ │ + ┌─────────────────────┐ │ + │ RpcClient │◀──────────────────────────────────────────────┘ + └─────────────────────┘ + ▲ + │ + ▼ + ┌─────────────────────┐ + │ Default gRPC impl │ + └─────────────────────┘ + ▲ + │ + ┌───────────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ + │ │ + ▼ ▼ ▼ +┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ +│ CeresDBx Node1 │ │ CeresDBx Node2 │ │ ... │ +└─────────────────────┘ └─────────────────────┘ └─────────────────────┘ +``` + +## 需要 +编译需要 Java 8 及以上 + +## 建表 +CeresDB 是一个 Schema-less 的时序数据引擎,你可以不必创建 schema 就立刻写入数据(CeresDB 会根据你的第一次写入帮你创建一个默认的 schema)。 +当然你也可以自行创建一个 schema 来更精细化的管理的表(比如索引等) + +下面的建表语句(使用 SDK 的 SQL API)包含了 CeresDB 支持的所有字段类型: + +```java +SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" + + "ts TIMESTAMP NOT NULL," + + "c1 STRING TAG NOT NULL," + + "c2 STRING TAG NOT NULL," + + "c3 DOUBLE NULL," + + "c4 STRING NULL," + + "c5 INT64 NULL," + + "c6 FLOAT NULL," + + "c7 INT32 NULL," + + "c8 INT16 NULL," + + "c9 INT8 NULL," + + "c10 BOOLEAN NULL," + "c11 UINT64 NULL," + "c12 UINT32 NULL," + "c13 UINT16 NULL," + "c14 UINT8 NULL," + "c15 TIMESTAMP NULL," + "c16 VARBINARY NULL," + "TIMESTAMP KEY(ts)) ENGINE=Analytic" +); +``` + +更多建表语句例子见 [这里](./table.md) + +## 写入 Example +```java +// CeresDBx options +final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8081) // + .tenant("test", "sub_test", "test_token") // 租户信息 + .writeMaxRetries(1) // 写入失败重试次数上限(只有部分错误 code 才会重试,比如路由表失效) + .readMaxRetries(1) // 查询失败重试次数上限(只有部分错误 code 才会重试,比如路由表失效) + .build(); + +final CeresDBxClient client = new CeresDBxClient(); +if (!client.init(this.opts)) { + throw new IllegalStateException("Fail to start CeresDBxClient"); +} + +final long t0 = System.currentTimeMillis(); +final long t1 = t0 + 1000; +final long t2 = t1 + 1000; +final Rows data = Series.newBuilder("machine_metric") + .tag("city", "Singapore") + .tag("ip", "127.0.01") + .toRowsBuilder() + // 下面针对 cpu、mem 两列,一次写入了三行数据(3 个时间戳),CeresDB 鼓励这种实践,SDK 可以通过高效的压缩来减少网络传输,并且对 server 端写入非常友好 + .field(t0, "cpu", FieldValue.withDouble(0.23)) // 第 1 行第 1 列 + .field(t0, "mem", FieldValue.withDouble(0.55)) // 第 1 行第 2 列 + .field(t1, "cpu", FieldValue.withDouble(0.25)) // 第 2 行第 1 列 + .field(t1, "mem", FieldValue.withDouble(0.56)) // 第 2 行第 2 列 + .field(t2, "cpu", FieldValue.withDouble(0.21)) // 第 3 行第 1 列 + .field(t2, "mem", FieldValue.withDouble(0.52)) // 第 3 行第 2 列 + .build(); + +final CompletableFuture> wf = client.write(data); +// 这里用 `future.get` 只是方便演示,推荐借助 CompletableFuture 强大的 API 实现异步编程 +final Result wr = wf.get(); + +Assert.assertTrue(wr.isOk()); +Assert.assertEquals(3, wr.getOk().getSuccess()); +// `Result` 类参考了 Rust 语言,提供了丰富的 mapXXX、andThen 类 function 方便对结果值进行转换,提高编程效率,欢迎参考 API 文档使用 +Assert.assertEquals(3, wr.mapOr(0, WriteOk::getSuccess())); +Assert.assertEquals(0, wr.getOk().getFailed()); +Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed)); + +final QueryRequest queryRequest = QueryRequest.newBuilder() + .forMetrics("machine_metric") // 表名可选填,不填的话 SQL Parser 会自动解析 ql 涉及到的表名并完成自动路由 + .ql("select timestamp, cpu, mem from machine_metric") // + .build(); +final CompletableFuture> qf = client.query(queryRequest); +// 这里用 `future.get` 只是方便演示,推荐借助 CompletableFuture 强大的 API 实现异步编程 +final Result qr = qf.get(); + +Assert.assertTrue(qr.isOk()); + +final QueryOk queryOk = qr.getOk(); + +final List records = queryOk.mapToRecord().collect(Collectors.toList()) +``` + +## Licensing +CeresDB 与其 Java client 都遵守 [Apache License 2.0](./LICENSE). + +## 社区与技术支持 +- 加入 Slack 社区与用户群:[Slack 入口](https://join.slack.com/t/ceresdbcommunity/shared_invite/zt-1au1ihbdy-5huC9J9s2462yBMIWmerTw) +- 加入微信社区与用户群 [微信二维码](https://github.com/CeresDB/assets/blob/main/WeChatQRCode.jpg) +- 搜索并加入钉钉社区与用户群: 44602802 From 8d5dc5ca89dde3904c6c0586c73787fdf8aceb6f Mon Sep 17 00:00:00 2001 From: Arthur Chern Date: Mon, 20 Jun 2022 16:08:50 +0800 Subject: [PATCH 2/4] docs: resolve doc reviewed problems --- README.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bc033a3..14102e6 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,13 @@ [中文](./docs/README_CN.md) ## Introduction -CeresDBxClient is a high-performance Java client for CeresDB. CeresDB is a high-performance, distributed, schema-less, cloud native time-series database that can handle both time-series and analytics workloads. +CeresDBxClient is a high-performance Java client for CeresDB. +CeresDB is a high-performance, distributed, schema-less, cloud native time-series database that can handle both time-series and analytics workloads. ## 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 +- 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 @@ -121,7 +122,7 @@ SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" ); ``` -For more examples of table creation statements, see the detail docs [here](./table.md) +For more examples of table creation statements, see the detail docs [here](./docs/table.md) ## Data ingestion example @@ -129,8 +130,12 @@ For more examples of table creation statements, see the detail docs [here](./tab // CeresDBx options final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8081) // .tenant("test", "sub_test", "test_token") // tenant info - .writeMaxRetries(1) // maximum retry times when write fails (only some error codes will be retried, such as the routing table failure) - .readMaxRetries(1) // maximum retry times when read fails (only some error codes will be retried, such as the routing table failure) + // 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 CeresDBxClient client = new CeresDBxClient(); @@ -185,4 +190,4 @@ CeresDB and its Java client is under [Apache License 2.0](./LICENSE). ## Community and support - Join the user group on [Slack](https://join.slack.com/t/ceresdbcommunity/shared_invite/zt-1au1ihbdy-5huC9J9s2462yBMIWmerTw) - Join the use group on WeChat [WeChat QR code](https://github.com/CeresDB/assets/blob/main/WeChatQRCode.jpg) -- Join the user group on DingTalk: 44602802 \ No newline at end of file +- Join the user group on DingTalk: 44602802 From 8d720b3d33e655ae01ea805ca7f796b4185476b5 Mon Sep 17 00:00:00 2001 From: Arthur Chern Date: Mon, 20 Jun 2022 17:51:38 +0800 Subject: [PATCH 3/4] docs: reorganize README.md and README_CN.md --- README.md | 9 +- docs/README_CN.md => README_CN.md | 2 - docs/README.md | 187 ------------------------------ 3 files changed, 3 insertions(+), 195 deletions(-) rename docs/README_CN.md => README_CN.md (99%) delete mode 100644 docs/README.md diff --git a/README.md b/README.md index 14102e6..59044e8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # CeresDB Java Client -[中文](./docs/README_CN.md) +[中文](./README_CN.md) ## Introduction -CeresDBxClient is a high-performance Java client for CeresDB. +CeresDBxClient is a high-performance Java client for CeresDB. CeresDB is a high-performance, distributed, schema-less, cloud native time-series database that can handle both time-series and analytics workloads. ## Features @@ -122,9 +122,6 @@ SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" ); ``` -For more examples of table creation statements, see the detail docs [here](./docs/table.md) - - ## Data ingestion example ```java // CeresDBx options @@ -185,7 +182,7 @@ final QueryOk queryOk = qr.getOk(); final List records = queryOk.mapToRecord().collect(Collectors.toList()) ``` ## Licensing -CeresDB and its Java client is under [Apache License 2.0](./LICENSE). +Under [Apache License 2.0](./LICENSE). ## Community and support - Join the user group on [Slack](https://join.slack.com/t/ceresdbcommunity/shared_invite/zt-1au1ihbdy-5huC9J9s2462yBMIWmerTw) diff --git a/docs/README_CN.md b/README_CN.md similarity index 99% rename from docs/README_CN.md rename to README_CN.md index 65ed8bb..e87968a 100644 --- a/docs/README_CN.md +++ b/README_CN.md @@ -120,8 +120,6 @@ SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" ); ``` -更多建表语句例子见 [这里](./table.md) - ## 写入 Example ```java // CeresDBx options diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 7d3edda..0000000 --- a/docs/README.md +++ /dev/null @@ -1,187 +0,0 @@ -# CeresDB Java Client - -## Introduction -CeresDBxClient is a high-performance Java client for CeresDB. CeresDB is a high-performance, distributed, schema-less, cloud native time-series database that can handle both time-series and analytics workloads. - -## 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 - -``` - ┌─────────────────────┐ - │ CeresDBxClient │ - └─────────────────────┘ - │ - ▼ - ┌─────────────────────┐ - │ WriteClient │───┐ - └─────────────────────┘ │ - │ Async to retry and merge responses - │ │ - ┌────Split requests │ - │ │ - │ ┌─────────────────────┐ │ ┌─────────────────────┐ ┌─────────────────────┐ - └─▶│ RouterClient │◀─┴──▶│ RouterCache │◀─────▶│ RouterFor │ - └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ - ▲ │ - │ │ - ▼ │ - ┌─────────────────────┐ │ - │ RpcClient │◀──────────────────────────────────────────────┘ - └─────────────────────┘ - ▲ - │ - ▼ - ┌─────────────────────┐ - │ Default gRPC impl │ - └─────────────────────┘ - ▲ - │ - ┌───────────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ - │ │ - ▼ ▼ ▼ -┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ -│ CeresDBx Node1 │ │ CeresDBx Node2 │ │ ... │ -└─────────────────────┘ └─────────────────────┘ └─────────────────────┘ -``` - -## Data query process -``` - ┌─────────────────────┐ - │ CeresDBxClient │ - └─────────────────────┘ - │ - ▼ - ┌─────────────────────┐ - │ QueryClient │───┐ - └─────────────────────┘ │ - │ │Async to retry - │ │ - ┌────────────┘ │ - │ │ - │ ┌─────────────────────┐ │ ┌─────────────────────┐ ┌─────────────────────┐ - └─▶│ RouterClient │◀─┴──▶│ RouterCache │◀─────▶│ RouterFor │ - └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ - ▲ │ - │ │ - ▼ │ - ┌─────────────────────┐ │ - │ RpcClient │◀──────────────────────────────────────────────┘ - └─────────────────────┘ - ▲ - │ - ▼ - ┌─────────────────────┐ - │ Default gRPC impl │ - └─────────────────────┘ - ▲ - │ - ┌───────────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ - │ │ - ▼ ▼ ▼ -┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ -│ CeresDBx Node1 │ │ CeresDBx Node2 │ │ ... │ -└─────────────────────┘ └─────────────────────┘ └─────────────────────┘ -``` - -## Requirements -- Java 8 or later is required for compilation - - -## Create table -CeresDB is a Schema-less time-series database, so creating table schema ahead of data ingestion is not required (CeresDB 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 CeresDB: - -```java -SqlResult result = client.management().executeSql("CREATE TABLE MY_FIRST_TABL(" + - "ts TIMESTAMP NOT NULL," + - "c1 STRING TAG NOT NULL," + - "c2 STRING TAG NOT NULL," + - "c3 DOUBLE NULL," + - "c4 STRING NULL," + - "c5 INT64 NULL," + - "c6 FLOAT NULL," + - "c7 INT32 NULL," + - "c8 INT16 NULL," + - "c9 INT8 NULL," + - "c10 BOOLEAN NULL," - "c11 UINT64 NULL," - "c12 UINT32 NULL," - "c13 UINT16 NULL," - "c14 UINT8 NULL," - "c15 TIMESTAMP NULL," - "c16 VARBINARY NULL," - "TIMESTAMP KEY(ts)) ENGINE=Analytic" -); -``` - -For more examples of table creation statements, see the detail docs [here](./table.md) - - -## Data ingestion example -```java -// CeresDBx options -final CeresDBxOptions opts = CeresDBxOptions.newBuilder("127.0.0.1", 8081) // - .tenant("test", "sub_test", "test_token") // tenant info - .writeMaxRetries(1) // maximum retry times when write fails (only some error codes will be retried, such as the routing table failure) - .readMaxRetries(1) // maximum retry times when read fails (only some error codes will be retried, such as the routing table failure) - .build(); - -final CeresDBxClient client = new CeresDBxClient(); -if (!client.init(this.opts)) { - throw new IllegalStateException("Fail to start CeresDBxClient"); -} - -final long t0 = System.currentTimeMillis(); -final long t1 = t0 + 1000; -final long t2 = t1 + 1000; -final Rows data = Series.newBuilder("machine_metric") - .tag("city", "Singapore") - .tag("ip", "127.0.01") - .toRowsBuilder() - // codes below organizes 3 lines data (3 timestamps) for the `cpu` and `mem` column, this will just transport once through network. CeresDB encourage practices like this, because the SDK could use efficient compression algorithm to reduce network overhead and also be friedly to the sever side. - .field(t0, "cpu", FieldValue.withDouble(0.23)) // first row, first column - .field(t0, "mem", FieldValue.withDouble(0.55)) // first row, second column - .field(t1, "cpu", FieldValue.withDouble(0.25)) // second row, first column - .field(t1, "mem", FieldValue.withDouble(0.56)) // second row, second column - .field(t2, "cpu", FieldValue.withDouble(0.21)) // third row, first column - .field(t2, "mem", FieldValue.withDouble(0.52)) // third row, second column - .build(); - -final CompletableFuture> wf = client.write(data); -// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API -final Result wr = wf.get(); - -Assert.assertTrue(wr.isOk()); -Assert.assertEquals(3, wr.getOk().getSuccess()); -// `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, wr.mapOr(0, WriteOk::getSuccess())); -Assert.assertEquals(0, wr.getOk().getFailed()); -Assert.assertEquals(0, wr.mapOr(-1, WriteOk::getFailed)); - -final QueryRequest queryRequest = QueryRequest.newBuilder() - .forMetrics("machine_metric") // table name is optional. If not provided, SQL parser will parse the `ql` to get the table name and do the routing automaticly - .ql("select timestamp, cpu, mem from machine_metric") // - .build(); -final CompletableFuture> qf = client.query(queryRequest); -// here the `future.get` is just for demonstration, a better async programming practice would be using the CompletableFuture API -final Result qr = qf.get(); - -Assert.assertTrue(qr.isOk()); - -final QueryOk queryOk = qr.getOk(); - -final List records = queryOk.mapToRecord().collect(Collectors.toList()) -``` -## Licensing -CeresDB and its Java client is under [Apache License 2.0](./LICENSE). - -## Community and support -- Join the user group on [Slack](https://join.slack.com/t/ceresdbcommunity/shared_invite/zt-1au1ihbdy-5huC9J9s2462yBMIWmerTw) -- Join the use group on WeChat [WeChat QR code](https://github.com/CeresDB/assets/blob/main/WeChatQRCode.jpg) -- Join the user group on DingTalk: 44602802 \ No newline at end of file From 566bd8f6189169eadbcc6a0d88aec2350c37b034 Mon Sep 17 00:00:00 2001 From: Arthur Chern Date: Mon, 20 Jun 2022 17:58:24 +0800 Subject: [PATCH 4/4] docs: optimize README_CN.md --- README_CN.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README_CN.md b/README_CN.md index e87968a..5f338c4 100644 --- a/README_CN.md +++ b/README_CN.md @@ -177,9 +177,9 @@ final List records = queryOk.mapToRecord().collect(Collectors.toList()) ``` ## Licensing -CeresDB 与其 Java client 都遵守 [Apache License 2.0](./LICENSE). +遵守 [Apache License 2.0](./LICENSE). ## 社区与技术支持 -- 加入 Slack 社区与用户群:[Slack 入口](https://join.slack.com/t/ceresdbcommunity/shared_invite/zt-1au1ihbdy-5huC9J9s2462yBMIWmerTw) +- 加入 Slack 社区与用户群 [Slack 入口](https://join.slack.com/t/ceresdbcommunity/shared_invite/zt-1au1ihbdy-5huC9J9s2462yBMIWmerTw) - 加入微信社区与用户群 [微信二维码](https://github.com/CeresDB/assets/blob/main/WeChatQRCode.jpg) -- 搜索并加入钉钉社区与用户群: 44602802 +- 搜索并加入钉钉社区与用户群 44602802