ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TDengine 3.0 整体架构深度解析:逻辑节点体系、一致性哈希分片、Raft 复制与多级存储

TDengine 3.0 整体架构深度解析:逻辑节点体系、一致性哈希分片、Raft 复制与多级存储 TDengine 3.0 整体架构深度解析逻辑节点体系、一致性哈希分片、Raft 复制与多级存储【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine本文基于 TDengine 官方架构文档系统梳理 TDengine 3.0 的分布式整体架构pnode/dnode/vnode/mnode/qnode/snode 六大逻辑单元的分工、节点间基于 FQDN 与端口的通信机制、典型写入消息的完整流转路径以及 vnode 数据分片、Raft 同步复制、写驱动缓存、预计算与多级存储的实现原理并结合开源仓库源码印证关键配置与调用链。读完本文你将能够理解 TDengine 集群的拓扑组织方式、定位数据在集群中的物理位置并为集群部署firstEp/serverPort等配置、数据库参数replica、duration、keep、cachemodel的调优打下坚实基础。集群与基本逻辑单元TDengine 的设计基于一个根本假设单台假设单个硬件、软件系统是不可靠的任何单台计算机都无法提供足够的计算与存储能力来处理海量数据。因此 TDengine 从研发第一天起就按照分布式高可靠架构设计支持水平扩展——任何单台或多台服务器发生硬件故障或软件错误都不影响系统的可用性与可靠性。同时通过节点虚拟化并辅以负载均衡技术TDengine 能最高效率地利用异构集群中的计算和存储资源降低硬件投资。一个完整的 TDengine 系统运行在一到多个物理节点上逻辑上包含数据节点dnode、TDengine 应用驱动taosc以及应用app。系统中存在一到多个数据节点这些数据节点组成一个集群cluster应用通过 taosc 的 API 与集群互动。物理节点pnodepnode 是一台独立运行、拥有自己的计算、存储和网络能力的计算机可以是安装有 OS 的物理机、虚拟机或 Docker 容器。物理节点由其配置的 FQDNFully Qualified Domain Name来标识TDengine 完全依赖 FQDN 来进行网络通讯。从源码看FQDN 的默认值是在服务端启动时自动获取的tglobal.c 中taosGetFqdnWithTimeCost()获取本机 FQDN获取失败时回退为localhost之后作为fqdn配置项的默认值注册进配置系统。数据节点dnodednode 是 TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例。在一个 TDengine 系统中至少需要一个 dnode 来确保系统正常运行。每个 dnode 包含零到多个逻辑的虚拟节点vnode但管理节点、计算节点和流式计算节点各有 0 个或 1 个逻辑实例。dnode 在集群中的唯一标识由其 endpointEP决定endpoint 由 dnode 所在物理节点的 FQDN 和配置的网络端口组合而成。通过配置不同端口一个 pnode无论是物理机、虚拟机还是 Docker 容器可以运行多个实例即拥有多个 dnode。端口的默认值与取值范围可直接在源码中确认tglobal.c 中tsServerPort初始化为6030配置项serverPort的合法范围为 165056。虚拟节点vnode为了更好地支持数据分片、负载均衡以及防止数据过热或倾斜TDengine 引入了 vnode虚拟节点概念。虚拟节点被虚拟化为多个独立的 vnode 实例如架构图中的 V2、V3、V4 等每个 vnode 都是相对独立的工作单元负责存储和管理一部分时序数据。每个 vnode 拥有独立的运行线程、内存空间和持久化存储路径确保数据的隔离性和高效访问一个 vnode 可包含多张表即数据采集点这些表在物理上分布在不同的 vnode 上实现数据均匀分布和负载均衡在集群中创建新数据库时系统会自动为该数据库创建相应的 vnode。一个 dnode 上能创建的 vnode 数量取决于其所在物理节点的 CPU、内存和存储容量一个 vnode 只能属于一个数据库但一个数据库可以包含多个 vnode除存储时序数据外每个 vnode 还保存其所含表的 schema 信息和标签值等元数据在集群内部一个 vnode 由其所归属 dnode 的 endpoint 和所属的 vgroup ID 唯一标识mnode 负责创建和管理这些 vnode确保它们正常运行并协同工作。管理节点mnodemnode管理节点是集群中的核心逻辑单元负责监控和维护所有 dnode 的运行状态并在节点之间实现负载均衡架构图中 M1、M2、M3。作为元数据用户、数据库、超级表等的存储和管理中心mnode 也被称为 MetaNode。为提高高可用性与可靠性集群允许存在多个最多 3 个mnode它们自动组成虚拟的 mnode 组共同承担管理职责mnode 支持多副本采用 Raft 一致性协议确保数据一致性和操作可靠性任何数据更新操作都必须在 leader 节点上执行mnode 集群的第 1 个节点在集群部署时自动创建其余节点的创建和删除由用户通过 SQL 手动完成每个 dnode 上最多有一个 mnode由其归属 dnode 的 endpoint 唯一标识每个 dnode 通过内部消息交互机制自动获取集群中所有 mnode 所在 dnode 的 endpoint。计算节点qnodeqnode 是集群中负责执行查询计算任务的虚拟逻辑单元同时处理基于系统表的 show 命令。为提高查询性能和并行处理能力集群可配置多个 qnode它们在整个集群范围内共享使用图中 Q1、Q2、Q3。与 dnode 不同qnode 不与特定数据库绑定一个 qnode 可同时处理来自多个数据库的查询任务每个 dnode 上最多有一个 qnode由其归属 dnode 的 endpoint 唯一标识。当客户端发起查询请求时首先与 mnode 交互以获取当前可用的 qnode 列表若集群中没有可用的 qnode计算任务将在 vnode 中执行。调度器会根据执行计划分配一个或多个 qnode 共同完成任务qnode 能从 vnode 获取数据并将计算结果发送给其他 qnode 进一步处理。通过引入独立的 qnodeTDengine 实现了存储与计算的分离。流式计算节点snodesnode 是集群中专门负责处理流式计算任务的虚拟逻辑单元图中 S1、S2、S3。为满足实时数据处理需求集群可配置多个 snode在集群范围内共享使用snode 不与特定流绑定可同时处理多个流的计算任务每个 dnode 上最多有一个 snode由其归属 dnode 的 endpoint 唯一标识。需要执行流式计算任务时mnode 会调度可用的 snode 来完成这些任务若集群中没有可用的 snode流式计算任务将无法按产品要求正常创建或运行以当前版本行为为准详见 流式计算文档。通过将流式计算任务集中在 snode 中处理TDengine 实现了流式计算与批量计算的分离提高系统对实时数据的处理能力。虚拟节点组VGroupvgroup虚拟节点组是由不同 dnode 上的 vnode 组成的逻辑单元。组内 vnode 采用 Raft 一致性协议确保集群高可用与高可靠写操作只能在 leader vnode 上执行数据以异步复制方式同步到其他 follower vnode从而在多个物理节点上保留数据副本。vgroup 中 vnode 的数量决定数据副本数。创建副本数为 N 的数据库集群必须至少包含 N 个 dnode副本数在创建数据库时通过参数replica指定默认值为 1利用多副本特性企业可以摒弃昂贵的硬盘阵列等传统存储设备依然实现数据的高可靠性vgroup 由 mnode 创建和管理并分配集群唯一的 vgroup ID。两个 vnode 的 vgroup ID 相同说明它们属于同一组、数据互为备份vgroup 中 vnode 数量可以动态调整但 vgroup ID 始终保持不变即使 vgroup 被删除其 ID 也不会被回收和重复利用。这种设计在保证数据安全性的同时实现了灵活的副本管理和动态扩展能力。Taosctaosc应用驱动是 TDengine 为应用程序提供的驱动程序负责处理应用与集群之间的接口交互。它提供 C/C 原生接口并被内嵌于 JDBC、C#、Python、Go、Node.js 等多种语言的连接库中。应用程序通过 taosc 而非直接连接集群中的 dnode 与整个集群通信taosc 负责获取并缓存元数据将写入、查询等请求转发到正确的 dnode并在将结果返回给应用之前执行最后一级聚合、排序、过滤等操作对于 JDBC、C/C、C#、Python、Go、Node.js 等接口taosc 运行在应用程序所处的物理节点上taosc 还可与 taosAdapter 交互支持全分布式的 RESTful 接口。这种设计使 TDengine 以统一方式支持多种编程语言和接口同时保持高性能与可扩展性。节点之间的通信通信方式集群内部各 dnode 之间、应用驱动与各 dnode 之间的通信均通过 TCP 实现确保传输的稳定性和可靠性。为优化网络传输性能并保障数据安全TDengine 会根据配置自动对传输数据做压缩/解压缩以减少带宽占用并支持数字签名和认证机制保障传输过程中的完整性与机密性。FQDN 配置每个 dnode 可拥有一个或多个 FQDN。在配置文件taos.cfg中使用fqdn参数指定未明确指定时dnode 自动获取所在计算机的 hostname 作为默认 FQDN——这与源码中defaultFqdn的获取逻辑一致tglobal.c。理论上可将fqdn设置为 IP 地址但官方不推荐IP 可能随网络环境变化导致集群无法正常工作。使用 FQDN 时需确保 DNS 正常工作或在节点与应用节点上正确配置 hosts 文件为保持兼容性和可移植性fqdn参数值的长度应控制在 96 个字符以内。端口配置每个 dnode 对外提供服务使用的端口由serverPort参数决定默认值为 6030取值范围 165056见 tglobal.c 中cfgAddInt32对serverPort的注册。通过调整该参数可灵活配置对外服务端口满足不同部署环境和安全策略需求。集群对外连接TDengine 集群可容纳单个、多个甚至几千个数据节点应用只需向集群中任意一个 dnode 发起连接即可简化了应用与集群的交互提高可扩展性和易用性。使用taosshell 连接集群时通过以下选项指定 dnode 的连接信息-h指定 dnode 的 FQDN。必需项告知应用连接到哪个 dnode-P指定 dnode 端口。可选项缺省时使用配置参数serverPort的默认值。这样应用可以灵活连接集群中任意 dnode无须关心集群的具体拓扑结构。集群内部通讯与 Mnode endpoint 的发现各 dnode 之间通过 TCP 通信。当一个 dnode 启动时先获取 mnode 所在 dnode 的 endpoint 信息再与集群中的 mnode 建立连接并交换信息从而及时加入集群、接收和执行集群层面的命令和任务。获取 mnode endpoint 信息的步骤为检查自己的dnode.json文件是否存在若不存在或无法正常打开以获得 mnode endpoint 信息进入第 2 步检查配置文件taos.cfg获取节点配置参数firstEp、secondEp这两个参数指定的节点可以是不带 mnode 的普通节点节点被连接时会尝试重定向到 mnode 节点若firstEp/secondEp不存在或无效进入第 3 步将自己的 endpoint 设为 mnode endpoint并独立运行。获取 mnode endpoint 列表后dnode 发起连接成功则加入工作集群失败则尝试列表中的下一个全部失败则休眠几秒后再次尝试。源码中firstEp是双端客户端/服务端作用域的配置项taosGetFqdnPortFromEp()负责解析 endpointtglobal.c默认回退值为localhost:6030。Mnode 的选择mnode 是逻辑概念并不对应单独执行代码的实体其功能由服务器侧的 taosd 进程管理。集群部署阶段第 1 个 dnode 自动承担 mnode 角色随后用户可通过 SQL 创建或删除额外 mnode数量与配置具有很高的灵活性。新数据节点的加入集群中有一个 dnode 启动并运行后集群即具备基本工作能力。扩展集群规模按以下两步添加新节点使用 TDengine CLI 连接现有 dnode执行create dnode命令添加新的 dnode引导完成新 dnode 的配置和注册在新加入 dnode 的配置文件taos.cfg中设置firstEp和secondEp参数分别指向现有集群中任意两个活跃 dnode 的 endpoint确保新 dnode 能正确加入集群并与现有节点通信。重定向无论是新启动的 dnode 还是 taosc首先需要与集群中的 mnode 建立连接但用户通常不知道哪个 dnode 正在运行 mnode。为此 TDengine 采用重定向机制不要求 dnode 或 taosc 直连特定 mnode只需向集群中任意一个正在工作的 dnode 发起连接每个活跃 dnode 都维护当前运行的 mnode endpoint 列表请求会被转发到适当的 mnode若接收请求的 dnode 不是 mnode它会立即将 mnode endpoint 列表回复给请求方taosc 或新 dnode 据此重新尝试连接当 mnode endpoint 列表变化时更新信息通过节点间消息机制迅速传播到各 dnode进而通知到 taosc。一个典型的消息流程为解释 vnode、mnode、taosc 和应用之间的关系与各自角色下面剖析写入数据这一典型操作的流程应用通过 JDBC 或其他 API 接口发起插入数据的请求taosc 检查缓存看是否保存有该表所在数据库的 vgroup-info 信息有则直接进入第 4 步否则向 mnode 发出 get vgroup-info 请求mnode 将该表所在数据库的 vgroup-info 返回给 taosc。vgroup-info 包含数据库的 vgroup 分布信息vnode ID 以及所在 dnode 的 End Point副本数为 N 就有 N 组 End Point还包含每个 vgroup 中存储数据表的 hash 范围。若 taosc 迟迟得不到 mnode 回应且存在多个 mnodetaosc 将向下一个 mnode 发出请求taosc 继续检查缓存看是否保存有该表的 meta-data有则进入第 6 步否则向 vnode 发出 get meta-data 请求vnode 将该表的 meta-data 返回给 taoscmeta-data 包含该表的 schemataosc 向 leader vnode 发起插入请求vnode 插入数据后给 taosc 应答表示插入成功。若 taosc 迟迟得不到 vnode 回应会认为该节点已离线此时若被插入数据库有多个副本taosc 将向 vgroup 里下一个 vnode 发出插入请求taosc 通知 APP 写入成功。其中两个关键细节对第 2 步mnode 发现taosc 启动时并不知道 mnode 的 End Point因此直接向配置的集群对外服务 End Point 发起请求。若接收该请求的 dnode 没有配置 mnode它会在回复消息中告知 mnode EP 列表taosc 据此重新向新的 mnode EP 发出请求对第 4 和第 6 步leader 定位没有缓存时taosc 无法知道 vgroup 里谁是 leader便假设第一个 vnodeID 就是 leader 并向它发请求。若接收请求的 vnode 不是 leader它会在回复中告知谁是 leadertaosc 便向建议的 leader vnode 发出请求得到插入成功回复后taosc 会缓存 leader 节点信息。查询、计算的流程与插入完全一致。taosc 把这些复杂流程全部封装屏蔽对应用无感知、无需任何特别处理。通过 taosc 的缓存机制只有第一次对一张表操作时才需要访问 mnode因此 mnode 不会成为系统瓶颈但由于 schema 可能变化、vgroup 可能改变如负载均衡发生taosc 会定时与 mnode 交互、自动更新缓存。存储模型与数据分区、分片存储模型TDengine 存储的数据包括采集的时序数据以及库、表相关的元数据、标签数据等具体分为三部分时序数据核心存储对象存储在 vnode 中由 data、head、sma 和 stt 4 类文件构成完整存储结构。针对时序数据量大、查询需求依场景而变的特点TDengine 采用一个数据采集点一张表的模型优化存储与查询一个时间段内数据连续存储对单张表的写入是简单的追加操作一次读取可获取多条记录确保单采集点的写入和查询都达到最优性能数据表元数据包含标签信息和 Table Schema 信息存放于 vnode 里的 meta 文件支持增删改查四个标准操作。表数量大N 张表即 N 条记录因此采用 LRU 存储并支持标签数据索引支持多核多线程并发查询。只要计算内存足够元数据全内存存储千万级规模的标签数据过滤结果能毫秒级返回内存不足时仍可支持数千万张表的快速查询数据库元数据存放于 mnode 中包含系统节点、用户、DB、STable Schema 等信息支持增删改查。这部分数据量不大可全内存保存且客户端有缓存、查询量也不大因此集中式存储管理不会构成性能瓶颈。与传统 NoSQL 存储模型相比TDengine 将标签数据与时序数据完全分离存储有两大优势显著降低标签数据存储冗余度。常见 NoSQL/时序数据库采用 Key-Value 模型Key 包含时间戳、设备 ID 及各种标签导致每条记录携带大量重复标签信息、浪费空间且要在历史数据上增删改标签就必须遍历整个数据集重写成本极高。标签与时序分离后这些问题被有效避免实现高效的多表聚合查询。进行多表聚合查询时TDengine 先根据标签过滤条件找出符合条件的表再查找这些表对应的数据块显著减少需要扫描的数据集大小大幅提升查询效率。数据分片实现水平扩展通常需要数据分片sharding与分区partitioning策略。TDengine 通过 vnode 实现数据分片通过按时间段划分数据文件实现时序数据分区。vnode 不仅负责时序数据的写入、查询和计算还承担负载均衡、数据恢复以及支持异构环境的角色。为实现这些目标TDengine 将一个 dnode 按计算和存储资源切分为多个 vnode整个过程对应用完全透明、由系统自动完成。对于单个数据采集点无论其数据量多大一个 vnode 都拥有足够的计算和存储资源来应对例如每秒生成一条 16B 的记录一年产生的原始数据量也不到 0.5GB。因此 TDengine 将一张表一个数据采集点的所有数据都存储在一个 vnode 中避免同一采集点的数据分散到两个或多个 dnode 上同时一个 vnode 可存储多个采集点表的数据最大可容纳表数上限为 100 万。设计上一个 vnode 中的所有表都属于同一个数据库。TDengine 3.0 采用一致性哈希算法确定每张数据表所在的 vnode创建数据库时集群立即分配指定数量的 vnode并确定每个 vnode 负责的数据表范围创建表时集群根据数据表名计算出其 vnode ID并在该 vnode 上创建表。若数据库有多个副本集群会创建一个 vgroup 而非仅一个 vnode。集群对 vnode 数量没有限制仅受限于物理节点本身的计算和存储资源。每张表的元数据schema、标签等也存储在 vnode 中而非集中存储在 mnode 上——这实际上是对元数据的分片有助于高效并行地执行标签过滤进一步提高查询性能。数据分区除 vnode 分片外TDengine 还按时间段对时序数据分区每个数据文件仅包含一个特定时间段的时序数据时间段长度由数据库参数duration决定。按时间段分区简化了数据管理便于高效实施数据保留策略——数据文件超过keep参数指定的天数后系统自动删除过期的数据文件。此外TDengine 支持将不同时间段的数据存储在不同路径和存储介质中使大数据冷热管理简单易行用户可按需实现多级存储优化存储成本和访问性能。综合来看TDengine 通过 vnode 和时间两个维度对大数据进行精细切分实现高效并行管理和水平扩展兼顾处理速度、效率和存储方案的灵活性。负载均衡与扩容每个 dnode 定期向 mnode 报告当前状态包括硬盘空间使用情况、内存大小、CPU 利用率、网络状况以及 vnode 数量等关键指标用于集群健康监控和资源调度。触发时机目前 TDengine 允许用户手动指定负载均衡的触发时机。当新的 dnode 加入集群后用户需要手动启动负载均衡流程动态再平衡随时间推移数据分布可能变化某些 vnode 会成为热点。TDengine 采用基于 Raft 协议的副本调整和数据拆分算法实现数据的动态扩容和再分配可在集群运行时无缝进行不影响数据写入和查询服务。数据写入与复制流程在一个具有 N 个副本的数据库中相应 vgroup 包含 N 个编号相同的 vnode其中只有一个被指定为 leader其余充当 follower。这种主从架构确保数据的一致性和可靠性。应用写入时只有 leader vnode 能接受请求若 follower vnode 意外收到写入请求集群会立即通知 taosc 重新定向到 leader vnode从而确保所有写入都发生在正确的 leader 上。Leader Vnode 写入流程leader vnode 收到应用的写入数据请求验证有效性后进入第 2 步vnode 将该请求的原始数据包写入数据库日志文件 WAL。若wal_level设置为 2 且wal_fsync_period设置为 0TDengine 还将 WAL 数据立即落盘保证即使宕机也能从数据库日志文件中恢复数据、避免丢失若存在多个副本vnode 将数据包转发给同一 vgroup 内的 follower vnodes转发包带有数据的版本号version写入内存并将记录加入 skip list若未达成一致会触发回滚操作leader vnode 返回确认信息给应用表示写入成功若第 2、3、4 步中任何一步失败将直接返回错误给应用。其中wal_fsync_period是数据库级参数可通过系统表查询systable.c 中注册了wal_fsync_period系统表列创建 vgroup 时该值经由 vnode 创建请求下发vmHandle.c 中pCfg-walCfg.fsyncPeriod pCreate-walFsyncPeriod将其写入 vnode 的 WAL 配置。Follower Vnode 写入流程follower vnode 的写入流程为follower vnode 收到 leader vnode 转发的数据插入请求vnode 将请求的原始数据包写入 WAL同样地若wal_level为 2 且wal_fsync_period为 0WAL 数据立即落盘以保证宕机可恢复写入内存更新内存中的 skip list。与 leader 相比follower 不存在转发环节和回复确认环节少了两步但写内存与 WAL 的行为完全一致。主从选择每个 vnode 维护一个数据版本号vnode 对内存数据持久化时版本号也被一并持久化每次更新数据无论时序数据还是元数据都会使版本号递增确保每次修改都被准确记录。vnode 启动时其角色leader 或 follower不确定且数据未同步。为确定角色并同步数据vnode 需与同一 vgroup 内其他节点建立 TCP 连接连接建立后互相交换版本号、任期等关键信息随后使用标准 Raft 一致性算法完成选主确定谁是 leader、谁是 follower。这一机制确保分布式环境下 vnode 之间有效协调一致维护数据一致性与系统稳定性。同步复制TDengine 中leader vnode 收到写入请求并转发给其他副本时不会立即通知应用写入成功——它需要等待超过半数的副本包括自身达成一致后才向应用确认若规定时间内未获得半数以上副本确认leader 将返回错误表明写入失败。这种同步复制机制确保多副本间的一致性和安全性但也带来写入性能挑战。为平衡一致性与性能TDengine 在同步复制中引入了流水线复制算法不同数据库连接的写入请求确认过程可以并行进行而非顺序等待即使某个副本确认延迟也不会阻塞其他副本的写入操作从而在保证一致性的同时显著提升写入性能满足高吞吐、低延迟的数据处理需求。成员变更在数据扩容、节点迁移等场景中需要调整 vgroup 的副本数目。此时存量数据的多少直接影响副本间数据复制的时间过多数据复制可能严重阻塞读写过程。为解决该问题TDengine 对 Raft 协议进行扩展引入learner 角色learner 在复制过程中负责接收数据复制但不参与投票由于不参与投票写入成功的判定条件不包括 learner 的确认。当 learner 与 leader 的数据差异较大时learner 采用快照snapshot方式同步数据快照同步完成后继续追赶 leader 的日志直至两者数据量接近一旦足够接近learner 便转变为 follower 角色开始参与数据写入的投票和选举投票过程。重定向taosc 写入新记录时首先需要定位当前的 leader vnode因为只有 leader 处理写入请求。若 taosc 将请求发送到 follower vnode集群会立即通知 taosc 重定向到正确的 leader vnode。为确保请求正确路由taosc 维护节点组拓扑的本地缓存收到集群通知后taosc 根据最新拓扑信息重新计算并确定 leader vnode 位置将请求发送给它同时更新本地缓存中的 leader 分布信息以备后续使用。这一机制确保应用通过 taosc 访问 TDengine 时无须关心网络重试问题——无论集群节点如何变化taosc 都能自动处理确保写入请求始终正确路由到 leader vnode。缓存与持久化时序数据缓存TDengine 采用独特的时间驱动写驱动缓存管理策略与传统的读驱动缓存模式不同核心是优先将最新写入的数据存储在集群缓存中当缓存容量接近阈值时将最早期的数据批量写入硬盘。具体机制每个 vnode 拥有独立内存空间内存被划分为多个固定大小的内存块不同 vnode 之间的内存完全隔离数据写入采用类似日志的顺序追加方式每个 vnode 维护自身的 SkipList 结构以便快速检索一旦超过三分之一的内存块被写满系统启动数据落盘过程并将新写入引导至新的内存块。如此 vnode 中三分之一的内存块始终保留最新数据既实现缓存目的又保证查询高效vnode 的内存大小可通过数据库参数buffer配置。物联网数据场景下用户通常最关注数据的实时性最新产生的数据。TDengine 利用了这一特点将最新到达的数据直接存入缓存快速响应用户对最新一条或多条数据的查询和分析需求从而提高整体查询响应速度。合理设置数据库参数后TDengine 完全可以作为数据缓存使用无须再部署 Redis 或其他额外缓存系统简化架构并降低运维成本。需要注意的是一旦 TDengine 重启缓存中的数据将被清除先前缓存的数据会被批量写入硬盘而不会像专业 Key-Value 缓存系统那样自动重新加载回缓存。last/last_row 缓存在时序场景下查询表的最后一条记录last_row或最后一条非 NULL 记录last是常见需求。为提高响应速度TDengine 为每张表的 last 和 last_row 数据提供 LRU 缓存缓存采用延迟加载策略首次查询某表 last/last_row 时缓存模块从内存池和磁盘文件加载数据处理后放入 LRU 缓存并返回给查询模块继续处理有新数据插入或删除时如缓存需要更新则进行相应更新若缓存中没有当前被写入表的数据则直接跳过缓存配置更新时也会更新缓存数据缓存功能默认关闭用户开启后在首次查询时加载数据关闭缓存开关时释放之前的缓存区查询子表的 last/last_row 时若缓存中没有则从内存池和磁盘文件加载对应数据到缓存查询超级表的 last/last_row 时该超级表对应的所有子表都需要加载到缓存中。数据库参数cachemodel用于配置某数据库的缓存参数默认值none不开启缓存其余三个取值为last_row、last_value、both分别表示开启 last_row 缓存、开启 last 缓存、两者同时开启。该参数在 mnode 侧由 mndDb.c 的getCacheModelStr()转换为字符串展示也是系统表中的列systable.c。缓存当前使用的内存数量可通过show vgroups;命令在cacheload列查看单位为字节。持久化存储TDengine 采用数据驱动的策略实现缓存数据的持久化当 vnode 中缓存数据积累到一定量时为避免阻塞后续写入系统启动落盘线程将缓存数据写入持久化存储设备。过程中会创建新的数据库日志文件用于数据落盘并在落盘成功后删除旧日志文件防止日志文件无限制增长。为充分发挥时序数据特性TDengine 将一个 vnode 的数据分割成多个文件每个文件仅存储固定天数的数据天数由数据库参数duration设定。分文件存储使得查询特定时间段数据时无须依赖索引即可迅速确定需要打开哪些数据文件极大提高读取效率。采集数据通常有保留期限由数据库参数keep指定超出天数的数据文件被集群自动移除并释放空间。参数规划原则设置duration和keep后典型工作状态的 vnode 中数据文件总数应为 ⌈keep/duration⌉ 1 个文件总数应保持在合理范围不宜过多也不宜过少通常 10100 之间较为适宜可据此反推duration的合理取值。注意keep可调整但duration一旦设定则无法更改。数据块与文件布局每个数据文件中表的数据以块block形式存储一张表可能包含一到多个文件块。块内数据采用列式存储、占据连续空间有助于显著提高读取速度块大小由数据库参数maxRows每块最大记录条数控制默认值 4096——过大导致定位特定时间段数据的搜索时间变长过小导致块索引过大、压缩效率降低均影响读取速度。每个数据文件块.data结尾配有一个索引文件.head结尾记录各文件块的摘要信息在数据文件中的偏移量、起始时间、结束时间等便于快速定位。此外每个数据块还关联一个 last 文件.last结尾防止文件块落盘碎片化若某表落盘记录条数未达到minRows每块最小记录条数要求记录先存入 last 文件待下次落盘时与新记录合并后再写入数据文件块。压缩写盘时是否压缩取决于数据库参数comp提供 3 种选项——无压缩、一级压缩、二级压缩对应值 0、1、2。一级压缩按数据类型采用相应算法如 delta-delta 编码、simple8B 编码、zig-zag 编码、LZ4 等二级压缩在一级压缩基础上进一步使用通用压缩算法以获得更高压缩率。预计算为显著提高查询处理效率TDengine 在数据文件块头部存储该块的统计信息最大值、最小值、数据总和即预计算单元。查询处理涉及这些计算时可直接利用预计算值无须访问块的具体内容对硬盘 I/O 成为瓶颈的查询场景预计算结果能有效减轻 I/O 压力、提高查询速度。除预计算外TDengine 还支持对原始数据进行多种降采样存储Rollup SMA自动对原始数据降采样存储支持 3 个不同的数据保存层级用户可指定每层数据的聚合周期和保存时长。适合关注数据趋势的场景核心目的是减少存储开销并提高查询速度Time-Range-Wise SMA根据聚合结果进行降采样存储非常适合高频 interval 查询场景。该功能采用与普通流式计算相同的逻辑允许用户通过设置 watermark 处理延时数据相应的实际查询结果也有一定时间延迟。多级存储与对象存储说明多级存储功能仅企业版支持。默认配置下TDengine 将所有数据保存在/var/lib/taos目录每个 vnode 的数据文件保存于该目录下不同子目录。为扩大存储空间、减少文件读取瓶颈、提高数据吞吐率可通过系统参数dataDir让多个挂载的硬盘被系统同时使用。TDengine 还提供数据分级存储功能将不同时间段的数据存储在挂载的不同介质目录中使不同热度的数据落在不同存储介质上充分利用存储、节约成本。例如最新采集的数据访问频繁、对读取性能要求高可配置存储在 SSD 盘上超过一定期限、查询需求降低的数据可存储在更便宜的 HDD 盘上。多级存储支持 3 级每级最多可配置 128 个挂载点。配置方式配置文件/etc/taos/taos.cfg中dataDir [path] level primary disable_create_new_file参数说明path挂载点的文件夹路径level介质存储等级取值 0、1、2。0 级存储最新数据1 级存储次新数据2 级存储最老数据省略默认为 0。各级存储之间数据流向为 0 级 - 1 级 - 2 级同一存储等级可挂载多个硬盘该等级上的数据文件分布在该等级所有硬盘上。数据在不同级别介质上的移动由系统自动完成用户无需干预primary是否为主挂载点0否或 1是省略默认为 1disable_create_new_file是否禁止创建新文件组0否或 1是省略默认为 0。配置中只允许存在一个主挂载点level0 且 primary1例如dataDir /mnt/data1 0 1 0 dataDir /mnt/data2 0 0 0 dataDir /mnt/data3 1 0 0 dataDir /mnt/data4 1 0 1 dataDir /mnt/data5 2 0 0 dataDir /mnt/data6 2 0 0可通过以下命令动态修改 dataDir 的 disable 来控制当前目录是否开启 disable_create_new_filealter dnode 1 /mnt/disk2/taos 1;多级存储的配置约束不允许跨级配置合法方案只有仅 0 级、0 级 1 级、0 级 1 级 2 级不允许只配置 level0 和 level2 而不配置 level1禁止手动移除使用中的挂载盘挂载盘目前不支持非本地的网络盘多级存储目前不支持删除已挂载硬盘的功能0 级存储至少存在一个 disable_create_new_file 为 0 的挂载点1 级和 2 级存储没有该限制。小结TDengine 3.0 的整体架构可以概括为以 pnode/dnode/vnode 为物理与逻辑骨架以 mnode 集中管理元数据、以 vgroup 的 Raft 复制保障多副本一致性以 qnode/snode 实现计算与流式计算分离以 taosc 屏蔽分布式复杂性存储侧则通过一致性哈希分片 时间分区、写驱动缓存、块级列存与预计算、Rollup/Time-Range SMA 降采样以及多级存储共同支撑起高吞吐写入与高效查询。源码层面taos.cfg 配置解析与默认值、vgroup 参数下发链路、mnode 元数据持久化 等模块与本文描述的架构一一对应读者可沿这些文件继续深入阅读实现细节。【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表