首页 › AI Agent实战项目案例库 › 智能制造Agent项目拆解:从对话框到真实生产力落地全流程 › 数据缓存Agent

数据缓存Agent

​

在现代物联网(IoT)和工业互联网(IIoT)应用中,数据的高效管理对系统性能和用户体验至关重要。​

​

​

🔔

为了应对高并发环境下的实时读写需求,设计了一套完整的缓存机制,包括写缓存、读缓存、元数据缓存和文件系统缓存。​

​

写缓存​

在物联网数据应用中,用户往往最关注最近产生的数据,即设备的当前状态。TDengine 充分利用了这一业务特性,将最近到达的当前状态数据优先存储在缓存中,以便用户能够快速获取所需信息。​

创建数据库时的两个关键参数 vgroups 和 buffer 分别决定了数据库中的数据由多少个 vgroup 进行处理,以及为每个 vnode 分配多少写入缓存。通过合理配置这两个参数,用户可以根据实际需求调整数据库的性能和存储容量,从而实现最佳的性能和成本效益。​

例如,下面的 SQL 创建了包含 10 个 vgroup、每个 vnode 占用 256MB 内存的数据库。​

​

代码块​

SQL

CREATE DATABASE POWER VGROUPS 10 BUFFER 256 CACHEMODEL 'NONE' PAGES 128 PAGESIZE 16;​

​

缓存越大越好,但超过一定阈值后再增加缓存对写入性能提升并无帮助。参数含义见 VGROUPS、BUFFER。​

读缓存​

通过设置 cachemodel 参数,TDengine 用户可以灵活选择适合的缓存模式,包括缓存最新一行数据、每列最近的非 NULL 值,或同时缓存行和列的数据。这种灵活性使 TDengine 能根据具体业务需求提供精准优化,在物联网场景下尤为突出,助力用户快速访问设备的最新状态。​

​

#tiSRRvsGSNJT text { white-space: pre; }#tiSRRvsGSNJT .fb0 { stroke: var(--N900-FG, 0.15); }#tiSRRvsGSNJT .fb0 {stroke: rgba(31,35,41, 0.15)}#tiSRRvsGSNJT .fx0 { stroke-miterlimit: 10; }#tiSRRvsGSNJT .fx0 {stroke-miterlimit: 10}#tiSRRvsGSNJT .fa1 { fill: rgb(187, 191, 196); }#tiSRRvsGSNJT .fa1 {fill: rgb(187, 191, 196)}#tiSRRvsGSNJT .fx1 { font: 400 12px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#tiSRRvsGSNJT .fx1 {font-style: normal}#tiSRRvsGSNJT .fx2 { text-anchor: middle; }#tiSRRvsGSNJT .fx2 {text-anchor: middle}#tiSRRvsGSNJT .fx3 { dominant-baseline: central; }#tiSRRvsGSNJT .fx3 {dominant-baseline: central}#tiSRRvsGSNJT .fx4 { stroke: none; }#tiSRRvsGSNJT .fx4 {stroke: none}#tiSRRvsGSNJT .fc0 { fill: var(--text-caption); }#tiSRRvsGSNJT .fc0 {fill: #646a73}#tiSRRvsGSNJT .fa2 { fill: var(--text-link-disabled); }#tiSRRvsGSNJT .fa2 {fill: rgb(187, 191, 196)}#tiSRRvsGSNJT .fx5 { font: 700 14px LarkHackSafariFont, LarkEmojiFont, "IBM Plex Mono", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, "Noto Sans", Tahoma, "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", STHeiti, SimHei, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", system-ui; }#tiSRRvsGSNJT .fx5 {font-style: normal}#tiSRRvsGSNJT .fx6 { text-anchor: start; }#tiSRRvsGSNJT .fx6 {text-anchor: start}#tiSRRvsGSNJT .fx7 { dominant-baseline: alphabetic; }#tiSRRvsGSNJT .fx7 {dominant-baseline: alphabetic}#tiSRRvsGSNJT .fc1 { fill: rgb(20, 20, 20); }#tiSRRvsGSNJT .fc1 {fill: rgb(20, 20, 20)}#tiSRRvsGSNJT .fx8 { font: 400 14px LarkHackSafariFont, LarkEmojiFont, "IBM Plex Mono", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, "Noto Sans", Tahoma, "Nimbus Sans L", Arial, "Liberation Sans", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Zen Hei", STHeiti, SimHei, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", system-ui; }#tiSRRvsGSNJT .fx8 {font-style: normal}#tiSRRvsGSNJT .fx9 { font: 700 16px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#tiSRRvsGSNJT .fx9 {font-style: normal}#tiSRRvsGSNJT .fx10 { font: 400 16px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#tiSRRvsGSNJT .fx10 {font-style: normal}#tiSRRvsGSNJT .fb1 { fill: var(--N900-FG, 0.15); }#tiSRRvsGSNJT .fb1 {fill: rgba(31,35,41, 0.15)}#tiSRRvsGSNJT .fb2 { fill: rgb(218, 221, 225); }#tiSRRvsGSNJT .fb2 {fill: rgb(218, 221, 225)}#tiSRRvsGSNJT .fa3 { fill: var(--bg-body); }#tiSRRvsGSNJT .fa3 {fill: #fff}ABC12345CACHEMODELnonelast_rowlast_valuebothLAST_ROWWHEREORDER BYGROUP BYINTERVALLASTLAST_ROWLAST缓存内容主要加速不缓存(默认)子表最近一行子表每列最近的非 NULL 值同时缓存最近行与最近列值—无 、、、 等特殊影响时的 与上述条件下的

​

这种设计不仅降低了查询的响应延迟,还能有效缓解存储系统的 I/O 压力。在高并发场景下,读缓存能够帮助系统维持更高的吞吐量,确保查询性能的稳定性。借助 TDengine 读缓存,用户无需再集成如 Redis 一类的外部缓存系统,避免了系统架构的复杂化,显著降低运维和部署成本。​

此外,TDengine 的读缓存机制还能够根据实际业务场景灵活调整。在数据访问热点集中在最新记录的场景中,这种内置缓存能够显著提高用户体验,让关键数据的获取更加快速高效。相比传统缓存方案,这种无缝集成的缓存策略不仅简化了开发流程,还为用户提供了更高的性能保障。​

关于 TDengine 读缓存的更多详细内容请看 读缓存。LAST / LAST_ROW 函数语义见 LAST、LAST_ROW;LRU、延迟加载等机制见 整体架构:last/last_row 缓存。​

元数据缓存​

为了提升查询和写入操作的效率,每个 vnode 都配备了缓存机制,用于存储其曾经获取过的元数据。这一元数据缓存的大小由创建数据库时的两个参数 pages 和 pagesize 共同决定。其中,pagesize 参数的单位是 KB,用于指定每个缓存页的大小。如下 SQL 会为数据库 power 的每个 vnode 创建 128 个 page、每个 page 16KB 的元数据缓存​

​

代码块​

SQL

CREATE DATABASE POWER PAGES 128 PAGESIZE 16;​

​

默认与取值范围见 PAGES、PAGESIZE。​

文件系统缓存​

TDengine 采用 WAL 技术作为基本的数据可靠性保障手段。WAL 是一种先进的数据保护机制,旨在确保在发生故障时能够迅速恢复数据。其核心原理在于,在数据实际写入数据存储层之前,先将其变更记录到一个日志文件中。这样一来,即便集群遭遇崩溃或其他故障,也能确保数据安全无损。​

TDengine 利用这些日志文件实现故障前的状态恢复。在写入 WAL 的过程中,数据是以顺序追加的方式写入硬盘文件的。因此,文件系统缓存在此过程中发挥着关键作用,对写入性能产生显著影响。为了确保数据真正落盘,系统会调用 fsync 函数,该函数负责将文件系统缓存中的数据强制写入硬盘。​

数据库参数 wal_level 和 wal_fsync_period 共同决定了 WAL 的保存行为。​

•

wal_level:此参数控制 WAL 的保存级别。级别 1 表示仅将数据写入 WAL,但不立即执行 fsync 函数;级别 2 则表示在写入 WAL 的同时执行 fsync 函数。默认情况下,wal_level 设为 1。虽然执行 fsync 函数可以提高数据的持久性,但相应地也会降低写入性能。​

•

wal_fsync_period:当 wal_level 设置为 2 时,这个参数控制执行 fsync 的频率。设置为 0 则表示每次写入后立即执行 fsync,这可以确保数据的安全性,但可能会牺牲一些性能。当设置为大于 0 的数值时,则表示 fsync 周期,默认为 3000,范围是[1, 180000],单位毫秒。​

​

代码块​

SQL

CREATE DATABASE POWER WAL_LEVEL 2 WAL_FSYNC_PERIOD 3000;​

​

在创建数据库时,用户可以根据需求选择不同的参数设置,以在性能和可靠性之间找到最佳平衡:​

•

性能优先:将数据写入 WAL,但不立即执行 fsync 操作,此时新写入的数据仅保存在文件系统缓存中,尚未同步到磁盘。这种配置能够显著提高写入性能。​

•

可靠性优先:将数据写入 WAL 的同时执行 fsync 操作,将数据立即同步到磁盘,确保数据持久化,可靠性更高。​