Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
709d045c
TDengine
项目概览
taosdata
/
TDengine
大约 1 年 前同步成功
通知
1181
Star
22014
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
709d045c
编写于
3月 12, 2021
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'develop' into feature/qrefactor
上级
3a6451d6
a618c58b
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
161 addition
and
27 deletion
+161
-27
documentation20/cn/11.administrator/docs.md
documentation20/cn/11.administrator/docs.md
+18
-18
documentation20/cn/12.taos-sql/docs.md
documentation20/cn/12.taos-sql/docs.md
+1
-1
src/connector/jdbc/pom.xml
src/connector/jdbc/pom.xml
+1
-0
src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java
...src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java
+130
-0
src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java
...c/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java
+11
-8
未找到文件。
documentation20/cn/11.administrator/docs.md
浏览文件 @
709d045c
...
...
@@ -2,52 +2,52 @@
## <a class="anchor" id="planning"></a>容量规划
使用
TDengine来搭建一个物联网大数据平台,计算资源、存储资源需要根据业务场景进行规划。下面分别讨论系统运行所需要的内存、CPU
以及硬盘空间。
使用
TDengine 来搭建一个物联网大数据平台,计算资源、存储资源需要根据业务场景进行规划。下面分别讨论系统运行所需要的内存、CPU
以及硬盘空间。
### 内存需求
每个
DB可以创建固定数目的vgroup,默认与CPU核数相同,可通过maxVgroupsPerDb配置;vgroup中的每个副本会是一个vnode;每个vnode会占用固定大小的内存(大小与数据库的配置参数blocks和cache有关);每个Table会占用与标签总长度有关的内存;此外,系统会有一些固定的内存开销。因此,每个DB
需要的系统内存可通过如下公式计算:
每个
DB 可以创建固定数目的 vgroup,默认与 CPU 核数相同,可通过 maxVgroupsPerDb 配置;vgroup 中的每个副本会是一个 vnode;每个 vnode 会占用固定大小的内存(大小与数据库的配置参数 blocks 和 cache 有关);每个 Table 会占用与标签总长度有关的内存;此外,系统会有一些固定的内存开销。因此,每个 DB
需要的系统内存可通过如下公式计算:
```
Memory Size = maxVgroupsPerDb * (blocks * cache + 10M
b) + numOfTables * (tagSizePerTable + 0.5Kb
)
Memory Size = maxVgroupsPerDb * (blocks * cache + 10M
B) + numOfTables * (tagSizePerTable + 0.5KB
)
```
示例:假设是
4核机器,cache是缺省大小16M, blocks是缺省值6,假设有10万张表,标签总长度是256字节,则总的内存需求为:4
\*
(16
\*
6+10) + 100000
\*
(0.25+0.5)/
1000 = 499M。
示例:假设是
4 核机器,cache 是缺省大小 16M, blocks 是缺省值 6,假设有 10 万张表,标签总长度是 256 字节,则总的内存需求为:4
\*
(16
\*
6 + 10) + 100000
\*
(0.25 + 0.5) /
1000 = 499M。
实际运行的系统往往会根据数据特点的不同,将数据存放在不同的
DB
里。因此做规划时,也需要考虑。
实际运行的系统往往会根据数据特点的不同,将数据存放在不同的
DB
里。因此做规划时,也需要考虑。
如果内存充裕,可以加大
Blocks
的配置,这样更多数据将保存在内存里,提高查询速度。
如果内存充裕,可以加大
Blocks
的配置,这样更多数据将保存在内存里,提高查询速度。
### CPU需求
### CPU
需求
CPU的需求取决于如下两方面:
CPU
的需求取决于如下两方面:
*
__数据插入__ TDengine
单核每秒能至少处理一万个插入请求。每个插入请求可以带多条记录,一次插入一条记录与插入10条记录,消耗的计算资源差别很小。因此每次插入,条数越大,插入效率越高。如果一个插入请求带200条以上记录,单核就能达到每秒插入100
万条记录的速度。但对前端数据采集的要求越高,因为需要缓存记录,然后一批插入。
*
__查询需求__ TDengine提供高效的查询,但是每个场景的查询差异很大,查询频次变化也很大,难以给出客观数字。需要用户针对自己的场景,写一些查询语句,才能确定。
*
__数据插入__ TDengine
单核每秒能至少处理一万个插入请求。每个插入请求可以带多条记录,一次插入一条记录与插入 10 条记录,消耗的计算资源差别很小。因此每次插入,条数越大,插入效率越高。如果一个插入请求带 200 条以上记录,单核就能达到每秒插入 100
万条记录的速度。但对前端数据采集的要求越高,因为需要缓存记录,然后一批插入。
*
__查询需求__ TDengine
提供高效的查询,但是每个场景的查询差异很大,查询频次变化也很大,难以给出客观数字。需要用户针对自己的场景,写一些查询语句,才能确定。
因此仅对数据插入而言,CPU
是可以估算出来的,但查询所耗的计算资源无法估算。在实际运营过程中,不建议CPU使用率超过
50%,超过后,需要增加新的节点,以获得更多计算资源。
因此仅对数据插入而言,CPU
是可以估算出来的,但查询所耗的计算资源无法估算。在实际运营过程中,不建议 CPU 使用率超过
50%,超过后,需要增加新的节点,以获得更多计算资源。
### 存储需求
TDengine
相对于通用数据库,有超高的压缩比,在绝大多数场景下,TDengine的压缩比不会低于5倍,有的场合,压缩比可达到10
倍以上,取决于实际场景的数据特征。压缩前的原始数据大小可通过如下方式计算:
TDengine
相对于通用数据库,有超高的压缩比,在绝大多数场景下,TDengine 的压缩比不会低于 5 倍,有的场合,压缩比可达到 10
倍以上,取决于实际场景的数据特征。压缩前的原始数据大小可通过如下方式计算:
```
Raw DataSize = numOfTables * rowSizePerTable * rowsPerTable
```
示例:1000
万台智能电表,每台电表每15分钟采集一次数据,每次采集的数据128字节,那么一年的原始数据量是:10000000
\*
128
\*
24
\*
60/15
\*
365 = 44.8512T。TDengine大概需要消耗44.851/5=8.97024T
空间。
示例:1000
万台智能电表,每台电表每 15 分钟采集一次数据,每次采集的数据 128 字节,那么一年的原始数据量是:10000000
\*
128
\*
24
\*
60 / 15
\*
365 = 44.8512T。TDengine大概需要消耗 44.851 / 5 = 8.97024T
空间。
用户可以通过参数
keep,设置数据在磁盘中的最大保存时长。为进一步减少存储成本,TDengine
还提供多级存储,最冷的数据可以存放在最廉价的存储介质上,应用的访问不用做任何调整,只是读取速度降低了。
用户可以通过参数
keep,设置数据在磁盘中的最大保存时长。为进一步减少存储成本,TDengine
还提供多级存储,最冷的数据可以存放在最廉价的存储介质上,应用的访问不用做任何调整,只是读取速度降低了。
为提高速度,可以配置多块硬盘,这样可以并发写入或读取数据。需要提醒的是,TDengine采取多副本的方式提供数据的高可靠,因此不再需要采用昂贵的磁盘阵列。
为提高速度,可以配置多块硬盘,这样可以并发写入或读取数据。需要提醒的是,TDengine
采取多副本的方式提供数据的高可靠,因此不再需要采用昂贵的磁盘阵列。
### 物理机或虚拟机台数
根据上面的内存、CPU、存储的预估,就可以知道整个系统需要多少核、多少内存、多少存储空间。如果数据副本数不为1,总需求量需要再乘以副本数。
根据上面的内存、CPU、存储的预估,就可以知道整个系统需要多少核、多少内存、多少存储空间。如果数据副本数不为
1,总需求量需要再乘以副本数。
因为
TDengine
具有很好的水平扩展能力,根据总量,再根据单个物理机或虚拟机的资源,就可以轻松决定需要购置多少台物理机或虚拟机了。
因为
TDengine
具有很好的水平扩展能力,根据总量,再根据单个物理机或虚拟机的资源,就可以轻松决定需要购置多少台物理机或虚拟机了。
**立即计算CPU、内存、存储,请参见:[资源估算方法](https://www.taosdata.com/config/config.html)**
**立即计算
CPU、内存、存储,请参见:[资源估算方法](https://www.taosdata.com/config/config.html)**
## <a class="anchor" id="tolerance"></a>容错和灾备
...
...
documentation20/cn/12.taos-sql/docs.md
浏览文件 @
709d045c
...
...
@@ -115,7 +115,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```mysql
ALTER DATABASE db_name QUORUM 2;
```
QUORUM 参数是指数据写入成功所需要的确认数,取值范围 [1,
3
]。对于异步复制,quorum 设为 1,具有 master 角色的虚拟节点自己确认即可。对于同步复制,需要至少大于等于 2。原则上,Quorum >= 1 并且 Quorum <= replica(副本数),这个参数在启动一个同步模块实例时需要提供。
QUORUM 参数是指数据写入成功所需要的确认数,取值范围 [1,
2
]。对于异步复制,quorum 设为 1,具有 master 角色的虚拟节点自己确认即可。对于同步复制,需要至少大于等于 2。原则上,Quorum >= 1 并且 Quorum <= replica(副本数),这个参数在启动一个同步模块实例时需要提供。
```mysql
ALTER DATABASE db_name BLOCKS 100;
...
...
src/connector/jdbc/pom.xml
浏览文件 @
709d045c
...
...
@@ -102,6 +102,7 @@
<include>
**/*Test.java
</include>
</includes>
<excludes>
<exclude>
**/DatetimeBefore1970Test.java
</exclude>
<exclude>
**/AppMemoryLeakTest.java
</exclude>
<exclude>
**/AuthenticationTest.java
</exclude>
<exclude>
**/TaosInfoMonitorTest.java
</exclude>
...
...
src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java
0 → 100644
浏览文件 @
709d045c
package
com.taosdata.jdbc
;
import
org.junit.Test
;
import
java.sql.SQLException
;
import
java.sql.SQLWarning
;
import
java.util.ArrayList
;
import
java.util.List
;
import
static
org
.
junit
.
Assert
.*;
public
class
TSDBJNIConnectorTest
{
public
static
void
main
(
String
[]
args
)
{
try
{
TSDBJNIConnector
.
init
(
"/etc/taos/taos.cfg"
,
"en_US.UTF-8"
,
""
,
""
);
TSDBJNIConnector
connector
=
new
TSDBJNIConnector
();
connector
.
connect
(
"127.0.0.1"
,
6030
,
"test"
,
"root"
,
"taosdata"
);
long
pSql
=
connector
.
executeQuery
(
"show dnodes"
);
// if pSql is create/insert/update/delete/alter SQL
if
(
connector
.
isUpdateQuery
(
pSql
))
{
connector
.
freeResultSet
(
pSql
);
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_INVALID_WITH_EXECUTEQUERY
);
}
List
<
ColumnMetaData
>
columnMetaDataList
=
new
ArrayList
<>();
int
code
=
connector
.
getSchemaMetaData
(
pSql
,
columnMetaDataList
);
if
(
code
==
TSDBConstants
.
JNI_CONNECTION_NULL
)
{
throw
new
SQLException
(
TSDBConstants
.
FixErrMsg
(
TSDBConstants
.
JNI_CONNECTION_NULL
));
}
if
(
code
==
TSDBConstants
.
JNI_RESULT_SET_NULL
)
{
throw
new
SQLException
(
TSDBConstants
.
FixErrMsg
(
TSDBConstants
.
JNI_RESULT_SET_NULL
));
}
if
(
code
==
TSDBConstants
.
JNI_NUM_OF_FIELDS_0
)
{
throw
new
SQLException
(
TSDBConstants
.
FixErrMsg
(
TSDBConstants
.
JNI_NUM_OF_FIELDS_0
));
}
}
catch
(
SQLWarning
throwables
)
{
throwables
.
printStackTrace
();
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
@Test
public
void
isClosed
()
{
}
@Test
public
void
isResultsetClosed
()
{
}
@Test
public
void
init
()
{
}
@Test
public
void
initImp
()
{
}
@Test
public
void
setOptions
()
{
}
@Test
public
void
getTsCharset
()
{
}
@Test
public
void
connect
()
{
}
@Test
public
void
executeQuery
()
{
}
@Test
public
void
getErrCode
()
{
}
@Test
public
void
getErrMsg
()
{
}
@Test
public
void
isUpdateQuery
()
{
}
@Test
public
void
freeResultSet
()
{
}
@Test
public
void
getAffectedRows
()
{
}
@Test
public
void
getSchemaMetaData
()
{
}
@Test
public
void
fetchRow
()
{
}
@Test
public
void
fetchBlock
()
{
}
@Test
public
void
closeConnection
()
{
}
@Test
public
void
subscribe
()
{
}
@Test
public
void
consume
()
{
}
@Test
public
void
unsubscribe
()
{
}
@Test
public
void
validateCreateTableSql
()
{
}
}
\ No newline at end of file
src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java
浏览文件 @
709d045c
...
...
@@ -4,7 +4,6 @@ import org.junit.Test;
import
java.sql.*
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.concurrent.TimeUnit
;
public
class
FailOverTest
{
...
...
@@ -18,13 +17,17 @@ public class FailOverTest {
long
end
=
System
.
currentTimeMillis
()
+
1000
*
60
*
5
;
while
(
System
.
currentTimeMillis
()
<
end
)
{
try
(
Connection
conn
=
DriverManager
.
getConnection
(
url
))
{
Statement
stmt
=
conn
.
createStatement
();
ResultSet
resultSet
=
stmt
.
executeQuery
(
"select server_status()"
);
resultSet
.
next
();
int
status
=
resultSet
.
getInt
(
"server_status()"
);
System
.
out
.
println
(
">>>>>>>>>"
+
sdf
.
format
(
new
Date
())
+
" status : "
+
status
);
stmt
.
close
();
try
(
Connection
conn
=
DriverManager
.
getConnection
(
url
);
Statement
stmt
=
conn
.
createStatement
())
{
ResultSet
rs
=
stmt
.
executeQuery
(
"show dnodes"
);
ResultSetMetaData
meta
=
rs
.
getMetaData
();
while
(
rs
.
next
())
{
for
(
int
i
=
1
;
i
<=
meta
.
getColumnCount
();
i
++)
{
System
.
out
.
print
(
meta
.
getColumnLabel
(
i
)
+
": "
+
rs
.
getString
(
i
)
+
"\t"
);
}
System
.
out
.
println
();
}
System
.
out
.
println
(
"======================="
);
rs
.
close
();
TimeUnit
.
SECONDS
.
sleep
(
5
);
}
catch
(
SQLException
|
InterruptedException
e
)
{
e
.
printStackTrace
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录