Merge pull request #12909 from taosdata/docs/TD-15928

docs: remove useful parts in 3.0 doc
This commit is contained in:
wade zhang 2022-05-24 13:13:52 +08:00 committed by GitHub
commit dd44257888
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 0 additions and 663 deletions

View File

@ -1,100 +0,0 @@
---
title: 性能优化
---
因数据行 [update](/train-faq/faq/#update)、表删除、数据过期等原因TDengine 的磁盘存储文件有可能出现数据碎片,影响查询操作的性能表现。从 2.1.3.0 版本开始,新增 SQL 指令 COMPACT 来启动碎片重整过程:
```sql
COMPACT VNODES IN (vg_id1, vg_id2, ...)
```
COMPACT 命令对指定的一个或多个 VGroup 启动碎片重整系统会通过任务队列尽快安排重整操作的具体执行。COMPACT 指令所需的 VGroup id可以通过 `SHOW VGROUPS;` 指令的输出结果获取;而且在 `SHOW VGROUPS;` 中会有一个 compacting 列,值为 2 时表示对应的 VGroup 处于排队等待进行重整的状态,值为 1 时表示正在进行碎片重整,为 0 时则表示并没有处于重整状态(未要求进行重整或已经完成重整)。
需要注意的是,碎片重整操作会大幅消耗磁盘 I/O。因此在重整进行期间有可能会影响节点的写入和查询性能甚至在极端情况下导致短时间的阻写。
## 存储参数优化
不同应用场景的数据往往具有不同的数据特征比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率TDengine 提供如下存储相关的系统配置参数(既可以作为 create database 指令的参数,也可以写在 taos.cfg 配置文件中用来设定创建新数据库时所采用的默认值):
| # | 配置参数名称 | 单位 | 含义 | **取值范围** | **缺省值** |
| --- | ------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------- |
| 1 | days | 天 | 一个数据文件存储数据的时间跨度 | 1-3650 | 10 |
| 2 | keep | 天 | (可通过 alter database 修改)数据库中数据保留的天数。 | 1-36500 | 3650 |
| 3 | cache | MB | 内存块的大小 | 1-128 | 16 |
| 4 | blocks | | (可通过 alter database 修改)每个 VNODETSDB中有多少个 cache 大小的内存块。因此一个 VNODE 使用的内存大小粗略为cache \* blocks。 | 3-10000 | 6 |
| 5 | quorum | | (可通过 alter database 修改)多副本环境下指令执行的确认数要求 | 1-2 | 1 |
| 6 | minRows | | 文件块中记录的最小条数 | 10-1000 | 100 |
| 7 | maxRows | | 文件块中记录的最大条数 | 200-10000 | 4096 |
| 8 | comp | | (可通过 alter database 修改)文件压缩标志位 | 0关闭1:一阶段压缩2:两阶段压缩 | 2 |
| 9 | walLevel | | (作为 database 的参数时名为 wal在 taos.cfg 中作为参数时需要写作 walLevelWAL 级别 | 1写 WAL但不执行 fsync2写 WAL, 而且执行 fsync | 1 |
| 10 | fsync | 毫秒 | 当 wal 设置为 2 时,执行 fsync 的周期。设置为 0表示每次写入立即执行 fsync。 | | 3000 |
| 11 | replica | | (可通过 alter database 修改)副本个数 | 1-3 | 1 |
| 12 | precision | | 时间戳精度标识2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。)(从 2.1.5.0 版本开始,新增对纳秒时间精度的支持) | ms 表示毫秒us 表示微秒ns 表示纳秒 | ms |
| 13 | update | | 是否允许数据更新(从 2.1.7.0 版本开始此参数支持 0 2 的取值范围,在此之前取值只能是 [0, 1];而 2.0.8.0 之前的版本在 SQL 指令中不支持此参数。) | 0不允许1允许更新整行2允许部分列更新。 | 0 |
| 14 | cacheLast | | (可通过 alter database 修改)是否在内存中缓存子表的最近数据(从 2.1.2.0 版本开始此参数支持 0 3 的取值范围,在此之前取值只能是 [0, 1];而 2.0.11.0 之前的版本在 SQL 指令中不支持此参数。2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。) | 0关闭1缓存子表最近一行数据2缓存子表每一列的最近的非 NULL 值3同时打开缓存最近行和列功能 | 0 |
对于一个应用场景可能有多种数据特征的数据并存最佳的设计是将具有相同数据特征的表放在一个库里这样一个应用有多个库而每个库可以配置不同的存储参数从而保证系统有最优的性能。TDengine 允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述 SQL
```sql
CREATE DATABASE demo DAYS 10 CACHE 32 BLOCKS 8 REPLICA 3 UPDATE 1;
```
该 SQL 创建了一个库 demo, 每个数据文件存储 10 天数据,内存块为 32 兆字节,每个 VNODE 占用 8 个内存块,副本数为 3允许更新而其他参数与系统配置完全一致。
一个数据库创建成功后,仅部分参数可以修改并实时生效,其余参数不能修改:
| **参数名** | **能否修改** | **范围** | **修改语法示例** |
| ----------- | ------------ | ---------------------------------------------------------- | -------------------------------------- |
| name | | | |
| create time | | | |
| ntables | | | |
| vgroups | | | |
| replica | **YES** | 在线 dnode 数目为:<br/>11-1<br/>21-2<br/>\>=31-3 | ALTER DATABASE <dbname\> REPLICA _n_ |
| quorum | **YES** | 1-2 | ALTER DATABASE <dbname\> QUORUM _n_ |
| days | | | |
| keep | **YES** | days-365000 | ALTER DATABASE <dbname\> KEEP _n_ |
| cache | | | |
| blocks | **YES** | 3-1000 | ALTER DATABASE <dbname\> BLOCKS _n_ |
| minrows | | | |
| maxrows | | | |
| wal | | | |
| fsync | | | |
| comp | **YES** | 0-2 | ALTER DATABASE <dbname\> COMP _n_ |
| precision | | | |
| status | | | |
| update | | | |
| cachelast | **YES** | 0 \| 1 \| 2 \| 3 | ALTER DATABASE <dbname\> CACHELAST _n_ |
**说明:**在 2.1.3.0 版本之前,通过 ALTER DATABASE 语句修改这些参数后,需要重启服务器才能生效。
TDengine 集群中加入一个新的 dnode 时,涉及集群相关的一些参数必须与已有集群的配置相同,否则不能成功加入到集群中。会进行校验的参数如下:
- numOfMnodes系统中管理节点个数。默认值3。2.0 版本从 2.0.20.11 开始、2.1 及以上版本从 2.1.6.0 开始numOfMnodes 默认值改为 1。
- mnodeEqualVnodeNum: 一个 mnode 等同于 vnode 消耗的个数。默认值4。
- offlineThreshold: dnode 离线阈值,超过该时间将导致该 dnode 从集群中删除。单位为秒默认值86400\*10即 10 天)。
- statusInterval: dnode 向 mnode 报告状态时长。单位为秒默认值1。
- maxTablesPerVnode: 每个 vnode 中能够创建的最大表个数。默认值1000000。
- maxVgroupsPerDb: 每个数据库中能够使用的最大 vgroup 个数。
- arbitrator: 系统中裁决器的 endpoint缺省为空。
- timezone、locale、charset 的配置见客户端配置。2.0.20.0 及以上的版本里,集群中加入新节点已不要求 locale 和 charset 参数取值一致)
- balance是否启用负载均衡。01是。默认值1。
- flowctrl是否启用非阻塞流控。01是。默认值1。
- slaveQuery是否启用 slave vnode 参与查询。01是。默认值1。
- adjustMaster是否启用 vnode master 负载均衡。01是。默认值1。
为方便调试,可通过 SQL 语句临时调整每个 dnode 的日志配置,系统重启后会失效:
```sql
ALTER DNODE <dnode_id> <config>
```
- dnode_id: 可以通过 SQL 语句"SHOW DNODES"命令获取
- config: 要调整的日志参数,在如下列表中取值
> resetlog 截断旧日志文件,创建一个新日志文件
> debugFlag < 131 | 135 | 143 > 设置 debugFlag 为 131、135 或者 143
例如:
```
alter dnode 1 debugFlag 135;
```

View File

@ -1,256 +0,0 @@
---
sidebar_label: 数据复制模块设计
title: 数据复制模块设计
---
## 数据复制概述
数据复制(Replication)是指同一份数据在多个物理地点保存。它的目的是防止数据丢失,提高系统的高可用性(High Availability),而且通过应用访问多个副本,提升数据查询性能。
在高可靠的大数据系统里,数据复制是必不可少的一大功能。数据复制又分为实时复制与非实时复制。实时复制是指任何数据的更新(包括数据的增加、删除、修改)操作,会被实时的复制到所有副本,这样任何一台机器宕机或网络出现故障,整个系统还能提供最新的数据,保证系统的正常工作。而非实时复制,是指传统的数据备份操作,按照固定的时间周期,将一份数据全量或增量复制到其他地方。如果主节点宕机,副本是很大可能没有最新数据,因此在有些场景是无法满足要求的。
TDengine面向的是物联网场景需要支持数据的实时复制来最大程度保证系统的可靠性。实时复制有两种方式一种是异步复制一种是同步复制。异步复制(Asynchronous Replication)是指数据由Master转发给Slave后Master并不需要等待Slave回复确认这种方式效率高但有极小的概率会丢失数据。同步复制是指Master将数据转发给Slave后需要等待Slave的回复确认才会通知应用写入成功这种方式效率偏低但能保证数据绝不丢失。
数据复制是与数据存储写入、读取密切相关的但两者又是相对独立可以完全脱耦的。在TDengine系统中有两种不同类型的数据一种是时序数据由TSDB模块负责一种是元数据(Meta Data), 由MNODE负责。这两种性质不同的数据都需要同步功能。数据复制模块通过不同的实例启动配置参数为这两种类型数据都提供同步功能。
在阅读本文之前,请先阅读《[TDengine 2.0 整体架构](/tdinternal/arch/)》了解TDengine的集群设计和基本概念
特别注明:本文中提到数据更新操作包括数据的增加、删除与修改。
## 基本概念和定义
TDengine里存在vnode, mnode, vnode用来存储时序数据mnode用来存储元数据。但从同步数据复制的模块来看两者没有本质的区别因此本文里的虚拟节点不仅包括vnode, 也包括mnode, vgroup也指mnode group, 除非特别注明。
**版本(version)**
一个虚拟节点组里多个虚拟节点互为备份来保证数据的有效与可靠是依靠虚拟节点组的数据版本号来维持的。TDengine2.0设计里对于版本的定义如下客户端发起增加、删除、修改的流程无论是一条记录还是多条只要是在一个请求里这个数据更新请求被TDengine的一个虚拟节点收到后经过合法性检查后可以被写入系统时就会被分配一个版本号。这个版本号在一个虚拟节点里从1开始是单调连续递增的。无论这条记录是采集的时序数据还是meta data, 一样处理。当Master转发一个写入请求到slave时必须带上版本号。一个虚拟节点将一数据更新请求写入WAL时需要带上版本号。
不同虚拟节点组的数据版本号是完全独立的互不相干的。版本号本质上是数据更新记录的transaction ID但用来标识数据集的版本。
**角色(role)**
一个虚拟节点可以是master, slave, unsynced或offline状态。
- master 具有最新的数据容许客户端往里写入数据一个虚拟节点组至多一个master.
- slave与master是同步的但不容许客户端往里写入数据根据配置可以容许客户端对其进行查询。
- unsynced: 节点处于非同步状态,比如虚拟节点刚启动、或与其他虚拟节点的连接出现故障等。处于该状态时,该虚拟节点既不能提供写入,也不能提供查询服务。
- offline: 由于宕机或网络原因无法访问到某虚拟节点时其他虚拟节点将该虚拟节点标为离线。但请注意该虚拟节点本身的状态可能是unsynced或其他但不会是离线。
**Quorum:**
指数据写入成功所需要的确认数。对于异步复制quorum设为1具有master角色的虚拟节点自己确认即可。对于同步复制需要至少大于等于2。原则上Quorum >=1 并且 Quorum <= replication(副本数)。这个参数在启动一个同步模块实例时需要提供。
**WAL**
TDengine的WAL(Write Ahead Log)与cassandra的commit log, mySQL的bin log, Postgres的WAL没本质区别。没有写入数据库文件还保存在内存的数据都会先存在WAL。当数据已经成功写入数据库数据文件相应的WAL会被删除。但需要特别指明的是在TDengine系统里有几点
- 每个虚拟节点有自己独立的wal
- WAL里包含而且仅仅包含来自客户端的数据更新操作每个更新操作都会被打上一个版本号
**复制实例:**
复制模块只是一可执行的代码复制实例是指正在运行的复制模块的一个实例一个节点里可以存在多个实例。原则上一个节点有多少虚拟节点就可以启动多少实例。对于副本数为1的场景应用可以决定是否需要启动同步实例。应用启动一个同步模块的实例时需要提供的就是虚拟节点组的配置信息包括
- 虚拟节点个数即replication number
- 各虚拟节点所在节点的信息包括node的end point
- quorum, 需要的数据写入成功的确认数
- 虚拟节点的初始版本号
## 数据复制模块的基本工作原理
TDengine采取的是Master-Slave模式进行同步与流行的RAFT一致性算法比较一致。总结下来有几点
1. 一个vgroup里有一到多个虚拟节点每个虚拟节点都有自己的角色
2. 客户端只能向角色是master的虚拟节点发起数据更新操作因为master具有最新版本的数据如果向非Master发起数据更新操作会直接收到错误
3. 客户端可以向master, 也可以向角色是Slave的虚拟节点发起查询操作但不能对unsynced的虚拟节点发起任何操作
4. 如果master不存在这个vgroup是不能对外提供数据更新和查询服务的
5. master收到客户端的数据更新操作时会将其转发给slave节点
6. 一个虚拟节点的版本号比master低的时候会发起数据恢复流程成功后才会成为slave
数据实时复制有三个主要流程:选主、数据转发、数据恢复。后续做详细讨论。
## 虚拟节点之间的网络连接
虚拟节点之间通过TCP进行连接节点之间的状态交换、数据包的转发都是通过这个TCP连接(peerFd)进行。为避免竞争两个虚拟节点之间的TCP连接总是由IP地址(UINT32)小的节点作为TCP客户端发起。一旦TCP连接被中断虚拟节点能通过TCP socket自动检测到将对方标为offline。如果监测到任何错误比如数据恢复流程虚拟节点将主动重置该连接。
一旦作为客户端的节点连接不成或中断它将周期性的每隔一秒钟去试图去连接一次。因为TCP本身有心跳机制虚拟节点之间不再另行提供心跳。
如果一个unsynced节点要发起数据恢复流程它与Master将建立起专有的TCP连接(syncFd)。数据恢复完成后,该连接会被关闭。而且为限制资源的使用,系统只容许一定数量(配置参数tsMaxSyncNum)的数据恢复的socket存在。如果超过这个数字系统会将新的数据恢复请求延后处理。
任意一个节点无论有多少虚拟节点都会启动而且只会启动一个TCP server, 来接受来自其他虚拟节点的上述两类TCP的连接请求。当TCP socket建立起来客户端侧发送的消息体里会带有vgId全局唯一的vgroup ID), TCP 服务器侧会检查该vgId是否已经在该节点启动运行。如果已经启动运行就接受其请求。如果不存在就直接将连接请求关闭。在TDengine代码里mnode group的vgId设置为1。
## 选主流程
当同一组的两个虚拟节点之间(vnode A, vnode B)建立连接后他们互换status消息。status消息里包含本地存储的同一虚拟节点组内所有虚拟节点的role和version。
如果一个虚拟节点(vnode A)检测到与同一虚拟节点组内另外一虚拟节点vnode B的连接中断vnode A将立即把vnode B的role设置为offline。无论是接收到另外一虚拟节点发来的status消息还是检测与另外一虚拟节点的连接中断该虚拟节点都将进入状态处理流程。状态处理流程的规则如下
1. 如果检测到在线的节点数没有超过一半则将自己的状态设置为unsynced.
2. 如果在线的虚拟节点数超过一半会检查master节点是否存在如果存在则会决定是否将自己状态改为slave或启动数据恢复流程。
3. 如果master不存在则会检查自己保存的各虚拟节点的状态信息与从另一节点接收到的是否一致如果一致说明节点组里状态已经稳定一致则会触发选举流程。如果不一致说明状态还没趋于一致即使master不存在也不进行选主。由于要求状态信息一致才进行选举每个虚拟节点根据同样的信息会选出同一个虚拟节点做master无需投票表决。
4. 自己的状态是根据规则自己决定并修改的并不需要其他节点同意包括成为master。一个节点无权修改其他节点的状态。
5. 如果一个虚拟节点检测到自己或其他虚拟节点的role发生改变该节点会广播它自己保存的各个虚拟节点的状态信息role和version)。
具体的流程图如下:
![replica-master.png](/img/architecture/replica-master.png)
选择Master的具体规则如下
1. 如果只有一个副本该副本永远就是master
2. 所有副本都在线时版本最高的被选为master
3. 在线的虚拟节点数过半而且有虚拟节点是slave的话该虚拟节点自动成为master
4. 对于2和3如果多个虚拟节点满足成为master的要求那么虚拟节点组的节点列表里最前面的选为master
按照上面的规则如果所有虚拟节点都是unsynced(比如全部重启只有所有虚拟节点上线才能选出master该虚拟节点组才能开始对外提供服务。当一个虚拟节点的role发生改变时sync模块回通过回调函数notifyRole通知应用。
## 数据转发流程
如果vnode A是master, vnode B是slave, vnode A能接受客户端的写请求而vnode B不能。当vnode A收到写的请求后遵循下面的流程
![replica-forward.png](/img/architecture/replica-forward.png)
1. 应用对写请求做基本的合法性检查,通过,则给该请求包打上一个版本号(version, 单调递增)
2. 应用将打上版本号的写请求封装一个WAL Head, 写入WAL(Write Ahead Log)
3. 应用调用API syncForwardToPeer如果vnode B是slave状态sync模块将包含WAL Head的数据包通过Forward消息发送给vnode B否则就不转发。
4. vnode B收到Forward消息后调用回调函数writeToCache, 交给应用处理
5. vnode B应用在写入成功后都需要调用syncConfirmForward通知sync模块已经写入成功。
6. 如果quorum大于1vnode B需要等待应用的回复确认收到确认后vnode B发送Forward Response消息给node A。
7. 如果quorum大于1vnode A需要等待vnode B或其他副本对Forward消息的确认。
8. 如果quorum大于1vnode A收到quorum-1条确认消息后调用回调函数confirmForward通知应用写入成功。
9. 如果quorum为1上述678步不会发生。
10. 如果要等待slave的确认master会启动2秒的定时器可配置如果超时则认为失败。
对于回复确认sync模块提供的是异步回调函数因此APP在调用syncForwardToPeer之后无需等待可以处理下一个操作。在Master与Slave的TCP连接管道里可能有多个Forward消息这些消息是严格按照应用提供的顺序排好的。对于Forward Response也是一样TCP管道里存在多个但都是排序好的。这个顺序SYNC模块并没有做特别的事情是由APP单线程顺序写来保证的(TDengine里每个vnode的写数据都是单线程
## 数据恢复流程
如果一虚拟节点(vnode B) 处于unsynced状态master存在vnode A)而且其版本号比master的低它将立即启动数据恢复流程。在理解恢复流程时需要澄清几个关于文件的概念和处理规则。
1. 每个文件无论是archived data的file还是wal)都有一个index, 这需要应用来维护(vnode里该index就是fileId*3 + 0/1/2, 对应data, head与last三个文件。如果index为0表示系统里最老的数据文件。对于mode里的文件数量是固定的对应于acct, user, db, table等文件。
2. 任何一个数据文件(file)有名字、大小还有一个magic number。只有文件名、大小与magic number一致时两个文件才判断是一样的无需同步。Magic number可以是checksum, 也可以是简单的文件大小。怎么计算magic换句话说如何检测数据文件是否有效完全由应用决定。
3. 文件名的处理有点复杂因为每台服务器的路径可能不一致。比如node A的TDengine的数据文件存放在 /etc/taos目录下而node B的数据存放在 /home/jhtao目录下。因此同步模块需要应用在启动一个同步实例时提供一个path这样两台服务器的绝对路径可以不一样但仍然可以做对比做同步。
4. 当sync模块调用回调函数getFileInfo获得数据文件信息时有如下的规则
* index 为0表示获取最老的文件同时修改index返回给sync模块。如果index不为0表示获取指定位置的文件。
* 如果name为空表示sync想获取位于index位置的文件信息包括magic, size。Master节点会这么调用
* 如果name不为空表示sync想获取指定文件名和index的信息slave节点会这么调用
* 如果某个index的文件不存在magic返回0表示文件已经是最后一个。因此整个系统里文件的index必须是连续的一段整数。
5. 当sync模块调用回调函数getWalInfo获得wal信息时有如下规则
* index为0表示获得最老的WAL文件, 返回时index更新为具体的数字
* 如果返回0表示这是最新的一个WAL文件如果返回值是1表示后面还有更新的WAL文件
* 返回的文件名为空那表示没有WAL文件
6. 无论是getFileInfo, 还是getWalInfo, 只要获取出错(不是文件不存在),返回-1即可系统会报错停止同步
整个数据恢复流程分为两大步骤第一步先恢复archived data(file), 然后恢复wal。具体流程如下
![replica-restore.png](/img/architecture/replica-restore.png)
1. 通过已经建立的TCP连接发送sync req给master节点
2. master收到sync req后以client的身份向vnode B主动建立一新的专用于同步的TCP连接syncFd)
3. 新的TCP连接建立成功后master将开始retrieve流程对应的vnode B将同步启动restore流程
4. Retrieve/Restore流程里先处理所有archived data (vnode里的data, head, last文件后处理WAL data。
5. 对于archived datamaster将通过回调函数getFileInfo获取数据文件的基本信息包括文件名、magic以及文件大小。
6. master 将获得的文件名、magic以及文件大小发给vnode B
7. vnode B将回调函数getFile获得magic和文件大小如果两者一致就认为无需同步如果两者不一致 就认为需要同步。vnode B将结果通过消息FileAck发回master
8. 如果文件需要同步master就调用sendfile把整个文件发往vnode B
9. 如果文件不需要同步master(vnode A)就重复5678直到所有文件被处理完
对于WAL同步流程如下
1. master节点调用回调函数getWalInfo获取WAL的文件名。
2. 如果getWalInfo返回值大于0表示该文件还不是最后一个WAL因此master调用sendfile一下把该文件发送给vnode B
3. 如果getWalInfo返回时为0表示该文件是最后一个WAL因为文件可能还处于写的状态中sync模块要根据WAL Head的定义逐条读出记录然后发往vnode B。
4. vnode A读取TCP连接传来的数据按照WAL Head逐条读取如果版本号比现有的大调用回调函数writeToCache交给应用处理。如果小直接扔掉。
5. 上述流程循环直到所有WAL文件都被处理完。处理完后master就会将新来的数据包通过Forward消息转发给slave。
从同步文件启动起sync模块会通过inotify监控所有处理过的file以及wal。一旦发现被处理过的文件有更新变化同步流程将中止会重新启动。因为有可能落盘操作正在进行比如历史数据导入内存数据落盘把已经处理过的文件进行了修改需要重新同步才行。
对于最后一个WAL (LastWal)的处理逻辑有点复杂,因为这个文件往往是打开写的状态,有很多场景需要考虑,比如:
- LastWal文件size在增长需要重新读
- LastWal文件虽然已经打开写但内容为空
- LastWal文件已经被关闭应用生成了新的Last WAL文件;
- LastWal文件没有被关闭但数据落盘的原因没有读到完整的一条记录;
- LastWal文件没有被关闭但数据落盘的原因还有部分记录暂时读取不到
sync模块通过inotify监控LastWal文件的更新和关闭操作。而且在确认已经尽可能读完LastWal的数据后会将对方同步状态设置为SYNC_CACHE。该状态下master节点会将新的记录转发给vnode B而此时vnode B并没有完成同步需要把这些转发包先存在recv buffer里等WAL处理完后vnode A再把recv buffer里的数据包通过回调writeToCache交给应用处理。
等vnode B把这些buffered forwards处理完同步流程才算结束vnode B正式变为slave。
## Master分布均匀性问题
因为Master负责写、转发消耗的资源会更多因此Master在整个集群里分布均匀比较理想。
但在TDengine的设计里如果多个虚拟节点都符合master条件TDengine选在列表中最前面的做Master, 这样是否导致在集群里Master数量的分布不均匀问题呢这取决于应用的设计。
给一个具体例子系统里仅仅有三个节点IP地址分别为IP1, IP2, IP3. 在各个节点上TDengine创建了多个虚拟节点组每个虚拟节点组都有三个副本。如果三个副本的顺序在所有虚拟节点组里都是IP1, IP2, IP3, 那毫无疑问master将集中在IP1这个节点这是我们不想看到的。
但是如果在创建虚拟节点组时增加随机性这个问题就不存在了。比如在vgroup 1, 顺序是IP1, IP2, IP3, 在vgroup 2里顺序是IP2, IP3, IP1, 在vgroup 3里顺序是IP3, IP1, IP2。最后master的分布会是均匀的。
因此在创建一个虚拟节点组时应用需要保证节点的顺序是round robin或完全随机。
## 少数虚拟节点写入成功的问题
在某种情况下写入成功的确认数大于0但小于配置的Quorum, 虽然有虚拟节点数据更新成功master仍然会认为数据更新失败并通知客户端写入失败。
这个时候系统存在数据不一致的问题因为有的虚拟节点已经写入成功而有的写入失败。一个处理方式是Master重置(reset)与其他虚拟节点的连接该虚拟节点组将自动进入选举流程。按照规则已经成功写入数据的虚拟节点将成为新的master组内的其他虚拟节点将从master那里恢复数据。
因为写入失败客户端会重新写入数据。但对于TDengine而言是OK的。因为时序数据都是有时间戳的时间戳相同的数据更新操作第一次会执行但第二次会自动扔掉。对于Meta Data(增加、删除库、表等等的操作也是OK的。一张表、库已经被创建或删除再创建或删除不会被执行的。
在TDengine的设计里虚拟节点与虚拟节点之间是一个TCP连接是一个pipeline数据块一个接一个按顺序在这个pipeline里等待处理。一旦某个数据块的处理失败这个连接会被重置后续的数据块的处理都会失败。因此不会存在Pipeline里一个数据块更新失败但下一个数据块成功的可能。
## Split Brain的问题
选举流程中有个强制要求那就是一定有超过半数的虚拟节点在线。但是如果replication正好是偶数这个时候完全可能存在splt brain问题。
为解决这个问题TDengine提供Arbitrator的解决方法。Arbitrator是一个节点它的任务就是接受任何虚拟节点的连接请求并保持它。
在启动复制模块实例时在配置参数中应用可以提供Arbitrator的IP地址。如果是奇数个副本复制模块不会与这个arbitrator去建立连接但如果是偶数个副本就会主动去建立连接。
Arbitrator的程序tarbitrator.c在复制模块的同一目录, 编译整个系统时会在bin目录生成。命令行参数“-”查看可以配置的参数比如绑定的IP地址监听的端口号。
## 与RAFT相比的异同
数据一致性协议流行的有两种Paxos与Raft. 本设计的实现与Raft有很多类同之处下面做一些比较
相同之处:
- 三大流程一致Raft里有Leader election, replication, safety完全对应TDengine的选举、数据转发、数据恢复三个流程。
- 节点状态定义一致Raft里每个节点有Leader, Follower, Candidate三个状态TDengine里是Master, Slave, Unsynced, Offline。多了一个offlince, 但本质上是一样的因为offline是外界看一个节点的状态但该节点本身是处于master, slave 或unsynced的。
- 数据转发流程完全一样Master(leader)需要等待回复确认。
- 数据恢复流程几乎一样Raft没有涉及历史数据同步问题只考虑了WAL数据同步。
不同之处:
- 选举流程不一样Raft里任何一个节点是candidate时主动向其他节点发出vote request如果超过半数回答Yes这个candidate就成为Leader开始一个新的term。而TDengine的实现里节点上线、离线或角色改变都会触发状态消息在节点组内传播等节点组里状态稳定一致之后才触发选举流程因为状态稳定一致基于同样的状态信息每个节点做出的决定会是一致的一旦某个节点符合成为master的条件无需其他节点认可它会自动将自己设为master。TDengine里任何一个节点检测到其他节点或自己的角色发生改变就会向节点组内其他节点进行广播。Raft里不存在这样的机制因此需要投票来解决。
- 对WAL的一条记录Raft用term + index来做唯一标识。但TDengine只用version类似index)在TDengine实现里仅仅用version是完全可行的, 因为TDengine的选举机制没有term的概念。
如果整个虚拟节点组全部宕机重启但不是所有虚拟节点都上线这个时候TDengine是不会选出master的因为未上线的节点有可能有最高version的数据。而RAFT协议只要超过半数上线就会选出Leader。
## Meta Data的数据复制
TDengine里存在时序数据也存在Meta Data。Meta Data对数据的可靠性要求更高那么TDengine设计能否满足要求呢下面做个仔细分析。
TDengine里Meta Data包括以下
- account 信息
- 一个account下面可以有多个user, 多个DB
- 一个DB下面有多个vgroup
- 一个DB下面有多个stable
- 一个vgroup下面有多个table
- 整个系统有多个mnode, dnode
- 一个dnode可以有多个vnode
上述的account, user, DB, vgroup, table, stable, mnode, dnode都有自己的属性这些属性是TDengine自己定义的不会开放给用户进行修改。这些Meta Data的查询都比较简单都可以采用key-value模型进行存储。这些Meta Data还具有几个特点
1. 上述的Meta Data之间有一定的层级关系比如必须先创建DB才能创建table, stable。只有先创建dnode才可能创建vnode, 才可能创建vgroup。因此他们创建的顺序是绝对不能错的。
2. 在客户端应用的数据更新操作得到TDengine服务器侧确认后所执行的数据更新操作绝对不能丢失。否则会造成客户端应用与服务器的数据不一致。
3. 上述的Meta Data是容许重复操作的。比如插入新记录后再插入一次删除一次后再删除一次更新一次后再更新一次不会对系统产生任何影响不会改变系统任何状态。
对于特点1本设计里数据的写入是单线程的按照到达的先后顺序给每个数据更新操作打上版本号版本号大的记录一定是晚于版本号小的写入系统数据写入顺序是100%保证的绝对不会让版本号大的记录先写入。复制过程中数据块的转发也是严格按照顺序进行的因此TDengine的数据复制设计是能保证Meta Data的创建顺序的。
对于特点2只要Quorum数设置等于replica那么一定能保证回复确认过的数据更新操作不会在服务器侧丢失。即使某节点永不起来只要超过一半的节点还是online, 查询服务不会受到任何影响。这时如果某个节点离线超过一定时长系统可以自动补充新的节点以保证在线的节点数在绝大部分时间是100%的。
对于特点3完全可能发生服务器确实持久化存储了某一数据更新操作但客户端应用出了问题认为操作不成功它会重新发起操作。但对于Meta Data而言没有关系客户端可以再次发起同样的操作不会有任何影响。
总结来看只要quorum设置大于一本数据复制的设计是能满足Meta Data的需求的。目前还没有发现漏洞。

View File

@ -1,119 +0,0 @@
---
sidebar_label: taosd 的设计
title: taosd的设计
---
逻辑上TDengine 系统包含 dnodetaosc 和 Appdnode 是服务器侧执行代码 taosd 的一个运行实例,因此 taosd 是 TDengine 的核心,本文对 taosd 的设计做一简单的介绍,模块内的实现细节请见其他文档。
## 系统模块图
taosd 包含 rpcdnodevnodetsdbquerycqsyncwalmnodehttpmonitor 等模块,具体如下图:
![modules.png](/img/architecture/modules.png)
taosd 的启动入口是 dnode 模块dnode 然后启动其他模块,包括可选配置的 httpmonitor 模块。taosc 或 dnode 之间交互的消息都是通过 rpc 模块进行dnode 模块根据接收到的消息类型,将消息分发到 vnode 或 mnode 的消息队列,或由 dnode 模块自己消费。dnode 的工作线程worker消费消息队列里的消息交给 mnode 或 vnode 进行处理。下面对各个模块做简要说明。
## RPC 模块
该模块负责 taosd 与 taosc以及其他数据节点之间的通讯。TDengine 没有采取标准的 HTTP 或 gRPC 等第三方工具,而是实现了自己的通讯模块 RPC。
考虑到物联网场景下,数据写入的包一般不大,因此除支持 TCP 连接之外RPC 还支持 UDP 连接。当数据包小于 15K 时RPC 将采用 UDP 方式进行连接,否则将采用 TCP 连接。对于查询类的消息RPC 不管包的大小,总是采取 TCP 连接。对于 UDP 连接RPC 实现了自己的超时、重传、顺序检查等机制,以保证数据可靠传输。
RPC 模块还提供数据压缩功能,如果数据包的字节数超过系统配置参数 compressMsgSizeRPC 在传输中将自动压缩数据,以节省带宽。
为保证数据的安全和数据的 integrityRPC 模块采用 MD5 做数字签名,对数据的真实性和完整性进行认证。
## DNODE 模块
该模块是整个 taosd 的入口,它具体负责如下任务:
- 系统的初始化,包括
- 从文件 taos.cfg 读取系统配置参数,从文件 dnodeCfg.json 读取数据节点的配置参数;
- 启动 RPC 模块,并建立起与 taosc 通讯的 server 连接,与其他数据节点通讯的 server 连接;
- 启动并初始化 dnode 的内部管理,该模块将扫描该数据节点已有的 vnode ,并打开它们;
- 初始化可配置的模块,如 mnodehttpmonitor 等。
- 数据节点的管理,包括
- 定时的向 mnode 发送 status 消息,报告自己的状态;
- 根据 mnode 的指示,创建、改变、删除 vnode
- 根据 mnode 的指示,修改自己的配置参数;
- 消息的分发、消费,包括
- 为每一个 vnode 和 mnode 的创建并维护一个读队列、一个写队列;
- 将从 taosc 或其他数据节点来的消息,根据消息类型,将其直接分发到不同的消息队列,或由自己的管理模块直接消费;
- 维护一个读的线程池,消费读队列的消息,交给 vnode 或 mnode 处理。为支持高并发一个读线程worker可以消费多个队列的消息一个读队列可以由多个 worker 消费;
- 维护一个写的线程池,消费写队列的消息,交给 vnode 或 mnode 处理。为保证写操作的序列化,一个写队列只能由一个写线程负责,但一个写线程可以负责多个写队列。
taosd 的消息消费由 dnode 通过读写线程池进行控制,是系统的中枢。该模块内的结构体图如下:
![dnode.png](/img/architecture/dnode.png)
## VNODE 模块
vnode 是一独立的数据存储查询逻辑单元,但因为一个 vnode 只能容许一个 DB ,因此 vnode 内部没有 accountDBuser 等概念。为实现更好的模块化、封装以及未来的扩展,它有很多子模块,包括负责存储的 TSDB负责查询的 query负责数据复制的 sync负责数据库日志的的 WAL负责连续查询的 cqcontinuous query负责事件触发的流计算的 event 等模块,这些子模块只与 vnode 模块发生关系,与其他模块没有任何调用关系。模块图如下:
![vnode.png](/img/architecture/vnode.png)
vnode 模块向下,与 dnodeVReaddnodeVWrite 发生互动,向上,与子模块发生互动。它主要的功能有:
- 协调各个子模块的互动。各个子模块之间都不直接调用,都需要通过 vnode 模块进行;
- 对于来自 taosc 或 mnode 的写操作vnode 模块将其分解为写日志WAL转发sync本地存储TSDB子模块的操作
- 对于查询操作,分发到 query 模块进行。
一个数据节点里有多个 vnode因此 vnode 模块是有多个运行实例的。每个运行实例是完全独立的。
vnode 与其子模块是通过 API 直接调用,而不是通过消息队列传递。而且各个子模块只与 vnode 模块有交互,不与 dnoderpc 等模块发生任何直接关联。
## MNODE 模块
mnode 是整个系统的大脑,负责整个系统的资源调度,负责 meta data 的管理与存储。
一个运行的系统里,只有一个 mnode但它有多个副本由系统配置参数 numOfMnodes 控制)。这些副本分布在不同的 dnode 里,目的是保证系统的高可靠运行。副本之间的数据复制是采用同步而非异步的方式,以确保数据的一致性,确保数据不会丢失。这些副本会自动选举一个 Master其他副本是 slave。所有数据更新类的操作都只能在 master 上进行,而查询类的可以在 slave 节点上进行。代码实现上,同步模块与 vnode 共享,但 mnode 被分配一个特殊的 vgroup ID: 1而且 quorum 大于 1。整个集群系统是由多个 dnode 组成的,运行的 mnode 的副本数不可能超过 dnode 的个数,但不会超过配置的副本数。如果某个 mnode 副本宕机一段时间,只要超过半数的 mnode 副本仍在运行,运行的 mnode 会自动根据整个系统的资源情况,在其他 dnode 里再启动一个 mnode以保证运行的副本数。
各个 dnode 通过信息交换,保存有 mnode 各个副本的 End Point 列表,并向其中的 master 节点定时(间隔由系统配置参数 statusInterval 控制)发送 status 消息,消息体里包含该 dnode 的 CPU、内存、剩余存储空间、vnode 个数,以及各个 vnode 的状态(存储空间、原始数据大小、记录条数、角色等)。这样 mnode 就了解整个系统的资源情况,如果用户创建新的表,就可以决定需要在哪个 dnode 创建;如果增加或删除 dnode或者监测到某 dnode 数据过热、或离线太长,就可以决定需要挪动那些 vnode以实现负载均衡。
mnode 里还负责 accountuserDBstabletablevgroupdnode 的创建、删除与更新。mnode 不仅把这些 entity 的 meta data 保存在内存,还做持久化存储。但为节省内存,各个表的标签值不保存在 mnode保存在 vnode而且子表不维护自己的 schema而是与 stable 共享。为减小 mnode 的查询压力taosc 会缓存 table、stable 的 schema。对于查询类的操作各个 slave mnode 也可以提供,以减轻 master 压力。
## TSDB 模块
TSDB 模块是 vnode 中的负责快速高并发地存储和读取属于该 vnode 的表的元数据及采集的时序数据的引擎。除此之外TSDB 还提供了表结构的修改、表标签值的修改等功能。TSDB 提供 API 供 vnode 和 query 等模块调用。TSDB 中存储了两类数据1元数据信息2时序数据
### 元数据信息
TSDB 中存储的元数据包含属于其所在的 vnode 中表的类型schema 的定义等。对于超级表和超级表下的子表而言,又包含了 tag 的 schema 定义以及子表的 tag 值等。对于元数据信息而言TSDB 就相当于一个全内存的 KV 型数据库,属于该 vnode 的表对象全部在内存中方便快速查询表的信息。除此之外TSDB 还对其中的子表,按照 tag 的第一列取值做了全内存的索引大大加快了对于标签的过滤查询。TSDB 中的元数据的最新状态在落盘时会以追加append-only的形式写入到 meta 文件中。meta 文件只进行追加操作即便是元数据的删除也会以一条记录的形式写入到文件末尾。TSDB 也提供了对于元数据的修改操作,如表 schema 的修改tag schema 的修改以及 tag 值的修改等。
### 时序数据
每个 TSDB 在创建时,都会事先分配一定量的内存缓冲区,且内存缓冲区的大小可配可修改。表采集的时序数据,在写入 TSDB 时,首先以追加的方式写入到分配的内存缓冲区中,同时建立基于时间戳的内存索引,方便快速查询。当内存缓冲区的数据积累到一定的程度时(达到内存缓冲区总大小的 1/3则会触发落盘操作将缓冲区中的数据持久化到硬盘文件上。时序数据在内存缓冲区中是以行row的形式存储的。
而时序数据在写入到 TSDB 的数据文件时是以列column的形式存储的。TSDB 中的数据文件包含多个数据文件组,每个数据文件组中又包含 .head、.data 和 .last 三个文件v2f1801.head、v2f1801.data、v2f1801.last数据文件组。TSDB 中的数据文件组是按照时间跨度进行分片的,默认是 10 天一个文件组,且可通过配置文件及建库选项进行配置。分片的数据文件组又按照编号递增排列,方便快速定位某一时间段的时序数据,高效定位数据文件组。时序数据在 TSDB 的数据文件中是以块的形式进行列式存储的,每个块中只包含一张表的数据,且数据在一个块中是按照时间顺序递增排列的。在一个数据文件组中,.head 文件负责存储数据块的索引及统计信息,如每个块的位置,压缩算法,时间戳范围等。存储在 .head 文件中一张表的索引信息是按照数据块中存储的数据的时间递增排列的,方便进行折半查找等工作。.head 和 .last 文件是存储真实数据块的文件,若数据块中的数据累计到一定程度,则会写入 .data 文件中,否则,会写入 .last 文件中,等待下次落盘时合并数据写入 .data 文件中,从而大大减少文件中块的个数,避免数据的过度碎片化。
## Query 模块
该模块负责整体系统的查询处理。客户端调用该该模块进行 SQL 语法解析,并将查询或写入请求发送到 vnode ,同时负责针对超级表的查询进行二阶段的聚合操作。在 vnode 端,该模块调用 TSDB 模块读取系统中存储的数据进行查询处理。query 模块还定义了系统能够支持的全部查询函数查询函数的实现机制与查询框架无耦合可以在不修改查询流程的情况下动态增加查询函数。详细的设计请参见《TDengine 2.0 查询模块设计》。
## SYNC 模块
该模块实现数据的多副本复制,包括 vnode 与 mnode 的数据复制,支持异步和同步两种复制方式,以满足 meta data 与时序数据不同复制的需求。因为它为 mnode 与 vnode 共享,系统为 mnode 副本预留了一个特殊的 vgroup ID:1。因此 vnode group 的 ID 是从 2 开始的。
每个 vnode/mnode 模块实例会有一对应的 sync 模块实例,他们是一一对应的。详细设计请见[TDengine 2.0 数据复制模块设计](/tdinternal/replica/)
## WAL 模块
该模块负责将新插入的数据写入 write ahead logWAL为 vnodemnode 共享。以保证服务器 crash 或其他故障,能从 WAL 中恢复数据。
每个 vnode/mnode 模块实例会有一对应的 WAL 模块实例是完全一一对应的。WAL 的落盘操作由两个参数 walLevelfsync 控制。看具体场景,如果要 100% 保证数据不会丢失,需要将 walLevel 配置为 2fsync 设置为 0每条数据插入请求都会实时落盘后才会给应用确认
## HTTP 模块
该模块负责处理系统对外的 RESTful 接口,可以通过配置,由 dnode 启动或停止 。(仅 2.2 及之前的版本中存在)
该模块将接收到的 RESTful 请求,做了各种合法性检查后,将其变成标准的 SQL 语句,通过 taosc 的异步接口,将请求发往整个系统中的任一 dnode 。收到处理后的结果后,再翻译成 HTTP 协议,返回给应用。
如果 HTTP 模块启动,就意味着启动了一个 taosc 的实例。任一一个 dnode 都可以启动该模块,以实现对 RESTful 请求的分布式处理。
## Monitor 模块
该模块负责检测一个 dnode 的运行状态,可以通过配置,由 dnode 启动或停止。原则上,每个 dnode 都应该启动一个 monitor 实例。
Monitor 采集 TDengine 里的关键操作,比如创建、删除、更新账号、表、库等,而且周期性的收集 CPU、内存、网络等资源的使用情况采集周期由系统配置参数 monitorInterval 控制。获得这些数据后monitor 模块将采集的数据写入系统的日志库DB 名字由系统配置参数 monitorDbName 控制)。
Monitor 模块使用 taosc 来将采集的数据写入系统,因此每个 monitor 实例,都有一个 taosc 运行实例。

View File

@ -1,44 +0,0 @@
---
title: TSZ 压缩算法
---
TSZ 压缩算法是 TDengine 为浮点数据类型提供更加丰富的压缩功能,可以实现浮点数的有损至无损全状态压缩,相比原来在 TDengine 中原有压缩算法TSZ 压缩算法压缩选项更丰富,压缩率更高,即使切到无损状态下对浮点数压缩,压缩率也会比原来的压缩算法高一倍。
## 适合场景
TSZ 压缩算法压缩率比原来的要高,但压缩时间会更长,即开启 TSZ 压缩算法写入速度会有一些下降,通常情况下会有 20% 左右的下降。影响写入速度是因为需要更多的 CPU 计算,所以从原始数据到压缩好数据的交付时间变长,导致写入速度变慢。如果您的服务器 CPU 配置很高的话,这个影响会变小甚至没有。
另外如果设备产生了大量的高精度浮点数,存储占用的空间非常庞大,但实际使用并不需要那么高的精度时,可以通过 TSZ 压缩的有损压缩功能,把精度压缩至指定的长度,节约存储空间。
总结:采集到了大量浮点数,存储时占用空间过大或出有存储空间不足,需要超高压缩率的场景。
## 使用步骤
- 检查版本支持2.4.0.10 及之后 TDengine 的版本都支持此功能
- 配置选项开启功能,在 TDengine 的配置文件 taos.cfg 增加一行以下内容,打开 TSZ 功能
```TSZ
lossyColumns float|double
```
- 根据自己需要配置其它选项,如果不配置都会按默认值处理。
- 重启服务,配置生效。
- 确认功能已开启,在服务启动过程中输出的信息如果有前面配置的内容,表明功能已生效:
```TSZ Test
02/22 10:49:27.607990 00002933 UTL lossyColumns float|double
```
## 注意事项
- 确认版本是否支持
- 除了服务器启动时的输出的配置成功信息外,不再会有其它的信息输出是使用的哪种压缩算法,可以通过配置前后数据库文件大小来比较效果
- 如果浮点数类型列较少,看整体数据文件大小效果会不太明显
- 此压缩产生的数据文件中浮点数据部分将不能被 2.4.0.10 以下的版本解析,即不向下兼容,使用时避免更换回旧版本,以免数据不能被读取出来。
- 在使用过程中允许反复开启和关闭 TSZ 压缩选项的操作,前后两种压缩算法产生的数据都能正常读取。

View File

@ -1,9 +0,0 @@
---
title: 物联网大数据
description: "物联网、工业互联网大数据的特点;物联网大数据平台应具备的功能和特点;通用大数据架构为什么不适合处理物联网数据;物联网、车联网、工业互联网大数据平台,为什么推荐使用 TDengine"
---
- [物联网、工业互联网大数据的特点](https://www.taosdata.com/blog/2019/07/09/105.html)
- [物联网大数据平台应具备的功能和特点](https://www.taosdata.com/blog/2019/07/29/542.html)
- [通用大数据架构为什么不适合处理物联网数据?](https://www.taosdata.com/blog/2019/07/09/107.html)
- [物联网、车联网、工业互联网大数据平台,为什么推荐使用 TDengine](https://www.taosdata.com/blog/2019/07/09/109.html)

View File

@ -1,25 +0,0 @@
---
title: 视频教程
---
## 技术公开课
- [技术公开课开源、高效的物联网大数据平台TDengine 内核技术剖析](https://www.taosdata.com/blog/2020/12/25/2126.html)
## 视频教程
- [TDengine 视频教程 - 快速上手](https://www.taosdata.com/blog/2020/11/11/1941.html)
- [TDengine 视频教程 - 数据建模](https://www.taosdata.com/blog/2020/11/11/1945.html)
- [TDengine 视频教程 - 集群搭建](https://www.taosdata.com/blog/2020/11/11/1961.html)
- [TDengine 视频教程 - Go Connector](https://www.taosdata.com/blog/2020/11/11/1951.html)
- [TDengine 视频教程 - JDBC Connector](https://www.taosdata.com/blog/2020/11/11/1955.html)
- [TDengine 视频教程 - Node.js Connector](https://www.taosdata.com/blog/2020/11/11/1957.html)
- [TDengine 视频教程 - Python Connector](https://www.taosdata.com/blog/2020/11/11/1963.html)
- [TDengine 视频教程 - RESTful Connector](https://www.taosdata.com/blog/2020/11/11/1965.html)
- [TDengine 视频教程 - “零”代码运维监控](https://www.taosdata.com/blog/2020/11/11/1959.html)
## 微课堂
关注 TDengine 视频号, 有精心制作的微课堂。
<img src="/img/shi-pin-hao.png" width={350} />

View File

@ -1,100 +0,0 @@
---
title: Performance Optimization
---
After a TDengine cluster has been running for long enough time, because of updating data, deleting tables and deleting expired data, there may be fragments in data files and query performance may be impacted. To resolve the problem of fragments, from version 2.1.3.0 a new SQL command `COMPACT` can be used to defragment the data files.
```sql
COMPACT VNODES IN (vg_id1, vg_id2, ...)
```
`COMPACT` can be used to defragment one or more vgroups. The defragmentation work will be put in task queue for scheduling execution by TDengine. `SHOW VGROUPS` command can be used to get the vgroup ids to be used in `COMPACT` command. There is a column `compacting` in the output of `SHOW GROUPS` to indicate the compacting status of the vgroup: 2 means the vgroup is waiting in task queue for compacting, 1 means compacting is in progress, and 0 means the vgroup has nothing to do with compacting.
Please be noted that a lot of disk I/O is required for defragementation operation, during which the performance may be impacted significantly for data insertion and query, data insertion may be blocked shortly in extreme cases.
## Optimize Storage Parameters
The data in different use cases may have different characteristics, such as the days to keep, number of replicas, collection interval, record size, number of collection points, compression or not, etc. To achieve best efficiency in storage, the parameters in below table can be used, all of them can be either configured in `taos.cfg` as default configuration or in the command `create database`. For detailed definition of these parameters please refer to [Configuration Parameters](/reference/config/).
| # | Parameter | Unit | Definition | **Value Range** | **Default Value** |
| --- | --------- | ---- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- | ----------------- |
| 1 | days | Day | The time range of the data stored in a single data file | 1-3650 | 10 |
| 2 | keep | Day | The number of days the data is kept in the database | 1-36500 | 3650 |
| 3 | cache | MB | The size of each memory block | 1-128 | 16 |
| 4 | blocks | None | The number of memory blocks used by each vnode | 3-10000 | 6 |
| 5 | quorum | None | The number of required confirmation in case of multiple replicas | 1-2 | 1 |
| 6 | minRows | None | The minimum number of rows in a data file | 10-1000 | 100 |
| 7 | maxRows | None | The maximum number of rows in a daa file | 200-10000 | 4096 |
| 8 | comp | None | Whether to compress the data | 0uncompressed; 1: One Phase compression; 2: Two Phase compression | 2 |
| 9 | walLevel | None | wal sync level (named as "wal" in create database ) | 1wal enabled without fsync; 2wal enabled with fsync | 1 |
| 10 | fsync | ms | The time to wait for invoking fsync when walLevel is set to 2; 0 means no wait | 3000 |
| 11 | replica | none | The number of replications | 1-3 | 1 |
| 12 | precision | none | Time precision | ms: millisecond; us: microsecond;ns: nanosecond | ms |
| 13 | update | none | Whether to allow updating data | 0: not allowed; 1: a row must be updated as whole; 2: a part of columns in a row can be updated | 0 |
| 14 | cacheLast | none | Whether the latest data of a table is cached in memory | 0: not cached; 1: the last row is cached; 2: the latest non-NULL value of each column is cached | 0 |
For a specific use case, there may be multiple kinds of data with different characteristics, it's best to put data with same characteristics in same database. So there may be multiple databases in a system while each database can be configured with different storage parameters to achieve best performance. The above parameters can be used when creating a database to override the default setting in configuration file.
```sql
CREATE DATABASE demo DAYS 10 CACHE 32 BLOCKS 8 REPLICA 3 UPDATE 1;
```
The above SQL statement creates a database named as `demo`, in which each data file stores data across 10 days, the size of each memory block is 32 MB and each vnode is allocated with 8 blocks, the replica is set to 3, update operation is allowed, and all other parameters not specified in the command follow the default configuration in `taos.cfg`.
Once a database is created, only some parameters can be changed and be effective immediately while others are can't.
| **Parameter** | **Alterable** | **Value Range** | **Syntax** |
| ------------- | ------------- | ---------------- | -------------------------------------- |
| name | | | |
| create time | | | |
| ntables | | | |
| vgroups | | | |
| replica | **YES** | 1-3 | ALTER DATABASE <dbname\> REPLICA _n_ |
| quorum | **YES** | 1-2 | ALTER DATABASE <dbname\> QUORUM _n_ |
| days | | | |
| keep | **YES** | days-365000 | ALTER DATABASE <dbname\> KEEP _n_ |
| cache | | | |
| blocks | **YES** | 3-1000 | ALTER DATABASE <dbname\> BLOCKS _n_ |
| minrows | | | |
| maxrows | | | |
| wal | | | |
| fsync | | | |
| comp | **YES** | 0-2 | ALTER DATABASE <dbname\> COMP _n_ |
| precision | | | |
| status | | | |
| update | | | |
| cachelast | **YES** | 0 \| 1 \| 2 \| 3 | ALTER DATABASE <dbname\> CACHELAST _n_ |
**Explanation** Prior to version 2.1.3.0, `taosd` server process needs to be restarted for these parameters to take in effect if they are changed using `ALTER DATABASE`.
When trying to join a new dnode into a running TDengine cluster, all the parameters related to cluster in the new dnode configuration must be consistent with the cluster, otherwise it can't join the cluster. The parameters that are checked when joining a dnode are as below. For detailed definition of these parameters please refer to [Configuration Parameters](/reference/config/).
- numOfMnodes
- mnodeEqualVnodeNum
- offlineThreshold
- statusInterval
- maxTablesPerVnode
- maxVgroupsPerDb
- arbitrator
- timezone
- balance
- flowctrl
- slaveQuery
- adjustMaster
For the convenience of debugging, the log setting of a dnode can be changed temporarily. The temporary change will be lost once the server is restarted.
```sql
ALTER DNODE <dnode_id> <config>
```
- dnode_id: from output of "SHOW DNODES"
- config: the parameter to be changed, as below
- resetlog: close the old log file and create the new on
- debugFlag: 131 (INFO/ERROR/WARNING), 135 (DEBUG), 143 (TRACE)
For example
```
alter dnode 1 debugFlag 135;
```

View File

@ -1,10 +0,0 @@
---
title: IoT Big Data
description: "Characteristics of IoT Big Data, why general big data platform does not work well for IoT? The required features for an IoT Big Data Platform"
---
- [Characteristics of IoT Big Data](https://tdengine.com/2019/07/09/86.html)
- [Why dont General Big Data Platforms Fit IoT Scenarios?](https://tdengine.com/2019/07/09/92.html)
- [Why TDengine is the Best Choice for IoT Big Data Processing?](https://tdengine.com/2019/07/09/94.html)
- [Why Redis, Kafka, Spark arent Needed if TDengine is Used in the IoT Platform?](https://tdengine.com/2019/07/09/96.html)