Update 02-cache.md

This commit is contained in:
eryue1993 2024-11-21 14:04:20 +08:00 committed by GitHub
parent 9d1fe8b233
commit d4c99244d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 24 additions and 48 deletions

View File

@ -1,68 +1,44 @@
---
sidebar_label: 数据缓存
title: 数据缓存
sidebar_label: 缓存
title: 缓存
toc_max_heading_level: 4
---
工业互联网和物联网大数据应用场景中,时序数据库的性能表现尤为关键。这类应用程序不仅要求数据的实时写入能力,还需求能够迅速获取设备的最新状态或对最新数据进行实时计算。通常,大数据平台会通过部署 Redis 或类似的缓存技术来满足这些需求。然而,这种做法会增加系统的复杂性和运营成本
物联网IoT和工业互联网IIoT大数据应用场景中实时数据的价值往往远超历史数据。企业不仅需要数据处理系统具备高效的实时写入能力更需要能快速获取设备的最新状态或者对最新数据进行实时计算和分析。无论是工业设备的状态监控、车联网中的车辆位置追踪还是智能仪表的实时读数当前值都是业务运行中不可或缺的核心数据。这些数据直接关系到生产安全、运营效率以及用户体验
为了解决这一问题TDengine 采用了针对性的缓存优化策略。通过精心设计的缓存机制TDengine 实现了数据的实时高效写入和快速查询,从而有效降低整个集群的复杂性和运营成本。这种优化不仅提升了性能,还为用户带来了更简洁、易用的解决方案,使他们能够更专注于核心业务的发展
例如,在工业生产中,生产线设备的当前运行状态至关重要。操作员需要实时监控温度、压力、转速等关键指标,一旦设备出现异常,这些数据必须即时呈现,以便迅速调整工艺参数,避免停产或更大的损失。在车联网领域,以滴滴为例,车辆的实时位置数据是滴滴平台优化派单策略、提升运营效率的关键,确保每位乘客快速上车并享受更高质量的出行体验
## 写缓存
同时,看板系统和智能仪表作为现场操作和用户端的窗口,也需要实时数据支撑。无论是工厂管理者通过看板获取的实时生产指标,还是家庭用户随时查询智能水表、电表的用量,实时性不仅影响到运营和决策效率,更直接关系到用户对服务的满意程度。
TDengine 采用了一种创新的时间驱动缓存管理策略,亦称为写驱动的缓存管理机制。这一策略与传统的读驱动的缓存模式有所不同,其核心思想是将最新写入的数据优先保存在缓存中。当缓存容量达到预设的临界值时,系统会将最早存储的数据批量写入硬盘,从而实现缓存与硬盘之间的动态平衡。
## 传统缓存方案的局限性
在物联网数据应用中用户往往最关注最近产生的数据即设备的当前状态。TDengine 充分利用了这一业务特性,将最近到达的当前状态数据优先存储在缓存中,以便用户能够快速获取所需信息。
为了满足这些高频实时查询需求,许多企业选择将 Redis 等缓存技术集成到大数据平台中,通过在数据库和应用之间添加一层缓存来提升查询性能。然而,这种方法也带来了不少问题:
- 系统复杂性增加:需要额外部署和维护缓存集群,对系统架构提出了更高的要求。
- 运营成本上升:需要额外的硬件资源来支撑缓存,增加了维护和管理的开销。
- 一致性问题:缓存和数据库之间的数据同步需要额外的机制来保障,否则可能出现数据不一致的情况。
为了实现数据的分布式存储和高可用性TDengine 引入了虚拟节点vnode的概念。每个 vnode 可以拥有多达 3 个副本,这些副本共同组成一个 vnode group简称 vgroup。在创建数据库时用户需要确定每个 vnode 的写入缓存大小,以确保数据的合理分配和高效存储。
## TDengine 的解决方案:内置读缓存
创建数据库时的两个关键参数 `vgroups``buffer` 分别决定了数据库中的数据由多少个 vgroup 进行处理,以及为每个 vnode 分配多少写入缓存。通过合理配置这两个
参数,用户可以根据实际需求调整数据库的性能和存储容量,从而实现最佳的性能和成本效益。
为了解决这些问题TDengine 针对物联网和工业互联网的高频实时查询场景,设计并实现了读缓存机制。这一机制能够自动将每张表的最后一条记录缓存到内存中,从而在不引入第三方缓存技术的情况下,直接满足用户对当前值的实时查询需求。
例 如, 下面的 SQL 创建了包含 10 个 vgroup每个 vnode 占 用 256MB 内存的数据库。
```sql
CREATE DATABASE POWER VGROUPS 10 BUFFER 256 CACHEMODEL 'NONE' PAGES 128 PAGESIZE 16;
```
TDengine 采用时间驱动的缓存管理策略,将最新数据优先存储在缓存中,查询时无需访问硬盘即可快速返回结果。当缓存容量达到设定上限时,系统会批量将最早的数据写入硬盘,既提升了查询效率,也有效减少了硬盘的写入负担,延长硬件使用寿命。
缓存越大越好,但超过一定阈值后再增加缓存对写入性能提升并无帮助
用户可通过设置 cachemodel 参数,自定义缓存模式,包括缓存最新一行数据、每列最近的非 NULL 值,或同时缓存行和列的数据。这种灵活设计在物联网场景中尤为重要,使设备状态的实时查询更加高效精准。
## 读缓存
这种读缓存机制的内置化设计显著降低了查询延迟,避免了引入 Redis 等外部系统的复杂性和运维成本。同时减少了频繁查询对存储系统的压力大幅提升系统的整体吞吐能力确保在高并发场景下依然稳定高效运行。通过读缓存TDengine 为用户提供了一种更轻量化的实时数据处理方案,不仅优化了查询性能,还降低了整体运维成本,为物联网和工业互联网用户提供强有力的技术支持。
在创建数据库时,用户可以选择是否启用缓存机制以存储该数据库中每张子表的最新数据。这一缓存机制由数据库创建参数 cachemodel 进行控制。参数 cachemodel 具有如
下 4 种情况:
- none: 不缓存
- last_row: 缓存子表最近一行数据,这将显著改善 last_row 函数的性能
- last_value: 缓存子表每一列最近的非 NULL 值,这将显著改善无特殊影响(比如 WHERE ORDER BY GROUP BY INTERVAL时的 last 函数的性能
- both: 同时缓存最近的行和列,即等同于上述 cachemodel 值为 last_row 和 last_value 的行为同时生效
## TDengine 的读缓存配置
在创建数据库时,用户可以选择是否启用缓存机制以存储该数据库中每张子表的最新数据。这一缓存机制由数据库创建参数 cachemodel 进行控制。参数 cachemodel 具有如 下 4 种情况:
- none不缓存
- last_row缓存子表最近一行数据这将显著改善 last_row 函数的性能
- last_value缓存子表每一列最近的非 NULL 值,这将显著改善无特殊影响(比如 WHERE,ORDER BY,GROUP BY, INTERVAL时的 last 函数的性能
- both同时缓存最近的行和列即等同于上述 cachemodel 值为 last_row 和 last_value 的行为同时生效
当使用数据库读缓存时,可以使用参数 cachesize 来配置每个 vnode 的内存大小。
- cachesize表示每个 vnode 中用于缓存子表最近数据的内存大小。默认为 1 ,范围是[1 65536],单位是 MB。需要根据机器内存合理配置。
- cachesize表示每个 vnode 中用于缓存子表最近数据的内存大小。默认为 1 ,范围是[165536],单位是 MB。需要根据机器内存合理配置。
## 元数据缓存
为了提升查询和写入操作的效率,每个 vnode 都配备了缓存机制,用于存储其曾经获取过的元数据。这一元数据缓存的大小由创建数据库时的两个参数 pages 和 pagesize 共同决定。其中pagesize 参数的单位是 KB用于指定每个缓存页的大小。如下 SQL 会为数据库 power 的每个 vnode 创建 128 个 page、每个 page 16KB 的元数据缓存
```sql
CREATE DATABASE POWER PAGES 128 PAGESIZE 16;
```
## 文件系统缓存
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;
```
在创建数据库时可以选择不同的参数类型,来选择性能优先或者可靠性优先。
- 1: 写 WAL 但不执行 fsync ,新写入 WAL 的数据保存在文件系统缓存中但并未写入磁盘,这种方式性能优先
- 2: 写 WAL 且执行 fsync新写入 WAL 的数据被立即同步到磁盘上,可靠性更高
关于数据库的具体创建,相关参数和操作说明请参考[创建数据库](../../reference/taos-sql/database/)
## 实时数据查询的缓存实践