未验证 提交 a726e411 编写于 作者: arielyangpan's avatar arielyangpan 提交者: GitHub

Merge branch 'taosdata:develop' into develop

# Alert # Alert
The Alert application reads data from [TDEngine](https://www.taosdata.com/), calculating according to predefined rules to generate alerts, and pushes alerts to downstream applications like [AlertManager](https://github.com/prometheus/alertmanager). The Alert application reads data from [TDengine](https://www.taosdata.com/), calculating according to predefined rules to generate alerts, and pushes alerts to downstream applications like [AlertManager](https://github.com/prometheus/alertmanager).
## Install ## Install
...@@ -22,7 +22,7 @@ $ ./install_driver.sh ...@@ -22,7 +22,7 @@ $ ./install_driver.sh
Two prerequisites are required to install from source. Two prerequisites are required to install from source.
1. TDEngine server or client must be installed. 1. TDengine server or client must be installed.
2. Latest [Go](https://golang.org) language must be installed. 2. Latest [Go](https://golang.org) language must be installed.
When these two prerequisites are ready, please follow steps below to build the application: When these two prerequisites are ready, please follow steps below to build the application:
...@@ -61,13 +61,13 @@ The use of each configuration item is: ...@@ -61,13 +61,13 @@ The use of each configuration item is:
* **port**: This is the `http` service port which enables other application to manage rules by `restful API`. * **port**: This is the `http` service port which enables other application to manage rules by `restful API`.
* **database**: rules are stored in a `sqlite` database, this is the path of the database file (if the file does not exist, the alert application creates it automatically). * **database**: rules are stored in a `sqlite` database, this is the path of the database file (if the file does not exist, the alert application creates it automatically).
* **tdengine**: connection string of `TDEngine` server (please refer the documentation of GO connector for the detailed format of this string), note the database name should be put in the `sql` field of a rule in most cases, thus it should NOT be included in the string. * **tdengine**: connection string of `TDengine` server (please refer the documentation of GO connector for the detailed format of this string), note the database name should be put in the `sql` field of a rule in most cases, thus it should NOT be included in the string.
* **log > level**: log level, could be `production` or `debug`. * **log > level**: log level, could be `production` or `debug`.
* **log > path**: log output file path. * **log > path**: log output file path.
* **receivers > alertManager**: the alert application pushes alerts to `AlertManager` at this URL. * **receivers > alertManager**: the alert application pushes alerts to `AlertManager` at this URL.
* **receivers > console**: print out alerts to console (stdout) or not. * **receivers > console**: print out alerts to console (stdout) or not.
When the configruation file is ready, the alert application can be started with below command (`alert.cfg` is the path of the configuration file): When the configuration file is ready, the alert application can be started with below command (`alert.cfg` is the path of the configuration file):
``` ```
$ ./alert -cfg alert.cfg $ ./alert -cfg alert.cfg
...@@ -75,7 +75,7 @@ $ ./alert -cfg alert.cfg ...@@ -75,7 +75,7 @@ $ ./alert -cfg alert.cfg
## Prepare an alert rule ## Prepare an alert rule
From technical aspect, an alert could be defined as: query and filter recent data from `TDEngine`, and calculating out a boolean value from these data according to a formula, and trigger an alert if the boolean value last for a certain duration. From technical aspect, an alert could be defined as: query and filter recent data from `TDengine`, and calculating out a boolean value from these data according to a formula, and trigger an alert if the boolean value last for a certain duration.
This is a rule example in `json` format: This is a rule example in `json` format:
...@@ -98,8 +98,8 @@ This is a rule example in `json` format: ...@@ -98,8 +98,8 @@ This is a rule example in `json` format:
The fields of the rule is explained below: The fields of the rule is explained below:
* **name**: the name of the rule, must be unique. * **name**: the name of the rule, must be unique.
* **sql**: this is the `sql` statement used to query data from `TDEngine`, columns of the query result are used in later processing, so please give the column an alias if aggregation functions are used. * **sql**: this is the `sql` statement used to query data from `TDengine`, columns of the query result are used in later processing, so please give the column an alias if aggregation functions are used.
* **expr**: an expression whose result is a boolean value, arithmatic and logical calculations can be included in the expression, and builtin functions (see below) are also supported. Alerts are only triggered when the expression evaluates to `true`. * **expr**: an expression whose result is a boolean value, arithmetic and logical calculations can be included in the expression, and builtin functions (see below) are also supported. Alerts are only triggered when the expression evaluates to `true`.
* **for**: this item is a duration which default value is zero second. when `expr` evaluates to `true` and last at least this duration, an alert is triggered. * **for**: this item is a duration which default value is zero second. when `expr` evaluates to `true` and last at least this duration, an alert is triggered.
* **period**: the interval for the alert application to check the rule, default is 1 minute. * **period**: the interval for the alert application to check the rule, default is 1 minute.
* **labels**: a label list, labels are used to generate alert information. note if the `sql` statement includes a `group by` clause, the `group by` columns are inserted into this list automatically. * **labels**: a label list, labels are used to generate alert information. note if the `sql` statement includes a `group by` clause, the `group by` columns are inserted into this list automatically.
......
# Alert # Alert
报警监测程序,从 [TDEngine](https://www.taosdata.com/) 读取数据后,根据预定义的规则计算和生成报警,并将它们推送到 [AlertManager](https://github.com/prometheus/alertmanager) 或其它下游应用。 报警监测程序,从 [TDengine](https://www.taosdata.com/) 读取数据后,根据预定义的规则计算和生成报警,并将它们推送到 [AlertManager](https://github.com/prometheus/alertmanager) 或其它下游应用。
## 安装 ## 安装
...@@ -20,7 +20,7 @@ $ ./install_driver.sh ...@@ -20,7 +20,7 @@ $ ./install_driver.sh
### 从源码安装 ### 从源码安装
从源码安装需要在您用于编译的计算机上提前安装好 TDEngine 的服务端或客户端,如果您还没有安装,可以参考 TDEngine 的文档。 从源码安装需要在您用于编译的计算机上提前安装好 TDengine 的服务端或客户端,如果您还没有安装,可以参考 TDengine 的文档。
报警监测程序使用 [Go语言](https://golang.org) 开发,请安装最新版的 Go 语言编译环境。 报警监测程序使用 [Go语言](https://golang.org) 开发,请安装最新版的 Go 语言编译环境。
...@@ -58,7 +58,7 @@ $ go build ...@@ -58,7 +58,7 @@ $ go build
* **port**:报警监测程序支持使用 `restful API` 对规则进行管理,这个参数用于配置 `http` 服务的侦听端口。 * **port**:报警监测程序支持使用 `restful API` 对规则进行管理,这个参数用于配置 `http` 服务的侦听端口。
* **database**:报警监测程序将规则保存到了一个 `sqlite` 数据库中,这个参数用于指定数据库文件的路径(不需要提前创建这个文件,如果它不存在,程序会自动创建它)。 * **database**:报警监测程序将规则保存到了一个 `sqlite` 数据库中,这个参数用于指定数据库文件的路径(不需要提前创建这个文件,如果它不存在,程序会自动创建它)。
* **tdengine**`TDEngine` 的连接字符串(这个字符串的详细格式说明请见 GO 连接器的文档),一般来说,数据库名应该在报警规则的 `sql` 语句中指定,所以这个字符串中 **不** 应包含数据库名。 * **tdengine**`TDengine` 的连接字符串(这个字符串的详细格式说明请见 GO 连接器的文档),一般来说,数据库名应该在报警规则的 `sql` 语句中指定,所以这个字符串中 **不** 应包含数据库名。
* **log > level**:日志的记录级别,可选 `production``debug` * **log > level**:日志的记录级别,可选 `production``debug`
* **log > path**:日志文件的路径。 * **log > path**:日志文件的路径。
* **receivers > alertManager**:报警监测程序会将报警推送到 `AlertManager`,在这里指定 `AlertManager` 的接收地址。 * **receivers > alertManager**:报警监测程序会将报警推送到 `AlertManager`,在这里指定 `AlertManager` 的接收地址。
...@@ -72,7 +72,7 @@ $ ./alert -cfg alert.cfg ...@@ -72,7 +72,7 @@ $ ./alert -cfg alert.cfg
## 编写报警规则 ## 编写报警规则
从技术角度,可以将报警描述为:从 `TDEngine` 中查询最近一段时间、符合一定过滤条件的数据,并基于这些数据根据定义好的计算方法得出一个结果,当结果符合某个条件且持续一定时间后,触发报警。 从技术角度,可以将报警描述为:从 `TDengine` 中查询最近一段时间、符合一定过滤条件的数据,并基于这些数据根据定义好的计算方法得出一个结果,当结果符合某个条件且持续一定时间后,触发报警。
根据上面的描述,可以很容易的知道报警规则中需要包含的大部分信息。 以下是一个完整的报警规则,采用标准 `json` 格式: 根据上面的描述,可以很容易的知道报警规则中需要包含的大部分信息。 以下是一个完整的报警规则,采用标准 `json` 格式:
...@@ -95,7 +95,7 @@ $ ./alert -cfg alert.cfg ...@@ -95,7 +95,7 @@ $ ./alert -cfg alert.cfg
其中: 其中:
* **name**:用于为规则指定一个唯一的名字。 * **name**:用于为规则指定一个唯一的名字。
* **sql**:从 `TDEngine` 中查询数据时使用的 `sql` 语句,查询结果中的列将被后续计算使用,所以,如果使用了聚合函数,请为这一列指定一个别名。 * **sql**:从 `TDengine` 中查询数据时使用的 `sql` 语句,查询结果中的列将被后续计算使用,所以,如果使用了聚合函数,请为这一列指定一个别名。
* **expr**:一个计算结果为布尔型的表达式,支持算数运算、逻辑运算,并且内置了部分函数,也可以引用查询结果中的列。 当表达式计算结果为 `true` 时,进入报警状态。 * **expr**:一个计算结果为布尔型的表达式,支持算数运算、逻辑运算,并且内置了部分函数,也可以引用查询结果中的列。 当表达式计算结果为 `true` 时,进入报警状态。
* **for**:当表达式计算结果为 `true` 的连续时长超过这个选项时,触发报警,否则报警处于“待定”状态。默认为0,表示一旦计算结果为 `true`,立即触发报警。 * **for**:当表达式计算结果为 `true` 的连续时长超过这个选项时,触发报警,否则报警处于“待定”状态。默认为0,表示一旦计算结果为 `true`,立即触发报警。
* **period**:规则的检查周期,默认1分钟。 * **period**:规则的检查周期,默认1分钟。
......
...@@ -4,36 +4,71 @@ title: 产品简介 ...@@ -4,36 +4,71 @@ title: 产品简介
toc_max_heading_level: 2 toc_max_heading_level: 2
--- ---
## TDengine 简介 ## TDengine 主要功能
TDengine 是一款高性能、分布式、支持 SQL 的时序数据库。而且除时序数据库功能外,它还提供[缓存](/develop/cache/)、数据订阅、流式计算等功能,最大程度减少研发和运维的复杂度,且核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。与其他时序数据数据库相比,TDengine 有以下特点 TDengine 是一款高性能、分布式、支持 SQL 的时序数据库,其核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。TDengine 能被广泛运用于物联网、工业互联网、车联网、IT 运维、金融等领域。除核心的时序数据库功能外,TDengine 还提供[缓存](/develop/cache/)[数据订阅](/develop/subscribe)[流式计算](/develop/continuous-query)等大数据平台所需要的系列功能,最大程度减少研发和运维的复杂度。主要功能如下
- **高性能**:通过创新的存储引擎设计,无论是数据写入还是查询,TDengine 的性能比通用数据库快 10 倍以上,也远超其他时序数据库,而且存储空间也大为节省。 1. 高速数据写入,除 [SQL 写入](/develop/insert-data/sql-writing)外,还支持 [Schemaless 写入](/reference/schemaless/),支持 [InfluxDB LINE 协议](/develop/insert-data/influxdb-line)[OpenTSDB Telnet](/develop/insert-data/opentsdb-telnet), [OpenTSDB JSON ](/develop/insert-data/opentsdb-json)等协议写入;
2. 第三方数据采集工具 [Telegraf](/third-party/telegraf)[Prometheus](/third-party/prometheus)[StatsD](/third-party/statsd)[collectd](/third-party/collectd)[icinga2](/third-party/icinga2), [Tcollector](/third-party/tcollector), [EMQ](/third-party/emq-broker), [HiveMQ](/third-party/hive-mq-broker) 等都可以进行配置后,不用任何代码,即可将数据写入;
3. 支持[各种查询](/query-data),包括聚合查询、嵌套查询、降采样查询、插值等
4. 支持[用户自定义函数](/develop/udf)
5. 支持[缓存](/develop/cache),将每张表的最后一条记录缓存起来,这样无需 Redis
6. 支持[连续查询](/develop/continuous-query)(Continuous Query)
7. 支持[数据订阅](/develop/subscribe),而且可以指定过滤条件
8. 支持[集群](/cluster/),可以通过多节点进行水平扩展,并通过多副本实现高可靠
9. 提供[命令行程序](/reference/taos-shell),便于管理集群,检查系统状态,做即席查询
10. 提供多种数据的[导入](/operation/import)[导出](/operation/export)
11. 支持对[TDengine 集群本身的监控](/operation/monitor)
12. 提供 [C/C++](/reference/connector/cpp), [Java](/reference/connector/java), [Python](/reference/connector/python), [Go](/reference/connector/go), [Rust](/reference/connector/rust), [Node.js](/reference/connector/node) 等多种编程语言的[连接器](/reference/connector/)
13. 支持 [REST 接口](/reference/rest-api/)
14. 支持与[ Grafana 无缝集成](/third-party/grafana)
15. 支持与 Google Data Studio 无缝集成
- **分布式**:通过原生分布式的设计,TDengine 提供了水平扩展的能力,只需要增加节点就能获得更强的数据处理能力,同时通过多副本机制保证了系统的高可用 更多细小的功能,请阅读整个文档
- **支持 SQL**:TDengine 采用 SQL 作为数据查询语言,减少学习和迁移成本,同时提供 SQL 扩展来处理时序数据特有的分析,而且支持方便灵活的 schemaless 数据写入。 ## TDengine 主要亮点
由于 TDengine 充分利用了[时序数据特点](https://www.taosdata.com/blog/2019/07/09/105.html),比如结构化、无需事务、很少删除或更新、写多读少等等,设计了全新的针对时序数据的存储引擎和计算引擎,因此与其他时序数据库相比,TDengine 有以下特点:
- **[高性能](https://www.taosdata.com/fast)**:通过创新的存储引擎设计,无论是数据写入还是查询,TDengine 的性能比通用数据库快 10 倍以上,也远超其他时序数据库,而且存储空间也大为节省。
- **[分布式](https://www.taosdata.com/scalable)**:通过原生分布式的设计,TDengine 提供了水平扩展的能力,只需要增加节点就能获得更强的数据处理能力,同时通过多副本机制保证了系统的高可用。
- **[支持 SQL](https://www.taosdata.com/sql-support)**:TDengine 采用 SQL 作为数据查询语言,减少学习和迁移成本,同时提供 SQL 扩展来处理时序数据特有的分析,而且支持方便灵活的 schemaless 数据写入。
- **All in One**:将数据库、消息队列、缓存、流式计算等功能融合一起,应用无需再集成 Kafka/Redis/HBase/Spark 等软件,大幅降低应用开发和维护成本。 - **All in One**:将数据库、消息队列、缓存、流式计算等功能融合一起,应用无需再集成 Kafka/Redis/HBase/Spark 等软件,大幅降低应用开发和维护成本。
- **零管理**:安装、集群几秒搞定,无任何依赖,不用分库分表,系统运行状态监测能与 Grafana 或其他运维工具无缝集成。 - **零管理**:安装、集群几秒搞定,无任何依赖,不用分库分表,系统运行状态监测能与 Grafana 或其他运维工具无缝集成。
- **零学习成本**:采用 SQL 查询语言,支持 Python, Java, C/C++, Go, Rust, Node.js 等多种编程语言,与 MySQL 相似,零学习成本。 - **零学习成本**:采用 SQL 查询语言,支持 C/C++、Python、Java、Go、Rust、Node.js、C#、Lua(社区贡献)、PHP(社区贡献) 等多种编程语言,与 MySQL 相似,零学习成本。
- **无缝集成**:不用一行代码,即可与 Telegraf, Grafana, EMQX, Prometheus, StatsD, collectd, Matlab, R 等第三方工具无缝集成。 - **无缝集成**:不用一行代码,即可与 Telegraf、Grafana、Prometheus、EMQX、HiveMQ、StatsD、collectd、icinga、TCollector、Matlab、R 等第三方工具无缝集成。
- **互动 Console**: 通过命令行 console,不用编程,执行 SQL 语句就能做即席查询、各种数据库的操作、管理以及集群的维护. - **互动 Console**: 通过命令行 console,不用编程,执行 SQL 语句就能做即席查询、各种数据库的操作、管理以及集群的维护.
采用 TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。表现在几个方面,1:由于其超强性能,它能将系统需要的计算资源和存储资源大幅降低;2:因为采用SQL接口,能与众多第三放软件无缝集成,学习迁移成本大幅下降;3:因为其All In One的特性,系统复杂度降低,能降研发成本;4:因为运维维护简单,运营维护成本能大幅降低。 采用 TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。表现在几个方面:
1. 由于其超强性能,它能将系统需要的计算资源和存储资源大幅降低
2. 因为采用 SQL 接口,能与众多第三放软件无缝集成,学习迁移成本大幅下降
3. 因为其 All In One 的特性,系统复杂度降低,能降研发成本
4. 因为运维维护简单,运营维护成本能大幅降低
## TDengine 技术生态
在整个时序大数据平台中,TDengine 在其中扮演的角色如下:
<figure>
在整个时序大数据平台中,TDengine在其中扮演的角色如下:
![TDengine技术生态图](eco_system.png) ![TDengine技术生态图](eco_system.png)
</figure>
<center>图 1. TDengine技术生态图</center> <center>图 1. TDengine技术生态图</center>
上图中,左侧是各种数据采集或消息队列,包括 OPC-UA、MQTT、Telegraf、也包括 Kafaka, 他们的数据将被源源不断的写入到 TDengine。右侧则是可视化、BI 工具、组态软件、应用程序。下侧则是 TDengine 自身提供的命令行程序 (CLI) 以及可视化管理管理。
## TDengine 总体适用场景 ## TDengine 总体适用场景
作为一个高性能、分布式、支持 SQL 的时序数据库,TDengine 的典型适用场景包括但不限于 IoT、工业互联网、车联网、IT运维、能源、金融证券等领域。需要指出的是,TDengine是针对时序数据场景设计的专用数据库和专用大数据处理工具,因充分利用了时序大数据的特点,它无法用来处理网络爬虫、微博、微信、电商、ERP、CRM 等通用型数据。本文对适用场景做更多详细的分析。 作为一个高性能、分布式、支持 SQL 的时序数据库,TDengine 的典型适用场景包括但不限于 IoT、工业互联网、车联网、IT 运维、能源、金融证券等领域。需要指出的是,TDengine 是针对时序数据场景设计的专用数据库和专用大数据处理工具,因充分利用了时序大数据的特点,它无法用来处理网络爬虫、微博、微信、电商、ERP、CRM 等通用型数据。本文对适用场景做更多详细的分析。
### 数据源特点和需求 ### 数据源特点和需求
......
...@@ -2,158 +2,136 @@ ...@@ -2,158 +2,136 @@
title: 数据模型和基本概念 title: 数据模型和基本概念
--- ---
## 物联网典型场景 为了便于解释基本概念,便于撰写示例程序,整个 TDengine 文档以智能电表作为典型时序数据场景。假设每个智能电表采集电流、电压、相位三个量,有多个智能电表,每个电表有位置 location 和分组 group ID 的静态属性. 其采集的数据类似如下的表格:
在典型的物联网、车联网、运维监测场景中,往往有多种不同类型的数据采集设备或采集点,采集一个到多个不同的物理量。而同一种采集设备类型,往往又有多个具体的采集设备分布在不同的地点。采集的物理量都带有时间标签,而且数据量随时间不断增长,但每个数据采集设备或采集点还有自身的静态属性。对于同一类设备,其采集的数据以及静态属性都是很规则的。以智能电表为例,假设每个智能电表采集电流、电压、相位三个量,其采集的数据类似如下的表格:
<div className="center-table">
<table> <table>
<thead><tr> <thead><tr>
<th >设备ID</th> <th>Device ID</th>
<th >时间戳</th> <th>Time Stamp</th>
<th colspan="3">采集量</th> <th colSpan="3">Collected Metrics</th>
<th colspan="2">标签</th> <th colSpan="2">Tags</th>
</tr> </tr>
<tr> <tr>
<th >Device ID</th> <th>Device ID</th>
<th >Time Stamp</th> <th>Time Stamp</th>
<th >current</th> <th>current</th>
<th >voltage</th> <th>voltage</th>
<th >phase</th> <th>phase</th>
<th >location</th> <th>location</th>
<th >groupId</th> <th>groupId</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td >d1001</td> <td>d1001</td>
<td >1538548685000</td> <td>1538548685000</td>
<td >10.3</td> <td>10.3</td>
<td >219</td> <td>219</td>
<td >0.31</td> <td>0.31</td>
<td >Beijing.Chaoyang</td> <td>Beijing.Chaoyang</td>
<td >2</td> <td>2</td>
</tr> </tr>
<tr> <tr>
<td >d1002</td> <td>d1002</td>
<td >1538548684000</td> <td>1538548684000</td>
<td >10.2</td> <td>10.2</td>
<td >220</td> <td>220</td>
<td >0.23</td> <td>0.23</td>
<td >Beijing.Chaoyang</td> <td>Beijing.Chaoyang</td>
<td >3</td> <td>3</td>
</tr> </tr>
<tr> <tr>
<td >d1003</td> <td>d1003</td>
<td >1538548686500</td> <td>1538548686500</td>
<td >11.5</td> <td>11.5</td>
<td >221</td> <td>221</td>
<td >0.35</td> <td>0.35</td>
<td >Beijing.Haidian</td> <td>Beijing.Haidian</td>
<td >3</td> <td>3</td>
</tr> </tr>
<tr> <tr>
<td >d1004</td> <td>d1004</td>
<td >1538548685500</td> <td>1538548685500</td>
<td >13.4</td> <td>13.4</td>
<td >223</td> <td>223</td>
<td >0.29</td> <td>0.29</td>
<td >Beijing.Haidian</td> <td>Beijing.Haidian</td>
<td >2</td> <td>2</td>
</tr> </tr>
<tr> <tr>
<td >d1001</td> <td>d1001</td>
<td >1538548695000</td> <td>1538548695000</td>
<td >12.6</td> <td>12.6</td>
<td >218</td> <td>218</td>
<td >0.33</td> <td>0.33</td>
<td >Beijing.Chaoyang</td> <td>Beijing.Chaoyang</td>
<td >2</td> <td>2</td>
</tr> </tr>
<tr> <tr>
<td >d1004</td> <td>d1004</td>
<td >1538548696600</td> <td>1538548696600</td>
<td >11.8</td> <td>11.8</td>
<td >221</td> <td>221</td>
<td >0.28</td> <td>0.28</td>
<td >Beijing.Haidian</td> <td>Beijing.Haidian</td>
<td >2</td> <td>2</td>
</tr> </tr>
<tr> <tr>
<td >d1002</td> <td>d1002</td>
<td >1538548696650</td> <td>1538548696650</td>
<td >10.3</td> <td>10.3</td>
<td >218</td> <td>218</td>
<td >0.25</td> <td>0.25</td>
<td >Beijing.Chaoyang</td> <td>Beijing.Chaoyang</td>
<td >3</td> <td>3</td>
</tr> </tr>
<tr> <tr>
<td >d1001</td> <td>d1001</td>
<td >1538548696800</td> <td>1538548696800</td>
<td >12.3</td> <td>12.3</td>
<td >221</td> <td>221</td>
<td >0.31</td> <td>0.31</td>
<td >Beijing.Chaoyang</td> <td>Beijing.Chaoyang</td>
<td >2</td> <td>2</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<a href="#model_table1">表 1:智能电表数据示例</a>
</div>
<center> <a href="#model_table1">表 1:智能电表数据示例</a></center> 每一条记录都有设备 ID,时间戳,采集的物理量以及每个设备相关的静态标签。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。
每一条记录都有设备 ID,时间戳,采集的物理量(如上图中的电流、电压、相位),还有与每个设备相关的静态标签(如上述表 1 中的位置 location 和分组 groupId)。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。
## 数据特征
除时序特征外,仔细研究发现,物联网、车联网、运维监测类数据及其应用还具有很多其他明显的特征。
1. 数据是结构化的;
2. 数据极少有更新或删除操作;
3. 无需传统数据库的事务处理;
4. 相对互联网应用,写多读少;
5. 流量平稳,根据设备数量和采集频次,可以预测出来;
6. 用户关注的是一段时间的趋势,而不是某一特点时间点的值;
7. 数据是有保留期限的;
8. 数据的查询分析一定是基于时间段和地理区域的;
9. 系统需要各种实时计算和统计操作,包括降采样、插值等特种操作;
10. 数据量巨大,一天采集的数据就可以超过 100 亿条。
充分利用上述特征,TDengine 采取了一特殊的优化的存储和计算设计来处理时序数据,能将系统处理能力显著提高。
## 采集量(Metric) ## 采集量 (Metric)
采集量是指传感器、设备或其他类型采集点采集的物理量,比如电流、电压、温度、压力、GPS位置等,是随时间变化的,数据类型可以是整型、浮点型、布尔型,也可是字符串。随着时间的推移,存储的采集量的数据量越来越大。 采集量是指传感器、设备或其他类型采集点采集的物理量,比如电流、电压、温度、压力、GPS 位置等,是随时间变化的,数据类型可以是整型、浮点型、布尔型,也可是字符串。随着时间的推移,存储的采集量的数据量越来越大。
## 标签(Label/Tag) ## 标签 (Label/Tag)
标签是指传感器、设备或其他类型采集点的静态属性,不是随时间变化的,比如设备型号、颜色、设备的所在地等,数据类型可以是任何类型。虽然是静态的,但TDengine容许用户修改、删除或增加标签值。与采集量不一样的是,随时间的推移,存储的标签的数据量不会有什么变化。 标签是指传感器、设备或其他类型采集点的静态属性,不是随时间变化的,比如设备型号、颜色、设备的所在地等,数据类型可以是任何类型。虽然是静态的,但 TDengine 容许用户修改、删除或增加标签值。与采集量不一样的是,随时间的推移,存储的标签的数据量不会有什么变化。
## 数据采集点(Data Colletion Point) ## 数据采集点 (Data Collection Point)
数据采集点是指按照预设时间周期或受事件触发采集物理量的硬件或软件。一个数据采集点可以采集一个或多个物理量,**但这些物理量都是同一时刻采集的,具有相同的时间戳**。对于复杂的设备,往往有多个数据采集点,每个采集点采集的周期都可能不一样,而且完全独立,不同步。比如对于一台汽车,有数据采集点专门采集GPS位置,有数据采集点专门采集发动机状态,有数据采集点专门采集车内的环境,这样一台汽车就有三个数据采集点。 数据采集点是指按照预设时间周期或受事件触发采集物理量的硬件或软件。一个数据采集点可以采集一个或多个采集量,**但这些采集量都是同一时刻采集的,具有相同的时间戳**。对于复杂的设备,往往有多个数据采集点,每个数据采集点采集的周期都可能不一样,而且完全独立,不同步。比如对于一台汽车,有数据采集点专门采集 GPS 位置,有数据采集点专门采集发动机状态,有数据采集点专门采集车内的环境,这样一台汽车就有三个数据采集点。
## 关系型数据库模型 ## 表 (Table)
因为采集的数据一般是结构化数据,同时为降低学习门槛,TDengine 采用传统的关系型数据库模型管理数据。用户需要先创建库,然后创建表,之后才能插入或查询数据。TDengine 采用的是结构化存储,而不是 NoSQL 的 key-value 存储 因为采集量一般是结构化数据,同时为降低学习门槛,TDengine 采用传统的关系型数据库模型管理数据。用户需要先创建库,然后创建表,之后才能插入或查询数据
与通用数据库相比,TDengine通过一个数据采集点一张表,来大幅提高单个数据采集点的插入和查询速度。同时TDengine引入了超级表的概念,让每个表都带有标签,解决多个数据采集点之间的聚合分析问题。 为充分利用其数据的时序性和其他数据特点,TDengine 采取**一个数据采集点一张表**的策略,要求对每个数据采集点单独建表(比如有一千万个智能电表,就需创建一千万张表,上述表格中的 d1001,d1002,d1003,d1004 都需单独建表),用来存储这个数据采集点所采集的时序数据。这种设计有几大优点:
## 一个数据采集点一张表 1. 由于不同数据采集点产生数据的过程完全独立,每个数据采集点的数据源是唯一的,一张表也就只有一个写入者,这样就可采用无锁方式来写,写入速度就能大幅提升。
为充分利用其数据的时序性和其他数据特点,TDengine 要求**对每个数据采集点单独建表**(比如有一千万个智能电表,就需创建一千万张表,上述表格中的 d1001,d1002,d1003,d1004 都需单独建表),用来存储这个采集点所采集的时序数据。这种设计有几大优点:
1. 由于不同采集设备产生数据的过程完全独立,每个设备的数据源是唯一的,一张表也就只有一个写入者,这样就可采用无锁方式来写,写入速度就能大幅提升。
2. 对于一个数据采集点而言,其产生的数据是按照时间排序的,因此写的操作可用追加的方式实现,进一步大幅提高数据写入速度。 2. 对于一个数据采集点而言,其产生的数据是按照时间排序的,因此写的操作可用追加的方式实现,进一步大幅提高数据写入速度。
3. 一个数据采集点的数据是以块为单位连续存储的。如果读取一个时间段的数据,它能大幅减少随机读取操作,成数量级的提升读取和查询速度。 3. 一个数据采集点的数据是以块为单位连续存储的。如果读取一个时间段的数据,它能大幅减少随机读取操作,成数量级的提升读取和查询速度。
4. 一个数据块内部,采用列式存储,对于不同数据类型,采用不同压缩算法,而且由于一个数据采集点的采集量的变化是缓慢的,压缩率更高。 4. 一个数据块内部,采用列式存储,对于不同数据类型,采用不同压缩算法,而且由于一个数据采集点的采集量的变化是缓慢的,压缩率更高。
如果采用传统的方式,将多个设备的数据写入一张表,由于网络延时不可控,不同设备的数据到达服务器的时序是无法保证的,写入操作是要有锁保护的,而且一个设备的数据是难以保证连续存储在一起的。**采用一个数据采集点一张表的方式,能最大程度的保证单个数据采集点的插入和查询的性能是最优的。** 如果采用传统的方式,将多个数据采集点的数据写入一张表,由于网络延时不可控,不同数据采集点的数据到达服务器的时序是无法保证的,写入操作是要有锁保护的,而且一个数据采集点的数据是难以保证连续存储在一起的。**采用一个数据采集点一张表的方式,能最大程度的保证单个数据采集点的插入和查询的性能是最优的。**
TDengine 建议用数据采集点的名字(如上表中的 D1001)来做表名。每个数据采集点可能同时采集多个物理量(如上表中的 curent,voltage,phase),每个物理量对应一张表中的一列,数据类型可以是整型、浮点型、字符串等。除此之外,表的第一列必须是时间戳,即数据类型为 timestamp。对采集的数据,TDengine 将自动按照时间戳建立索引,但对采集的物理量不建任何索引。数据用列式存储方式保存。 TDengine 建议用数据采集点的名字(如上表中的 D1001)来做表名。每个数据采集点可能同时采集多个采集量(如上表中的 curent,voltage,phase),每个采集量对应一张表中的一列,数据类型可以是整型、浮点型、字符串等。除此之外,表的第一列必须是时间戳,即数据类型为 timestamp。对采集量,TDengine 将自动按照时间戳建立索引,但对采集量本身不建任何索引。数据用列式存储方式保存。
对于复杂的设备,比如汽车,它有多个数据采集点,那么就需要为一台汽车建立多张表。 对于复杂的设备,比如汽车,它有多个数据采集点,那么就需要为一台汽车建立多张表。
## 超级表:同一类型数据采集点的集合 ## 超级表 (STable)
由于一个数据采集点一张表,导致表的数量巨增,难以管理,而且应用经常需要做采集点之间的聚合操作,聚合的操作也变得复杂起来。为解决这个问题,TDengine 引入超级表(Super Table,简称为 STable)的概念。 由于一个数据采集点一张表,导致表的数量巨增,难以管理,而且应用经常需要做采集点之间的聚合操作,聚合的操作也变得复杂起来。为解决这个问题,TDengine 引入超级表(Super Table,简称为 STable)的概念。
...@@ -165,12 +143,18 @@ TDengine 建议用数据采集点的名字(如上表中的 D1001)来做表 ...@@ -165,12 +143,18 @@ TDengine 建议用数据采集点的名字(如上表中的 D1001)来做表
2. 不能通过子表调整数据或标签的模式,对于超级表的数据模式修改立即对所有的子表生效。 2. 不能通过子表调整数据或标签的模式,对于超级表的数据模式修改立即对所有的子表生效。
3. 超级表只定义一个模板,自身不存储任何数据或标签信息。因此,不能向一个超级表写入数据,只能将数据写入子表中。 3. 超级表只定义一个模板,自身不存储任何数据或标签信息。因此,不能向一个超级表写入数据,只能将数据写入子表中。
针对超级表的查询,TDengine将把所有子表中的数据视为一个整体数据集进行处理,会先把满足标签过滤条件的表从超级表中找出来,然后再扫描这些表的时序数据,进行聚合操作,这样需要扫描的数据集会大幅减少,从而显著提高查询的性能。本质上,TDengine通过对超级表查询的支持,实现了多个同类数据采集点的高效聚合。 查询既可以在表上进行,也可以在超级表上进行。针对超级表的查询,TDengine 将把所有子表中的数据视为一个整体数据集进行处理,会先把满足标签过滤条件的表从超级表中找出来,然后再扫描这些表的时序数据,进行聚合操作,这样需要扫描的数据集会大幅减少,从而显著提高查询的性能。本质上,TDengine 通过对超级表查询的支持,实现了多个同类数据采集点的高效聚合。
## 库 (database)
库是指一组表的集合。TDengine 容许一个运行实例有多个库,而且每个库可以配置不同的存储策略。不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为了在各种场景下 TDengine 都能最大效率的工作,TDengine 建议将不同数据特征的超级表创建在不同的库里。
一个库里,可以有一到多个超级表,但一个超级表只属于一个库。一个超级表所拥有的子表全部存在一个库里。
## FQDN & End Point ## FQDN & End Point
FQDN (fully qualified domain name, 完全限定域名)是 Internet 上特定计算机或主机的完整域名。FQDN由两部分组成:主机名和域名。例如,假设邮件服务器的FQDN可能是mail.tdengine.com。主机名是mail,主机位于域名tdengine.com中。DNS(Domain Name System),负责将FQDN翻译成IP,是互联网应用的寻址方式。对于没有DNS的系统,可以通过配置hosts文件来解决。 FQDN (fully qualified domain name, 完全限定域名)是 Internet 上特定计算机或主机的完整域名。FQDN 由两部分组成:主机名和域名。例如,假设邮件服务器的 FQDN 可能是 mail.tdengine.com。主机名是 mail,主机位于域名 tdengine.com 中。DNS(Domain Name System),负责将 FQDN 翻译成 IP,是互联网应用的寻址方式。对于没有 DNS 的系统,可以通过配置 hosts 文件来解决。
TDengine集群的每个节点是由End Point来唯一标识的,End Point是由 FQDN 外加 Port 组成,比如 h1.tdengine.com:6030。这样当IP发生变化的时候,我们依然可以使用 FQDN 来动态找到节点,不需要更改集群的任何配置。而且采用 FQDN,便于内网和外网对同一个集群的统一访问。 TDengine 集群的每个节点是由 End Point 来唯一标识的,End Point 是由 FQDN 外加 Port 组成,比如 h1.tdengine.com:6030。这样当 IP 发生变化的时候,我们依然可以使用 FQDN 来动态找到节点,不需要更改集群的任何配置。而且采用 FQDN,便于内网和外网对同一个集群的统一访问。
TDengine 不建议采用直接的IP地址访问集群,不利于管理。不了解 FQDN 概念,请看博文[《一篇文章说清楚 TDengine 的 FQDN》](https://www.taosdata.com/blog/2020/09/11/1824.html) TDengine 不建议采用直接的 IP 地址访问集群,不利于管理。不了解 FQDN 概念,请看博文[《一篇文章说清楚 TDengine 的 FQDN》](https://www.taosdata.com/blog/2020/09/11/1824.html)
```csharp title="原生连接" ```csharp title="原生连接"
{{#include docs-examples/csharp/ConnectExample.cs}} {{#include docs-examples/csharp/ConnectExample.cs}}
``` ```
:::info :::info
C# 连接器目前只支持原生连接。 C# 连接器目前只支持原生连接。
::: :::
\ No newline at end of file
#### 使用数据库访问统一接口 #### 使用数据库访问统一接口
```go title="原生连接" ```go title="原生连接"
{{#include docs-examples/go/connect/cgoexample/main.go}} {{#include docs-examples/go/connect/cgoexample/main.go}}
``` ```
```go title="REST 连接" ```go title="REST 连接"
{{#include docs-examples/go/connect/restexample/main.go}} {{#include docs-examples/go/connect/restexample/main.go}}
``` ```
#### 使用高级封装 #### 使用高级封装
也可以使用 driver-go 的 af 包建立连接。这个模块封装了 TDengine 的高级功能, 如:参数绑定、订阅等。 也可以使用 driver-go 的 af 包建立连接。这个模块封装了 TDengine 的高级功能, 如:参数绑定、订阅等。
```go title="使用 af 包建立原生连接" ```go title="使用 af 包建立原生连接"
{{#include docs-examples/go/connect/afconn/main.go}} {{#include docs-examples/go/connect/afconn/main.go}}
``` ```
```java title="原生连接" ```java title="原生连接"
{{#include docs-examples/java/src/main/java/com/taos/example/JNIConnectExample.java}} {{#include docs-examples/java/src/main/java/com/taos/example/JNIConnectExample.java}}
``` ```
```java title="REST 连接" ```java title="REST 连接"
{{#include docs-examples/java/src/main/java/com/taos/example/RESTConnectExample.java:main}} {{#include docs-examples/java/src/main/java/com/taos/example/RESTConnectExample.java:main}}
``` ```
使用REST 连接时,如果查询数据量比较大,还可开启批量拉取功能。
使用 REST 连接时,如果查询数据量比较大,还可开启批量拉取功能。
```java title="开启批量拉取功能" {4} ```java title="开启批量拉取功能" {4}
{{#include docs-examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} {{#include docs-examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}}
``` ```
更多连接参数配置,参考[Java 连接器](/reference/connector/java)
\ No newline at end of file 更多连接参数配置,参考[Java 连接器](/reference/connector/java)
```js title="原生连接" ```js title="原生连接"
{{#include docs-examples/node/nativeexample/connect.js}} {{#include docs-examples/node/nativeexample/connect.js}}
``` ```
```js title="REST 连接" ```js title="REST 连接"
{{#include docs-examples/node/restexample/connect.js}} {{#include docs-examples/node/restexample/connect.js}}
``` ```
\ No newline at end of file
```php title="原生连接"
{{#include docs-examples/php/connect.php}}
```
```python title="原生连接" ```python title="原生连接"
{{#include docs-examples/python/connect_exmaple.py}} {{#include docs-examples/python/connect_exmaple.py}}
``` ```
\ No newline at end of file
```r title="原生连接" ```r title="原生连接"
{{#include docs-examples/R/connect_native.r:demo}} {{#include docs-examples/R/connect_native.r:demo}}
``` ```
\ No newline at end of file
```rust title="原生连接/REST 连接" ```rust title="原生连接/REST 连接"
{{#include docs-examples/rust/nativeexample/examples/connect.rs}} {{#include docs-examples/rust/nativeexample/examples/connect.rs}}
``` ```
:::note :::note
对于 Rust 连接器, 连接方式的不同只体现在使用的特性不同。如果启用了 "rest" 特性,那么只有 RESTful 的实现会被编译进来。 对于 Rust 连接器, 连接方式的不同只体现在使用的特性不同。如果启用了 "rest" 特性,那么只有 RESTful 的实现会被编译进来。
......
...@@ -13,18 +13,19 @@ import ConnPythonNative from "./_connect_python.mdx"; ...@@ -13,18 +13,19 @@ import ConnPythonNative from "./_connect_python.mdx";
import ConnCSNative from "./_connect_cs.mdx"; import ConnCSNative from "./_connect_cs.mdx";
import ConnC from "./_connect_c.mdx"; import ConnC from "./_connect_c.mdx";
import ConnR from "./_connect_r.mdx"; import ConnR from "./_connect_r.mdx";
import ConnPHP from "./_connect_php.mdx";
import InstallOnWindows from "../../14-reference/03-connector/_linux_install.mdx"; import InstallOnWindows from "../../14-reference/03-connector/_linux_install.mdx";
import InstallOnLinux from "../../14-reference/03-connector/_windows_install.mdx"; import InstallOnLinux from "../../14-reference/03-connector/_windows_install.mdx";
import VerifyLinux from "../../14-reference/03-connector/_verify_linux.mdx"; import VerifyLinux from "../../14-reference/03-connector/_verify_linux.mdx";
import VerifyWindows from "../../14-reference/03-connector/_verify_windows.mdx"; import VerifyWindows from "../../14-reference/03-connector/_verify_windows.mdx";
TDengine 提供 REST API,容许在任何平台的任何应用程序通过它访问 TDengine 运行实例,详细介绍请看 [REST API](/reference/rest-api/)。除 REST API 之外,TDengine 还提供多种编程语言的连接器方便用户开发应用程序,其中包括 C/C++、Java、Python、Go、Node.js、C# 等。 本节介绍如何使用连接器建立与 TDengine 的连接,给出连接器安装、连接的简单说明。关于各连接器的详细功能说明,请查看[连接器](https://docs.taosdata.com/reference/connector/) TDengine 提供了丰富的应用程序开发接口,为了便于用户快速开发自己的应用,TDengine 支持了多种编程语言的连接器,其中官方连接器包括支持 C/C++、Java、Python、Go、Node.js、C#、Rust、Lua(社区贡献)和 PHP (社区贡献)的连接器。这些连接器支持使用原生接口(taosc)和 REST 接口(部分语言暂不支持)连接 TDengine 集群。社区开发者也贡献了多个非官方连接器,例如 ADO.NET 连接器、Lua 连接器和 PHP 连接器。
## 连接器建立连接的方式 ## 连接器建立连接的方式
连接器建立连接的方式,TDengine 提供两种: 连接器建立连接的方式,TDengine 提供两种:
1. 通过 taosAdapter 组件提供的 REST API 建立与 taosd 的连接,这种连接方式下文中简称"REST 连接“ 1. 通过 taosAdapter 组件提供的 REST API 建立与 taosd 的连接,这种连接方式下文中简称“REST 连接”
2. 通过客户端驱动程序 taosc 直接与服务端程序 taosd 建立连接,这种连接方式下文中简称“原生连接”。 2. 通过客户端驱动程序 taosc 直接与服务端程序 taosd 建立连接,这种连接方式下文中简称“原生连接”。
无论使用何种方式建立连接,连接器都提供了相同或相似的 API 操作数据库,都可以执行 SQL 语句,只是初始化连接的方式稍有不同,用户在使用上不会感到什么差别。 无论使用何种方式建立连接,连接器都提供了相同或相似的 API 操作数据库,都可以执行 SQL 语句,只是初始化连接的方式稍有不同,用户在使用上不会感到什么差别。
...@@ -200,6 +201,46 @@ install.packages("RJDBC") ...@@ -200,6 +201,46 @@ install.packages("RJDBC")
如果已经安装了 TDengine 服务端软件或 TDengine 客户端驱动 taosc, 那么已经安装了 C 连接器,无需额外操作。 如果已经安装了 TDengine 服务端软件或 TDengine 客户端驱动 taosc, 那么已经安装了 C 连接器,无需额外操作。
<br/> <br/>
</TabItem>
<TabItem label="PHP" value="php">
**下载代码并解压:**
```shell
curl -L -o php-tdengine.tar.gz https://github.com/Yurunsoft/php-tdengine/archive/refs/tags/v1.0.2.tar.gz \
&& mkdir php-tdengine \
&& tar -xzf php-tdengine.tar.gz -C php-tdengine --strip-components=1
```
> 版本 `v1.0.0` 可替换为任意更新的版本,可在 Release 中查看最新版本。
**非 Swoole 环境:**
```shell
phpize && ./configure && make -j && make install
```
**手动指定 tdengine 目录:**
```shell
phpize && ./configure --with-tdengine-dir=/usr/local/Cellar/tdengine/2.4.0.0 && make -j && make install
```
> `--with-tdengine-dir=` 后跟上 tdengine 目录。
> 适用于默认找不到的情况,或者 MacOS 系统用户。
**Swoole 环境:**
```shell
phpize && ./configure --enable-swoole && make -j && make install
```
**启用扩展:**
方法一:在 `php.ini` 中加入 `extension=tdengine`
方法二:运行带参数 `php -dextension=tdengine test.php
</TabItem> </TabItem>
</Tabs> </Tabs>
...@@ -232,6 +273,9 @@ install.packages("RJDBC") ...@@ -232,6 +273,9 @@ install.packages("RJDBC")
<TabItem label="C" value="c"> <TabItem label="C" value="c">
<ConnC /> <ConnC />
</TabItem> </TabItem>
<TabItem label="PHP" value="php">
<ConnPHP />
</TabItem>
</Tabs> </Tabs>
:::tip :::tip
......
...@@ -18,6 +18,8 @@ import CsSQL from "./_cs_sql.mdx"; ...@@ -18,6 +18,8 @@ import CsSQL from "./_cs_sql.mdx";
import CsStmt from "./_cs_stmt.mdx"; import CsStmt from "./_cs_stmt.mdx";
import CSQL from "./_c_sql.mdx"; import CSQL from "./_c_sql.mdx";
import CStmt from "./_c_stmt.mdx"; import CStmt from "./_c_stmt.mdx";
import PhpSQL from "./_php_sql.mdx";
import PhpStmt from "./_php_stmt.mdx";
## SQL 写入简介 ## SQL 写入简介
...@@ -88,6 +90,9 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, ...@@ -88,6 +90,9 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6,
<TabItem label="C" value="c"> <TabItem label="C" value="c">
<CSQL /> <CSQL />
</TabItem> </TabItem>
<TabItem label="PHP" value="php">
<PhpSQL />
</TabItem>
</Tabs> </Tabs>
:::note :::note
...@@ -125,5 +130,8 @@ TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 类似,这 ...@@ -125,5 +130,8 @@ TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 类似,这
<TabItem label="C" value="c"> <TabItem label="C" value="c">
<CStmt /> <CStmt />
</TabItem> </TabItem>
<TabItem label="PHP" value="php">
<PhpStmt />
</TabItem>
</Tabs> </Tabs>
```php
{{#include docs-examples/php/insert.php}}
```
```php
{{#include docs-examples/php/insert_stmt.php}}
```
```go
{{#include docs-examples/php/query.php}}
```
...@@ -13,6 +13,7 @@ import RustQuery from "./_rust.mdx"; ...@@ -13,6 +13,7 @@ import RustQuery from "./_rust.mdx";
import NodeQuery from "./_js.mdx"; import NodeQuery from "./_js.mdx";
import CsQuery from "./_cs.mdx"; import CsQuery from "./_cs.mdx";
import CQuery from "./_c.mdx"; import CQuery from "./_c.mdx";
import PhpQuery from "./_php.mdx";
import PyAsync from "./_py_async.mdx"; import PyAsync from "./_py_async.mdx";
import NodeAsync from "./_js_async.mdx"; import NodeAsync from "./_js_async.mdx";
import CsAsync from "./_cs_async.mdx"; import CsAsync from "./_cs_async.mdx";
...@@ -150,12 +151,15 @@ Query OK, 5 row(s) in set (0.001521s) ...@@ -150,12 +151,15 @@ Query OK, 5 row(s) in set (0.001521s)
<TabItem label="C" value="c"> <TabItem label="C" value="c">
<CQuery /> <CQuery />
</TabItem> </TabItem>
<TabItem label="PHP" value="php">
<PhpQuery />
</TabItem>
</Tabs> </Tabs>
:::note :::note
1. 无论是使用 REST 连接还是原生连接的连接器,以上示例代码都能正常工作。 1. 无论是使用 REST 连接还是原生连接的连接器,以上示例代码都能正常工作。
2. 唯一需要注意的是:由于 RESTful 接口无状态, 不能使用 `use db` 语句来切换数据库。 2. 唯一需要注意的是:由于 REST 接口无状态, 不能使用 `use db` 语句来切换数据库。
::: :::
......
...@@ -915,9 +915,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -915,9 +915,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### CSUM ### CSUM
```sql ```sql
SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:累加和(Cumulative sum),输出行与输入行数相同。 **功能说明**:累加和(Cumulative sum),输出行与输入行数相同。
...@@ -937,9 +937,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -937,9 +937,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### MAVG ### MAVG
```sql ```sql
SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause] SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**: 计算连续 k 个值的移动平均数(moving average)。如果输入行数小于 k,则无结果输出。参数 k 的合法输入范围是 1≤ k ≤ 1000。 **功能说明**: 计算连续 k 个值的移动平均数(moving average)。如果输入行数小于 k,则无结果输出。参数 k 的合法输入范围是 1≤ k ≤ 1000。
...@@ -959,9 +959,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -959,9 +959,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### SAMPLE ### SAMPLE
```sql ```sql
SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause] SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**: 获取数据的 k 个采样值。参数 k 的合法输入范围是 1≤ k ≤ 1000。 **功能说明**: 获取数据的 k 个采样值。参数 k 的合法输入范围是 1≤ k ≤ 1000。
...@@ -980,9 +980,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -980,9 +980,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### ASIN ### ASIN
```sql ```sql
SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的反正弦结果 **功能说明**:获得指定列的反正弦结果
...@@ -1000,9 +1000,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1000,9 +1000,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### ACOS ### ACOS
```sql ```sql
SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的反余弦结果 **功能说明**:获得指定列的反余弦结果
...@@ -1020,9 +1020,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1020,9 +1020,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### ATAN ### ATAN
```sql ```sql
SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的反正切结果 **功能说明**:获得指定列的反正切结果
...@@ -1040,9 +1040,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1040,9 +1040,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### SIN ### SIN
```sql ```sql
SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的正弦结果 **功能说明**:获得指定列的正弦结果
...@@ -1060,9 +1060,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1060,9 +1060,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### COS ### COS
```sql ```sql
SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的余弦结果 **功能说明**:获得指定列的余弦结果
...@@ -1080,9 +1080,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1080,9 +1080,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### TAN ### TAN
```sql ```sql
SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的正切结果 **功能说明**:获得指定列的正切结果
...@@ -1100,9 +1100,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1100,9 +1100,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### POW ### POW
```sql ```sql
SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause] SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的指数为 power 的幂 **功能说明**:获得指定列的指数为 power 的幂
...@@ -1120,9 +1120,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1120,9 +1120,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### LOG ### LOG
```sql ```sql
SELECT LOG(field_name, base) FROM { tb_name | stb_name } [WHERE clause] SELECT LOG(field_name, base) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列对于底数 base 的对数 **功能说明**:获得指定列对于底数 base 的对数
...@@ -1140,9 +1140,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1140,9 +1140,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### ABS ### ABS
```sql ```sql
SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的绝对值 **功能说明**:获得指定列的绝对值
...@@ -1160,9 +1160,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1160,9 +1160,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### SQRT ### SQRT
```sql ```sql
SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause] SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:获得指定列的平方根 **功能说明**:获得指定列的平方根
...@@ -1180,9 +1180,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1180,9 +1180,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### CAST ### CAST
```sql ```sql
SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause] SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:数据类型转换函数,输入参数 expression 支持普通列、常量、标量函数及它们之间的四则运算,不支持 tag 列,只适用于 select 子句中。 **功能说明**:数据类型转换函数,输入参数 expression 支持普通列、常量、标量函数及它们之间的四则运算,不支持 tag 列,只适用于 select 子句中。
...@@ -1206,9 +1206,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1206,9 +1206,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### CONCAT ### CONCAT
```sql ```sql
SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause] SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:字符串连接函数。 **功能说明**:字符串连接函数。
...@@ -1226,9 +1226,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1226,9 +1226,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### CONCAT_WS ### CONCAT_WS
``` ```
SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause] SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:带分隔符的字符串连接函数。 **功能说明**:带分隔符的字符串连接函数。
...@@ -1246,9 +1246,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1246,9 +1246,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### LENGTH ### LENGTH
``` ```
SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause] SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:以字节计数的字符串长度。 **功能说明**:以字节计数的字符串长度。
...@@ -1265,9 +1265,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1265,9 +1265,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### CHAR_LENGTH ### CHAR_LENGTH
``` ```
SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause] SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:以字符计数的字符串长度。 **功能说明**:以字符计数的字符串长度。
...@@ -1284,9 +1284,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1284,9 +1284,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### LOWER ### LOWER
``` ```
SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause] SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:将字符串参数值转换为全小写字母。 **功能说明**:将字符串参数值转换为全小写字母。
...@@ -1303,9 +1303,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1303,9 +1303,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### UPPER ### UPPER
``` ```
SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause] SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:将字符串参数值转换为全大写字母。 **功能说明**:将字符串参数值转换为全大写字母。
...@@ -1322,9 +1322,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1322,9 +1322,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### LTRIM ### LTRIM
``` ```
SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause] SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:返回清除左边空格后的字符串。 **功能说明**:返回清除左边空格后的字符串。
...@@ -1341,9 +1341,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1341,9 +1341,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### RTRIM ### RTRIM
``` ```
SELECT RTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause] SELECT RTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:返回清除右边空格后的字符串。 **功能说明**:返回清除右边空格后的字符串。
...@@ -1360,9 +1360,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause]; ...@@ -1360,9 +1360,9 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
### SUBSTR ### SUBSTR
``` ```
SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause] SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
``` ```
**功能说明**:从源字符串 str 中的指定位置 pos 开始取一个长度为 len 的子串并返回。 **功能说明**:从源字符串 str 中的指定位置 pos 开始取一个长度为 len 的子串并返回。
...@@ -1461,7 +1461,7 @@ Query OK, 6 row(s) in set (0.002791s) ...@@ -1461,7 +1461,7 @@ Query OK, 6 row(s) in set (0.002791s)
### STATEDURATION ### STATEDURATION
``` ```sql
SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause]; SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
``` ```
......
...@@ -20,11 +20,11 @@ import PkgList from "/components/PkgList"; ...@@ -20,11 +20,11 @@ import PkgList from "/components/PkgList";
运行 install_client.sh 进行安装。 运行 install_client.sh 进行安装。
4. 配置 taos.cfg 4. 配置 taos.cfg
编辑 taos.cfg 文件(默认路径/etc/taos/taos.cfg),将 firstEP 修改为 TDengine 服务器的 End Point,例如:`h1.tdengine.com:6030` 编辑 `taos.cfg` 文件(默认路径/etc/taos/taos.cfg),将 `firstEP` 修改为 TDengine 服务器的 End Point,例如:`h1.tdengine.com:6030`
:::tip :::tip
1. 如本机没有部署 TDengine 服务,仅安装了应用驱动,则 taos.cfg 中仅需配置 firstEP,无需在本机配置 FQDN 1. 如本机没有部署 TDengine 服务,仅安装了应用驱动,则 `taos.cfg` 中仅需配置 `firstEP`,无需在本机配置 `FQDN`
2. 为防止与服务器端连接时出现“Unable to resolve FQDN”错误,建议确认本机的 hosts 文件已经配置了服务器正确的 FQDN 值,或配置好了 DNS 服务。 2. 为防止与服务器端连接时出现“Unable to resolve FQDN”错误,建议确认本机的 `/etc/hosts` 文件已经配置了服务器正确的 FQDN 值,或配置好了 DNS 服务。
::: :::
...@@ -136,7 +136,7 @@ import ( ...@@ -136,7 +136,7 @@ import (
) )
func main() { func main() {
var taosUri = "root:taosdata/tcp(localhost:6030)/" var taosUri = "root:taosdata@tcp(localhost:6030)/"
taos, err := sql.Open("taosSql", taosUri) taos, err := sql.Open("taosSql", taosUri)
if err != nil { if err != nil {
fmt.Println("failed to connect TDengine, err:", err) fmt.Println("failed to connect TDengine, err:", err)
...@@ -168,7 +168,7 @@ import ( ...@@ -168,7 +168,7 @@ import (
) )
func main() { func main() {
var taosUri = "root:taosdata/http(localhost:6041)/" var taosUri = "root:taosdata@http(localhost:6041)/"
taos, err := sql.Open("taosRestful", taosUri) taos, err := sql.Open("taosRestful", taosUri)
if err != nil { if err != nil {
fmt.Println("failed to connect TDengine, err:", err) fmt.Println("failed to connect TDengine, err:", err)
......
...@@ -211,7 +211,7 @@ url 中的配置参数如下: ...@@ -211,7 +211,7 @@ url 中的配置参数如下:
INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('beijing') VALUES(now, 24.6); INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('beijing') VALUES(now, 24.6);
``` ```
- 从 taos-jdbcdriver-2.0.36 和 TDengine 2.2.0.0 版本开始,如果在 url 中指定了 dbname,那么,JDBC REST 连接会默认使用/rest/sql/dbname 作为 resful 请求的 url,在 SQL 中不需要指定 dbname。例如:url 为 jdbc:TAOS-RS://127.0.0.1:6041/test,那么,可以执行 sql:insert into t1 using weather(ts, temperatrue) tags('beijing') values(now, 24.6); - 从 taos-jdbcdriver-2.0.36 和 TDengine 2.2.0.0 版本开始,如果在 url 中指定了 dbname,那么,JDBC REST 连接会默认使用/rest/sql/dbname 作为 restful 请求的 url,在 SQL 中不需要指定 dbname。例如:url 为 jdbc:TAOS-RS://127.0.0.1:6041/test,那么,可以执行 sql:insert into t1 using weather(ts, temperature) tags('beijing') values(now, 24.6);
::: :::
...@@ -348,8 +348,8 @@ JDBC 连接器可能报错的错误码包括 3 种:JDBC driver 本身的报错 ...@@ -348,8 +348,8 @@ JDBC 连接器可能报错的错误码包括 3 种:JDBC driver 本身的报错
具体的错误码请参考: 具体的错误码请参考:
- https://github.com/taosdata/TDengine/blob/develop/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java - [TDengine Java Connector](https://github.com/taosdata/TDengine/blob/develop/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java)
- https://github.com/taosdata/TDengine/blob/develop/src/inc/taoserror.h - [TDengine_ERROR_CODE](https://github.com/taosdata/TDengine/blob/develop/src/inc/taoserror.h)
### 通过参数绑定写入数据 ### 通过参数绑定写入数据
...@@ -816,21 +816,21 @@ Query OK, 1 row(s) in set (0.000141s) ...@@ -816,21 +816,21 @@ Query OK, 1 row(s) in set (0.000141s)
1. 使用 Statement 的 `addBatch` 和 `executeBatch` 来执行“批量写入/更行”,为什么没有带来性能上的提升? 1. 使用 Statement 的 `addBatch` 和 `executeBatch` 来执行“批量写入/更行”,为什么没有带来性能上的提升?
**原因**:TDengine 的 JDBC 实现中,通过 `addBatch` 方法提交的 SQL 语句,会按照添加的顺序,依次执行,这种方式没有减少与服务端的交互次数,不会带来性能上的提升。 **原因**:TDengine 的 JDBC 实现中,通过 `addBatch` 方法提交的 SQL 语句,会按照添加的顺序,依次执行,这种方式没有减少与服务端的交互次数,不会带来性能上的提升。
**解决方法**:1. 在一条 insert 语句中拼接多个 values 值;2. 使用多线程的方式并发插入;3. 使用参数绑定的写入方式 **解决方法**:1. 在一条 insert 语句中拼接多个 values 值;2. 使用多线程的方式并发插入;3. 使用参数绑定的写入方式
2. java.lang.UnsatisfiedLinkError: no taos in java.library.path 2. java.lang.UnsatisfiedLinkError: no taos in java.library.path
**原因**:程序没有找到依赖的本地函数库 taos。 **原因**:程序没有找到依赖的本地函数库 taos。
**解决方法**:Windows 下可以将 C:\TDengine\driver\taos.dll 拷贝到 C:\Windows\System32\ 目录下,Linux 下将建立如下软链 `ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so` 即可。 **解决方法**:Windows 下可以将 C:\TDengine\driver\taos.dll 拷贝到 C:\Windows\System32\ 目录下,Linux 下将建立如下软链 `ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so` 即可。
3. java.lang.UnsatisfiedLinkError: taos.dll Can't load AMD 64 bit on a IA 32-bit platform 3. java.lang.UnsatisfiedLinkError: taos.dll Can't load AMD 64 bit on a IA 32-bit platform
**原因**:目前 TDengine 只支持 64 位 JDK。 **原因**:目前 TDengine 只支持 64 位 JDK。
**解决方法**:重新安装 64 位 JDK。 **解决方法**:重新安装 64 位 JDK。
4. 其它问题请参考 [FAQ](/train-faq/faq) 4. 其它问题请参考 [FAQ](/train-faq/faq)
......
...@@ -38,7 +38,7 @@ LoadPlugin network ...@@ -38,7 +38,7 @@ LoadPlugin network
其中 <taosAdapter's host\> 填写运行 taosAdapter 的服务器域名或 IP 地址。<port for collectd direct\> 填写 taosAdapter 用于接收 collectd 数据的端口(默认为 6045)。 其中 <taosAdapter's host\> 填写运行 taosAdapter 的服务器域名或 IP 地址。<port for collectd direct\> 填写 taosAdapter 用于接收 collectd 数据的端口(默认为 6045)。
例如下: 例如下:
```text ```text
LoadPlugin network LoadPlugin network
......
...@@ -33,7 +33,7 @@ object OpenTsdbWriter "opentsdb" { ...@@ -33,7 +33,7 @@ object OpenTsdbWriter "opentsdb" {
} }
``` ```
例文件: 例文件:
``` ```
object OpenTsdbWriter "opentsdb" { object OpenTsdbWriter "opentsdb" {
......
...@@ -5,6 +5,12 @@ title: Grafana ...@@ -5,6 +5,12 @@ title: Grafana
TDengine 能够与开源数据可视化系统 [Grafana](https://www.grafana.com/) 快速集成搭建数据监测报警系统,整个过程无需任何代码开发,TDengine 中数据表的内容可以在仪表盘(DashBoard)上进行可视化展现。关于 TDengine 插件的使用您可以在[GitHub](https://github.com/taosdata/grafanaplugin/blob/master/README.md)中了解更多。 TDengine 能够与开源数据可视化系统 [Grafana](https://www.grafana.com/) 快速集成搭建数据监测报警系统,整个过程无需任何代码开发,TDengine 中数据表的内容可以在仪表盘(DashBoard)上进行可视化展现。关于 TDengine 插件的使用您可以在[GitHub](https://github.com/taosdata/grafanaplugin/blob/master/README.md)中了解更多。
## 前置条件
要让 Grafana 能正常添加 TDengine 数据源,需要以下几方面的准备工作。
- TDengine 集群已经部署并正常运行
- taosAdapter 已经安装并正常运行。具体细节请参考 [taosAdapter 的使用手册](/reference/taosadapter)
## 安装 Grafana ## 安装 Grafana
目前 TDengine 支持 Grafana 7.0 以上的版本。用户可以根据当前的操作系统,到 Grafana 官网下载安装包,并执行安装。下载地址如下:<https://grafana.com/grafana/download>。 目前 TDengine 支持 Grafana 7.0 以上的版本。用户可以根据当前的操作系统,到 Grafana 官网下载安装包,并执行安装。下载地址如下:<https://grafana.com/grafana/download>。
...@@ -78,7 +84,7 @@ GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=tdengine-datasource ...@@ -78,7 +84,7 @@ GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=tdengine-datasource
![img](/img/connections/create_dashboard1.jpg) ![img](/img/connections/create_dashboard1.jpg)
如上图所示,在 Query 中选中 `TDengine` 数据源,在下方查询框可输入相应 sql 进行查询,具体说明如下: 如上图所示,在 Query 中选中 `TDengine` 数据源,在下方查询框可输入相应 SQL 进行查询,具体说明如下:
- INPUT SQL:输入要查询的语句(该 SQL 语句的结果集应为两列多行),例如:`select avg(mem_system) from log.dn where ts >= $from and ts < $to interval($interval)` ,其中,from、to 和 interval 为 TDengine 插件的内置变量,表示从 Grafana 插件面板获取的查询范围和时间间隔。除了内置变量外,`也支持可以使用自定义模板变量`。 - INPUT SQL:输入要查询的语句(该 SQL 语句的结果集应为两列多行),例如:`select avg(mem_system) from log.dn where ts >= $from and ts < $to interval($interval)` ,其中,from、to 和 interval 为 TDengine 插件的内置变量,表示从 Grafana 插件面板获取的查询范围和时间间隔。除了内置变量外,`也支持可以使用自定义模板变量`。
- ALIAS BY:可设置当前查询别名。 - ALIAS BY:可设置当前查询别名。
......
---
sidebar_label: EMQ Broker
title: EMQ Broker 写入
---
MQTT 是流行的物联网数据传输协议,[EMQ](https://github.com/emqx/emqx)是一开源的 MQTT Broker 软件,无需任何代码,只需要在 EMQ Dashboard 里使用“规则”做简单配置,即可将 MQTT 的数据直接写入 TDengine。EMQ X 支持通过 发送到 Web 服务的方式保存数据到 TDEngine,也在企业版上提供原生的 TDEngine 驱动实现直接保存。详细使用方法请参考 [EMQ 官方文档](https://docs.emqx.io/broker/latest/cn/rule/rule-example.html#%E4%BF%9D%E5%AD%98%E6%95%B0%E6%8D%AE%E5%88%B0-tdengine)
---
sidebar_label: EMQX Broker
title: EMQX Broker 写入
---
MQTT 是流行的物联网数据传输协议,[EMQX](https://github.com/emqx/emqx)是一开源的 MQTT Broker 软件,无需任何代码,只需要在 EMQX Dashboard 里使用“规则”做简单配置,即可将 MQTT 的数据直接写入 TDengine。EMQX 支持通过 发送到 Web 服务的方式保存数据到 TDengine,也在企业版上提供原生的 TDengine 驱动实现直接保存。
## 前置条件
要让 EMQX 能正常添加 TDengine 数据源,需要以下几方面的准备工作。
- TDengine 集群已经部署并正常运行
- taosAdapter 已经安装并正常运行。具体细节请参考 [taosAdapter 的使用手册](/reference/taosadapter)
- 如果使用后文介绍的模拟写入程序,需要安装合适版本的 Node.js,推荐安装 v12。
## 安装并启动 EMQX
用户可以根据当前的操作系统,到 EMQX 官网下载安装包,并执行安装。下载地址如下:<https://www.emqx.io/zh/downloads>。安装后使用 `sudo emqx start``sudo systemctl start emqx` 启动 EMQX 服务。
## 在 TDengine 中为接收 MQTT 数据创建相应数据库和表结构
### 以 Docker 安装 TDengine 为例
```bash
docker exec -it tdengine bash
taos
```
### 创建数据库和表
```sql
create database test;
use test;
create table:
CREATE TABLE sensor_data (ts timestamp, temperature float, humidity float, volume float, PM10 float, pm25 float, SO2 float, NO2 float, CO float, sensor_id NCHAR(255), area TINYINT, coll_time timestamp);
```
注:表结构以博客[数据传输、存储、展现,EMQ X + TDengine 搭建 MQTT 物联网数据可视化平台](https://www.taosdata.com/blog/2020/08/04/1722.html)为例。后续操作均以此博客场景为例进行,请你根据实际应用场景进行修改。
## 配置 EMQX 规则
由于 EMQX 不同版本配置界面所有不同,这里仅以 v4.4.3 为例,其他版本请参考相应官网文档。
### 登录 EMQX Dashboard
使用浏览器打开网址 http://IP:18083 并登录 EMQX Dashboard。初次安装用户名为 `admin` 密码为:`public`
![img](./emqx/login-dashboard.png)
### 创建规则(Rule)
选择左侧“规则引擎(Rule Engine)”中的“规则(Rule)”并点击“创建(Create)”按钮:
![img](./emqx/rule-engine.png)
### 编辑 SQL 字段
![img](./emqx/create-rule.png)
### 新增“动作(action handler)”
![img](./emqx/add-action-handler.png)
### 新增“资源(Resource)”
![img](./emqx/create-resource.png)
选择“发送数据到 Web 服务“并点击“新建资源”按钮:
### 编辑“资源(Resource)”
选择“发送数据到 Web 服务“并填写 请求 URL 为 运行 taosAdapter 的服务器地址和端口(默认为 6041)。其他属性请保持默认值。
![img](./emqx/edit-resource.png)
### 编辑“动作(action)”
编辑资源配置,增加 Authorization 认证的键/值配对项,相关文档请参考[ TDengine REST API 文档](https://docs.taosdata.com/reference/rest-api/)。在消息体中输入规则引擎替换模板。
![img](./emqx/edit-action.png)
## 编写模拟测试程序
```javascript
// mock.js
const mqtt = require('mqtt')
const Mock = require('mockjs')
const EMQX_SERVER = 'mqtt://localhost:1883'
const CLIENT_NUM = 10
const STEP = 5000 // 模拟采集时间间隔 ms
const AWAIT = 5000 // 每次发送完后休眠时间,防止消息速率过快 ms
const CLIENT_POOL = []
startMock()
function sleep(timer = 100) {
return new Promise(resolve => {
setTimeout(resolve, timer)
})
}
async function startMock() {
const now = Date.now()
for (let i = 0; i < CLIENT_NUM; i++) {
const client = await createClient(`mock_client_${i}`)
CLIENT_POOL.push(client)
}
// last 24h every 5s
const last = 24 * 3600 * 1000
for (let ts = now - last; ts <= now; ts += STEP) {
for (const client of CLIENT_POOL) {
const mockData = generateMockData()
const data = {
...mockData,
id: client.clientId,
area: 0,
ts,
}
client.publish('sensor/data', JSON.stringify(data))
}
const dateStr = new Date(ts).toLocaleTimeString()
console.log(`${dateStr} send success.`)
await sleep(AWAIT)
}
console.log(`Done, use ${(Date.now() - now) / 1000}s`)
}
/**
* Init a virtual mqtt client
* @param {string} clientId ClientID
*/
function createClient(clientId) {
return new Promise((resolve, reject) => {
const client = mqtt.connect(EMQX_SERVER, {
clientId,
})
client.on('connect', () => {
console.log(`client ${clientId} connected`)
resolve(client)
})
client.on('reconnect', () => {
console.log('reconnect')
})
client.on('error', (e) => {
console.error(e)
reject(e)
})
})
}
/**
* Generate mock data
*/
function generateMockData() {
return {
"temperature": parseFloat(Mock.Random.float(22, 100).toFixed(2)),
"humidity": parseFloat(Mock.Random.float(12, 86).toFixed(2)),
"volume": parseFloat(Mock.Random.float(20, 200).toFixed(2)),
"PM10": parseFloat(Mock.Random.float(0, 300).toFixed(2)),
"pm25": parseFloat(Mock.Random.float(0, 300).toFixed(2)),
"SO2": parseFloat(Mock.Random.float(0, 50).toFixed(2)),
"NO2": parseFloat(Mock.Random.float(0, 50).toFixed(2)),
"CO": parseFloat(Mock.Random.float(0, 50).toFixed(2)),
"area": Mock.Random.integer(0, 20),
"ts": 1596157444170,
}
}
```
注意:代码中 CLIENT_NUM 在开始测试中可以先设置一个较小的值,避免硬件性能不能完全处理较大并发客户端数量。
![img](./emqx/client-num.png)
## 执行测试模拟发送 MQTT 数据
```
npm install mqtt mockjs --save --registry=https://registry.npm.taobao.org
node mock.js
```
![img](./emqx/run-mock.png)
## 验证 EMQX 接收到数据
在 EMQX Dashboard 规则引擎界面进行刷新,可以看到有多少条记录被正确接收到:
![img](./emqx/check-rule-matched.png)
## 验证数据写入到 TDengine
使用 TDengine CLI 程序登录并查询相应数据库和表,验证数据是否被正确写入到 TDengine 中:
![img](./emqx/check-result-in-taos.png)
TDengine 详细使用方法请参考 [TDengine 官方文档](https://docs.taosdata.com/)
EMQX 详细使用方法请参考 [EMQ 官方文档](https://www.emqx.io/docs/zh/v4.4/rule/rule-engine.html)
...@@ -34,11 +34,11 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ...@@ -34,11 +34,11 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
### TDengine ### TDengine
从涛思数据官网[下载](http://taosdata.com/cn/all-downloads/)页面下载最新 TDengine-server 2.3.0.0 或以上版本安装。 从涛思数据官网[下载](http://taosdata.com/cn/all-downloads/)页面下载最新 TDengine-server 2.4.0.x 或以上版本安装。
## 数据链路设置 ## 数据链路设置
### 下载 TDengine 插件到 grafana 插件目录 ### 下载 TDengine 插件到 Grafana 插件目录
```bash ```bash
1. wget -c https://github.com/taosdata/grafanaplugin/releases/download/v3.1.3/tdengine-datasource-3.1.3.zip 1. wget -c https://github.com/taosdata/grafanaplugin/releases/download/v3.1.3/tdengine-datasource-3.1.3.zip
...@@ -50,7 +50,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ...@@ -50,7 +50,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
### 修改 /etc/telegraf/telegraf.conf ### 修改 /etc/telegraf/telegraf.conf
配置方法,在 /etc/telegraf/telegraf.conf 增加如下文字,其中 database name 请填写希望在 TDengine 保存 Telegraf 数据的数据库名,TDengine server/cluster host、username 和 password 填写 TDengine 实际值: 配置方法,在 `/etc/telegraf/telegraf.conf` 增加如下文字,其中 `database name` 请填写希望在 TDengine 保存 Telegraf 数据的数据库名,`TDengine server/cluster host``username``password` 填写 TDengine 实际值:
``` ```
[[outputs.http]] [[outputs.http]]
...@@ -63,7 +63,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ...@@ -63,7 +63,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
influx_max_line_bytes = 250 influx_max_line_bytes = 250
``` ```
然后重启 telegraf: 然后重启 Telegraf:
```bash ```bash
sudo systemctl start telegraf sudo systemctl start telegraf
...@@ -71,12 +71,12 @@ sudo systemctl start telegraf ...@@ -71,12 +71,12 @@ sudo systemctl start telegraf
### 导入 Dashboard ### 导入 Dashboard
使用 Web 浏览器访问 IP:3000 登录 Grafana 界面,系统初始用户名密码为 admin/admin。 使用 Web 浏览器访问 `IP:3000` 登录 Grafana 界面,系统初始用户名密码为 admin/admin。
点击左侧齿轮图标并选择 Plugins,应该可以找到 TDengine data source 插件图标。 点击左侧齿轮图标并选择 `Plugins`,应该可以找到 TDengine data source 插件图标。
点击左侧加号图标并选择 Import,从 `https://github.com/taosdata/grafanaplugin/blob/master/examples/telegraf/grafana/dashboards/telegraf-dashboard-v0.1.0.json` 下载 dashboard JSON 文件后导入。之后可以看到如下界面的仪表盘: 点击左侧加号图标并选择 `Import`,从 `https://github.com/taosdata/grafanaplugin/blob/master/examples/telegraf/grafana/dashboards/telegraf-dashboard-v0.1.0.json` 下载 dashboard JSON 文件后导入。之后可以看到如下界面的仪表盘:
![IT-DevOps-Solutions-telegraf-dashboard.png](/img/IT-DevOps-Solutions-telegraf-dashboard.png) ![IT-DevOps-Solutions-telegraf-dashboard.png](/img/IT-DevOps-Solutions-telegraf-dashboard.png)
## 总结 ## 总结
以上演示如何快速搭建一个完整的 IT 运维展示系统。得力于 TDengine 2.3.0.0 版本中新增的 schemaless 协议解析功能,以及强大的生态软件适配能力,用户可以短短数分钟就可以搭建一个高效易用的 IT 运维系统。TDengine 强大的数据写入查询性能和其他丰富功能请参考官方文档和产品落地案例。 以上演示如何快速搭建一个完整的 IT 运维展示系统。得力于 TDengine 2.4.0.0 版本中新增的 schemaless 协议解析功能,以及强大的生态软件适配能力,用户可以短短数分钟就可以搭建一个高效易用的 IT 运维系统。TDengine 强大的数据写入查询性能和其他丰富功能请参考官方文档和产品落地案例。
...@@ -36,7 +36,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ...@@ -36,7 +36,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
### 安装 TDengine ### 安装 TDengine
从涛思数据官网[下载](http://taosdata.com/cn/all-downloads/)页面下载最新 TDengine-server 2.3.0.0 或以上版本安装。 从涛思数据官网[下载](http://taosdata.com/cn/all-downloads/)页面下载最新 TDengine-server 2.4.0.x 或以上版本安装。
## 数据链路设置 ## 数据链路设置
...@@ -52,7 +52,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ...@@ -52,7 +52,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
### 配置 collectd ### 配置 collectd
`/etc/collectd/collectd.conf` 文件中增加如下内容,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值: `/etc/collectd/collectd.conf` 文件中增加如下内容,其中 `host``port` 请填写 TDengine 和 taosAdapter 配置的实际值:
``` ```
LoadPlugin network LoadPlugin network
...@@ -65,7 +65,7 @@ sudo systemctl start collectd ...@@ -65,7 +65,7 @@ sudo systemctl start collectd
### 配置 StatsD ### 配置 StatsD
`config.js` 文件中增加如下内容后启动 StatsD,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值: `config.js` 文件中增加如下内容后启动 StatsD,其中 `host``port` 请填写 TDengine 和 taosAdapter 配置的实际值:
``` ```
backends 部分添加 "./backends/repeater" backends 部分添加 "./backends/repeater"
...@@ -74,22 +74,22 @@ repeater 部分添加 { host:'<TDengine server/cluster host>', port: <port for S ...@@ -74,22 +74,22 @@ repeater 部分添加 { host:'<TDengine server/cluster host>', port: <port for S
### 导入 Dashboard ### 导入 Dashboard
使用 Web 浏览器访问运行 Grafana 的服务器的 3000 端口 host:3000 登录 Grafana 界面,系统初始用户名密码为 admin/admin 使用 Web 浏览器访问运行 Grafana 的服务器的 3000 端口 `host:3000` 登录 Grafana 界面,系统初始用户名密码为 `admin/admin`
点击左侧齿轮图标并选择 Plugins,应该可以找到 TDengine data source 插件图标。 点击左侧齿轮图标并选择 `Plugins`,应该可以找到 TDengine data source 插件图标。
#### 导入 collectd 仪表盘 #### 导入 collectd 仪表盘
从 https://github.com/taosdata/grafanaplugin/blob/master/examples/collectd/grafana/dashboards/collect-metrics-with-tdengine-v0.1.0.json 下载 dashboard json 文件,点击左侧加号图标并选择 Import,按照界面提示选择 JSON 文件导入。之后可以看到如下界面的仪表盘: 从 https://github.com/taosdata/grafanaplugin/blob/master/examples/collectd/grafana/dashboards/collect-metrics-with-tdengine-v0.1.0.json 下载 dashboard json 文件,点击左侧加号图标并选择 `Import`,按照界面提示选择 JSON 文件导入。之后可以看到如下界面的仪表盘:
![IT-DevOps-Solutions-collectd-dashboard.png](/img/IT-DevOps-Solutions-collectd-dashboard.png) ![IT-DevOps-Solutions-collectd-dashboard.png](/img/IT-DevOps-Solutions-collectd-dashboard.png)
#### 导入 StatsD 仪表盘 #### 导入 StatsD 仪表盘
https://github.com/taosdata/grafanaplugin/blob/master/examples/statsd/dashboards/statsd-with-tdengine-v0.1.0.json 下载 dashboard json 文件,点击左侧加号图标并选择 Import,按照界面提示导入 JSON 文件。之后可以看到如下界面的仪表盘: `https://github.com/taosdata/grafanaplugin/blob/master/examples/statsd/dashboards/statsd-with-tdengine-v0.1.0.json` 下载 dashboard json 文件,点击左侧加号图标并选择 `Import`,按照界面提示导入 JSON 文件。之后可以看到如下界面的仪表盘:
![IT-DevOps-Solutions-statsd-dashboard.png](/img/IT-DevOps-Solutions-statsd-dashboard.png) ![IT-DevOps-Solutions-statsd-dashboard.png](/img/IT-DevOps-Solutions-statsd-dashboard.png)
## 总结 ## 总结
TDengine 作为新兴的时序大数据平台,具备极强的高性能、高可靠、易管理、易维护的优势。得力于 TDengine 2.3.0.0 版本中新增的 schemaless 协议解析功能,以及强大的生态软件适配能力,用户可以短短数分钟就可以搭建一个高效易用的 IT 运维系统或者适配一个已存在的系统。 TDengine 作为新兴的时序大数据平台,具备极强的高性能、高可靠、易管理、易维护的优势。得力于 TDengine 2.4.0.0 版本中新增的 schemaless 协议解析功能,以及强大的生态软件适配能力,用户可以短短数分钟就可以搭建一个高效易用的 IT 运维系统或者适配一个已存在的系统。
TDengine 强大的数据写入查询性能和其他丰富功能请参考官方文档和产品成功落地案例。 TDengine 强大的数据写入查询性能和其他丰富功能请参考官方文档和产品成功落地案例。
...@@ -177,40 +177,9 @@ title: 常见问题及反馈 ...@@ -177,40 +177,9 @@ title: 常见问题及反馈
<a class="anchor" id="timezone"></a> <a class="anchor" id="timezone"></a>
**18. 时间戳的时区信息是怎样处理的?** **18. go 语言编写组件编译失败怎样解决?**
TDengine 中时间戳的时区总是由客户端进行处理,而与服务端无关。具体来说,客户端会对 SQL 语句中的时间戳进行时区转换,转为 UTC 时区(即 Unix 时间戳——Unix Timestamp)再交由服务端进行写入和查询;在读取数据时,服务端也是采用 UTC 时区提供原始数据,客户端收到后再根据本地设置,把时间戳转换为本地系统所要求的时区进行显示。 TDengine 2.3.0.0 及之后的版本包含一个使用 go 语言开发的 taosAdapter 独立组件,需要单独运行,取代之前 taosd 内置的 httpd ,提供包含原 httpd 功能以及支持多种其他软件(Prometheus、Telegraf、collectd、StatsD 等)的数据接入功能。
客户端在处理时间戳字符串时,会采取如下逻辑:
1. 在未做特殊设置的情况下,客户端默认使用所在操作系统的时区设置。
2. 如果在 taos.cfg 中设置了 timezone 参数,则客户端会以这个配置文件中的设置为准。
3. 如果在 C/C++/Java/Python 等各种编程语言的 Connector Driver 中,在建立数据库连接时显式指定了 timezone,那么会以这个指定的时区设置为准。例如 Java Connector 的 JDBC URL 中就有 timezone 参数。
4. 在书写 SQL 语句时,也可以直接使用 Unix 时间戳(例如 `1554984068000`)或带有时区的时间戳字符串,也即以 RFC 3339 格式(例如 `2013-04-12T15:52:01.123+08:00`)或 ISO-8601 格式(例如 `2013-04-12T15:52:01.123+0800`)来书写时间戳,此时这些时间戳的取值将不再受其他时区设置的影响。
<a class="anchor" id="port"></a>
**19. TDengine 都会用到哪些网络端口?**
在 TDengine 2.0 版本中,会用到以下这些网络端口(以默认端口 6030 为前提进行说明,如果修改了配置文件中的设置,那么这里列举的端口都会出现变化),管理员可以参考这里的信息调整防火墙设置:
| 协议 | 默认端口 | 用途说明 | 修改方法 |
| :--- | :-------- | :---------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
| TCP | 6030 | 客户端与服务端之间通讯。 | 由配置文件设置 serverPort 决定。 |
| TCP | 6035 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 |
| TCP | 6040 | 多节点集群的节点间数据同步。 | 随 serverPort 端口变化。 |
| TCP | 6041 | 客户端与服务端之间的 RESTful 通讯。 | 随 serverPort 端口变化。注意 taosAdapter 配置或有不同,请参考相应[文档](/reference/taosadapter/)。 |
| TCP | 6042 | Arbitrator 的服务端口。 | 随 Arbitrator 启动参数设置变化。 |
| TCP | 6043 | TaosKeeper 监控服务端口。 | 随 TaosKeeper 启动参数设置变化。 |
| TCP | 6044 | 支持 StatsD 的数据接入端口。 | 随 taosAdapter 启动参数设置变化(2.3.0.1+以上版本)。 |
| TCP | 6045 | 支持 collectd 数据接入端口。 | 随 taosAdapter 启动参数设置变化(2.3.0.1+以上版本)。 |
| TCP | 6060 | 企业版内 Monitor 服务的网络端口。 | |
| UDP | 6030-6034 | 客户端与服务端之间通讯。 | 随 serverPort 端口变化。 |
| UDP | 6035-6039 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 |
**20. go 语言编写组件编译失败怎样解决?**
新版本 TDengine 2.3.0.0 包含一个使用 go 语言开发的 taosAdapter 独立组件,需要单独运行,取代之前 taosd 内置的 httpd ,提供包含原 httpd 功能以及支持多种其他软件(Prometheus、Telegraf、collectd、StatsD 等)的数据接入功能。
使用最新 develop 分支代码编译需要先 `git submodule update --init --recursive` 下载 taosAdapter 仓库代码后再编译。 使用最新 develop 分支代码编译需要先 `git submodule update --init --recursive` 下载 taosAdapter 仓库代码后再编译。
目前编译方式默认自动编译 taosAdapter。go 语言版本要求 1.14 以上,如果发生 go 编译错误,往往是国内访问 go mod 问题,可以通过设置 go 环境变量来解决: 目前编译方式默认自动编译 taosAdapter。go 语言版本要求 1.14 以上,如果发生 go 编译错误,往往是国内访问 go mod 问题,可以通过设置 go 环境变量来解决:
...@@ -222,3 +191,14 @@ title: 常见问题及反馈 ...@@ -222,3 +191,14 @@ title: 常见问题及反馈
如果希望继续使用之前的内置 httpd,可以关闭 taosAdapter 编译,使用 如果希望继续使用之前的内置 httpd,可以关闭 taosAdapter 编译,使用
`cmake .. -DBUILD_HTTP=true` 使用原来内置的 httpd。 `cmake .. -DBUILD_HTTP=true` 使用原来内置的 httpd。
**19. 如何查询数据占用的存储空间大小?**
默认情况下,TDengine 的数据文件存储在 /var/lib/taos ,日志文件存储在 /var/log/taos 。
若想查看所有数据文件占用的具体大小,可以执行 Shell 指令:`du -sh /var/lib/taos/vnode --exclude='wal'` 来查看。此处排除了 wal 目录,因为在持续写入的情况下,这里大小几乎是固定的,并且每当正常关闭 TDengine 让数据落盘后, wal 目录都会清空。
若想查看单个数据库占用的大小,可在命令行程序 taos 内指定要查看的数据库后执行 `show vgroups;` ,通过得到的 VGroup id 去 /var/lib/taos/vnode 下查看包含的文件夹大小。
若仅仅想查看指定(超级)表的数据块分布及大小,可查看[_block_dist 函数](https://docs.taosdata.com/taos-sql/select/#_block_dist-%E5%87%BD%E6%95%B0)
此差异已折叠。
label: TDengine 介绍 label: Introduction
此差异已折叠。
label: 基本概念 label: Concepts
\ No newline at end of file \ No newline at end of file
--- ---
title: 立即开始 title: Get Started
description: " Docker,安装包或使用 apt-get 快速安装 TDengine, 通过命令行程序TAOS CLI和工具 taosdemo 快速体验 TDengine 功能" description: "Install TDengine from Docker image, apt-get or package, and run TAOS CLI and taosBenchmark to experience the features"
--- ---
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
...@@ -8,38 +8,38 @@ import TabItem from "@theme/TabItem"; ...@@ -8,38 +8,38 @@ import TabItem from "@theme/TabItem";
import PkgInstall from "./\_pkg_install.mdx"; import PkgInstall from "./\_pkg_install.mdx";
import AptGetInstall from "./\_apt_get_install.mdx"; import AptGetInstall from "./\_apt_get_install.mdx";
## 安装 ## Quick Install
TDengine 完整的软件包包括服务端(taosd)、用于与第三方系统对接并提供RESTful接口的taosAdapter、应用驱动(taosc)、命令行程序 (CLI,taos) 和一些工具软件,目前 2.X 版服务端taosd、taosAdapter 仅在 Linux 系统上安装和运行,后续将支持 Windows、macOS 等系统。应用驱动 taosc 与 TDengine CLI 可以在 Windows 或 Linux 上安装和运行。TDengine 除 RESTful接口外,还提供一些列编程语言的连接器。2.4 之前的版本中,无 taosAdapter,RESTfule 接口均由 taosd 内置的 http 服务提供。 The full package of TDengine includes server(taosd), taosAdapter for connecting with third-party systems and providing RESTful interface, application driver(taosc), command line program(CLI, taos) and some tools. For current version, the server taosd and taosAdapter can only be installed and run on Linux systems, and will support Windows, macOS and other systems in the future. The application driver taosc and TDengine CLI can be installed and run on Windows or Linux. In addition to the RESTful interface, TDengine also provides connectors for a number of programming languages. In versions before 2.4, there is no taosAdapter, and the RESTfule interface is provided by the built-in http service of taosd.
TDengine 支持 X64/ARM64/MIPS64/Alpha64 硬件平台,后续将支持 ARM32、RISC-V 等 CPU 架构。 TDengine supports X64/ARM64/MIPS64/Alpha64 hardware platforms, and will support ARM32, RISC-V and other CPU architectures in the future.
<Tabs defaultValue="apt-get"> <Tabs defaultValue="apt-get">
<TabItem value="docker" label="Docker"> <TabItem value="docker" label="Docker">
如果已经安装了 docker, 只需执行下面的命令。 If docker is already installed on your computer, execute the following command:
```shell ```shell
docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp tdengine/tdengine docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp tdengine/tdengine
``` ```
确定该容器已经启动并且在正常运行 Make sure the container is running
```shell ```shell
docker ps docker ps
``` ```
进入该容器并执行 bash Enter into container and execute bash
```shell ```shell
docker exec -it <containrid> bash docker exec -it <containrid> bash
``` ```
然后就可以执行相关的 Linux 命令操作和访问 TDengine Then you can execute the Linux commands and access TDengine.
详细操作方法请参照 [通过 Docker 快速体验 TDengine](/train-faq/docker) For detailed steps, please visit [Experience TDengine via Docker](/train-faq/docker)
:::info :::info
从 2.4.0.10 开始,除 taosd 以外,Docker 镜像还包含:taos、taosAdapter、taosdump、taosBenchmark、TDinsight 安装脚本和示例代码。启动 Docker 容器时,将同时启动 taosAdapter 和 taosd,实现对 RESTful 的支持。 Starting from 2.4.0.10,besides taosd,TDengine docker image includes: taos,taosAdapter,taosdump,taosBenchmark,TDinsight, scripts and sample code. Once the TDengine container is started,it will start both taosAdapter and taosd automatically to support RESTful interface.
::: :::
...@@ -47,66 +47,64 @@ docker exec -it <containrid> bash ...@@ -47,66 +47,64 @@ docker exec -it <containrid> bash
<TabItem value="apt-get" label="apt-get"> <TabItem value="apt-get" label="apt-get">
<AptGetInstall /> <AptGetInstall />
</TabItem> </TabItem>
<TabItem value="pkg" label="安装包"> <TabItem value="pkg" label="Package">
<PkgInstall /> <PkgInstall />
</TabItem> </TabItem>
<TabItem value="src" label="源码"> <TabItem value="src" label="Source Code">
如果您希望对 TDengine 贡献代码或对内部实现感兴趣,请参考我们的 [TDengine GitHub 主页](https://github.com/taosdata/TDengine) 下载源码构建和安装. If you like to check the source code, build the package by youself or contribute to the project, please check [TDengine GitHub Repository](https://github.com/taosdata/TDengine)
下载其他组件、最新 Beta 版及之前版本的安装包,请点击[这里](https://www.taosdata.com/cn/all-downloads/)
</TabItem> </TabItem>
</Tabs> </Tabs>
## 启动 ## Quick Launch
安装后,请使用 `systemctl` 命令来启动 TDengine 的服务进程。 After installation, you can launch the TDengine service by the 'systemctl' command to start 'taosd'.
```bash ```bash
systemctl start taosd systemctl start taosd
``` ```
检查服务是否正常工作 Check if taosd is running
```bash ```bash
systemctl status taosd systemctl status taosd
``` ```
如果 TDengine 服务正常工作,那么您可以通过 TDengine 的命令行程序 `taos` 来访问并体验 TDengine。 If everything is fine,you can run TDengine command line interface `taos` to access TDengine and play around it.
:::info :::info
- systemctl 命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo 。 - systemctl requires _root_ privileges,if you are not _root_ ,please add sudo before the command.
- 为更好的获得产品反馈,改善产品,TDengine 会采集基本的使用信息,但您可以修改系统配置文件 taos.cfg 里的配置参数 telemetryReporting,将其设为 0,就可将其关闭。 - To get feedback and keep polishing the prodcut, TDengine is colleting some basic usage information, but you can turn it off by setting telemetryReporting to 0 in configuration file taos.cfg.
- TDengine 采用 FQDN(一般就是 hostname)作为节点的 ID,为保证正常运行,需要给运行 taosd 的服务器配置好 FQDN,在 TDengine CLI 或应用运行的机器配置好 DNS 服务或 hosts 文件,保证 FQDN 能够解析。 - TDengine uses FQDN (usually hostname)as the ID for a node. To make system work, you need to configure the FQDN for the server running taosd, and configure the DNS service or hosts file on the the machine where the application or TDengine CLI runs to ensure that the FQDN can be resolved.
- `systemctl stop taosd` 指令在执行后并不会马上停止 TDengine 服务,而是会等待系统中必要的落盘工作正常完成。在数据量很大的情况下,这可能会消耗较长时间。 - `systemctl stop taosd` won't stop the server right away, it will wait until all the data in memory are flushed to disk. It may takes time depending on the cache size.
TDengine 支持在使用 [`systemd`](https://en.wikipedia.org/wiki/Systemd) 做进程服务管理的 Linux 系统上安装,用 `which systemctl` 命令来检测系统中是否存在 `systemd`: TDengine supports the installation on system which runs [`systemd`](https://en.wikipedia.org/wiki/Systemd) for process management,use `which systemctl` to check if the system has `systemd` installed:
```bash ```bash
which systemctl which systemctl
``` ```
如果系统中不支持 `systemd`,也可以用手动运行 `/usr/local/taos/bin/taosd` 方式启动 TDengine 服务。 If the system does not have `systemd`,you can start TDengine manually by executing `/usr/local/taos/bin/taosd`
:::note :::note
## TDengine 命令行 (CLI) ## Command Line Interface
为便于检查 TDengine 的状态,执行各种即席(Ad Hoc)查询,TDengine 提供一命令行应用程序(以下简称为 TDengine CLI) taos。要进入 TDengine 命令行,您只要在安装有 TDengine 的 Linux 终端执行 `taos` 即可。 To manage the TDengine running instance,or execute ad-hoc queries, TDengine provides a Command Line Interface(hereinafter referred to as TDengine CLI) taos. To enter into the interactive CLI,execute `taos` on a Linux terminal where TDengine is installed.
```bash ```bash
taos taos
``` ```
如果连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息出来(请参考 [FAQ](/train-faq/faq) 来解决终端连接服务端失败的问题)。 TDengine CLI 的提示符号如下 If it connects to the TDengine server successfully, it will print out the version and welcome message. If it fails, it will print out the error message, please check [FAQ](/train-faq/faq) for trouble shooting connection issue. TDengine CLI's prompt is
```cmd ```cmd
taos> taos>
``` ```
在 TDengine CLI中,用户可以通过 SQL 命令来创建/删除数据库、表等,并进行插入查询操作。在终端中运行的 SQL 语句需要以分号结束来运行。示例: Inside TDengine CLI,you can execute SQL commands to create/drop database/table, and run queries. The SQL command must be eneded with a semicolon. For example:
```sql ```sql
create database demo; create database demo;
...@@ -121,52 +119,50 @@ select * from t; ...@@ -121,52 +119,50 @@ select * from t;
2019-07-15 01:00:00.000 | 20 | 2019-07-15 01:00:00.000 | 20 |
Query OK, 2 row(s) in set (0.003128s) Query OK, 2 row(s) in set (0.003128s)
``` ```
Besides executing SQL commands, system administrator can check running status, add/drop user accounts and manage the running instances. TAOS CLI with application driver can be installed and run on either Linux or windows machine. For more details on CLI, please [check here](../reference/taos-shell/).
除执行 SQL 语句外,系统管理员还可以从 TDengine CLI 进行检查系统运行状态、添加删除用户账号等操作。TAOS CLI 连同应用驱动也可以独立安装在 Linux 或 windows 机器上运行,更多细节请参考 [这里](../reference/taos-shell/) ## Experience the blazing fast speed
## 使用 taosBenchmark 体验写入速度
启动 TDengine 的服务,在 Linux 终端执行 `taosBenchmark` (曾命名为 `taosdemo` After TDengine server is running,execute `taosBenchmark`(named as taosdemo before) from a Linux terminal
```bash ```bash
taosBenchmark taosBenchmark
``` ```
This command will create a super table "meters" under database "test". Unde "meters", 10000 tables are created with name from "d0" to "d9999". Each table has 10000 rows and each row has four columns (ts, current, voltage, phase). Time stamp is starting from "2017-07-14 10:40:00 000" to "2017-07-14 10:40:09 999". Each table has tags "location" and "groupId". groupId is set 1 to 10 randomly, and location is set to "beijing" or "shanghai".
该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "beijing" 或者 "shanghai"。 This command will insert 100 million rows into database quickly. Depends on the hardware configuration, it only takes a dozen seconds for a regular PC server.
这条命令很快完成 1 亿条记录的插入。具体时间取决于硬件性能,即使在一台普通的 PC 服务器往往也仅需十几秒。
taosBenchmark 命令本身带有很多选项,配置表的数目、记录条数等等,您可以设置不同参数进行体验,请执行 `taosBenchmark --help` 详细列出。taosBenchmark 详细使用方法请参照 [如何使用 taosBenchmark 对 TDengine 进行性能测试](https://www.taosdata.com/2021/10/09/3111.html)
## 使用 TDengine CLI 体验查询速度 taosBenchmark provides you command line options and confuguration file to customize the scenarios, like number of tables, number of rows per table, number of columns and more. Please execute `taosBenchmark --help` to list them. For details on running taosBenchmark, please check [reference for taosBenchmark](/reference/taosbenchmark)
使用上述 taosBenchmark 插入数据后,可以在 TDengine CLI 输入查询命令,体验查询速度。 ## Experience query speed
After using taosBenchmark to insert a number of rows data, you can execute queries from TDengine CLI to experience the lightning query speed.
查询超级表下记录总条数 query the total number of rows under super table "meters"
```sql ```sql
taos> select count(*) from test.meters; taos> select count(*) from test.meters;
``` ```
查询 1 亿条记录的平均值、最大值、最小值等: query the average, maximum, minimum of 100 million rows:
```sql ```sql
taos> select avg(current), max(voltage), min(phase) from test.meters; taos> select avg(current), max(voltage), min(phase) from test.meters;
``` ```
查询 location="beijing" 的记录总条数: query the total number of rows with location="beijing":
```sql ```sql
taos> select count(*) from test.meters where location="beijing"; taos> select count(*) from test.meters where location="beijing";
``` ```
查询 groupId=10 的所有记录的平均值、最大值、最小值等: query the average, maximum, minimum of all rows with groupId=10:
```sql ```sql
taos> select avg(current), max(voltage), min(phase) from test.meters where groupId=10; taos> select avg(current), max(voltage), min(phase) from test.meters where groupId=10;
``` ```
对表 d10 按 10s 进行平均值、最大值和最小值聚合统计 query the average, maximum, minimum for table d10 in 10 seconds time interal
```sql ```sql
taos> select avg(current), max(voltage), min(phase) from test.d10 interval(10s); taos> select avg(current), max(voltage), min(phase) from test.d10 interval(10s);
......
可以使用 apt-get 工具从官方仓库安装。 `apt-get` can be used to install TDengine from official package repository.
**安装包仓库** **Package Repository**
``` ```
wget -qO - http://repos.taosdata.com/tdengine.key | sudo apt-key add - wget -qO - http://repos.taosdata.com/tdengine.key | sudo apt-key add -
echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-stable stable main" | sudo tee /etc/apt/sources.list.d/tdengine-stable.list echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-stable stable main" | sudo tee /etc/apt/sources.list.d/tdengine-stable.list
``` ```
如果安装 Beta 版需要安装包仓库 The repository required for installing beta versions can be configured as below:
``` ```
echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-beta beta main" | sudo tee /etc/apt/sources.list.d/tdengine-beta.list echo "deb [arch=amd64] http://repos.taosdata.com/tdengine-beta beta main" | sudo tee /etc/apt/sources.list.d/tdengine-beta.list
``` ```
**使用 apt-get 命令安装** **Install With apt-get**
``` ```
sudo apt-get update sudo apt-get update
...@@ -22,5 +22,5 @@ sudo apt-get install tdengine ...@@ -22,5 +22,5 @@ sudo apt-get install tdengine
``` ```
:::tip :::tip
apt-get 方式只适用于 Debian 或 Ubuntu 系统 `apt-get` can only be used on Debian or Ubuntu Linux.
:::: ::::
```c title="原生连接" ```c title="Native Connection"
{{#include docs-examples/c/connect_example.c}} {{#include docs-examples/c/connect_example.c}}
``` ```
```csharp title="原生连接" ```csharp title="Native Connection"
{{#include docs-examples/csharp/ConnectExample.cs}} {{#include docs-examples/csharp/ConnectExample.cs}}
``` ```
:::info :::info
C# 连接器目前只支持原生连接。 C# connector supports only native connection for now.
::: :::
\ No newline at end of file
#### 使用数据库访问统一接口 #### Unified Database Access Interface
```go title="原生连接"
```go title="Native Connection"
{{#include docs-examples/go/connect/cgoexample/main.go}} {{#include docs-examples/go/connect/cgoexample/main.go}}
``` ```
```go title="REST 连接"
```go title="REST Connection"
{{#include docs-examples/go/connect/restexample/main.go}} {{#include docs-examples/go/connect/restexample/main.go}}
``` ```
#### 使用高级封装
也可以使用 driver-go 的 af 包建立连接。这个模块封装了 TDengine 的高级功能, 如:参数绑定、订阅等。
```go title="使用 af 包建立原生连接" #### Advanced Features
{{#include docs-examples/go/connect/afconn/main.go}}
```
The af package of driver-go can also be used to establish connection, with this way some advanced features of TDengine, like parameter binding and subscription, can be used.
```go title="Establish native connection using af package"
{{#include docs-examples/go/connect/afconn/main.go}}
```
```java title="原生连接" ```java title="Native Connection"
{{#include docs-examples/java/src/main/java/com/taos/example/JNIConnectExample.java}} {{#include docs-examples/java/src/main/java/com/taos/example/JNIConnectExample.java}}
``` ```
```java title="REST 连接"
```java title="REST Connection"
{{#include docs-examples/java/src/main/java/com/taos/example/RESTConnectExample.java:main}} {{#include docs-examples/java/src/main/java/com/taos/example/RESTConnectExample.java:main}}
``` ```
使用REST 连接时,如果查询数据量比较大,还可开启批量拉取功能。
```java title="开启批量拉取功能" {4} When using REST connection, the feature of bulk pulling can be enabled if the size of resulting data set is huge.
```java title="Enable Bulk Pulling" {4}
{{#include docs-examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} {{#include docs-examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}}
``` ```
更多连接参数配置,参考[Java 连接器](/reference/connector/java)
\ No newline at end of file More configuration about connection,please refer to [Java Connector](/reference/connector/java)
```js title="原生连接" ```js title="Native Connection"
{{#include docs-examples/node/nativeexample/connect.js}} {{#include docs-examples/node/nativeexample/connect.js}}
``` ```
```js title="REST 连接"
```js title="REST Connection"
{{#include docs-examples/node/restexample/connect.js}} {{#include docs-examples/node/restexample/connect.js}}
``` ```
\ No newline at end of file
```python title="原生连接" ```python title="Native Connection"
{{#include docs-examples/python/connect_exmaple.py}} {{#include docs-examples/python/connect_exmaple.py}}
``` ```
\ No newline at end of file
```r title="原生连接" ```r title="Native Connection"
{{#include docs-examples/R/connect_native.r:demo}} {{#include docs-examples/R/connect_native.r:demo}}
``` ```
\ No newline at end of file
```rust title="原生连接/REST 连接" ```rust title="Native Connection/REST Connection"
{{#include docs-examples/rust/nativeexample/examples/connect.rs}} {{#include docs-examples/rust/nativeexample/examples/connect.rs}}
``` ```
:::note :::note
对于 Rust 连接器, 连接方式的不同只体现在使用的特性不同。如果启用了 "rest" 特性,那么只有 RESTful 的实现会被编译进来。 For Rust connector, the connection depends on the feature being used. If "rest" feature is enabled, then only the implementation for "rest" is compiled and packaged.
::: :::
--- ---
title: 建立连接 sidebar_label: Connect
description: "本节介绍如何使用连接器建立与 TDengine 的连接,给出连接器安装、连接的简单说明。" title: Connect to TDengine
description: "This document explains how to establish connection to TDengine, and briefly introduce how to install and use TDengine connectors."
--- ---
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem"; import TabItem from "@theme/TabItem";
import ConnJava from "./_connect_java.mdx"; import ConnJava from "./\_connect_java.mdx";
import ConnGo from "./_connect_go.mdx"; import ConnGo from "./\_connect_go.mdx";
import ConnRust from "./_connect_rust.mdx"; import ConnRust from "./\_connect_rust.mdx";
import ConnNode from "./_connect_node.mdx"; import ConnNode from "./\_connect_node.mdx";
import ConnPythonNative from "./_connect_python.mdx"; import ConnPythonNative from "./\_connect_python.mdx";
import ConnCSNative from "./_connect_cs.mdx"; import ConnCSNative from "./\_connect_cs.mdx";
import ConnC from "./_connect_c.mdx"; import ConnC from "./\_connect_c.mdx";
import ConnR from "./_connect_r.mdx"; import ConnR from "./\_connect_r.mdx";
import InstallOnWindows from "../../14-reference/03-connector/_linux_install.mdx"; import InstallOnWindows from "../../14-reference/03-connector/\_linux_install.mdx";
import InstallOnLinux from "../../14-reference/03-connector/_windows_install.mdx"; import InstallOnLinux from "../../14-reference/03-connector/\_windows_install.mdx";
import VerifyLinux from "../../14-reference/03-connector/_verify_linux.mdx"; import VerifyLinux from "../../14-reference/03-connector/\_verify_linux.mdx";
import VerifyWindows from "../../14-reference/03-connector/_verify_windows.mdx"; import VerifyWindows from "../../14-reference/03-connector/\_verify_windows.mdx";
TDengine 提供 REST API,容许在任何平台的任何应用程序通过它访问 TDengine 运行实例,详细介绍请看 [REST API](/reference/rest-api/)。除 REST API 之外,TDengine 还提供多种编程语言的连接器方便用户开发应用程序,其中包括 C/C++、Java、Python、Go、Node.js、C# 等。 本节介绍如何使用连接器建立与 TDengine 的连接,给出连接器安装、连接的简单说明。关于各连接器的详细功能说明,请查看[连接器](https://docs.taosdata.com/reference/connector/) Any application programs running on any kind of platforms can access TDengine through the REST API provided by TDengine. For the details please refer to [REST API](/reference/rest-api/). Besides, application programs can use the connectors of multiple languages to access TDengine, including C/C++, Java, Python, Go, Node.js, C#, and Rust. This chapter describes how to establish connection to TDengine and briefly introduce how to install and use connectors. For details about the connectors please refer to [Connectors](/reference/connector/)
## 连接器建立连接的方式 ## Establish Connection
连接器建立连接的方式,TDengine 提供两种: There are two ways to establish connections to TDengine:
1. 通过 taosAdapter 组件提供的 REST API 建立与 taosd 的连接,这种连接方式下文中简称"REST 连接“ 1. Connection to taosd can be established through the REST API provided by taosAdapter component, this way is called "REST connection" hereinafter.
2. 通过客户端驱动程序 taosc 直接与服务端程序 taosd 建立连接,这种连接方式下文中简称“原生连接”。 2. Connection to taosd can be established through the client side driver taosc, this way is called "Native connection" hereinafter.
无论使用何种方式建立连接,连接器都提供了相同或相似的 API 操作数据库,都可以执行 SQL 语句,只是初始化连接的方式稍有不同,用户在使用上不会感到什么差别。 Either way, same or similar APIs are provided by connectors to access database or execute SQL statements, no obvious difference can be observed.
关键不同点在于 Key differences
1. 使用 REST 连接,用户无需安装客户端驱动程序 taosc,具有跨平台易用的优势,但性能要下降 30%左右。 1. With REST connection, it's not necessary to install the client side driver taosc, it's more friendly for cross-platform with the cost of 30% performance downgrade.
2. 使用原生连接可以体验 TDengine 的全部功能,如[参数绑定接口](/reference/connector/cpp#参数绑定-api)[订阅](reference/connector/cpp#数据订阅接口)等等。 2. With native connection, full compatibility of TDengine can be utilized, like [Parameter Binding](/reference/connector/cpp#Parameter Binding-api), [Subscription](reference/connector/cpp#Subscription), etc.
## 安装客户端驱动 taosc ## Install Client Driver taosc
如果选择原生连接,而且应用程序不在 TDengine 同一台服务器上运行,你需要先安装客户端驱动,否则可以跳过此一步。为避免客户端驱动和服务端不兼容,请使用一致的版本。 If choosing to use native connection and the client program is not on the same host as TDengine server, TDengine client driver needs to be installed on the host where the client program is. If choosing to use REST connection or the client is on the same host as server side, this step can be skipped. It's better to use same version of client as the server.
### 安装步骤 ### Install
<Tabs defaultValue="linux" groupId="os"> <Tabs defaultValue="linux" groupId="os">
<TabItem value="linux" label="Linux"> <TabItem value="linux" label="Linux">
...@@ -49,9 +50,9 @@ TDengine 提供 REST API,容许在任何平台的任何应用程序通过它 ...@@ -49,9 +50,9 @@ TDengine 提供 REST API,容许在任何平台的任何应用程序通过它
</TabItem> </TabItem>
</Tabs> </Tabs>
### 安装验证 ### Verify
以上安装和配置完成后,并确认 TDengine 服务已经正常启动运行,此时可以执行安装包里带有的 TDengine 命令行程序 taos 进行登录。 After the above installation and configuration are done and making sure TDengine service is already started and in service, the Shell command `taos` can be launched to access TDengine.以
<Tabs defaultValue="linux" groupId="os"> <Tabs defaultValue="linux" groupId="os">
<TabItem value="linux" label="Linux"> <TabItem value="linux" label="Linux">
...@@ -62,12 +63,12 @@ TDengine 提供 REST API,容许在任何平台的任何应用程序通过它 ...@@ -62,12 +63,12 @@ TDengine 提供 REST API,容许在任何平台的任何应用程序通过它
</TabItem> </TabItem>
</Tabs> </Tabs>
## 安装连接器 ## Install Connectors
<Tabs groupId="lang"> <Tabs groupId="lang">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
如果使用 maven 管理项目,只需在 pom.xml 中加入以下依赖。 If `maven` is used to manage the projects, what needs to be done is only adding below dependency in `pom.xml`.
```xml ```xml
<dependency> <dependency>
...@@ -80,13 +81,13 @@ TDengine 提供 REST API,容许在任何平台的任何应用程序通过它 ...@@ -80,13 +81,13 @@ TDengine 提供 REST API,容许在任何平台的任何应用程序通过它
</TabItem> </TabItem>
<TabItem label="Python" value="python"> <TabItem label="Python" value="python">
使用 `pip` 从 PyPI 安装: Install from PyPI using `pip`:
``` ```
pip install taospy pip install taospy
``` ```
从 Git URL 安装: Install from Git URL:
``` ```
pip install git+https://github.com/taosdata/taos-connector-python.git pip install git+https://github.com/taosdata/taos-connector-python.git
...@@ -95,7 +96,7 @@ pip install git+https://github.com/taosdata/taos-connector-python.git ...@@ -95,7 +96,7 @@ pip install git+https://github.com/taosdata/taos-connector-python.git
</TabItem> </TabItem>
<TabItem label="Go" value="go"> <TabItem label="Go" value="go">
编辑 `go.mod` 添加 `driver-go` 依赖即可。 Just need to add `driver-go` dependency in `go.mod` .
```go-mod title=go.mod ```go-mod title=go.mod
module goexample module goexample
...@@ -106,14 +107,14 @@ require github.com/taosdata/driver-go/v2 develop ...@@ -106,14 +107,14 @@ require github.com/taosdata/driver-go/v2 develop
``` ```
:::note :::note
driver-go 使用 cgo 封装了 taosc 的 API。cgo 需要使用 gcc 编译 C 的源码。因此需要确保你的系统上有 gcc。 `driver-go` uses `cgo` to wrap the APIs provided by taosc, while `cgo` needs `gcc` to compile source code in C language, so please make sure you have proper `gcc` on your system.
::: :::
</TabItem> </TabItem>
<TabItem label="Rust" value="rust"> <TabItem label="Rust" value="rust">
编辑 `Cargo.toml` 添加 `libtaos` 依赖即可。 Just need to add `libtaos` dependency in `Cargo.toml`.
```toml title=Cargo.toml ```toml title=Cargo.toml
[dependencies] [dependencies]
...@@ -121,7 +122,7 @@ libtaos = { version = "0.4.2"} ...@@ -121,7 +122,7 @@ libtaos = { version = "0.4.2"}
``` ```
:::info :::info
Rust 连接器通过不同的特性区分不同的连接方式。如果要建立 REST 连接,需要开启 `rest` 特性: Rust connector uses different features to distinguish the way to establish connection. To establish REST connection, please enable `rest` feature.
```toml ```toml
libtaos = { version = "*", features = ["rest"] } libtaos = { version = "*", features = ["rest"] }
...@@ -132,28 +133,28 @@ libtaos = { version = "*", features = ["rest"] } ...@@ -132,28 +133,28 @@ libtaos = { version = "*", features = ["rest"] }
</TabItem> </TabItem>
<TabItem label="Node.js" value="node"> <TabItem label="Node.js" value="node">
Node.js 连接器通过不同的包提供不同的连接方式。 Node.js connector provides different ways of establishing connections by providing different packages.
1. 安装 Node.js 原生连接器 1. Install Node.js Native Connector
``` ```
npm i td2.0-connector npm i td2.0-connector
``` ```
:::note :::note
推荐 Node 版本大于等于 `node-v12.8.0` 小于 `node-v13.0.0` It's recommend to use Node whose version is between `node-v12.8.0` and `node-v13.0.0`.
::: :::
2. 安装 Node.js REST 连接器
``` 2. Install Node.js REST Connector
npm i td2.0-rest-connector
``` ```
npm i td2.0-rest-connector
```
</TabItem> </TabItem>
<TabItem label="C#" value="csharp"> <TabItem label="C#" value="csharp">
编辑项目配置文件中添加 [TDengine.Connector](https://www.nuget.org/packages/TDengine.Connector/) 的引用即可: Just need to add the reference to [TDengine.Connector](https://www.nuget.org/packages/TDengine.Connector/) in the project configuration file.
```xml title=csharp.csproj {12} ```xml title=csharp.csproj {12}
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
...@@ -173,22 +174,22 @@ Node.js 连接器通过不同的包提供不同的连接方式。 ...@@ -173,22 +174,22 @@ Node.js 连接器通过不同的包提供不同的连接方式。
</Project> </Project>
``` ```
也可通过 dotnet 命令添加: Or add by `dotnet` command.
``` ```
dotnet add package TDengine.Connector dotnet add package TDengine.Connector
``` ```
:::note :::note
以下示例代码,均基于 dotnet6.0,如果使用其它版本,可能需要做适当调整。 The sample code below are based on dotnet6.0, they may need to be adjusted if your dotnet version is not exactly same.
::: :::
</TabItem> </TabItem>
<TabItem label="R" value="r"> <TabItem label="R" value="r">
1. 下载 [taos-jdbcdriver-version-dist.jar](https://repo1.maven.org/maven2/com/taosdata/jdbc/taos-jdbcdriver/2.0.38/) 1. Download [taos-jdbcdriver-version-dist.jar](https://repo1.maven.org/maven2/com/taosdata/jdbc/taos-jdbcdriver/2.0.38/).
2. 安装 R 的依赖包`RJDBC` 2. Install the dependency package `RJDBC`
```R ```R
install.packages("RJDBC") install.packages("RJDBC")
...@@ -197,15 +198,15 @@ install.packages("RJDBC") ...@@ -197,15 +198,15 @@ install.packages("RJDBC")
</TabItem> </TabItem>
<TabItem label="C" value="c"> <TabItem label="C" value="c">
如果已经安装了 TDengine 服务端软件或 TDengine 客户端驱动 taosc, 那么已经安装了 C 连接器,无需额外操作。 If the client driver taosc is already installed, then the C connector is already available.
<br/> <br/>
</TabItem> </TabItem>
</Tabs> </Tabs>
## 建立连接 ## Establish Connection
在执行这一步之前,请确保有一个正在运行的,且可以访问到的 TDengine,而且服务端的 FQDN 配置正确。以下示例代码,都假设 TDengine 安装在本机,且 FQDN(默认 localhost) 和 serverPort(默认 6030) 都使用默认配置。 Prior to establishing connection, please make sure TDengine is already running and accessible. The following sample code assumes TDengine is running on the same host as the client program, with FQDN configured to "localhost" and serverPort configured to "6030".
<Tabs groupId="lang" defaultValue="java"> <Tabs groupId="lang" defaultValue="java">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
...@@ -235,6 +236,6 @@ install.packages("RJDBC") ...@@ -235,6 +236,6 @@ install.packages("RJDBC")
</Tabs> </Tabs>
:::tip :::tip
如果建立连接失败,大部分情况下是 FQDN 或防火墙的配置不正确,详细的排查方法请看[《常见问题及反馈》](https://docs.taosdata.com/train-faq/faq)中的“遇到错误 Unable to establish connection, 我怎么办?” If the connection fails, in most cases it's caused by improper configuration for FQDN or firewall. Please refer to the section "Unable to establish connection" in [FAQ](https://docs.taosdata.com/train-faq/faq).
::: :::
--- ---
sidebar_label: Data Model
slug: /model slug: /model
title: TDengine 数据建模 title: Data Model
--- ---
TDengine 采用类关系型数据模型,需要建库、建表。因此对于一个具体的应用场景,需要考虑库、超级表和普通表的设计。本节不讨论细致的语法规则,只介绍概念。 The data model employed by TDengine is similar to relational database, you need to create databases and tables. For a specific application, the design of databases, STables (abbreviated for super table), and tables need to be considered. This chapter will explain the big picture without syntax details.
关于数据建模请参考[视频教程](https://www.taosdata.com/blog/2020/11/11/1945.html)。 ## Create Database
## 创建库 The characteristics of data from different data collection points may be different, such as collection frequency, days to keep, number of replicas, data block size, whether it's allowed to update data, etc. For TDengine to operate with the best performance, it's strongly suggested to put the data with different characteristics into different databases because different storage policy can be set for each database. When creating a database, there are a lot of parameters that can be configured, such as the days to keep data, the number of replicas, the number of memory blocks, time precision, the minimum and maximum number of rows in each data block, compress or not, the time range of the data in single data file, etc. Below is an example of the SQL statement for creating a database.
不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为了在各种场景下 TDengine 都能最大效率的工作,TDengine 建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。创建一个库时,除 SQL 标准的选项外,还可以指定保留时长、副本数、内存块个数、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如:
```sql ```sql
CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 6 UPDATE 1; CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 6 UPDATE 1;
``` ```
上述语句将创建一个名为 power 的库,这个库的数据将保留 365 天(超过 365 天将被自动删除),每 10 天一个数据文件,内存块数为 6,允许更新数据。详细的语法及参数请见 [数据库管理](/taos-sql/database) 章节。 In the above SQL statement, a database named "power" will be created, the data in it will be kept for 365 days, which means the data older than 365 days will be deleted automatically, a new data file will be created every 10 days, the number of memory blocks is 6, data is allowed to be updated. For more details please refer to [Database](/taos-sql/database).
创建库之后,需要使用 SQL 命令 `USE` 将当前库切换过来,例如: After creating a database, the current database in use can be switched using SQL command `USE`, for example below SQL statement switches the current database to `power`. Without current database specified, table name must be preceded with the corresponding database name.
```sql ```sql
USE power; USE power;
``` ```
将当前连接里操作的库换为 power,否则对具体表操作前,需要使用“库名.表名”来指定库的名字。
:::note :::note
- 任何一张表或超级表必须属于某个库,在创建表之前,必须先创建库。 - Any table or STable must belong to a database. To create a table or STable, the database it belongs to must be ready.
- 处于两个不同库的表是不能进行 JOIN 操作的。 - JOIN operation can't be performed tables from two different databases.
- 创建并插入记录、查询历史记录的时候,均需要指定时间戳。 - Timestamp needs to be specified when inserting rows or querying historical rows.
::: :::
## 创建超级表 ## Create STable
一个物联网系统,往往存在多种类型的设备,比如对于电网,存在智能电表、变压器、母线、开关等等。为便于多表之间的聚合,使用 TDengine, 需要对每个类型的数据采集点创建一个超级表。以[表 1](/tdinternal/arch#model_table1) 中的智能电表为例,可以使用如下的 SQL 命令创建超级表: In a time-series application, there may be multiple kinds of data collection points. For example, in the electrical power system there are meters, transformers, bus bars, switches, etc. For easy and efficient aggregation of multiple tables, one STable needs to be created for each kind of data collection point. For example, for the meters in [table 1](/tdinternal/arch#model_table1), below SQL statement can be used to create the super table.
```sql ```sql
CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int); CREATE STable meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);
``` ```
:::note :::note
这一指令中的 STABLE 关键字,在 2.0.15 之前的版本中需写作 TABLE 。 If you are using versions prior to 2.0.15, the `STable` keyword needs to be replaced with `TABLE`.
::: :::
与创建普通表一样,创建超级表时,需要提供表名(示例中为 meters),表结构 Schema,即数据列的定义。第一列必须为时间戳(示例中为 ts),其他列为采集的物理量(示例中为 current, voltage, phase),数据类型可以为整型、浮点型、字符串等。除此之外,还需要提供标签的 schema (示例中为 location, groupId),标签的数据类型可以为整型、浮点型、字符串等。采集点的静态属性往往可以作为标签,比如采集点的地理位置、设备型号、设备组 ID、管理员 ID 等等。标签的 schema 可以事后增加、删除、修改。具体定义以及细节请见 [TAOS SQL 的超级表管理](/taos-sql/stable) 章节。 Similar to creating a normal table, when creating a STable, name and schema need to be provided too. In the STable schema, the first column must be timestamp (like ts in the example), and other columns (like current, voltage and phase in the example) are the data collected. The type of a column can be integer, floating point number, string ,etc. Besides, the schema for tags need to be provided, like location and groupId in the example. The type of a tag can be integer, floating point number, string, etc. The static properties of a data collection point can be defined as tags, like the location, device type, device group ID, manager ID, etc. Tags in the schema can be added, removed or updated. Please refer to [STable](/taos-sql/stable) for more details.
Each kind of data collection points needs a corresponding STable to be created, so there may be many STables in an application. For electrical power system, we need to create a STable respectively for meters, transformers, busbars, switches. There may be multiple kinds of data collection points on a single device, for example there may be one data collection point for electrical data like current and voltage and another point for environmental data like temperature, humidity and wind direction, multiple STables are required for such kind of device.
每一种类型的数据采集点需要建立一个超级表,因此一个物联网系统,往往会有多个超级表。对于电网,我们就需要对智能电表、变压器、母线、开关等都建立一个超级表。在物联网中,一个设备就可能有多个数据采集点(比如一台风力发电的风机,有的采集点采集电流、电压等电参数,有的采集点采集温度、湿度、风向等环境参数),这个时候,对这一类型的设备,需要建立多张超级表。 At most 4096 (or 1024 prior to version 2.1.7.0) columns are allowed in a STable. If there are more than 4096 of metrics to bo collected for a data collection point, multiple STables are required for such kind of data collection point. There can be multiple databases in system, while one or more STables can exist in a database.
一张超级表最多容许 4096 列 (在 2.1.7.0 版本之前,列数限制为 1024 列),如果一个采集点采集的物理量个数超过 4096,需要建多张超级表来处理。一个系统可以有多个 DB,一个 DB 里可以有一到多个超级表。
## 创建表 ## Create Table
TDengine 对每个数据采集点需要独立建表。与标准的关系型数据库一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以[表 1](/tdinternal/arch#model_table1)中的智能电表为例,可以使用如下的 SQL 命令建表: A specific table needs to be created for each data collection point. Similar to RDBMS, table name and schema are required to create a table. Beside, one or more tags can be created for each table. To create a table, a STable needs to be used as template and the values need to be specified for the tags. For example, for the meters in [Table 1](/tdinternal/arch#model_table1), the table can be created using below SQL statement.
```sql ```sql
CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2); CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);
``` ```
其中 d1001 是表名,meters 是超级表的表名,后面紧跟标签 Location 的具体标签值 ”Beijing.Chaoyang",标签 groupId 的具体标签值 2。虽然在创建表时,需要指定标签值,但可以事后修改。详细细则请见 [TAOS SQL 的表管理](/taos-sql/table) 章节。 In the above SQL statement, "d1001" is the table name, "meters" is the STable name, followed by the value of tag "Location" and the value of tag "groupId", which are "Beijing.Chaoyang" and "2" respectively in the example. The tag values can be updated after the table is created. Please refer to [Tables](/taos-sql/table) for details.
:::warning
目前 TDengine 没有从技术层面限制使用一个 database (db1) 的超级表作为模板建立另一个 database (db2) 的子表,后续会禁止这种用法,不建议使用这种方法建表。
::: :::warning
It's not recommended to create a table in a database while using a STable from another database as template.
TDengine 建议将数据采集点的全局唯一 ID 作为表名(比如设备序列号)。但对于有的场景,并没有唯一的 ID,可以将多个 ID 组合成一个唯一的 ID。不建议将具有唯一性的 ID 作为标签值。 :::tip
It's suggested to use the global unique ID of a data collection point as the table name, for example the device serial number. If there isn't such a unique ID, multiple IDs that are not global unique can be combined to form a global unique ID. It's not recommended to use a global unique ID as tag value.
### 自动建表 ## Create Table Automatically
在某些特殊场景中,用户在写数据时并不确定某个数据采集点的表是否存在,此时可在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表且后面的 USING 语句被忽略。比如: In some circumstances, it's not sure whether the table already exists when inserting rows. The table can be created automatically using the SQL statement below, and nothing will happen if the table already exist.
```sql ```sql
INSERT INTO d1001 USING meters TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32); INSERT INTO d1001 USING meters TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);
``` ```
上述 SQL 语句将记录`(now, 10.2, 219, 0.32)`插入表 d1001。如果表 d1001 还未创建,则使用超级表 meters 做模板自动创建,同时打上标签值 `"Beijing.Chaoyang", 2`。 In the above SQL statement, a row with value `(now, 10.2, 219, 0.32)` will be inserted into table "d1001". If table "d1001" doesn't exist, it will be created automatically using STable "meters" as template with tag value `"Beijing.Chaoyang", 2`.
关于自动建表的详细语法请参见 [插入记录时自动建表](/taos-sql/insert#插入记录时自动建表) 章节。 For more details please refer to [Create Table Automatically](/taos-sql/insert#automatically-create-table-when-inserting).
## 多列模型 vs 单列模型 ## Single Column vs Multiple Column
TDengine 支持多列模型,只要物理量是一个数据采集点同时采集的(时间戳一致),这些量就可以作为不同列放在一张超级表里。但还有一种极限的设计,单列模型,每个采集的物理量都单独建表,因此每种类型的物理量都单独建立一超级表。比如电流、电压、相位,就建三张超级表。 Multiple columns data model is supported in TDengine. As long as multiple metrics are collected by same data collection point at same time, i.e. the timestamp are identical, these metrics can be put in single stable as columns. However, there is another kind of design, i.e. single column data model, a table is created for each metric, which means a STable is required for each kind of metric. For example, 3 STables are required for current, voltage and phase.
TDengine 建议尽可能采用多列模型,因为插入效率以及存储效率更高。但对于有些场景,一个采集点的采集量的种类经常变化,这个时候,如果采用多列模型,就需要频繁修改超级表的结构定义,让应用变的复杂,这个时候,采用单列模型会显得更简单。 It's recommended to use multiple column data model as much as possible because it's better in the performance of inserting or querying rows. In some cases, however, the metrics to be collected vary frequently and correspondingly the STable schema needs to be changed frequently too. In such case, it's more convenient to use single column data model.
--- ---
title: SQL 写入 sidebar_label: SQL
title: Insert Using SQL
--- ---
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
...@@ -19,52 +20,53 @@ import CsStmt from "./_cs_stmt.mdx"; ...@@ -19,52 +20,53 @@ import CsStmt from "./_cs_stmt.mdx";
import CSQL from "./_c_sql.mdx"; import CSQL from "./_c_sql.mdx";
import CStmt from "./_c_stmt.mdx"; import CStmt from "./_c_stmt.mdx";
## SQL 写入简介 ## Introduction
应用通过连接器执行 INSERT 语句来插入数据,用户还可以通过 TAOS Shell,手动输入 INSERT 语句插入数据。 Application program can execute `INSERT` statement through connectors to insert rows. TAOS Shell can be launched manually to insert data too.
### 一次写入一条 ### Insert Single Row
下面这条 INSERT 就将一条记录写入到表 d1001 中:
Below SQL statement is used to insert one row into table "d1001".
```sql ```sql
INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31); INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31);
``` ```
### 一次写入多条 ### Insert Multiple Rows
TDengine 支持一次写入多条记录,比如下面这条命令就将两条记录写入到表 d1001 中: Multiple rows can be inserted in single SQL statement. Below example inserts 2 rows into table "d1001".
```sql ```sql
INSERT INTO d1001 VALUES (1538548684000, 10.2, 220, 0.23) (1538548696650, 10.3, 218, 0.25); INSERT INTO d1001 VALUES (1538548684000, 10.2, 220, 0.23) (1538548696650, 10.3, 218, 0.25);
``` ```
### 一次写入多表 ### Insert into Multiple Tables
TDengine 也支持一次向多个表写入数据,比如下面这条命令就向 d1001 写入两条记录,向 d1002 写入一条记录: Data can be inserted into multiple tables in same SQL statement. Below example inserts 2 rows into table "d1001" and 1 row into table "d1002".
```sql ```sql
INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, 218, 0.33) d1002 VALUES (1538548696800, 12.3, 221, 0.31); INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, 218, 0.33) d1002 VALUES (1538548696800, 12.3, 221, 0.31);
``` ```
详细的 SQL INSERT 语法规则参考 [TAOS SQL 的数据写入](/taos-sql/insert)。 For more details about `INSERT` please refer to [INSERT](/taos-sql/insert).
:::info :::info
- 要提高写入效率,需要批量写入。一批写入的记录条数越多,插入效率就越高。但一条记录不能超过 16K,一条 SQL 语句总长度不能超过 1M 。 - Inserting in batch can gain better performance. Normally, the higher the batch size, the better the performance. Please be noted each single row can't exceed 16K bytes and each single SQL statement can't exceed 1M bytes.
- TDengine 支持多线程同时写入,要进一步提高写入速度,一个客户端需要打开 20 个以上的线程同时写。但线程数达到一定数量后,无法再提高,甚至还会下降,因为线程频繁切换,带来额外开销。 - Inserting with multiple threads can gain better performance too. However, depending on the system resources on the client side and the server side, with the number of inserting threads grows to a specific point, the performance may drop instead of growing. The proper number of threads need to be tested in a specific environment to find the best number.
::: :::
:::warning :::warning
- 对同一张表,如果新插入记录的时间戳已经存在,默认情形下(UPDATE=0)新记录将被直接抛弃,也就是说,在一张表里,时间戳必须是唯一的。如果应用自动生成记录,很有可能生成的时间戳是一样的,这样,成功插入的记录条数会小于应用插入的记录条数。如果在创建数据库时使用了 UPDATE 1 选项,插入相同时间戳的新记录将覆盖原有记录。 - If the timestamp for the row to be inserted already exists in the table, the behavior depends on the value of parameter `UPDATE`. If it's set to 0 (also the default value), the row will be discarded. If it's set to 1, the new values will override the old values for the same row.
- 写入的数据的时间戳必须大于当前时间减去配置参数 keep 的时间。如果 keep 配置为 3650 天,那么无法写入比 3650 天还早的数据。写入数据的时间戳也不能大于当前时间加配置参数 days。如果 days 为 2,那么无法写入比当前时间还晚 2 天的数据。 - The timestamp to be inserted must be newer than the timestamp of subtracting current time by the parameter `KEEP`. If `KEEP` is set to 3650 days, then the data older than 3650 days ago can't be inserted. The timestamp to be inserted can't be newer than the timestamp of current time plus parameter `DAYS`. If `DAYS` is set to 2, the data newer than 2 days later can't be inserted.
::: :::
## 示例程序 ## Examples
### 普通 SQL 写入 ### Insert Using SQL
<Tabs defaultValue="java" groupId="lang"> <Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
...@@ -92,16 +94,16 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, ...@@ -92,16 +94,16 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6,
:::note :::note
1. 无论 RESTful 方式建立连接还是本地驱动方式建立连接,以上示例代码都能正常工作。 1. With either native connection or REST connection, the above samples can work well.
2. 唯一需要注意的是:由于 RESTful 接口无状态, 不能使用 `use db` 语句来切换数据库, 所以在上面示例中使用了`dbName.tbName`指定表名。 2. Please be noted that `use db` can't be used with REST connection because REST connection is stateless, so in the samples `dbName.tbName` is used to specify the table name.
::: :::
### 参数绑定写入 ### Insert with Parameter Binding
TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 类似,这些 API 目前也仅支持用问号 `?` 来代表待绑定的参数。从 2.1.1.0 和 2.1.2.0 版本开始,TDengine 大幅改进了参数绑定接口对数据写入(INSERT)场景的支持。这样在通过参数绑定接口写入数据时,就避免了 SQL 语法解析的资源消耗,从而在绝大多数情况下显著提升写入性能。 TDengine also provides Prepare API that support parameter binding. Similar to MySQL, only `?` can be used in these APIs to represent the parameters to bind. From version 2.1.1.0 and 2.1.2.0, parameter binding support for inserting data has been improved significantly to improve the insert performance by avoiding the cost of parsing SQL statements.
需要注意的是,只有使用原生连接的连接器,才能使用参数绑定功能。 Parameter binding is available only with native connection.
<Tabs defaultValue="java" groupId="lang"> <Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
...@@ -126,4 +128,3 @@ TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 类似,这 ...@@ -126,4 +128,3 @@ TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 类似,这
<CStmt /> <CStmt />
</TabItem> </TabItem>
</Tabs> </Tabs>
--- ---
sidebar_label: InfluxDB 行协议 sidebar_label: InfluxDB Line Protocol
title: InfluxDB 行协议 title: InfluxDB Line Protocol
--- ---
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
...@@ -13,20 +13,20 @@ import NodeLine from "./_js_line.mdx"; ...@@ -13,20 +13,20 @@ import NodeLine from "./_js_line.mdx";
import CsLine from "./_cs_line.mdx"; import CsLine from "./_cs_line.mdx";
import CLine from "./_c_line.mdx"; import CLine from "./_c_line.mdx";
## 协议介绍 ## Introduction
InfluxDB Line 协议采用一行字符串来表示一行数据。分为四部分: A single line of text is used in InfluxDB Line protocol format represents one row of data, each line contains 4 parts as shown below.
``` ```
measurement,tag_set field_set timestamp measurement,tag_set field_set timestamp
``` ```
- measurement 将作为超级表名。它与 tag_set 之间使用一个英文逗号来分隔。 - `measurement` will be used as the STable name
- tag_set 将作为标签数据,其格式形如 `<tag_key>=<tag_value>,<tag_key>=<tag_value>`,也即可以使用英文逗号来分隔多个标签数据。它与 field_set 之间使用一个半角空格来分隔。 - `tag_set` will be used as tags, with format like `<tag_key>=<tag_value>,<tag_key>=<tag_value>`
- field_set 将作为普通列数据,其格式形如 `<field_key>=<field_value>,<field_key>=<field_value>`,同样是使用英文逗号来分隔多个普通列的数据。它与 timestamp 之间使用一个半角空格来分隔。 - `field_set`will be used as data columns, with format like `<field_key>=<field_value>,<field_key>=<field_value>`
- timestamp 即本行数据对应的主键时间戳。 - `timestamp` is the primary key timestamp corresponding to this row of data
例如: For example:
``` ```
meters,location=Beijing.Haidian,groupid=2 current=13.4,voltage=223,phase=0.29 1648432611249500 meters,location=Beijing.Haidian,groupid=2 current=13.4,voltage=223,phase=0.29 1648432611249500
...@@ -34,16 +34,16 @@ meters,location=Beijing.Haidian,groupid=2 current=13.4,voltage=223,phase=0.29 16 ...@@ -34,16 +34,16 @@ meters,location=Beijing.Haidian,groupid=2 current=13.4,voltage=223,phase=0.29 16
:::note :::note
- tag_set 中的所有的数据自动转化为 nchar 数据类型; - All the data in `tag_set` will be converted to ncahr type automatically .
- field_set 中的每个数据项都需要对自身的数据类型进行描述, 比如 1.2f32 代表 float 类型的数值 1.2, 如果不带类型后缀会被当作 double 处理; - Each data in `field_set` must be self-description for its data type. For example 1.2f32 means a value 1.2 of float type, it will be treated as double without the "f" type suffix.
- timestamp 支持多种时间精度。写入数据的时候需要用参数指定时间精度,支持从小时到纳秒的 6 种时间精度。 - Multiple kinds of precision can be used for the `timestamp` field. Time precision can be from nanosecond (ns) to hour (h).
::: :::
要了解更多可参考:[InfluxDB Line 协议官方文档](https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol/) 和 [TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议) For more details please refer to [InfluxDB Line Protocol](https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol/) and [TDengine Schemaless](/reference/schemaless/#Schemaless-Line-Protocol)
## 示例代码 ## Examples
<Tabs defaultValue="java" groupId="lang"> <Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
......
--- ---
sidebar_label: OpenTSDB 行协议 sidebar_label: OpenTSDB Line Protocol
title: OpenTSDB 行协议 title: OpenTSDB Line Protocol
--- ---
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
...@@ -13,28 +13,28 @@ import NodeTelnet from "./_js_opts_telnet.mdx"; ...@@ -13,28 +13,28 @@ import NodeTelnet from "./_js_opts_telnet.mdx";
import CsTelnet from "./_cs_opts_telnet.mdx"; import CsTelnet from "./_cs_opts_telnet.mdx";
import CTelnet from "./_c_opts_telnet.mdx"; import CTelnet from "./_c_opts_telnet.mdx";
## 协议介绍 ## Introduction
OpenTSDB 行协议同样采用一行字符串来表示一行数据。OpenTSDB 采用的是单列模型,因此一行只能包含一个普通数据列。标签列依然可以有多个。分为四部分,具体格式约定如下: A single line of text is used in OpenTSDB line protocol to represent one row of data. OpenTSDB employs single column data model, so one line can only contains single data column. There can be multiple tags. Each line contains 4 parts as below:
```txt ```
<metric> <timestamp> <value> <tagk_1>=<tagv_1>[ <tagk_n>=<tagv_n>] <metric> <timestamp> <value> <tagk_1>=<tagv_1>[ <tagk_n>=<tagv_n>]
``` ```
- metric 将作为超级表名。 - `metric` will be used as STable name.
- timestamp 本行数据对应的时间戳。根据时间戳的长度自动识别时间精度。支持秒和毫秒两种时间精度 - `timestamp` is the timestamp of current row of data. The time precision will be determined automatically based on the length of the timestamp. second and millisecond time precision are supported.\
- value 度量值,必须为一个数值。对应的列名也是 “value”。 - `value` is a metric which must be a numeric value, the corresponding column name is "value".
- 最后一部分是标签集, 用空格分隔不同标签, 所有标签自动转化为 nchar 数据类型; - The last part is tag sets separated by space, all tags will be converted to nchar type automatically.
例如: For example:
```txt ```txt
meters.current 1648432611250 11.3 location=Beijing.Haidian groupid=3 meters.current 1648432611250 11.3 location=Beijing.Haidian groupid=3
``` ```
参考[OpenTSDB Telnet API文档](http://opentsdb.net/docs/build/html/api_telnet/put.html)。 Please refer to [OpenTSDB Telnet API](http://opentsdb.net/docs/build/html/api_telnet/put.html) for more details.
## 示例代码 ## Examples
<Tabs defaultValue="java" groupId="lang"> <Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
...@@ -60,13 +60,13 @@ meters.current 1648432611250 11.3 location=Beijing.Haidian groupid=3 ...@@ -60,13 +60,13 @@ meters.current 1648432611250 11.3 location=Beijing.Haidian groupid=3
</TabItem> </TabItem>
</Tabs> </Tabs>
以上示例代码会自动创建 2 个超级表, 每个超级表有 4 条数据。 2 STables will be crated automatically while each STable has 4 rows of data in the above sample code.
```cmd ```cmd
taos> use test; taos> use test;
Database changed. Database changed.
taos> show stables; taos> show STables;
name | created_time | columns | tags | tables | name | created_time | columns | tags | tables |
============================================================================================ ============================================================================================
meters.current | 2022-03-30 17:04:10.877 | 2 | 2 | 2 | meters.current | 2022-03-30 17:04:10.877 | 2 | 2 | 2 |
......
--- ---
sidebar_label: OpenTSDB JSON 格式协议 sidebar_label: OpenTSDB JSON Protocol
title: OpenTSDB JSON 格式协议 title: OpenTSDB JSON Protocol
--- ---
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
...@@ -13,9 +13,9 @@ import NodeJson from "./_js_opts_json.mdx"; ...@@ -13,9 +13,9 @@ import NodeJson from "./_js_opts_json.mdx";
import CsJson from "./_cs_opts_json.mdx"; import CsJson from "./_cs_opts_json.mdx";
import CJson from "./_c_opts_json.mdx"; import CJson from "./_c_opts_json.mdx";
## 协议介绍 ## Introduction
OpenTSDB JSON 格式协议采用一个 JSON 字符串表示一行或多行数据。例如: A JSON string is sued in OpenTSDB JSON to represent one or more rows of data, for exmaple:
```json ```json
[ [
...@@ -40,18 +40,18 @@ OpenTSDB JSON 格式协议采用一个 JSON 字符串表示一行或多行数据 ...@@ -40,18 +40,18 @@ OpenTSDB JSON 格式协议采用一个 JSON 字符串表示一行或多行数据
] ]
``` ```
与 OpenTSDB 行协议类似, metric 将作为超级表名, timestamp 表示时间戳,value 表示度量值, tags 表示标签集。 Similar to OpenTSDB line protocol, `metric` will be used as the STable name, `timestamp` is the timestamp to be used, `value` represents the metric collected, `tags` are the tag sets.
参考[OpenTSDB HTTP API文档](http://opentsdb.net/docs/build/html/api_http/put.html)。 Please refer to [OpenTSDB HTTP API](http://opentsdb.net/docs/build/html/api_http/put.html) for more details.
:::note :::note
- 对于 JSON 格式协议,TDengine 并不会自动把所有标签转成 nchar 类型, 字符串将将转为 nchar 类型, 数值将同样转换为 double 类型。 - In JSON protocol, strings will be converted to nchar type and numeric values will be converted to double type.
- TDengine 只接收 JSON **数组格式**的字符串,即使一行数据也需要转换成数组形式。 - Only data in array format is accepted, array must be used even there is only one row.
::: :::
## 示例代码 ## Examples
<Tabs defaultValue="java" groupId="lang"> <Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
...@@ -77,13 +77,13 @@ OpenTSDB JSON 格式协议采用一个 JSON 字符串表示一行或多行数据 ...@@ -77,13 +77,13 @@ OpenTSDB JSON 格式协议采用一个 JSON 字符串表示一行或多行数据
</TabItem> </TabItem>
</Tabs> </Tabs>
以上示例代码会自动创建 2 个超级表, 每个超级表有 2 条数据。 The above sample code will created 2 STables automatically while each STable has 2 rows of data.
```cmd ```cmd
taos> use test; taos> use test;
Database changed. Database changed.
taos> show stables; taos> show STables;
name | created_time | columns | tags | tables | name | created_time | columns | tags | tables |
============================================================================================ ============================================================================================
meters.current | 2022-03-29 16:05:25.193 | 2 | 2 | 1 | meters.current | 2022-03-29 16:05:25.193 | 2 | 2 | 1 |
......
```c title=一次绑定一行 ```c title=Single Row Binding
{{#include docs-examples/c/stmt_example.c}} {{#include docs-examples/c/stmt_example.c}}
``` ```
```c title=一次绑定多行 72:117 ```c title=Multiple Row Binding 72:117
{{#include docs-examples/c/multi_bind_example.c}} {{#include docs-examples/c/multi_bind_example.c}}
``` ```
\ No newline at end of file
label: 写入数据 label: Insert
link: link:
type: generated-index type: generated-index
slug: /insert-data/ slug: /insert-data/
description: "TDengine 支持多种写入协议,包括 SQL,InfluxDB Line 协议, OpenTSDB Telnet 协议,OpenTSDB JSON 格式协议。数据可以单条插入,也可以批量插入,可以插入一个数据采集点的数据,也可以同时插入多个数据采集点的数据。同时,TDengine 支持多线程插入,支持时间乱序数据插入,也支持历史数据插入。InfluxDB Line 协议、OpenTSDB Telnet 协议和 OpenTSDB JSON 格式协议是 TDengine 支持的三种无模式写入协议。使用无模式方式写入无需提前创建超级表和子表,并且引擎能自适用数据对表结构做调整。" description: "TDengine supports multiple protocols of inserting data, including SQL, InfluxDB Line protocol, OpenTSDB Telnet protocol, OpenTSDB JSON protocol. Data can be inserted row by row, or in batch. Data from one or more collecting points can be inserted simultaneously. In the meantime, data can be inserted with multiple threads, out of order data and historical data can be inserted too. InfluxDB Line protocol, OpenTSDB Telnet protocol and OpenTSDB JSON protocol are the 3 kinds of schemaless insert protocols supported by TDengine. It's not necessary to create stable and table in advance if using schemaless protocols, and the schemas can be adjusted automatically according to the data to be inserted."
...@@ -3,6 +3,6 @@ ...@@ -3,6 +3,6 @@
``` ```
:::tip :::tip
driver-go 的模块 `github.com/taosdata/driver-go/v2/wrapper` 是 C 接口的底层封装。使用这个模块也可以实现参数绑定写入。 `github.com/taosdata/driver-go/v2/wrapper` module in driver-go is the wrapper for C API, it can be used to insert data with parameter binding.
::: :::
```js title=一次绑定一行 ```js title=Single Row Binding
{{#include docs-examples/node/nativeexample/param_bind_example.js}} {{#include docs-examples/node/nativeexample/param_bind_example.js}}
``` ```
```js title=一次绑定多行 ```js title=Multiple Row Binding
{{#include docs-examples/node/nativeexample/multi_bind_example.js:insertData}} {{#include docs-examples/node/nativeexample/multi_bind_example.js:insertData}}
``` ```
:::info :::info
一次绑定一行效率不如一次绑定多行,但支持非 INSERT 语句。一次绑定多行效率更高,但仅支持 INSERT 语句。 Multiple row binding is better in performance than single row binding, but it can only be used with `INSERT` statement while single row binding can be used for other SQL statements besides `INSERT`.
::: :::
```py title=一次绑定一行 ```py title=Single Row Binding
{{#include docs-examples/python/bind_param_example.py}} {{#include docs-examples/python/bind_param_example.py}}
``` ```
```py title=一次绑定多行 ```py title=Multiple Row Binding
{{#include docs-examples/python/multi_bind_example.py:bind_batch}} {{#include docs-examples/python/multi_bind_example.py:bind_batch}}
``` ```
:::info :::info
一次绑定一行效率不如一次绑定多行,但支持非 INSERT 语句。一次绑定多行效率更高,但仅支持 INSERT 语句。 Multiple row binding is better in performance than single row binding, but it can only be used with `INSERT` statement while single row binding can be used for other SQL statements besides `INSERT`.
::: :::
\ No newline at end of file
通过迭代逐行获取查询结果。 Result set is iterated row by row.
```py ```py
{{#include docs-examples/python/query_example.py:iter}} {{#include docs-examples/python/query_example.py:iter}}
``` ```
一次获取所有查询结果,并把每一行转化为一个字典返回。 Result set is retrieved as a whole, each row is converted to a dict and returned.
```py ```py
{{#include docs-examples/python/query_example.py:fetch_all}} {{#include docs-examples/python/query_example.py:fetch_all}}
``` ```
\ No newline at end of file
...@@ -3,6 +3,6 @@ ...@@ -3,6 +3,6 @@
``` ```
:::note :::note
这个示例程序,目前在 Windows 系统上还无法运行 This sample code can't be run on Windows system for now.
::: :::
--- ---
slug: /query-data slug: /query-data
title: 查询数据 Sidebar_label: Select
description: "主要查询功能,通过连接器执行同步查询和异步查询" title: Select
description: "This chapter introduces major query functionalities and how to perform sync and async query using connectors."
--- ---
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
...@@ -18,20 +19,26 @@ import NodeAsync from "./_js_async.mdx"; ...@@ -18,20 +19,26 @@ import NodeAsync from "./_js_async.mdx";
import CsAsync from "./_cs_async.mdx"; import CsAsync from "./_cs_async.mdx";
import CAsync from "./_c_async.mdx"; import CAsync from "./_c_async.mdx";
## 主要查询功能 ## Introduction
TDengine 采用 SQL 作为查询语言。应用程序可以通过 REST API 或连接器发送 SQL 语句,用户还可以通过 TDengine 命令行工具 taos 手动执行 SQL 即席查询(Ad-Hoc Query)。TDengine 支持如下查询功能 SQL is used by TDengine as the language for query. Application programs can send SQL statements to TDengine through REST API or connectors. TDengine CLI `taos` can also be used to execute SQL Ad-Hoc query. Here is the list of major query functionalities supported by TDengine
- 单列、多列数据查询 - Query on single column or multiple columns
- 标签和数值的多种过滤条件:>, <, =, <\>, like 等 - Filter on tags or data columns:>, <, =, <\>, like
- 聚合结果的分组(Group by)、排序(Order by)、约束输出(Limit/Offset) - Grouping of results: `Group By`
- 数值列及聚合结果的四则运算 - Sorting of results: `Order By`
- 时间戳对齐的连接查询(Join Query: 隐式连接)操作 - Limit the number of results: `Limit/Offset`
- 多种聚合/计算函数: count, max, min, avg, sum, twa, stddev, leastsquares, top, bottom, first, last, percentile, apercentile, last_row, spread, diff 等 - Arithmetic on columns of numeric types or aggregate results
- Join query with timestamp alignment
- Aggregate functions: count, max, min, avg, sum, twa, stddev, leastsquares, top, bottom, first, last, percentile, apercentile, last_row, spread, diff
例如:在命令行工具 taos 中,从表 d1001 中查询出 voltage > 215 的记录,按时间降序排列,仅仅输出 2 条。 For example, below SQL statement can be executed in TDengine CLI `taos` to select the rows whose voltage column is bigger than 215 and limit the output to only 2 rows.
```sql ```sql
select * from d1001 where voltage > 215 order by ts desc limit 2;
```
```title=Output
taos> select * from d1001 where voltage > 215 order by ts desc limit 2; taos> select * from d1001 where voltage > 215 order by ts desc limit 2;
ts | current | voltage | phase | ts | current | voltage | phase |
====================================================================================== ======================================================================================
...@@ -40,17 +47,17 @@ taos> select * from d1001 where voltage > 215 order by ts desc limit 2; ...@@ -40,17 +47,17 @@ taos> select * from d1001 where voltage > 215 order by ts desc limit 2;
Query OK, 2 row(s) in set (0.001100s) Query OK, 2 row(s) in set (0.001100s)
``` ```
为满足物联网场景的需求,TDengine 支持几个特殊的函数,比如 twa(时间加权平均),spread (最大值与最小值的差),last_row(最后一条记录)等,更多与物联网场景相关的函数将添加进来。TDengine 还支持连续查询。 To meet the requirements in IoT use cases, some special functions have been added in TDengine, for example `twa` (Time Weighted Average), `spared` (The difference between the maximum and the minimum), `last_row` (the last row), more and more functions will be added to better perform in IoT use cases. Furthermore, continuous query is also supported in TDengine.
具体的查询语法请看 [TAOS SQL 的数据查询](/taos-sql/select) 章节。 For detailed query syntax please refer to [Select](/taos-sql/select).
## 多表聚合查询 ## Join Query
物联网场景中,往往同一个类型的数据采集点有多个。TDengine 采用超级表(STable)的概念来描述某一个类型的数据采集点,一张普通的表来描述一个具体的数据采集点。同时 TDengine 使用标签来描述数据采集点的静态属性,一个具体的数据采集点有具体的标签值。通过指定标签的过滤条件,TDengine 提供了一高效的方法将超级表(某一类型的数据采集点)所属的子表进行聚合查询。对普通表的聚合函数以及绝大部分操作都适用于超级表,语法完全一样。 In IoT use cases, there are always multiple data collection points of same kind. A new concept, called STable (abbreviated for super table), is used in TDengine to represent a kind of data collection points, and a table is used to represent a specific data collection point. Tags are used by TDengine to represent the static properties of data collection points. A specific data collection point has its own values for static properties. By specifying filter conditions on tags, join query can be performed efficiently between all the tables belonging to same STable, i.e. same kind of data collection points, can be. Aggregate functions applicable for tables can be used directly on STables, syntax is exactly same.
### 示例一 ### Example 1
在 TAOS Shell,查找北京所有智能电表采集的电压平均值,并按照 location 分组。 In TDengine CLI `taos`, use below SQL to get the average voltage of all the meters in BeiJing grouped by location.
``` ```
taos> SELECT AVG(voltage) FROM meters GROUP BY location; taos> SELECT AVG(voltage) FROM meters GROUP BY location;
...@@ -61,9 +68,9 @@ taos> SELECT AVG(voltage) FROM meters GROUP BY location; ...@@ -61,9 +68,9 @@ taos> SELECT AVG(voltage) FROM meters GROUP BY location;
Query OK, 2 row(s) in set (0.002136s) Query OK, 2 row(s) in set (0.002136s)
``` ```
### 示例二 ### Example 2
在 TAOS shell, 查找 groupId 为 2 的所有智能电表过去 24 小时的记录条数,电流的最大值。 In TDengine CLI `taos`, use below SQL to get the number of rows and the maximum current in the past 24 hours from meters whose groupId is 2.
``` ```
taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now - 24h; taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now - 24h;
...@@ -73,11 +80,11 @@ taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now - ...@@ -73,11 +80,11 @@ taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now -
Query OK, 1 row(s) in set (0.002136s) Query OK, 1 row(s) in set (0.002136s)
``` ```
TDengine 仅容许对属于同一个超级表的表之间进行聚合查询,不同超级表之间的聚合查询不支持。在 [TAOS SQL 的数据查询](/taos-sql/select) 一章,查询类操作都会注明是否支持超级表。 Join query is allowed between only the tables of same STable. In [Select](/taos-sql/select), all query operations are marked as whether it supports STable or not.
## 降采样查询、插值 ## Down Sampling and Interpolation
物联网场景里,经常需要通过降采样(down sampling)将采集的数据按时间段进行聚合。TDengine 提供了一个简便的关键词 interval 让按照时间窗口的查询操作变得极为简单。比如,将智能电表 d1001 采集的电流值每 10 秒钟求和 In IoT use cases, down sampling is widely used to aggregate the data by time range. `INTERVAL` keyword in TDengine can be used to simplify the query by time window. For example, below SQL statement can be used to get the sum of current every 10 seconds from meters table d1001.
``` ```
taos> SELECT sum(current) FROM d1001 INTERVAL(10s); taos> SELECT sum(current) FROM d1001 INTERVAL(10s);
...@@ -88,7 +95,7 @@ taos> SELECT sum(current) FROM d1001 INTERVAL(10s); ...@@ -88,7 +95,7 @@ taos> SELECT sum(current) FROM d1001 INTERVAL(10s);
Query OK, 2 row(s) in set (0.000883s) Query OK, 2 row(s) in set (0.000883s)
``` ```
降采样操作也适用于超级表,比如:将北京所有智能电表采集的电流值每秒钟求和 Down sampling can also be used for STable. For example, below SQL statement can be used to get the sum of current from all meters in BeiJing.
``` ```
taos> SELECT SUM(current) FROM meters where location like "Beijing%" INTERVAL(1s); taos> SELECT SUM(current) FROM meters where location like "Beijing%" INTERVAL(1s);
...@@ -102,7 +109,7 @@ taos> SELECT SUM(current) FROM meters where location like "Beijing%" INTERVAL(1s ...@@ -102,7 +109,7 @@ taos> SELECT SUM(current) FROM meters where location like "Beijing%" INTERVAL(1s
Query OK, 5 row(s) in set (0.001538s) Query OK, 5 row(s) in set (0.001538s)
``` ```
降采样操作也支持时间偏移,比如:将所有智能电表采集的电流值每秒钟求和,但要求每个时间窗口从 500 毫秒开始 Down sample also supports time offset. For example, below SQL statement can be used to get the sum of current from all meters but each time window must start at the boundary of 500 milliseconds.
``` ```
taos> SELECT SUM(current) FROM meters INTERVAL(1s, 500a); taos> SELECT SUM(current) FROM meters INTERVAL(1s, 500a);
...@@ -116,17 +123,17 @@ taos> SELECT SUM(current) FROM meters INTERVAL(1s, 500a); ...@@ -116,17 +123,17 @@ taos> SELECT SUM(current) FROM meters INTERVAL(1s, 500a);
Query OK, 5 row(s) in set (0.001521s) Query OK, 5 row(s) in set (0.001521s)
``` ```
物联网场景里,每个数据采集点采集数据的时间是难同步的,但很多分析算法(比如 FFT)需要把采集的数据严格按照时间等间隔的对齐,在很多系统里,需要应用自己写程序来处理,但使用 TDengine 的降采样操作就轻松解决。 In IoT use cases, it's hard to align the timestamp of the data collected by each collection point. However, a lot of algorithms like FFT require the data to be aligned with same time interval and application programs have to handle by themselves in many systems. In TDengine, it's easy to achieve the alignment using down sampling.
如果一个时间间隔里,没有采集的数据,TDengine 还提供插值计算的功能。 Interpolation can be performed in TDengine if there is no data in a time range.
语法规则细节请见 [TAOS SQL 的按时间窗口切分聚合](/taos-sql/interval) 章节。 For more details please refer to [Aggregate by Window](/taos-sql/interval).
## 示例代码 ## Examples
### 查询数据 ### Query
在 [SQL 写入](/develop/insert-data/sql-writing) 一章,我们创建了 power 数据库,并向 meters 表写入了一些数据,以下示例代码展示如何查询这个表的数据。 In the section describing [Insert](/develop/insert-data/sql-writing), a database named `power` is created and some data are inserted into STable `meters`. Below sample code demonstrates how to query the data in this STable.
<Tabs defaultValue="java" groupId="lang"> <Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
...@@ -154,16 +161,16 @@ Query OK, 5 row(s) in set (0.001521s) ...@@ -154,16 +161,16 @@ Query OK, 5 row(s) in set (0.001521s)
:::note :::note
1. 无论是使用 REST 连接还是原生连接的连接器,以上示例代码都能正常工作。 1. With either REST connection or native connection, the above sample code work well.
2. 唯一需要注意的是:由于 RESTful 接口无状态, 不能使用 `use db` 语句来切换数据库。 2. Please be noted that `use db` can't be used in case of REST connection because it's stateless.
::: :::
### 异步查询 ### Asynchronous Query
除同步查询 API 之外,TDengine 还提供性能更高的异步调用 API 处理数据插入、查询操作。在软硬件环境相同的情况下,异步 API 处理数据插入的速度比同步 API 快 2-4 倍。异步 API 采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步 API 在网络延迟严重的情况下,优点尤为突出。 Besides synchronous query, asynchronous query API is also provided by TDengine to insert or query data more efficiently. With similar hardware and software environment, async API is 2~4 times faster than sync APIs. Async API works in non-blocking mode, which means an operation can be returned without finishing so that the calling thread can switch to other works to improve the performance of the whole application system. Async APIs perform especially better in case of poor network.
需要注意的是,只有使用原生连接的连接器,才能使用异步查询功能。 Please be noted that async query can only be used with native connection.
<Tabs defaultValue="python" groupId="lang"> <Tabs defaultValue="python" groupId="lang">
<TabItem label="Python" value="python"> <TabItem label="Python" value="python">
......
--- ---
sidebar_label: 连续查询 sidebar_label: Continuous Query
description: "连续查询是一个按照预设频率自动执行的查询功能,提供按照时间窗口的聚合查询能力,是一种简化的时间驱动流式计算。" description: "Continuous query is a query that's executed automatically according to predefined frequency to provide aggregate query capability by time window, it's actually a simplified time driven stream computing."
title: "连续查询(Continuous Query)" title: "Continuous Query"
--- ---
连续查询是 TDengine 定期自动执行的查询,采用滑动窗口的方式进行计算,是一种简化的时间驱动的流式计算。针对库中的表或超级表,TDengine 可提供定期自动执行的连续查询,用户可让 TDengine 推送查询的结果,也可以将结果再写回到 TDengine 中。每次执行的查询是一个时间窗口,时间窗口随着时间流动向前滑动。在定义连续查询的时候需要指定时间窗口(time window, 参数 interval)大小和每次前向增量时间(forward sliding times, 参数 sliding)。 Continuous query is a query that's executed automatically according to predefined frequency to provide aggregate query capability by time window, it's actually a simplified time driven stream computing. Continuous query can be performed on a table or STable in TDengine. The result of continuous query can be pushed to client or written back to TDengine. Each query is executed on a time window, which moves forward with time. The size of time window and the forward sliding time need to be specified with parameter `INTERVAL` and `SLIDING` respectively.
TDengine 的连续查询采用时间驱动模式,可以直接使用 TAOS SQL 进行定义,不需要额外的操作。使用连续查询,可以方便快捷地按照时间窗口生成结果,从而对原始采集数据进行降采样(down sampling)。用户通过 TAOS SQL 定义连续查询以后,TDengine 自动在最后的一个完整的时间周期末端拉起查询,并将计算获得的结果推送给用户或者写回 TDengine。 Continuous query in TDengine is time driven, and can be defined using TAOS SQL directly without any extra operations. With continuous query, the result can be generated according to time window to achieve down sampling of original data. Once a continuous query is defined using TAOS SQL, the query is automatically executed at the end of each time window and the result is pushed back to client or written to TDengine.
TDengine 提供的连续查询与普通流计算中的时间窗口计算具有以下区别 There are some differences between continuous query in TDengine and time window computation in stream computing
- 不同于流计算的实时反馈计算结果,连续查询只在时间窗口关闭以后才开始计算。例如时间周期是 1 天,那么当天的结果只会在 23:59:59 以后才会生成。 - The computation is performed and the result is returned in real time in stream computing, but the computation in continuous query is only started when a time window closes. For example, if the time window is 1 day, then the result will only be generated at 23:59:59.
- 如果有历史记录写入到已经计算完成的时间区间,连续查询并不会重新进行计算,也不会重新将结果推送给用户。对于写回 TDengine 的模式,也不会更新已经存在的计算结果。 - If a historical data row is written in to a time widow for which the computation has been finished, the computation will not be performed again and the result will not be pushed to client again either. If the result has been written into TDengine, there will be no update for the result.
- 使用连续查询推送结果的模式,服务端并不缓存客户端计算状态,也不提供 Exactly-Once 的语义保证。如果用户的应用端崩溃,再次拉起的连续查询将只会从再次拉起的时间开始重新计算最近的一个完整的时间窗口。如果使用写回模式,TDengine 可确保数据写回的有效性和连续性。 - In continuous query, if the result is pushed to client, the client status is not cached on the server side and Exactly-once is not guaranteed by the server either. If the client program crashes, a new time window will be generated from the time where the continuous query is restarted. If the result is written into TDengine, the data written into TDengine can be guaranteed as valid and continuous.
## 连续查询语法 ## Syntax
```sql ```sql
[CREATE TABLE AS] SELECT select_expr [, select_expr ...] [CREATE TABLE AS] SELECT select_expr [, select_expr ...]
...@@ -24,40 +24,39 @@ TDengine 提供的连续查询与普通流计算中的时间窗口计算具有 ...@@ -24,40 +24,39 @@ TDengine 提供的连续查询与普通流计算中的时间窗口计算具有
``` ```
INTERVAL: 连续查询作用的时间窗口 INTERVAL: The time window for which continuous query is performed
SLIDING: 连续查询的时间窗口向前滑动的时间间隔 SLIDING: The time step for which the time window moves forward each time
## 使用连续查询 ## How to Use
下面以智能电表场景为例介绍连续查询的具体使用方法。假设我们通过下列 SQL 语句创建了超级表和子表: In this section the use case of meters will be used to introduce how to use continuous query. Assume the STable and sub tables have been created using below SQL statement.
```sql ```sql
create table meters (ts timestamp, current float, voltage int, phase float) tags (location binary(64), groupId int); create table meters (ts timestamp, current float, voltage int, phase float) tags (location binary(64), groupId int);
create table D1001 using meters tags ("Beijing.Chaoyang", 2); create table D1001 using meters tags ("Beijing.Chaoyang", 2);
create table D1002 using meters tags ("Beijing.Haidian", 2); create table D1002 using meters tags ("Beijing.Haidian", 2);
...
``` ```
可以通过下面这条 SQL 语句以一分钟为时间窗口、30 秒为前向增量统计这些电表的平均电压。 The average voltage for each time window of one minute with 30 seconds as the length of moving forward can be retrieved using below SQL statement.
```sql ```sql
select avg(voltage) from meters interval(1m) sliding(30s); select avg(voltage) from meters interval(1m) sliding(30s);
``` ```
每次执行这条语句,都会重新计算所有数据。 如果需要每隔 30 秒执行一次来增量计算最近一分钟的数据,可以把上面的语句改进成下面的样子,每次使用不同的 `startTime` 并定期执行: Whenever the above SQL statement is executed, all the existing data will be computed again. If the computation needs to be performed every 30 seconds automatically to compute on the data in the past one minute, the above SQL statement needs to be revised as below, in which `{startTime}` stands for the beginning timestamp in the latest time window.
```sql ```sql
select avg(voltage) from meters where ts > {startTime} interval(1m) sliding(30s); select avg(voltage) from meters where ts > {startTime} interval(1m) sliding(30s);
``` ```
这样做没有问题,但 TDengine 提供了更简单的方法,只要在最初的查询语句前面加上 `create table {tableName} as` 就可以了,例如: Another easier way for same purpose is prepend `create table {tableName} as` before the `select`.
```sql ```sql
create table avg_vol as select avg(voltage) from meters interval(1m) sliding(30s); create table avg_vol as select avg(voltage) from meters interval(1m) sliding(30s);
``` ```
会自动创建一个名为 `avg_vol` 的新表,然后每隔 30 秒,TDengine 会增量执行 `as` 后面的 SQL 语句,并将查询结果写入这个表中,用户程序后续只要从 `avg_vol` 中查询数据即可。例如: A table named as `avg_vol` will be created automatically, then every 30 seconds the `select` statement will be executed automatically on the data in the past 1 minutes, i.e. the latest time window, and the result is written into table `avg_vol`. The client program just needs to query from table `avg_vol`. For example:
```sql ```sql
taos> select * from avg_vol; taos> select * from avg_vol;
...@@ -69,16 +68,16 @@ taos> select * from avg_vol; ...@@ -69,16 +68,16 @@ taos> select * from avg_vol;
2020-07-29 13:39:00.000 | 223.0800000 | 2020-07-29 13:39:00.000 | 223.0800000 |
``` ```
需要注意,查询时间窗口的最小值是 10 毫秒,没有时间窗口范围的上限。 Please be noted that the minimum allowed time window is 10 milliseconds, and no upper limit.
此外,TDengine 还支持用户指定连续查询的起止时间。如果不输入开始时间,连续查询将从第一条原始数据所在的时间窗口开始;如果没有输入结束时间,连续查询将永久运行;如果用户指定了结束时间,连续查询在系统时间达到指定的时间以后停止运行。比如使用下面的 SQL 创建的连续查询将运行一小时,之后会自动停止。 Besides, it's allowed to specify the start and end time of continuous query. If the start time is not specified, the timestamp of the first original row will be considered as the start time; if the end time is not specified, the continuous will be performed infinitely, otherwise it will be terminated once the end time is reached. For example, the continuous query in below SQL statement will be started from now and terminated one hour later.
```sql ```sql
create table avg_vol as select avg(voltage) from meters where ts > now and ts <= now + 1h interval(1m) sliding(30s); create table avg_vol as select avg(voltage) from meters where ts > now and ts <= now + 1h interval(1m) sliding(30s);
``` ```
需要说明的是,上面例子中的 `now` 是指创建连续查询的时间,而不是查询执行的时间,否则,查询就无法自动停止了。另外,为了尽量避免原始数据延迟写入导致的问题,TDengine 中连续查询的计算有一定的延迟。也就是说,一个时间窗口过去后,TDengine 并不会立即计算这个窗口的数据,所以要稍等一会(一般不会超过 1 分钟)才能查到计算结果。 `now` in above SQL statement stands for the time when the continuous query is created, not the time when the computation is actually performed. Besides, to avoid the trouble caused by the delay of original data as much as possible, the actual computation in continuous query is also started with a little delay. That means, once a time window closes, the computation is not started immediately. Normally, the result can only be available a little time later, normally within one minute, after the time window closes.
## 管理连续查询 ## How to Manage
用户可在控制台中通过 `show streams` 命令来查看系统中全部运行的连续查询,并可以通过 `kill stream` 命令杀掉对应的连续查询。后续版本会提供更细粒度和便捷的连续查询管理命令。 `show streams` command can be used in TDengine CLI `taos` to show all the continuous queries in the system, and `kill stream` can be used to terminate a continuous query.
--- ---
sidebar_label: 数据订阅 sidebar_label: Subscription
description: "轻量级的数据订阅与推送服务。连续写入到 TDengine 中的时序数据能够被自动推送到订阅客户端。" description: "Lightweight service for data subscription and pushing, the time series data inserted into TDengine continuously can be pushed automatically to the subscribing clients."
title: 数据订阅 title: Data Subscription
--- ---
import Tabs from "@theme/Tabs"; import Tabs from "@theme/Tabs";
...@@ -14,13 +14,13 @@ import Node from "./_sub_node.mdx"; ...@@ -14,13 +14,13 @@ import Node from "./_sub_node.mdx";
import CSharp from "./_sub_cs.mdx"; import CSharp from "./_sub_cs.mdx";
import CDemo from "./_sub_c.mdx"; import CDemo from "./_sub_c.mdx";
基于数据天然的时间序列特性,TDengine 的数据写入(insert)与消息系统的数据发布(pub)逻辑上一致,均可视为系统中插入一条带时间戳的新记录。同时,TDengine 在内部严格按照数据时间序列单调递增的方式保存数据。本质上来说,TDengine 中每一张表均可视为一个标准的消息队列。 ## Introduction
TDengine 内嵌支持轻量级的消息订阅与推送服务。使用系统提供的 API,用户可使用普通查询语句订阅数据库中的一张或多张表。订阅的逻辑和操作状态的维护均是由客户端完成,客户端定时轮询服务器是否有新的记录到达,有新的记录到达就会将结果反馈到客户。 According to the time series nature of the data, data inserting in TDengine is similar to data publishing in message queues, they both can be considered as a new data record with timestamp is inserted into the system. Data is stored in ascending order of timestamp inside TDengine, so essentially each table in TDengine can be considered as a message queue.
TDengine 的订阅与推送服务的状态是由客户端维持,TDengine 服务端并不维持。因此如果应用重启,从哪个时间点开始获取最新数据,由应用决定。 Lightweight service for data subscription and pushing is built in TDengine. With the API provided by TDengine, client programs can used `select` statement to subscribe the data from one or more tables. The subscription and and state maintenance is performed on the client side, the client programs polls the server to check whether there is new data, and if so the new data will be pushed back to the client side. If the client program is restarted, where to start for retrieving new data is up to the client side.
TDengine 的 API 中,与订阅相关的主要有以下三个: There are 3 major APIs related to subscription provided in the TDengine client driver.
```c ```c
taos_subscribe taos_subscribe
...@@ -28,9 +28,11 @@ taos_consume ...@@ -28,9 +28,11 @@ taos_consume
taos_unsubscribe taos_unsubscribe
``` ```
这些 API 的文档请见 [C/C++ Connector](/reference/connector/cpp),下面仍以智能电表场景为例介绍一下它们的具体用法(超级表和子表结构请参考上一节“连续查询”),完整的示例代码可以在 [这里](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c) 找到。 For more details about these API please refer to [C/C++ Connector](/reference/connector/cpp). Their usage will be introduced below using the use case of meters, in which the schema of STable and sub tables please refer to the previous section "continuous query". Full sample code can be found [here](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c).
如果我们希望当某个电表的电流超过一定限制(比如 10A)后能得到通知并进行一些处理, 有两种方法:一是分别对每张子表进行查询,每次查询后记录最后一条数据的时间戳,后续只查询这个时间戳之后的数据: If we want to get notification and take some actions if the current exceeds a threshold, like 10A, from some meters, there are two ways:
The first way is to query on each sub table and record the last timestamp matching the criteria, then after some time query on the data later than recorded timestamp and repeat this process. The SQL statements for this way are as below.
```sql ```sql
select * from D1001 where ts > {last_timestamp1} and current > 10; select * from D1001 where ts > {last_timestamp1} and current > 10;
...@@ -38,19 +40,19 @@ select * from D1002 where ts > {last_timestamp2} and current > 10; ...@@ -38,19 +40,19 @@ select * from D1002 where ts > {last_timestamp2} and current > 10;
... ...
``` ```
这确实可行,但随着电表数量的增加,查询数量也会增加,客户端和服务端的性能都会受到影响,当电表数增长到一定的程度,系统就无法承受了。 The above way works, but the problem is that the number of `select` statements increases with the number of meters grows. Finally the performance of both client side and server side will be unacceptable once the number of meters grows to a big enough number.
另一种方法是对超级表进行查询。这样,无论有多少电表,都只需一次查询: A better way is to query on the STable, only one `select` is enough regardless of the number of meters, like below:
```sql ```sql
select * from meters where ts > {last_timestamp} and current > 10; select * from meters where ts > {last_timestamp} and current > 10;
``` ```
但是,如何选择 `last_timestamp` 就成了一个新的问题。因为,一方面数据的产生时间(也就是数据时间戳)和数据入库的时间一般并不相同,有时偏差还很大;另一方面,不同电表的数据到达 TDengine 的时间也会有差异。所以,如果我们在查询中使用最慢的那台电表的数据的时间戳作为 `last_timestamp`,就可能重复读入其它电表的数据;如果使用最快的电表的时间戳,其它电表的数据就可能被漏掉。 However, how to choose `last_timestamp` becomes a new problem if using this way. Firstly, the timestamp when the data is generated is different from the timestamp when the data is inserted into the database, sometimes the difference between them may be very big. Secondly, the time when the data from different meters may arrives at the database may be different too. If the timestamp of the "slowest" meter is used as `last_timestamp` in the query, the data from other meters may be selected repeatedly; but if the timestamp of the "fasted" meters is used as `last_timestamp`, some data from other meters may be missed.
TDengine 的订阅功能为上面这个问题提供了一个彻底的解决方案。 All the problems mentioned above can be resolved thoroughly using subscription provided by TDengine.
首先是使用 `taos_subscribe` 创建订阅: The first step is to create subscription using `taos_subscribe`.
```c ```c
TAOS_SUB* tsub = NULL; TAOS_SUB* tsub = NULL;
...@@ -63,31 +65,31 @@ if (async) { ...@@ -63,31 +65,31 @@ if (async) {
} }
``` ```
TDengine 中的订阅既可以是同步的,也可以是异步的,上面的代码会根据从命令行获取的参数 `async` 的值来决定使用哪种方式。这里,同步的意思是用户程序要直接调用 `taos_consume` 来拉取数据,而异步则由 API 在内部的另一个线程中调用 `taos_consume`,然后把拉取到的数据交给回调函数 `subscribe_callback`去处理。(注意,`subscribe_callback` 中不宜做较为耗时的操作,否则有可能导致客户端阻塞等不可控的问题。) The subscription in TDengine can be either synchronous or asynchronous. In the above sample code, the value of variable `async` is determined from the CLI input, then it's used to create either an async or sync subscription. Sync subscription means the client program needs to invoke `taos_consume` to retrieve data, and async subscription means another thread created by `taos_subscribe` internally invokes `taos_consume` to retrieve data and pass the data to `subscribe_callback` for processing, `subscribe_callback` is a call back function provided by the client program and it's suggested not to do time consuming operation in the call back function.
参数 `taos` 是一个已经建立好的数据库连接,在同步模式下无特殊要求。但在异步模式下,需要注意它不会被其它线程使用,否则可能导致不可预计的错误,因为回调函数在 API 的内部线程中被调用,而 TDengine 的部分 API 不是线程安全的。 The parameter `taos` is an established connection. There is nothing special in sync subscription mode. In async subscription, it should be exclusively by current thread, otherwise unpredictable error may occur.
参数 `sql` 是查询语句,可以在其中使用 where 子句指定过滤条件。在我们的例子中,如果只想订阅电流超过 10A 时的数据,可以这样写: The parameter `sql` is a `select` statement in which `where` clause can be used to specify filter conditions. In our example, the data whose current exceeds 10A needs to be subscribed like below SQL statement:
```sql ```sql
select * from meters where current > 10; select * from meters where current > 10;
``` ```
注意,这里没有指定起始时间,所以会读到所有时间的数据。如果只想从一天前的数据开始订阅,而不需要更早的历史数据,可以再加上一个时间条件: Please be noted that, all the data will be processed because no start time is specified. If only the data from one day ago needs to be processed, a time related condition can be added:
```sql ```sql
select * from meters where ts > now - 1d and current > 10; select * from meters where ts > now - 1d and current > 10;
``` ```
订阅的 `topic` 实际上是它的名字,因为订阅功能是在客户端 API 中实现的,所以没必要保证它全局唯一,但需要它在一台客户端机器上唯一。 The parameter `topic` is the name of the subscription, it needs to be guaranteed unique in the client program, but it's not necessary to be globally unique because subscription is implemented in the APIs on client side.
如果名为 `topic` 的订阅不存在,参数 `restart` 没有意义;但如果用户程序创建这个订阅后退出,当它再次启动并重新使用这个 `topic` 时,`restart` 就会被用于决定是从头开始读取数据,还是接续上次的位置进行读取。本例中,如果 `restart` 是 **true**(非零值),用户程序肯定会读到所有数据。但如果这个订阅之前就存在了,并且已经读取了一部分数据,且 `restart` 是 **false**(**0**),用户程序就不会读到之前已经读取的数据了。 If the subscription named as `topic` doesn't exist, parameter `restart` would be ignored. If the subscription named as `topic` has been created before by the client program which then exited, when the client program is restarted to use this `topic`, parameter `restart` is used to determine retrieving data from beginning or from the last point where the subscription was broken. If the value of `restart` is **true** (i.e. a non-zero value), the data will be retrieved from beginning, or if it is **false** (i.e. zero), the data already consumed before will not be processed again.
`taos_subscribe`的最后一个参数是以毫秒为单位的轮询周期。在同步模式下,如果前后两次调用 `taos_consume` 的时间间隔小于此时间,`taos_consume` 会阻塞,直到间隔超过此时间。异步模式下,这个时间是两次调用回调函数的最小时间间隔。 The last parameter of `taos_subscribe` is the polling interval in unit of millisecond. In sync mode, if the time difference between two continuous invocations to `taos_consume` is smaller than the interval specified by `taos_subscribe`, `taos_consume` would be blocked until the interval is reached. In async mode, this interval is the minimum interval between two invocations to the call back function.
`taos_subscribe` 的倒数第二个参数用于用户程序向回调函数传递附加参数,订阅 API 不对其做任何处理,只原样传递给回调函数。此参数在同步模式下无意义。 The last second parameter of `taos_subscribe` is used to pass arguments to the call back function. `taos_subscribe` doesn't process this parameter and simply passes it to the call back function. This parameter is simply ignored in sync mode.
订阅创建以后,就可以消费其数据了,同步模式下,示例代码是下面的 else 部分: After a subscription is created, its data can be consumed and processed, below is the sample code of how to consume data in sync mode, in the else part if `if (async)`.
```c ```c
if (async) { if (async) {
...@@ -104,7 +106,7 @@ if (async) { ...@@ -104,7 +106,7 @@ if (async) {
} }
``` ```
这里是一个 **while** 循环,用户每按一次回车键就调用一次 `taos_consume`,而 `taos_consume` 的返回值是查询到的结果集,与 `taos_use_result` 完全相同,例子中使用这个结果集的代码是函数 `print_result`: In the above sample code, there is an infinite loop, each time carriage return is entered `taos_consume` is invoked, the return value of `taos_consume` is the selected result set, exactly as the input of `taos_use_result`, in the above sample `print_result` is used instead to simplify the sample. Below is the implementation of `print_result`.
```c ```c
void print_result(TAOS_RES* res, int blockFetch) { void print_result(TAOS_RES* res, int blockFetch) {
...@@ -131,7 +133,9 @@ void print_result(TAOS_RES* res, int blockFetch) { ...@@ -131,7 +133,9 @@ void print_result(TAOS_RES* res, int blockFetch) {
} }
``` ```
其中的 `taos_print_row` 用于处理订阅到数据,在我们的例子中,它会打印出所有符合条件的记录。而异步模式下,消费订阅到的数据则显得更为简单: In the above code `taos_print_row` is used to process the data consumed. All the matching rows will be printed.
In async mode, the data consuming is simpler as below.
```c ```c
void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) { void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
...@@ -139,44 +143,43 @@ void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) { ...@@ -139,44 +143,43 @@ void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
} }
``` ```
当要结束一次数据订阅时,需要调用 `taos_unsubscribe`: `taos_unsubscribe` can be invoked to terminate a subscription.
```c ```c
taos_unsubscribe(tsub, keep); taos_unsubscribe(tsub, keep);
``` ```
其第二个参数,用于决定是否在客户端保留订阅的进度信息。如果这个参数是**false**(**0**),那无论下次调用 `taos_subscribe` 时的 `restart` 参数是什么,订阅都只能重新开始。另外,进度信息的保存位置是 _{DataDir}/subscribe/_ 这个目录下,每个订阅有一个与其 `topic` 同名的文件,删掉某个文件,同样会导致下次创建其对应的订阅时只能重新开始。 The second parameter `keep` is used to specify whether to keep the subscription progress on the client sde. If it is **false**, i.e. **0**, then subscription will be restarted from beginning regardless of the `restart` parameter's value in when `taos_subscribe` is invoked again. The subscription progress information is stored in _{DataDir}/subscribe/_ , under which there is a file with same name as `topic` for each subscription, the subscription will be restarted from beginning if the corresponding progress file is removed.
代码介绍完毕,我们来看一下实际的运行效果。假设: Now let's see the effect of the above sample code, assuming below prerequisites have been done.
- 示例代码已经下载到本地 - The sample code has been downloaded to local system 示
- TDengine 也已经在同一台机器上安装好 - TDengine has been installed and launched properly on same system
- 示例所需的数据库、超级表、子表已经全部创建好 - The database, STable, sub tables required in the sample code have been ready
则可以在示例代码所在目录执行以下命令来编译并启动示例程序: It's ready to launch below command in the directory where the sample code resides to compile and start the program.
```bash ```bash
make make
./subscribe -sql='select * from meters where current > 10;' ./subscribe -sql='select * from meters where current > 10;'
``` ```
示例程序启动后,打开另一个终端窗口,启动 TDengine CLI 向 **D1001** 插入一条电流为 12A 的数据: After the program is started, open another terminal and launch TDengine CLI `taos`, then use below SQL commands to insert a row whose current is 12A into table **D1001**.
```sql ```sql
$ taos use test;
> use test; insert into D1001 values(now, 12, 220, 1);
> insert into D1001 values(now, 12, 220, 1);
``` ```
这时,因为电流超过了 10A,您应该可以看到示例程序将它输出到了屏幕上。您可以继续插入一些数据观察示例程序的输出。 Then, this row of data will be shown by the example program on the first terminal because its current exceeds 10A. More data can be inserted for you to observe the output of the example program.
## 示例程序 ## Examples
下面的示例程序展示是如何使用连接器订阅所有电流超过 10A 的记录。 Below example program demonstrates how to subscribe the data rows whose current exceeds 10A using connectors.
### 准备数据 ### Prepare Data
``` ```bash
# create database "power" # create database "power"
taos> create database power; taos> create database power;
# use "power" as the database in following operations # use "power" as the database in following operations
...@@ -200,20 +203,21 @@ taos> select * from meters where current > 10; ...@@ -200,20 +203,21 @@ taos> select * from meters where current > 10;
2020-08-15 12:20:00.000 | 12.20000 | 220 | 1 | Beijing.Chaoyang | 2 | 2020-08-15 12:20:00.000 | 12.20000 | 220 | 1 | Beijing.Chaoyang | 2 |
Query OK, 5 row(s) in set (0.004896s) Query OK, 5 row(s) in set (0.004896s)
``` ```
### 示例代码
### Example Programs
<Tabs defaultValue="java" groupId="lang"> <Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java"> <TabItem label="Java" value="java">
<Java/> <Java />
</TabItem> </TabItem>
<TabItem label="Python" value="Python"> <TabItem label="Python" value="Python">
<Python/> <Python />
</TabItem> </TabItem>
{/* <TabItem label="Go" value="go"> {/* <TabItem label="Go" value="go">
<Go/> <Go/>
</TabItem> */} </TabItem> */}
<TabItem label="Rust" value="rust"> <TabItem label="Rust" value="rust">
<Rust/> <Rust />
</TabItem> </TabItem>
{/* <TabItem label="Node.js" value="nodejs"> {/* <TabItem label="Node.js" value="nodejs">
<Node/> <Node/>
...@@ -222,13 +226,13 @@ Query OK, 5 row(s) in set (0.004896s) ...@@ -222,13 +226,13 @@ Query OK, 5 row(s) in set (0.004896s)
<CSharp/> <CSharp/>
</TabItem> */} </TabItem> */}
<TabItem label="C" value="c"> <TabItem label="C" value="c">
<CDemo/> <CDemo />
</TabItem> </TabItem>
</Tabs> </Tabs>
### 运行示例程序 ### Run the Examples
示例程序会先消费符合查询条件的所有历史数据: The example programs firstly consume all historical data matching the criteria.
```bash ```bash
ts: 1597464000000 current: 12.0 voltage: 220 phase: 1 location: Beijing.Chaoyang groupid : 2 ts: 1597464000000 current: 12.0 voltage: 220 phase: 1 location: Beijing.Chaoyang groupid : 2
...@@ -238,7 +242,7 @@ ts: 1597464600000 current: 10.3 voltage: 220 phase: 1 location: Beijing.Haidian ...@@ -238,7 +242,7 @@ ts: 1597464600000 current: 10.3 voltage: 220 phase: 1 location: Beijing.Haidian
ts: 1597465200000 current: 11.2 voltage: 220 phase: 1 location: Beijing.Haidian groupid : 2 ts: 1597465200000 current: 11.2 voltage: 220 phase: 1 location: Beijing.Haidian groupid : 2
``` ```
接着,使用 TDengine CLI 向表中新增一条数据: Next, use TDengine CLI to insert a new row.
``` ```
# taos # taos
...@@ -246,7 +250,7 @@ taos> use power; ...@@ -246,7 +250,7 @@ taos> use power;
taos> insert into d1001 values(now, 12.4, 220, 1); taos> insert into d1001 values(now, 12.4, 220, 1);
``` ```
因为这条数据的电流大于 10A,示例程序会将其消费: Because the current in inserted row exceeds 10A, it will be consumed by the example program.
``` ```
ts: 1651146662805 current: 12.4 voltage: 220 phase: 1 location: Beijing.Chaoyang groupid: 2 ts: 1651146662805 current: 12.4 voltage: 220 phase: 1 location: Beijing.Chaoyang groupid: 2
......
--- ---
sidebar_label: 缓存 sidebar_label: Cache
title: 缓存 title: Cache
description: "提供写驱动的缓存管理机制,将每个表最近写入的一条记录持续保存在缓存中,可以提供高性能的最近状态查询。" description: "The latest row of each table is kept in cache to provide high performance query of latest state."
--- ---
TDengine 采用时间驱动缓存管理策略(First-In-First-Out,FIFO),又称为写驱动的缓存管理机制。这种策略有别于读驱动的数据缓存模式(Least-Recent-Used,LRU),直接将最近写入的数据保存在系统的缓存中。当缓存达到临界值的时候,将最早的数据批量写入磁盘。一般意义上来说,对于物联网数据的使用,用户最为关心最近产生的数据,即当前状态。TDengine 充分利用了这一特性,将最近到达的(当前状态)数据保存在缓存中。 The cache management policy in TDengine is First-In-First-Out (FIFO), which is also known as insert driven cache management policy and different from read driven cache management, i.e. Least-Recent-Used (LRU). It simply stores the latest data in cache and flushes the oldest data in cache to disk when the cache usage reaches a threshold. In IoT use cases, the most cared about data is the latest data, i.e. current state. The cache policy in TDengine is based the nature of IoT data.
TDengine 通过查询函数向用户提供毫秒级的数据获取能力。直接将最近到达的数据保存在缓存中,可以更加快速地响应用户针对最近一条或一批数据的查询分析,整体上提供更快的数据库查询响应能力。从这个意义上来说,可通过设置合适的配置参数将 TDengine 作为数据缓存来使用,而不需要再部署额外的缓存系统,可有效地简化系统架构,降低运维的成本。需要注意的是,TDengine 重启以后系统的缓存将被清空,之前缓存的数据均会被批量写入磁盘,缓存的数据将不会像专门的 key-value 缓存系统再将之前缓存的数据重新加载到缓存中。 Caching the latest data provides the capability of retrieving data in milliseconds. With this capability, TDengine can be configured properly to be used as caching system without deploying another separate caching system to simplify the system architecture and minimize the operation cost. The cache will be emptied after TDengine is restarted, TDengine doesn't reload data from disk into cache like a real key-value caching system.
TDengine 分配固定大小的内存空间作为缓存空间,缓存空间可根据应用的需求和硬件资源配置。通过适当的设置缓存空间,TDengine 可以提供极高性能的写入和查询的支持。TDengine 中每个虚拟节点(virtual node)创建时分配独立的缓存池。每个虚拟节点管理自己的缓存池,不同虚拟节点间不共享缓存池。每个虚拟节点内部所属的全部表共享该虚拟节点的缓存池。 The memory space used by TDengine cache is fixed in size, according to the configuration based on application requirement and system resources. Independent memory pool is allocated for and managed by each vnode (virtual node) in TDengine, there is no sharing of memory pools between vnodes. All the tables belonging to a vnode share all the cache memory of the vnode.
TDengine 将内存池按块划分进行管理,数据在内存块里是以行(row)的形式存储。一个 vnode 的内存池是在 vnode 创建时按块分配好,而且每个内存块按照先进先出的原则进行管理。在创建内存池时,块的大小由系统配置参数 cache 决定;每个 vnode 中内存块的数目则由配置参数 blocks 决定。因此对于一个 vnode,总的内存大小为:`cache * blocks`。一个 cache block 需要保证每张表能存储至少几十条以上记录,才会有效率。 Memory pool is divided into blocks and data is stored in row format in memory and each block follows FIFO policy. The size of each block is determined by configuration parameter `cache`, the number of blocks for each vnode is determined by `blocks`. For each vnode, the total cache size is `cache * blocks`. It's better to set the size of each block to hold at least tends of rows.
你可以通过函数 last_row() 快速获取一张表或一张超级表的最后一条记录,这样很便于在大屏显示各设备的实时状态或采集值。例如: `last_row` function can be used to retrieve the last row of a table or a STable to quickly show the current state of devices on monitoring screen. For example below SQL statement retrieves the latest voltage of all meters in Chaoyang district of Beijing.
```sql ```sql
select last_row(voltage) from meters where location='Beijing.Chaoyang'; select last_row(voltage) from meters where location='Beijing.Chaoyang';
``` ```
该 SQL 语句将获取所有位于北京朝阳区的电表最后记录的电压值。
此差异已折叠。
label: 开发指南 label: Develop
link: link:
type: generated-index type: generated-index
slug: /develop slug: /develop
description: "开始指南是对开发者友好的使用教程,既包括数据建模、写入、查询等基础功能的使用,也包括数据订阅、连续查询等高级功能的使用。对于每个主题,都配有各编程语言的连接器的示例代码,方便开发者快速上手。如果想更深入地了解各连接器的使用,请阅读连接器参考指南。" description: "The guide is for developers to quickly learn about the functionalities of TDengine, including fundamentals like data model, inserting data, query and advanced features like data subscription, continuous query. For each functionality, sample code of multiple programming languages are provided for developers to get started quickly."
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
{{#include docs-examples/java/src/main/java/com/taos/example/SubscribeDemo.java}} {{#include docs-examples/java/src/main/java/com/taos/example/SubscribeDemo.java}}
``` ```
:::note :::note
目前 Java 接口没有提供异步订阅模式,但用户程序可以通过创建 `TimerTask` 等方式达到同样的效果。 For now Java connector doesn't provide asynchronous subscription, but `TimerTask` can be used to achieve similar purpose.
::: :::
\ No newline at end of file
--- ---
title: 集群部署 title: Deploy
--- ---
## 准备工作 ## Prerequisites
### 第零步 ### Step 1
规划集群所有物理节点的 FQDN,将规划好的 FQDN 分别添加到每个物理节点的 /etc/hosts;修改每个物理节点的 /etc/hosts,将所有集群物理节点的 IP 与 FQDN 的对应添加好。【如部署了 DNS,请联系网络管理员在 DNS 上做好相关配置】 The FQDN of all hosts need to be setup properly, all the FQDNs need to be configured in the /etc/hosts of each host. It must be guaranteed that each FQDN can be accessed (by ping, for example) from any other hosts.
### 第一步 On each host command `hostname -f` can be executed to get the hostname. `ping` command can be executed on each host to check whether any other host is accessible from it. If any host is not accessible, the network configuration, like /etc/hosts or DNS configuration, need to be checked and revised to make any two hosts accessible to each other.
如果搭建集群的物理节点中,存有之前的测试数据、装过 1.X 的版本,或者装过其他版本的 TDengine,请先将其删除,并清空所有数据(如果需要保留原有数据,请联系涛思交付团队进行旧版本升级、数据迁移),具体步骤请参考博客[《TDengine 多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html)
:::note
因为 FQDN 的信息会写进文件,如果之前没有配置或者更改 FQDN,且启动了 TDengine。请一定在确保数据无用或者备份的前提下,清理一下之前的数据(rm -rf /var/lib/taos/\*);
:::
:::note :::note
客户端所在服务器也需要配置,确保它可以正确解析每个节点的 FQDN 配置,不管是通过 DNS 服务,还是修改 hosts 文件。
:::
### 第二步
建议关闭所有物理节点的防火墙,至少保证端口:6030 - 6042 的 TCP 和 UDP 端口都是开放的。强烈建议先关闭防火墙,集群搭建完毕之后,再来配置端口;
### 第三步 - The host where the client program runs also needs to configured properly for FQDN, to make sure all hosts for client or server can be accessed from any other. In other words, the hosts where the client is running are also considered as a part of the cluster.
在所有物理节点安装 TDengine,且版本必须是一致的,但不要启动 taosd。安装时,提示输入是否要加入一个已经存在的 TDengine 集群时,第一个物理节点直接回车创建新集群,后续物理节点则输入该集群任何一个在线的物理节点的 FQDN:端口号(默认 6030); - It's suggested to disable the firewall for all hosts in the cluster. At least TCP/UDP for port 6030~6042 need to be open if firewall is enabled.
### 第四步 :::
检查所有数据节点,以及应用程序所在物理节点的网络设置:
每个物理节点上执行命令 `hostname -f`,查看和确认所有节点的 hostname 是不相同的(应用驱动所在节点无需做此项检查); ### Step 2
每个物理节点上执行 ping host,其中 host 是其他物理节点的 hostname,看能否 ping 通其它物理节点;如果不能 ping 通,需要检查网络设置,或 /etc/hosts 文件(Windows 系统默认路径为 C:\Windows\system32\drivers\etc\hosts),或 DNS 的配置。如果无法 ping 通,是无法组成集群的; If any previous version of TDengine has been installed and configured on any host, the installation needs to be removed and the data needs to be cleaned up. For details about uninstalling please refer to [Install and Uninstall](/operation/pkg-install). To clean up the data, please use `rm -rf /var/lib/taos/\*` assuming the `dataDir` is configured as `/var/lib/taos`.
从应用运行的物理节点,ping taosd 运行的数据节点,如果无法 ping 通,应用是无法连接 taosd 的,请检查应用所在物理节点的 DNS 设置或 hosts 文件; ### Step 3
每个数据节点的 End Point 就是输出的 hostname 外加端口号,比如 h1.taosdata.com:6030。 Now it's time to install TDengine on all hosts without starting `taosd`, the versions on all hosts should be same. If it's prompted to input the existing TDengine cluster, simply press carriage return to ignore it. `install.sh -e no` can also be used to disable this prompt. For details please refer to [Install and Uninstall](/operation/pkg-install).
### 第五步 ### Step 4
修改 TDengine 的配置文件(所有节点的文件 /etc/taos/taos.cfg 都需要修改)。假设准备启动的第一个数据节点 End Point 为 h1.taosdata.com:6030,其与集群配置相关参数如下: Now each physical node (referred to as `dnode` hereinafter, it's abbreviation for "data node") of TDengine need to be configured properly. Please be noted that one dnode doesn't stand for one host, multiple TDengine nodes can be started on single host as long as they are configured properly without conflicting. More specifically each instance of the configuration file `taos.cfg` stands for a dnode. Assuming the first dnode of TDengine cluster is "h1.taosdata.com:6030", its `taos.cfg` is configured as following.
```c ```c
// firstEp 是每个数据节点首次启动后连接的第一个数据节点 // firstEp is the end point to connect to when any dnode starts
firstEp h1.taosdata.com:6030 firstEp h1.taosdata.com:6030
// 必须配置为本数据节点的 FQDN,如果本机只有一个 hostname,可注释掉本项 // must be configured to the FQDN of the host where the dnode is launched
fqdn h1.taosdata.com fqdn h1.taosdata.com
// 配置本数据节点的端口号,缺省是 6030 // the port used by the dnode, default is 6030
serverPort 6030 serverPort 6030
// 副本数为偶数的时候,需要配置,请参考《Arbitrator 的使用》的部分 // only necessary when replica is configured to an even number
arbitrator ha.taosdata.com:6042 #arbitrator ha.taosdata.com:6042
``` ```
一定要修改的参数是 firstEp 和 fqdn。在每个数据节点,firstEp 需全部配置成一样,但 fqdn 一定要配置成其所在数据节点的值。其他参数可不做任何修改,除非你很清楚为什么要修改。 `firstEp` and `fqdn` must be configured properly. In `taos.cfg` of all dnodes in TDengine cluster, `firstEp` must be configured to point to same address, i.e. the first dnode of the cluster. `fqdn` and `serverPort` compose the address of each node itself. If you want to start multiple TDengine dnodes on a single host, please also make sure all other configurations like `dataDir`, `logDir`, and other resources related parameters are not conflicting.
加入到集群中的数据节点 dnode,涉及集群相关的下表 9 项参数必须完全相同,否则不能成功加入到集群中。 For all the dnodes in a TDengine cluster, below parameters must be configured as exactly same, any node whose configuration is different from dnodes already in the cluster can't join the cluster.
| **#** | **配置参数名称** | **含义** | | **#** | **Parameter** | **Definition** |
| ----- | ------------------ | ------------------------------------------- | | ----- | ------------------ | --------------------------------------------------------------------------------- |
| 1 | numOfMnodes | 系统中管理节点个数 | | 1 | numOfMnodes | The number of management nodes in the cluster |
| 2 | mnodeEqualVnodeNum | 一个 mnode 等同于 vnode 消耗的个数 | | 2 | mnodeEqualVnodeNum | The ratio of resource consuming of mnode to vnode |
| 3 | offlineThreshold | dnode 离线阈值,超过该时间将导致 Dnode 离线 | | 3 | offlineThreshold | The threshold of dnode offline, once it's reached the dnode is considered as down |
| 4 | statusInterval | dnode 向 mnode 报告状态时长 | | 4 | statusInterval | The interval by which dnode reports its status to mnode |
| 5 | arbitrator | 系统中裁决器的 End Point | | 5 | arbitrator | End point of the arbitrator component in the cluster |
| 6 | timezone | 时区 | | 6 | timezone | Timezone |
| 7 | balance | 是否启动负载均衡 | | 7 | balance | Enable load balance automatically |
| 8 | maxTablesPerVnode | 每个 vnode 中能够创建的最大表个数 | | 8 | maxTablesPerVnode | Maximum number of tables that can be created in each vnode |
| 9 | maxVgroupsPerDb | 每个 DB 中能够使用的最大 vgroup 个数 | | 9 | maxVgroupsPerDb | Maximum number vgroups that can be used by each DB |
:::note :::note
在 2.0.19.0 及更早的版本中,除以上 9 项参数外,dnode 加入集群时,还会要求 locale 和 charset 参数的取值也一致。 Prior to version 2.0.19.0, besides the above parameters, `locale` and `charset` must be configured as same too for each dnode.
::: :::
## 启动集群 ## Start Cluster
### 启动第一个数据节点 ### Start The First DNODE
按照《立即开始》里的步骤,启动第一个数据节点,例如 h1.taosdata.com,然后执行 taos,启动 taos shell,从 shell 里执行命令“SHOW DNODES”,如下所示: The first dnode can be started following the instructions in [Get Started](/get-started/), for example h1.taosdata.com. Then TDengine CLI `taos` can be launched to execute command `show dnodes`, the output is as following for example:
``` ```
Welcome to the TDengine shell from Linux, Client Version:2.0.0.0 Welcome to the TDengine shell from Linux, Client Version:2.0.0.0
...@@ -100,39 +86,29 @@ Query OK, 1 row(s) in set (0.006385s) ...@@ -100,39 +86,29 @@ Query OK, 1 row(s) in set (0.006385s)
taos> taos>
``` ```
上述命令里,可以看到刚启动的数据节点的 End Point 是:h1.taos.com:6030,就是这个新集群的 firstEp。 From the above output, it is shown that the end point of the started dnode is "h1.taos.com:6030", which is the `firstEp` of the cluster.
### 启动后续数据节点 ### Start Other DNODEs
将后续的数据节点添加到现有集群,具体有以下几步: There are a few steps necessary to add other dnodes in the cluster.
按照《立即开始》一章的方法在每个物理节点启动 taosd;(注意:每个物理节点都需要在 taos.cfg 文件中将 firstEp 参数配置为新集群首个节点的 End Point——在本例中是 h1.taos.com:6030) Firstly, start `taosd` as instructed in [Get Started](/get-started/), assuming it's for the second dnode. Before starting `taosd`, please making sure the configuration is correct, especially `firstEp`, `FQDN` and `serverPort`, `firstEp` must be same as the dnode shown in the section "Start First DNODE", i.e. "h1.taosdata.com" in this example.
在第一个数据节点,使用 CLI 程序 taos,登录进 TDengine 系统,执行命令: Then, on the first dnode, use TDengine CLI `taos` to execute below command to add the end point of the dnode in the cluster. In the command "fqdn:port" should be quoted using double quotes.
```sql ```sql
CREATE DNODE "h2.taos.com:6030"; CREATE DNODE "h2.taos.com:6030";
``` ```
将新数据节点的 End Point(准备工作中第四步获知的)添加进集群的 EP 列表。“fqdn:port”需要用双引号引起来,否则出错。请注意将示例的“h2.taos.com:6030” 替换为这个新数据节点的 End Point。 Then on the first dnode, execute `show dnodes` in `taos` to show whether the second dnode has been added in the cluster successfully or not.
然后执行命令
```sql ```sql
SHOW DNODES; SHOW DNODES;
``` ```
查看新节点是否被成功加入。如果该被加入的数据节点处于离线状态,请做两个检查: If the status of the newly added dnode is offlie, please check:
查看该数据节点的 taosd 是否正常工作,如果没有正常运行,需要先检查为什么? - Whether the `taosd` process is running properly or not
查看该数据节点 taosd 日志文件 taosdlog.0 里前面几行日志(一般在 /var/log/taos 目录),看日志里输出的该数据节点 fqdn 以及端口号是否为刚添加的 End Point。如果不一致,需要将正确的 End Point 添加进去。 - In the log file `taosdlog.0` to see whether the fqdn and port are correct or not 查
按照上述步骤可以源源不断的将新的数据节点加入到集群。
:::tip The above process can be repeated to add more dnodes in the cluster.
任何已经加入集群在线的数据节点,都可以作为后续待加入节点的 firstEp。
firstEp 这个参数仅仅在该数据节点首次加入集群时有作用,加入集群后,该数据节点会保存最新的 mnode 的 End Point 列表,不再依赖这个参数。
接下来,配置文件中的 firstEp 参数就主要在客户端连接的时候使用了,例如 taos shell 如果不加参数,会默认连接由 firstEp 指定的节点。
两个没有配置 firstEp 参数的数据节点 dnode 启动后,会独立运行起来。这个时候,无法将其中一个数据节点加入到另外一个数据节点,形成集群。无法将两个独立的集群合并成为新的集群。
:::
--- ---
title: 数据节点管理 sidebar_label: Operation
title: Manage DNODEs
--- ---
上面已经介绍如何从零开始搭建集群。集群组建完成后,可以随时查看集群中当前的数据节点的状态,还可以添加新的数据节点进行扩容,删除数据节点,甚至手动进行数据节点之间的负载均衡操作。 It has been introduced that how to deploy and start a cluster from scratch. Once a cluster is ready, the dnode status in the cluster can be shown at any time, new dnode can be added to scale out the cluster, an existing dnode can be removed, even load balance can be performed manually.\
:::note :::note
All the commands to be introduced in this chapter need to be run after login TDengine, sometimes it's necessary to use root privilege.
以下所有执行命令的操作需要先登陆进 TDengine 系统,必要时请使用 root 权限。
::: :::
## 查看数据节点 ## Show DNODEs
启动 TDengine CLI 程序 taos,然后执行: below command can be executed in TDengine CLI `taos` to list all dnodes in the cluster, including ID, end point (fqdn:port), status (ready, offline), number of vnodes, number of free vnodes, etc. It's suggested to execute this command to check after adding or removing a dnode.
```sql ```sql
SHOW DNODES; SHOW DNODES;
``` ```
它将列出集群中所有的 dnode,每个 dnode 的 ID,end_point(fqdn:port),状态(ready,offline 等),vnode 数目,还未使用的 vnode 数目等信息。在添加或删除一个数据节点后,可以使用该命令查看。 Below is the example output of this command.
输出如下(具体内容仅供参考,取决于实际的集群配置)
``` ```
taos> show dnodes; taos> show dnodes;
...@@ -30,18 +28,18 @@ taos> show dnodes; ...@@ -30,18 +28,18 @@ taos> show dnodes;
Query OK, 1 row(s) in set (0.008298s) Query OK, 1 row(s) in set (0.008298s)
``` ```
## 查看虚拟节点组 ## Show VGROUPs
为充分利用多核技术,并提供 scalability,数据需要分片处理。因此 TDengine 会将一个 DB 的数据切分成多份,存放在多个 vnode 里。这些 vnode 可能分布在多个数据节点 dnode 里,这样就实现了水平扩展。一个 vnode 仅仅属于一个 DB,但一个 DB 可以有多个 vnode。vnode 所在的数据节点是 mnode 根据当前系统资源的情况,自动进行分配的,无需任何人工干预。 To utilize system resources efficiently and provide scalability, data sharding is required. The data of each database is divided into multiple shards and stored in multiple vnodes. These vnodes may be located in different dnodes, scaling out can be achieved by adding more vnodes from more dnodes. Each vnode can only be used for a single DB, but one DB can have multiple vnodes. The allocation of vnode is scheduled automatically by mnode according to system resources of the dnodes.
启动 CLI 程序 taos,然后执行: Launch TDengine CLI `taos` and execute below command:
```sql ```sql
USE SOME_DATABASE; USE SOME_DATABASE;
SHOW VGROUPS; SHOW VGROUPS;
``` ```
输出如下(具体内容仅供参考,取决于实际的集群配置) The example output is as below:
``` ```
taos> show dnodes; taos> show dnodes;
...@@ -67,17 +65,16 @@ taos> show vgroups; ...@@ -67,17 +65,16 @@ taos> show vgroups;
Query OK, 8 row(s) in set (0.001154s) Query OK, 8 row(s) in set (0.001154s)
``` ```
## 添加数据节点 ## Add DNODE
启动 CLI 程序 taos,然后执行: Launch TDengine CLI `taos` and execute to add the end point of a new dnode into the EPI (end point) list of the cluster. "fqdn:port" must be quoted using double quotes.
```sql ```sql
CREATE DNODE "fqdn:port"; CREATE DNODE "fqdn:port";
``` ```
将新数据节点的 End Point 添加进集群的 EP 列表。“fqdn:port“需要用双引号引起来,否则出错。一个数据节点对外服务的 fqdn 和 port 可以通过配置文件 taos.cfg 进行配置,缺省是自动获取。【强烈不建议用自动获取方式来配置 FQDN,可能导致生成的数据节点的 End Point 不是所期望的】 The example output is as below:
示例如下:
``` ```
taos> create dnode "localhost:7030"; taos> create dnode "localhost:7030";
Query OK, 0 of 0 row(s) in database (0.008203s) Query OK, 0 of 0 row(s) in database (0.008203s)
...@@ -90,7 +87,7 @@ taos> show dnodes; ...@@ -90,7 +87,7 @@ taos> show dnodes;
Query OK, 2 row(s) in set (0.001017s) Query OK, 2 row(s) in set (0.001017s)
``` ```
在上面的示例中可以看到新创建的 dnode 的状态为 offline,待该 dnode 被启动并连接上配置文件中指定的 firstEp后再次查看,得到如下结果(示例) It can be seen that the status of the new dnode is "offline", once the dnode is started and connects the firstEp of the cluster, execute the command again and get below example output, from which it can be seen that two dnodes are both in "ready" status.
``` ```
taos> show dnodes; taos> show dnodes;
...@@ -100,24 +97,23 @@ taos> show dnodes; ...@@ -100,24 +97,23 @@ taos> show dnodes;
2 | localhost:7030 | 6 | 8 | ready | any | 2022-04-19 08:14:59.165 | | 2 | localhost:7030 | 6 | 8 | ready | any | 2022-04-19 08:14:59.165 | |
Query OK, 2 row(s) in set (0.001316s) Query OK, 2 row(s) in set (0.001316s)
``` ```
从中可以看到两个 dnode 状态都为 ready
## 删除数据节点 ## Drop DNODE
启动 CLI 程序 taos,然后执行: Launch TDengine CLI `taos` and execute command below to drop or remove a dndoe from the cluster. In the command, `dnodeId` can be gotten from `show dnodes`.
```sql ```sql
DROP DNODE "fqdn:port"; DROP DNODE "fqdn:port";
``` ```
或者
or
```sql ```sql
DROP DNODE dnodeId; DROP DNODE dnodeId;
``` ```
通过 “fqdn:port” 或 dnodeID 来指定一个具体的节点都是可以的。其中 fqdn 是被删除的节点的 FQDN,port 是其对外服务器的端口号;dnodeID 可以通过 SHOW DNODES 获得。 The example output is as below:
示例如下:
``` ```
taos> show dnodes; taos> show dnodes;
id | end_point | vnodes | cores | status | role | create_time | offline reason | id | end_point | vnodes | cores | status | role | create_time | offline reason |
...@@ -136,30 +132,31 @@ taos> show dnodes; ...@@ -136,30 +132,31 @@ taos> show dnodes;
Query OK, 1 row(s) in set (0.001137s) Query OK, 1 row(s) in set (0.001137s)
``` ```
上面的示例中,初次执行 `show dnodes` 列出了两个 dnode, 执行 `drop dnode 2` 删除其中 ID 为 2 的 dnode 之后再次执行 `show dnodes`,可以看到只剩下 ID 为 1 的 dnode 。 In the above example, when `show dnodes` is executed the first time, two dnodes are shown. Then `drop dnode 2` is executed, after that from the output of executing `show dnodes` again it can be seen that only the dnode with ID 1 is still in the cluster.
:::warning :::note
数据节点一旦被 drop 之后,不能重新加入集群。需要将此节点重新部署(清空数据文件夹)。集群在完成 `drop dnode` 操作之前,会将该 dnode 的数据迁移走。 - Once a dnode is dropped, it can't rejoin the cluster. To rejoin, the dnode needs to deployed again after cleaning up the data directory. Normally, before dropping a dnode, the data belonging to the dnode needs to be migrated to other place.
请注意 `drop dnode` 和 停止 taosd 进程是两个不同的概念,不要混淆:因为删除 dnode 之前要执行迁移数据的操作,因此被删除的 dnode 必须保持在线状态。待删除操作结束之后,才能停止 taosd 进程。 - Please be noted that `drop dnode` is different from stopping `taosd` process. `drop dnode` just removes the dnode out of TDengine cluster. Only after a dnode is dropped, can the corresponding `taosd` process be stopped.
一个数据节点被 drop 之后,其他节点都会感知到这个 dnodeID 的删除操作,任何集群中的节点都不会再接收此 dnodeID 的请求。 - Once a dnode is dropped, other dnodes in the cluster will be notified of the drop and will not accept the request from the dropped dnode.
dnodeID 是集群自动分配的,不得人工指定。它在生成时是递增的,不会重复。 - dnodeID is allocated automatically and can't be interfered manually. dnodeID is generated in ascending order without duplication.
::: :::
## 手动迁移数据节点 ## Move VNODE
手动将某个 vnode 迁移到指定的 dnode。 A vnode can be manually moved from one dnode to another.
启动 CLI 程序 taos,然后执行: Launch TDengine CLI `taos` and execute below command:
```sql ```sql
ALTER DNODE <source-dnodeId> BALANCE "VNODE:<vgId>-DNODE:<dest-dnodeId>"; ALTER DNODE <source-dnodeId> BALANCE "VNODE:<vgId>-DNODE:<dest-dnodeId>";
``` ```
其中:source-dnodeId 是源 dnodeId,也就是待迁移的 vnode 所在的 dnodeID;vgId 可以通过 SHOW VGROUPS 获得,列表的第一列;dest-dnodeId 是目标 dnodeId。 In the above command, `source-dnodeId` is the original dnodeId where the vnode resides, `dest-dnodeId` specifies the target dnode. vgId (vgroup ID) can be shown by `SHOW VGROUPS `.
Firstly `show vgroups` is executed to show the vgrup distribution.
首先执行 `show vgroups` 查看 vgroup 的分布情况
``` ```
taos> show vgroups; taos> show vgroups;
vgId | tables | status | onlines | v1_dnode | v1_status | compacting | vgId | tables | status | onlines | v1_dnode | v1_status | compacting |
...@@ -175,7 +172,7 @@ taos> show vgroups; ...@@ -175,7 +172,7 @@ taos> show vgroups;
Query OK, 8 row(s) in set (0.001314s) Query OK, 8 row(s) in set (0.001314s)
``` ```
从中可以看到在 dnode 3 中有5个 vgroup,而 dnode 1 有 3 个 vgroup,假定我们想将其中 vgId 为18 的 vgroup 从 dnode 3 迁移到 dnode 1 It can be seen that there are 5 vgroups in dnode 3 and 3 vgroups in node 1, now we want to move vgId 18 from dnode 3 to dnode 1. Execute below command in `taos`
``` ```
taos> alter dnode 3 balance "vnode:18-dnode:1"; taos> alter dnode 3 balance "vnode:18-dnode:1";
...@@ -183,9 +180,10 @@ taos> alter dnode 3 balance "vnode:18-dnode:1"; ...@@ -183,9 +180,10 @@ taos> alter dnode 3 balance "vnode:18-dnode:1";
DB error: Balance already enabled (0.00755 DB error: Balance already enabled (0.00755
``` ```
上面的结果表明目前所在数据库已经启动了 balance 选项,所以无法进行手动迁移。 However, the operation fails with error message show above, which means automatic load balancing has been enabled in the current database so manual load balance can't be performed.
Shutdown the cluster, configure `balance` parameter in all the dnodes to 0, then restart the cluster, and execute `alter dnode` and `show vgroups` as below.
停止整个集群,将两个 dnode 的配置文件中的 balance 都设置为 0 (默认为1)之后,重新启动集群,再次执行 ` alter dnode``show vgroups` 命令如下
``` ```
taos> alter dnode 3 balance "vnode:18-dnode:1"; taos> alter dnode 3 balance "vnode:18-dnode:1";
Query OK, 0 row(s) in set (0.000575s) Query OK, 0 row(s) in set (0.000575s)
...@@ -204,13 +202,12 @@ taos> show vgroups; ...@@ -204,13 +202,12 @@ taos> show vgroups;
Query OK, 8 row(s) in set (0.001242s) Query OK, 8 row(s) in set (0.001242s)
``` ```
从上面的输出可以看到 vgId 为 18 的 vnode 被从 dnode 3 迁移到了 dnode 1。 It can be seen from above output that vgId 18 has been moved from dndoe 3 to dnode 1.
:::warning :::note
只有在集群的自动负载均衡选项关闭时(balance 设置为 0),才允许手动迁移。 - Manual load balancing can only be performed when the automatic load balancing is disabled, i.e. `balance` is set to 0 只.
只有处于正常工作状态的 vnode 才能被迁移:master/slave;当处于 offline/unsynced/syncing 状态时,是不能迁移的。 - Only vnode in normal state, i.e. master or slave, can be moved. vnode can't moved when its in status offline, unsynced or syncing.
迁移前,务必核实目标 dnode 的资源足够:CPU、内存、硬盘。 - Before moving a vnode, it's necessary to make sure the target dnode has enough resources: CPU, memory and disk.
::: :::
--- ---
title: 高可用与负载均衡 sidebar_label: HA & LB
title: High Availability and Load Balancing
--- ---
## Vnode 的高可用性 ## High Availability of Vnode
TDengine 通过多副本的机制来提供系统的高可用性,包括 vnode 和 mnode 的高可用性。 High availability of vnode and mnode can be achieved through replicas in TDengine.
vnode 的副本数是与 DB 关联的,一个集群里可以有多个 DB,根据运营的需求,每个 DB 可以配置不同的副本数。创建数据库时,通过参数 replica 指定副本数(缺省为 1)。如果副本数为 1,系统的可靠性无法保证,只要数据所在的节点宕机,就将无法提供服务。集群的节点数必须大于等于副本数,否则创建表时将返回错误“more dnodes are needed”。比如下面的命令将创建副本数为 3 的数据库 demo: The number of vnodes is associated with each DB, there can be multiple DBs in a TDengine cluster. For the purpose of operation, different number of replicas can be configured properly for each DB. When creating a database, the parameter `replica` is used to specify the number of replicas, the default value is 1. With single replica, the reliability of the system can't be guaranteed. Whenever one node is down, data service would be unavailable. The number of dnodes in the cluster must NOT be lower than the number of replicas set for any DB, otherwise the `create table` operation would fail with error "more dnodes are needed". Below SQL statement is used to create a database named as "demo" with 3 replicas.
```sql ```sql
CREATE DATABASE demo replica 3; CREATE DATABASE demo replica 3;
``` ```
一个 DB 里的数据会被切片分到多个 vnode group,vnode group 里的 vnode 数目就是 DB 的副本数,同一个 vnode group 里各 vnode 的数据是完全一致的。为保证高可用性,vnode group 里的 vnode 一定要分布在不同的数据节点 dnode 里(实际部署时,需要在不同的物理机上),只要一个 vnode group 里超过半数的 vnode 处于工作状态,这个 vnode group 就能正常的对外服务。 The data in a DB is divided into multiple shards and stored in multiple vgroups. The number of vnodes in each group is determined by the number of replicas set for the DB. The vnodes in each vgroups store exactly same data. For the purpose of high availability, the vnodes in a vgroup must be located in different dnodes on different hosts. As long as over half of the vnodes in a vgroup are in online state, the vgroup is able to serve data access. Otherwise the vgroup can't handle any data access for reading or inserting data.
一个数据节点 dnode 里可能有多个 DB 的数据,因此一个 dnode 离线时,可能会影响到多个 DB。如果一个 vnode group 里的一半或一半以上的 vnode 不工作,那么该 vnode group 就无法对外服务,无法插入或读取数据,这样会影响到它所属的 DB 的一部分表的读写操作。 There may be data for multiple DBs in a dnode. Once a dnode is down, multiple DBs may be affected. However, it's hard to say the cluster is guaranteed to work properly as long as over half of dnodes are online because vnodes are introduced and there may be complex mapping between vnodes and dnodes.
因为 vnode 的引入,无法简单地给出结论:“集群中过半数据节点 dnode 工作,集群就应该工作”。但是对于简单的情形,很好下结论。比如副本数为 3,只有三个 dnode,那如果仅有一个节点不工作,整个集群还是可以正常工作的,但如果有两个数据节点不工作,那整个集群就无法正常工作了。 ## High Availability of Mnode
## Mnode 的高可用性 Each TDengine cluster is managed by `mnode`, which is a module of `taosd`. For the high availability of mnode, multiple mnodes can be configured using system parameter `numOfMNodes`, the valid time range is [1,3]. To make sure the data consistency between mnodes, the data replication between mnodes is performed in synchronous way.
TDengine 集群是由 mnode(taosd 的一个模块,管理节点)负责管理的,为保证 mnode 的高可用,可以配置多个 mnode 副本,副本数由系统配置参数 numOfMnodes 决定,有效范围为 1-3。为保证元数据的强一致性,mnode 副本之间是通过同步的方式进行数据复制的。 There may be multiple dnodes in a cluster, but only one mnode can be started in each dnode. Which one or ones of the dnodes will be designated as mnodes is automatically determined by TDengine according to the cluster configuration and system resources. Command `show mnodes` can be executed in TDengine `taos` to show the mnodes in the cluster.
一个集群有多个数据节点 dnode,但一个 dnode 至多运行一个 mnode 实例。多个 dnode 情况下,哪个 dnode 可以作为 mnode 呢?这是完全由系统根据整个系统资源情况,自动指定的。用户可通过 CLI 程序 taos,在 TDengine 的 console 里,执行如下命令:
```sql ```sql
SHOW MNODES; SHOW MNODES;
``` ```
来查看 mnode 列表,该列表将列出 mnode 所处的 dnode 的 End Point 和角色(master,slave,unsynced 或 offline)。当集群中第一个数据节点启动时,该数据节点一定会运行一个 mnode 实例,否则该数据节点 dnode 无法正常工作,因为一个系统是必须有至少一个 mnode 的。如果 numOfMnodes 配置为 2,启动第二个 dnode 时,该 dnode 也将运行一个 mnode 实例。 The end point and role/status (master, slave, unsynced, or offline) of all mnodes can be shown by the above command. When the first dnode is started in a cluster, there must be one mnode in this dnode, because there must be at least one mnode otherwise the cluster doesn't work. If `numOfMNodes` is configured to 2, another mnode will be started when the second dnode is launched.
为保证 mnode 服务的高可用性,numOfMnodes 必须设置为 2 或更大。因为 mnode 保存的元数据必须是强一致的,如果 numOfMnodes 大于 2,复制参数 quorum 自动设为 2,也就是说,至少要保证有两个副本写入数据成功,才通知客户端应用写入成功。 For the high availability of mnode, `numOfMnodes` needs to be configured to 2 or a higher value. Because the data consistency between mnodes must be guaranteed, the replica confirmation parameter `quorum` is set to 2 automatically if `numOfMNodes` is set to 2 or higher.
:::note :::note
一个 TDengine 高可用系统,无论是 vnode 还是 mnode,都必须配置多个副本。 If high availability is important for your system, both vnode and mnode must be configured to have multiple replicas. How to configure for them are different and have been described.
::: :::
## 负载均衡 ## Load Balance
有三种情况,将触发负载均衡,而且都无需人工干预。
当一个新数据节点添加进集群时,系统将自动触发负载均衡,一些节点上的数据将被自动转移到新数据节点上,无需任何人工干预。 Load balance will be triggered in 3 cades without manual intervention.
当一个数据节点从集群中移除时,系统将自动把该数据节点上的数据转移到其他数据节点,无需任何人工干预。
如果一个数据节点过热(数据量过大),系统将自动进行负载均衡,将该数据节点的一些 vnode 自动挪到其他节点。
当上述三种情况发生时,系统将启动各个数据节点的负载计算,从而决定如何挪动。
:::tip - When a new dnode is joined in the cluster, automatic load balancing may be triggered, some data from some dnodes may be transferred to the new dnode automatically.当
负载均衡由参数 balance 控制,它决定是否启动自动负载均衡,0 表示禁用,1 表示启用自动负载均衡。 - When a dnode is removed from the cluster, the data from this dnode will be transferred to other dnodes automatically.
- When a dnode is too hot, i.e. too much data has been stored in it, automatic load balancing may be triggered to migrate some vnodes from this dnode to other dnodes.
- :::tip
Automatic load balancing is controlled by parameter `balance`, 0 means disabled and 1 means enabled.
::: :::
## 数据节点离线处理 ## Dnode Offline
如果一个数据节点离线,TDengine 集群将自动检测到。有如下两种情况: When a dnode is offline, it can be detected by the TDengine cluster. There are two cases:
该数据节点离线超过一定时间(taos.cfg 里配置参数 offlineThreshold 控制时长),系统将自动把该数据节点删除,产生系统报警信息,触发负载均衡流程。如果该被删除的数据节点重新上线时,它将无法加入集群,需要系统管理员重新将其添加进集群才会开始工作。 - The dnode becomes online again before the threshold configured in `offlineThreshold` is reached, it is still in the cluster and data replication is started automatically. The dnode can work properly after the data syncup is finished.
离线后,在 offlineThreshold 的时长内重新上线,系统将自动启动数据恢复流程,等数据完全恢复后,该节点将开始正常工作。 - If the dnode has been offline over the threshold configured in `offlineThreshold` in `taos.cfg`, the dnode will be removed from the cluster automatically. System alert will be generated and automatic load balancing will be triggered too if `balance` is set to 1. When the removed dnode is restarted and becomes online, it will not be joined in the cluster automatically, it can only be joined manually by the system operator.
:::note :::note
如果一个虚拟节点组(包括 mnode 组)里所归属的每个数据节点都处于离线或 unsynced 状态,必须等该虚拟节点组里的所有数据节点都上线、都能交换状态信息后,才能选出 Master,该虚拟节点组才能对外提供服务。比如整个集群有 3 个数据节点,副本数为 3,如果 3 个数据节点都宕机,然后 2 个数据节点重启,是无法工作的,只有等 3 个数据节点都重启成功,才能对外服务。 If all the vnodes in a vgroup (or mnodes in mnode group) are in offline or unsynced status, the master node can only be voted after all the vnodes or mnodes in the group become online and can exchange status, then the vgroup (or mnode group) is able to provide service.
::: :::
## Arbitrator 的使用 ## Arbitrator
如果副本数为偶数,当一个 vnode group 里一半或超过一半的 vnode 不工作时,是无法从中选出 master 的。同理,一半或超过一半的 mnode 不工作时,是无法选出 mnode 的 master 的,因为存在“split brain”问题。
为解决这个问题,TDengine 引入了 Arbitrator 的概念。Arbitrator 模拟一个 vnode 或 mnode 在工作,但只简单的负责网络连接,不处理任何数据插入或访问。只要包含 Arbitrator 在内,超过半数的 vnode 或 mnode 工作,那么该 vnode group 或 mnode 组就可以正常的提供数据插入或查询服务。比如对于副本数为 2 的情形,如果一个节点 A 离线,但另外一个节点 B 正常,而且能连接到 Arbitrator,那么节点 B 就能正常工作。 If the number of replicas is set to an even number like 2, when half of the vnodes in a vgroup don't work master node can't be voted. Similar case is also applicable to mnode if the number of mnodes is set to an even number like 2.
总之,在目前版本下,TDengine 建议在双副本环境要配置 Arbitrator,以提升系统的可用性。 To resolve this problem, a new arbitrator component named `tarbitrator`, abbreviated for TDengine Arbitrator, was introduced. Arbitrator simulates a vnode or mnode but it's only responsible for network communication and doesn't handle any actual data access. With Arbitrator, any vgroup or mnode group can be considered as having number of member nodes and master node can be selected.
Arbitrator 的执行程序名为 tarbitrator。该程序对系统资源几乎没有要求,只需要保证有网络连接,找任何一台 Linux 服务器运行它即可。以下简要描述安装配置的步骤: Normally, it's suggested to configure replica number of each DB or system parameter `numOfMNodes` to an odd number. However, if a user is very sensitive to storage space, replica number of 2 plus arbitrator component can be used to achieve both lower cost of storage space and high availability.
请点击 安装包下载,在 TDengine Arbitrator Linux 一节中,选择合适的版本下载并安装。 Arbitrator component is installed with the server package. For details about how to install, please refer to [Install](/operation/pkg-install). The `-p` parameter of `tarbitrator` can be used to specify the port on which it provides service.
该应用的命令行参数 -p 可以指定其对外服务的端口号,缺省是 6042。
修改每个 taosd 实例的配置文件,在 taos.cfg 里将参数 arbitrator 设置为 tarbitrator 程序所对应的 End Point。(如果该参数配置了,当副本数为偶数时,系统将自动连接配置的 Arbitrator。如果副本数为奇数,即使配置了 Arbitrator,系统也不会去建立连接。) In the configuration file `taos.cfg` of each dnode, parameter `arbitrator` needs to be configured to the end point of the `tarbitrator` process. arbitrator component will be used automatically if the replica is configured to an even number and will be ignored if the replica is configured to an odd number.
在配置文件中配置了的 Arbitrator,会出现在 SHOW DNODES 指令的返回结果中,对应的 role 列的值会是“arb”。 Arbitrator can be shown by executing command in TDengine CLI `taos` with its role shown as "arb".
查看集群 Arbitrator 的状态【2.0.14.0 以后支持】
```sql ```sql
SHOW DNODES; SHOW DNODES;
......
label: 集群管理 label: Cluster
link: link:
type: generated-index type: generated-index
slug: /cluster/ slug: /cluster/
description: "TDengine支持以集群方式部署,以提升系统的处理能力和高可用性。TDengine集群支持任意数据的多副本从而提升高可用性,并自动实现负载均衡。同时TDengine集群具有很好的横向扩展能力以处理更多的数据采集点和更大的数据量。" description: "TDengine can be deployed in cluster mode to increase the processing capability and high availability. In cluster mode, any data can have multiple replications for the purpose of high availability and load balance. TDengine cluster can be scaled out easily to support more data collecting points and more data."
keywords: keywords:
[ [
集群, cluster,
高可用, high availability,
负载均衡, load balance,
横向扩展 scale out
] ]
--- ---
sidebar_label: 支持的数据类型 sidebar_label: Data Types
title: 支持的数据类型 title: Data Types
description: "TDengine 支持的数据类型: 时间戳、浮点型、JSON 类型等" description: "The data types supported by TDengine include timestamp, float, JSON, etc"
--- ---
使用 TDengine,最重要的是时间戳。创建并插入记录、查询历史记录的时候,均需要指定时间戳。时间戳有如下规则: When using TDengine to store and query data, the most important part of the data is timestamp. Timestamp must be specified when creating and inserting data rows or querying data, timestamp must follow below rules:
- 时间格式为 `YYYY-MM-DD HH:mm:ss.MS`,默认时间分辨率为毫秒。比如:`2017-08-12 18:25:58.128` - the format must be `YYYY-MM-DD HH:mm:ss.MS`, the default time precision is millisecond (ms), for example `2017-08-12 18:25:58.128`
- 内部函数 now 是客户端的当前时间 - internal function `now` can be used to get the current timestamp of the client side
- 插入记录时,如果时间戳为 now,插入数据时使用提交这条记录的客户端的当前时间 - the current timestamp of the client side is applied when `now` is used to insert data
- Epoch Time:时间戳也可以是一个长整数,表示从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始的毫秒数(相应地,如果所在 Database 的时间精度设置为“微秒”,则长整型格式的时间戳含义也就对应于从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始的微秒数;纳秒精度逻辑类似。) - Epoch Time:timestamp can also be a long integer number, which means the number of seconds, milliseconds or nanoseconds, depending on the time precision, from 1970-01-01 00:00:00.000 (UTC/GMT)
- 时间可以加减,比如 now-2h,表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 b(纳秒)、u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。 比如 `select * from t1 where ts > now-2w and ts <= now-1w`,表示查询两周前整整一周的数据。在指定降采样操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n (自然月) 和 y (自然年)。 - timestamp can be applied with add/substract operation, for example `now-2h` means 2 hours back from the time at which query is executed,the unit can be b(nanosecond), u(microsecond), a(millisecond), s(second), m(minute), h(hour), d(day), w(week.。 So `select * from t1 where ts > now-2w and ts <= now-1w` means the data between two weeks ago and one week ago. The time unit can also be n (calendar month) or y (calendar year) when specifying the time window for down sampling operation.
TDengine 缺省的时间戳精度是毫秒,但通过在 `CREATE DATABASE` 时传递的 PRECISION 参数也可以支持微秒和纳秒。(从 2.1.5.0 版本开始支持纳秒精度) Time precision in TDengine can be set by the `PRECISION` parameter when executing `CREATE DATABASE`, like below, the default time precision is millisecond.
```sql ```sql
CREATE DATABASE db_name PRECISION 'ns'; CREATE DATABASE db_name PRECISION 'ns';
``` ```
在 TDengine 中,普通表的数据模型中可使用以下 10 种数据类型。 In TDengine, below data types can be used when specifying a column or tag.
| # | **类型** | **Bytes** | **说明** | | # | **类型** | **Bytes** | **说明** |
| --- | :-------: | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --- | :-------: | --------- | ------------------------- |
| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒和纳秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18.0 版本开始,已经去除了这一时间范围限制)(从 2.1.5.0 版本开始支持纳秒精度) | | 1 | TIMESTAMP | 8 | Default precision is millisecond, microsecond and nanosecond are also supported |
| 2 | INT | 4 | 整型,范围 [-2^31+1, 2^31-1], -2^31 用作 NULL | | 2 | INT | 4 | Integer, the value range is [-2^31+1, 2^31-1], while -2^31 is treated as NULL |
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用作 NULL | | 3 | BIGINT | 8 | Long integer, the value range is [-2^63+1, 2^63-1], while -2^63 is treated as NULL |
| 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] | | 4 | FLOAT | 4 | Floating point number, the effective number of digits is 6-7, the value range is [-3.4E38, 3.4E38] |
| 5 | DOUBLE | 8 | 双精度浮点型,有效位数 15-16,范围 [-1.7E308, 1.7E308] | | 5 | DOUBLE | 8 | double precision floating point number, the effective number of digits is 15-16, the value range is [-1.7E308, 1.7E308] |
| 6 | BINARY | 自定义 | 记录单字节字符串,建议只用于处理 ASCII 可见字符,中文等多字节字符需使用 nchar。理论上,最长可以有 16374 字节。binary 仅支持字符串输入,字符串两端需使用单引号引用。使用时须指定大小,如 binary(20) 定义了最长为 20 个单字节字符的字符串,每个字符占 1 byte 的存储空间,总共固定占用 20 bytes 的空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’` | | 6 | BINARY | User Defined | Single-byte string for ASCII visible characters. Length must be specified when defining a column or tag of binary type. The string length can be up to 16374 bytes. The string value must be quoted with single quotes. The literal single quote inside the string must be preceded with back slash like `\'` |
| 7 | SMALLINT | 2 | 短整型, 范围 [-32767, 32767], -32768 用作 NULL | | 7 | SMALLINT | 2 | Short integer, the value range is [-32767, 32767], while -32768 is treated as NULL |
| 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128 用作 NULL | | 8 | TINYINT | 1 | Single-byte integer, the value range is [-127, 127], while -128 is treated as NLLL |
| 9 | BOOL | 1 | 布尔型,{true, false} | | 9 | BOOL | 1 | Bool, the value range is {true, false} |
| 10 | NCHAR | 自定义 | 记录包含多字节字符在内的字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 | | 10 | NCHAR | User Defined| Multiple-Byte string that can include like Chinese characters. Each character of NCHAR type consumes 4 bytes storage. The string value should be quoted with single quotes. Literal single quote inside the string must be preceded with backslash, like `\’`. The length must be specified when defining a column or tag of NCHAR type, for example nchar(10) means it can store at most 10 characters of nchar type and will consume fixed storage of 40 bytes. Error will be reported the string value exceeds the length defined. |
| 11 | JSON | | json 数据类型, 只有 tag 可以是 json 格式 | | 11 | JSON | | json type can only be used on tag, a tag of json type is excluded with any other tags of any other type |
:::tip :::tip
TDengine 对 SQL 语句中的英文字符不区分大小写,自动转化为小写执行。因此用户大小写敏感的字符串及密码,需要使用单引号将字符串引起来。 TDengine is case insensitive and treats any characters in the sql command as lower case by default, case sensitive strings must be quoted with single quotes.
::: :::
:::note :::note
虽然 BINARY 类型在底层存储上支持字节型的二进制字符,但不同编程语言对二进制数据的处理方式并不保证一致,因此建议在 BINARY 类型中只存储 ASCII 可见字符,而避免存储不可见字符。多字节的数据,例如中文字符,则需要使用 NCHAR 类型进行保存。如果强行使用 BINARY 类型保存中文字符,虽然有时也能正常读写,但并不带有字符集信息,很容易出现数据乱码甚至数据损坏等情况。 Only ASCII visible characters are suggested to be used in a column or tag of BINARY type. Multiple-byte characters must be stored in NCHAR type.
::: :::
:::note :::note
SQL 语句中的数值类型将依据是否存在小数点,或使用科学计数法表示,来判断数值类型是否为整型或者浮点型,因此在使用时要注意相应类型越界的情况。例如,9999999999999999999 会认为超过长整型的上边界而溢出,而 9999999999999999999.0 会被认为是有效的浮点数。 Numeric values in SQL statements will be determined as integer or float type according to whether there is decimal point or whether scientific notation is used, so attention must be paid to avoid overflow. For example, 9999999999999999999 will be considered as overflow because it exceeds the upper limit of long integer, but 9999999999999999999.0 will be considered as a legal float number.
::: :::
--- ---
sidebar_label: 数据库管理 sidebar_label: Database
title: 数据库管理 title: Database
description: "创建、删除数据库,查看、修改数据库参数" description: "create and drop database, show or change database parameters"
--- ---
## 创建数据库 ## Create Datable
``` ```
CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1]; CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1];
``` ```
:::info :::info
1. KEEP 是该数据库的数据保留多长天数,缺省是 3650 天(10 年),数据库会自动删除超过时限的数据;<!-- REPLACE_OPEN_TO_ENTERPRISE__KEEP_PARAM_DESCRIPTION -->
2. UPDATE 标志数据库支持更新相同时间戳数据;(从 2.1.7.0 版本开始此参数支持设为 2,表示允许部分列更新,也即更新数据行时未被设置的列会保留原值。)(从 2.0.8.0 版本开始支持此参数。注意此参数不能通过 `ALTER DATABASE` 指令进行修改。) 1. KEEP specifies the number of days for which the data in the database to be created will be kept, the default value is 3650 days, i.e. 10 years. The data will be deleted automatically once its age exceeds this threshold.
1. UPDATE 设为 0 时,表示不允许更新数据,后发送的相同时间戳的数据会被直接丢弃; 2. UPDATE specifies whether the data can be updated and how the data can be updated.
2. UPDATE 设为 1 时,表示更新全部列数据,即如果更新一个数据行,其中某些列没有提供取值,那么这些列会被设为 NULL; 1. UPDATE set to 0 means update operation is not allowed, the data with an existing timestamp will be dropped silently.
3. UPDATE 设为 2 时,表示支持更新部分列数据,即如果更新一个数据行,其中某些列没有提供取值,那么这些列会保持原有数据行中的对应值; 2. UPDATE set to 1 means the whole row will be updated, the columns for which no value is specified will be set to NULL
4. 更多关于 UPDATE 参数的用法,请参考[FAQ](/train-faq/faq) 3. UPDATE set to 2 means updating a part of columns for a row is allowed, the columns for which no value is specified will be kept as no change
3. 数据库名最大长度为 33; 3. The maximum length of database name is 33 bytes.
4. 一条 SQL 语句的最大长度为 65480 个字符; 4. The maximum length of a SQL statement is 65,480 bytes.
5. 数据库还有更多与数据库相关的配置参数,如 cache, blocks, days, keep, minRows, maxRows, wal, fsync, update, cacheLast, replica, quorum, maxVgroupsPerDb, ctime, comp, prec, 具体细节请参见 [配置参数](/reference/config/) 章节。 5. For more parameters that can be used when creating a database, like cache, blocks, days, keep, minRows, maxRows, wal, fsync, update, cacheLast, replica, quorum, maxVgroupsPerDb, ctime, comp, prec, Please refer to [Configuration Parameters](/reference/config/).
::: :::
## 显示系统当前参数 ## Show Current Configuration
``` ```
SHOW VARIABLES; SHOW VARIABLES;
``` ```
## 使用数据库 ## Specify The Database In Use
``` ```
USE db_name; USE db_name;
``` ```
使用/切换数据库(在 REST 连接方式下无效)。 :::note
This way is not applicable when using a REST connection
:::
## 删除数据库 ## Drop Database
``` ```
DROP DATABASE [IF EXISTS] db_name; DROP DATABASE [IF EXISTS] db_name;
``` ```
删除数据库。指定 Database 所包含的全部数据表将被删除,谨慎使用! :::note
All data in the database will be deleted too. This command must be used with caution.
:::
## Change Database Configuration
## 修改数据库参数 Some examples are shown below to demonstrate how to change the configuration of a database. Please be noted that some configuration parameters can be changed after the database is created, but some others can't, for details of the configuration parameters of database please refer to [Configuration Parameters](/reference/config/).
``` ```
ALTER DATABASE db_name COMP 2; ALTER DATABASE db_name COMP 2;
``` ```
COMP 参数是指修改数据库文件压缩标志位,缺省值为 2,取值范围为 [0, 2]。0 表示不压缩,1 表示一阶段压缩,2 表示两阶段压缩。 COMP parameter specifies whether the data is compressed and how the data is compressed.
``` ```
ALTER DATABASE db_name REPLICA 2; ALTER DATABASE db_name REPLICA 2;
``` ```
REPLICA 参数是指修改数据库副本数,取值范围 [1, 3]。在集群中使用,副本数必须小于或等于 DNODE 的数目。 REPLICA parameter specifies the number of replications of the database.
``` ```
ALTER DATABASE db_name KEEP 365; ALTER DATABASE db_name KEEP 365;
``` ```
KEEP 参数是指修改数据文件保存的天数,缺省值为 3650,取值范围 [days, 365000],必须大于或等于 days 参数值。 KEEP parameter specifies the number of days for which the data will be kept.
``` ```
ALTER DATABASE db_name QUORUM 2; ALTER DATABASE db_name QUORUM 2;
``` ```
QUORUM 参数是指数据写入成功所需要的确认数,取值范围 [1, 2]。对于异步复制,quorum 设为 1,具有 master 角色的虚拟节点自己确认即可。对于同步复制,quorum 设为 2。原则上,Quorum >= 1 并且 Quorum <= replica(副本数),这个参数在启动一个同步模块实例时需要提供。 QUORUM parameter specifies the necessary number of confirmations to determine whether the data is written successfully.
``` ```
ALTER DATABASE db_name BLOCKS 100; ALTER DATABASE db_name BLOCKS 100;
``` ```
BLOCKS 参数是每个 VNODE (TSDB) 中有多少 cache 大小的内存块,因此一个 VNODE 的用的内存大小粗略为(cache \* blocks)。取值范围 [3, 1000]。 BLOCKS parameter specifies the number of memory blocks used by each VNODE.
``` ```
ALTER DATABASE db_name CACHELAST 0; ALTER DATABASE db_name CACHELAST 0;
``` ```
CACHELAST 参数控制是否在内存中缓存子表的最近数据。缺省值为 0,取值范围 [0, 1, 2, 3]。其中 0 表示不缓存,1 表示缓存子表最近一行数据,2 表示缓存子表每一列的最近的非 NULL 值,3 表示同时打开缓存最近行和列功能。(从 2.0.11.0 版本开始支持参数值 [0, 1],从 2.1.2.0 版本开始支持参数值 [0, 1, 2, 3]。) CACHELAST parameter specifies whether and how the latest data of a sub table is cached.
说明:缓存最近行,将显著改善 LAST_ROW 函数的性能表现;缓存每列的最近非 NULL 值,将显著改善无特殊影响(WHERE、ORDER BY、GROUP BY、INTERVAL)下的 LAST 函数的性能表现。
:::tip :::tip
以上所有参数修改后都可以用 show databases 来确认是否修改成功。另外,从 2.1.3.0 版本开始,修改这些参数后无需重启服务器即可生效。 The above parameters can be changed using `ALTER DATABASE` command without restarting. For more details of all configuration parameters please refer to [Configuration Parameters](/reference/config/).
:::tip
## 显示系统所有数据库 :::
## Show All Databases
``` ```
SHOW DATABASES; SHOW DATABASES;
``` ```
## 显示一个数据库的创建语句 ## Show The Create Statement of A Database
``` ```
SHOW CREATE DATABASE db_name; SHOW CREATE DATABASE db_name;
``` ```
常用于数据库迁移。对一个已经存在的数据库,返回其创建语句;在另一个集群中执行该语句,就能得到一个设置完全相同的 Database。 This command is useful when migrating the data from one TDengine cluster to another one. Firstly this command can be used to get the CREATE statement, which in turn can be used in another TDengine to create an exactly same database.
--- ---
title: 表管理 sidebar_label: Table
title: Table
description: create super table, normal table and sub table, drop tables and change tables
--- ---
## 创建数据表 ## Create Table
``` ```
CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]); CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]);
``` ```
:::info 说明 :::info
1. 表的第一个字段必须是 TIMESTAMP,并且系统自动将其设为主键; 1. The first column of a table must be in TIMESTAMP type, and it will be set as primary key automatically
2. 表名最大长度为 192; 2. The maximum length of table name is 192 bytes.
3. 表的每行长度不能超过 16k 个字符;(注意:每个 BINARY/NCHAR 类型的列还会额外占用 2 个字节的存储位置) 3. The maximum length of each row is 16k bytes, please be notes that the extra 2 bytes used by each BINARY/NCHAR column are also counted in.
4. 子表名只能由字母、数字和下划线组成,且不能以数字开头,不区分大小写 4. The name of sub-table can only be consisted of English characters, digits and underscore, and can't be started with digit. Table names are case insensitive.
5. 使用数据类型 binary 或 nchar,需指定其最长的字节数,如 binary(20),表示 20 字节; 5. The maximum length in bytes must be specified when using BINARY or NCHAR type.
6. 为了兼容支持更多形式的表名,TDengine 引入新的转义符 "\`",可以让表名与关键词不冲突,同时不受限于上述表名称合法性约束检查。但是同样具有长度限制要求。使用转义字符以后,不再对转义字符中的内容进行大小写统一。 6. Escape character "\`" can be used to avoid the conflict between table names and reserved keywords, above rules will be bypassed when using escape character on table names, but the upper limit for name length is still valid. The table names specified using escape character are case sensitive. Only ASCII visible characters can be used with escape character.
例如:\`aBc\`\`abc\` 是不同的表名,但是 abc 和 aBc 是相同的表名。 For example \`aBc\` and \`abc\` are different table names but `abc` and `aBc` are same table names because they are both converted to `abc` internally.
需要注意的是转义字符中的内容必须是可打印字符。
上述的操作逻辑和约束要求与 MySQL 数据的操作一致。
从 2.3.0.0 版本开始支持这种方式。
::: :::
### 以超级表为模板创建数据表 ### Create Table Using STable As Template
``` ```
CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...); CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
``` ```
以指定的超级表为模板,指定 TAGS 的值来创建数据表。 The above command creates a sub table using the specified super table as template and the specified tab values.
### 以超级表为模板创建数据表,并指定具体的 TAGS 列 ### Create Table Using STable As Template With A Part of Tags
``` ```
CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...); CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
``` ```
以指定的超级表为模板,指定一部分 TAGS 列的值来创建数据表(没被指定的 TAGS 列会设为空值)。 The tags for which no value is specified will be set to NULL.
说明:从 2.0.17.0 版本开始支持这种方式。在之前的版本中,不允许指定 TAGS 列,而必须显式给出所有 TAGS 列的取值。
### 批量创建数据表 ### Create Tables in Batch
``` ```
CREATE TABLE [IF NOT EXISTS] tb_name1 USING stb_name TAGS (tag_value1, ...) [IF NOT EXISTS] tb_name2 USING stb_name TAGS (tag_value2, ...) ...; CREATE TABLE [IF NOT EXISTS] tb_name1 USING stb_name TAGS (tag_value1, ...) [IF NOT EXISTS] tb_name2 USING stb_name TAGS (tag_value2, ...) ...;
``` ```
以更快的速度批量创建大量数据表(服务器端 2.0.14 及以上版本)。 This way can be used to create a lot of tables in a single SQL statement to accelerate the speed of the creating tables.
:::info :::info
1.批量建表方式要求数据表必须以超级表为模板。 2.在不超出 SQL 语句长度限制的前提下,单条语句中的建表数量建议控制在 1000 ~ 3000 之间,将会获得比较理想的建表速度。 - Creating tables in batch must use super table as template.
- The length of single statement is suggested to be between 1,000 and 3,000 bytes for best performance.
::: :::
## 删除数据表 ## Drop Tables
``` ```
DROP TABLE [IF EXISTS] tb_name; DROP TABLE [IF EXISTS] tb_name;
``` ```
## 显示当前数据库下的所有数据表信息 ## Show All Tables In Current Database
``` ```
SHOW TABLES [LIKE tb_name_wildcar]; SHOW TABLES [LIKE tb_name_wildcar];
``` ```
显示当前数据库下的所有数据表信息。 ## Show Create Statement of A Table
## 显示一个数据表的创建语句
``` ```
SHOW CREATE TABLE tb_name; SHOW CREATE TABLE tb_name;
``` ```
常用于数据库迁移。对一个已经存在的数据表,返回其创建语句;在另一个集群中执行该语句,就能得到一个结构完全相同的数据表。 This way is useful when migrating the data in one TDengine cluster to another one because it can be used to create exactly same tables in the target database.
## 获取表的结构信息 ## Show Table Definition
``` ```
DESCRIBE tb_name; DESCRIBE tb_name;
``` ```
## 修改表定义 ## Change Table Definition
### 表增加列 ### Add A Column
``` ```
ALTER TABLE tb_name ADD COLUMN field_name data_type; ALTER TABLE tb_name ADD COLUMN field_name data_type;
...@@ -93,31 +89,39 @@ ALTER TABLE tb_name ADD COLUMN field_name data_type; ...@@ -93,31 +89,39 @@ ALTER TABLE tb_name ADD COLUMN field_name data_type;
:::info :::info
1. 列的最大个数为 1024,最小个数为 2;(从 2.1.7.0 版本开始,改为最多允许 4096 列) 1. The maximum number of columns is 4096, the minimum number of columns is 2.
2. 列名最大长度为 64。 2. The maximum length of column name is 64 bytes.
::: :::
### 表删除列 ### Remove A Column
``` ```
ALTER TABLE tb_name DROP COLUMN field_name; ALTER TABLE tb_name DROP COLUMN field_name;
``` ```
如果表是通过超级表创建,更改表结构的操作只能对超级表进行。同时针对超级表的结构更改对所有通过该结构创建的表生效。对于不是通过超级表创建的表,可以直接修改表结构。 :::note
If a table is created using a super table as template, the table definition can only be changed on the corresponding super table, but the change will be automatically applied to all the sub tables created using this super table as template. For tables created in normal way, the table definition can be changed directly on the table.
:::
### 表修改列宽 ### Change Column Length
``` ```
ALTER TABLE tb_name MODIFY COLUMN field_name data_type(length); ALTER TABLE tb_name MODIFY COLUMN field_name data_type(length);
``` ```
如果数据列的类型是可变长格式(BINARY 或 NCHAR),那么可以使用此指令修改其宽度(只能改大,不能改小)。(2.1.3.0 版本新增) The the type of a column is variable length, like BINARY or NCHAR, this way can be used to change (or increase) the length of the column.
如果表是通过超级表创建,更改表结构的操作只能对超级表进行。同时针对超级表的结构更改对所有通过该结构创建的表生效。对于不是通过超级表创建的表,可以直接修改表结构。
### 修改子表标签值 :::note
If a table is created using a super table as template, the table definition can only be changed on the corresponding super table, but the change will be automatically applied to all the sub tables created using this super table as template. For tables created in normal way, the table definition can be changed directly on the table.
:::
### Change Tag Value Of Sub Table
``` ```
ALTER TABLE tb_name SET TAG tag_name=new_tag_value; ALTER TABLE tb_name SET TAG tag_name=new_tag_value;
``` ```
如果表是通过超级表创建,可以使用此指令修改其标签值
This command can be used to change the tag value if the table is created using a super table as template.
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
--- ---
sidebar_label: 边界限制 sidebar_label: Limits
title: 边界限制 title: Limits and Restrictions
--- ---
## 一般限制 ## Naming Rules
- 数据库名最大长度为 32。 1. Only English characters, digits and underscore are allowed
- 表名最大长度为 192,不包括数据库名前缀和分隔符 2. Can't be started with digits
- 每行数据最大长度 16k 个字符, 从 2.1.7.0 版本开始,每行数据最大长度 48k 个字符(注意:数据行内每个 BINARY/NCHAR 类型的列还会额外占用 2 个字节的存储位置)。 3. Case Insensitive without escape character "\`"
- 列名最大长度为 64,最多允许 4096 列,最少需要 2 列,第一列必须是时间戳。注:从 2.1.7.0 版本(不含)以前最多允许 4096 列 4. Identifier with escape character "\`"
- 标签名最大长度为 64,最多允许 128 个,至少要有 1 个标签,一个表中标签值的总长度不超过 16k 个字符。 To support more flexible table or column names, a new escape character "\`" is introduced. For more details please refer to [escape](/taos-sql/escape).
- SQL 语句最大长度 1048576 个字符,也可通过客户端配置参数 maxSQLLength 修改,取值范围 65480 ~ 1048576。
- SELECT 语句的查询结果,最多允许返回 4096 列(语句中的函数调用可能也会占用一些列空间),超限时需要显式指定较少的返回数据列,以避免语句执行报错。注: 2.1.7.0 版本(不含)之前为最多允许 1024 列
- 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制。
## GROUP BY 的限制 ## Password Rule
TAOS SQL 支持对标签、TBNAME 进行 GROUP BY 操作,也支持普通列进行 GROUP BY,前提是:仅限一列且该列的唯一值小于 10 万个。注意:group by 不支持 float,double 类型。 The legal character set is `[a-zA-Z0-9!?$%^&*()_–+={[}]:;@~#|<,>.?/]`.
## IS NOT NULL 的限制 ## General Limits
IS NOT NULL 与不为空的表达式适用范围。 - Maximum length of database name is 32 bytes
- Maximum length of table name is 192 bytes, excluding the database name prefix and the separator
- Maximum length of each data row is 48K bytes from version 2.1.7.0 , before which the limit is 16K bytes. Please be noted that the upper limit includes the extra 2 bytes consumed by each column of BINARY/NCHAR type.
- Maximum of column name is 64.
- Maximum number of columns is 4096. There must be at least 2 columns, and the first column must be timestamp.
- Maximum length of tag name is 64.
- Maximum number of tags is 128. There must be at least 1 tag. The total length of tag values should not exceed 16K bytes.
- Maximum length of singe SQL statement is 1048576, i.e. 1 MB bytes. It can be configured in the parameter `maxSQLLength` in the client side, the applicable range is [65480, 1048576].
- At most 4096 columns (or 1024 prior to 2.1.7.0) can be returned by `SELECT`, functions in the query statement may constitute columns. Error will be returned if the limit is exceeded.
- Maximum numbers of databases, STables, tables are only depending on the system resources.
- Maximum of database name is 32 bytes, can't include "." and special characters.
- Maximum replica number of database is 3
- Maximum length of user name is 23 bytes
- Maximum length of password is 15 bytes
- Maximum number of rows depends on the storage space only.
- Maximum number of tables depends on the number of nodes only.
- Maximum number of databases depends on the number of nodes only.
- Maximum number of vnodes for single database is 64.
IS NOT NULL 支持所有类型的列。不为空的表达式为 <\>"",仅对非数值类型的列适用。 ## Restrictions of `GROUP BY`
## ORDER BY 的限制 `GROUP BY` can be performed on tags and `TBNAME`. It can be performed on data columns too, with one restriction that only one column and the number of unique values on that column is lower than 100,000. Please be noted that `GROUP BY` can't be performed on float or double type.
- 非超级表只能有一个 order by. ## Restrictions of `IS NOT NULL`
- 超级表最多两个 order by, 并且第二个必须为 ts.
- order by tag,必须和 group by tag 一起,并且是同一个 tag。 tbname 和 tag 一样逻辑。 只适用于超级表
- order by 普通列,必须和 group by 一起或者和 top/bottom 一起,并且是同一个普通列。 适用于超级表和普通表。如果同时存在 group by 和 top/bottom 一起,order by 优先必须和 group by 同一列。
- order by ts. 适用于超级表和普通表。
- order by ts 同时含有 group by 时 针对 group 内部用 ts 排序
## 表(列)名合法性说明 `IS NOT NULL` can be used on any data type of columns. The non-empty string evaluation expression, i.e. `<\>""` can only be used on non-numeric data types.
### TDengine 中的表(列)名命名规则如下: ## Restrictions of `ORDER BY`
只能由字母、数字、下划线构成,数字不能在首位,长度不能超过 192 字节,不区分大小写。这里表名称不包括数据库名的前缀和分隔符。
### 转义后表(列)名规则: - Only one `order by` is allowed for normal table and sub table.
为了兼容支持更多形式的表(列)名,TDengine 引入新的转义符 "`",可以避免表名与关键词的冲突,同时不受限于上述表名合法性约束检查,转义符不计入表名的长度。 - At most two `order by` are allowed for STable, and the second one must be `ts`.
转义后的表(列)名同样受到长度限制要求,且长度计算的时候不计算转义符。使用转义字符以后,不再对转义字符中的内容进行大小写统一。 - `order by tag` must be used with `group by tag` on same tag, this rule is also applicable to `tbname`.
- `order by column` must be used with `group by column` or `top/bottom` on same column. This rule is applicable to table and STable.
- `order by ts` is applicable to table and STable.
- If `order by ts` is used with `group by`, the result set is sorted using `ts` in each group.
例如: ## Restrictions of Table/Column Names
\`aBc\`\`abc\` 是不同的表(列)名,但是 abc 和 aBc 是相同的表(列)名。
### Name Restrictions of Table/Column
The name of a table or column can only be composed of ASCII characters, digits and underscore, while digit can't be used as the beginning. The maximum length is 192 bytes. Names are case insensitive. The name mentioned in this rule doesn't include the database name prefix and the separator.
### Name Restrictions After Escaping
To support more flexible table or column names, new escape character "`" is introduced in TDengine to avoid the conflict between table name and keywords and break the above restrictions for table name. The escape character is not counted in the length of table name.
With escaping, the string inside escape characters are case sensitive, i.e. will not be converted to lower case internally.
For example:
\`aBc\` and \`abc\` are different table or column names, but "abc" and "aBc" are same names because internally they are all "abc".
:::note :::note
转义字符中的内容必须是可打印字符。 The characters inside escape characters must be printable characters.
::: :::
### 支持版本 ### Applicable Versions
支持转义符的功能从 2.3.0.1 版本开始。
\ No newline at end of file Escape character "\`" is available from version 2.3.0.1.
此差异已折叠。
此差异已折叠。
label: 参数限制与保留关键字
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册