本文实际使用的是KaiwuDB的社区开源版本KWDB。

一、序列概括:

随着物联网技术在各行业的使用将越来越广,物联网与人工智能的深度结合,特别是在智能家居、智慧城市、工业4.0等领域有着广泛的应用‌,AIoT(Artificial Intelligence of Things)正成为企业实现智能化转型的关键路径。

上面一篇长文已经介绍了KWDB的安装以及踩过的坑,而且也对TSBS专门针对时间序列场景做了压力测试。

在这里插入图片描述

接下来,将从第2个方向“场景案例”一起来探索公司实际物联网IoT项目的思考,是否能让KWDB 分布式多模数据库碰撞出不一样的火花呢?


二、正文前言:

本人在学校毕业后一直从事开发工作,经过了以下几个阶段的软件开发历程,从早期的Web时代编程、到云时代分布式编程,到如今的物联网AIoT时代,都是解决企业级项目开发的效率问题,通过不断的技术演进,来为公司带来降本增效的原则。

在这里插入图片描述

2.1 传统Web时代编程开发时代:

传统Web时代编程开发时代是一个以静态网页为主,依赖HTML、CSS和JavaScript等技术栈,通过服务器端处理逻辑和数据库交互,实现网页动态内容和交互功能的时代。

2.2 云时代分布式编程时代:

云时代分布式编程时代,强调利用云计算平台进行数据的分布式处理和应用程序的编写与开发。依托分布式架构构建高可用服务集群,以服务化SaaS交付模式降低IT运维复杂度,推动企业从固定硬件投入向灵活智能的数字化服务转型。

2.3 物联网AIoT时代:

物联网AIoT时代,就像给世界装上“超级感官”与“智慧大脑”——机器之间能“对话”,数据像血液般流动:红灯预判车流、工厂设备自主巡检,甚至冰箱会提醒牛奶过期;万物从沉默到觉醒,效率与便利在指尖悄然生长,生活像被施了魔法,一切变得更聪明、更贴心。


三、物联网AIoT时代数据管理的新途径 – “时序数据库”:

KWDB 的时序数据库(Timeseries Database)和关系型数据库(Relational Database)使用不同的存储引擎和元数据管理方式:

在这里插入图片描述

  • ①. 时序数据库:专门存储带时间戳的序列化数据,要求表结构包含主时间戳字段和标签字段。
  • ②. 关系型数据库:支持传统关系模型,可定义主键、外键、索引等约束,适用于非时间序列数据。

在这里插入图片描述

KWDB 正在成为新一代物联网与智能系统的核心数据引擎。如果您正面临复杂的数据接入、多模数据管理或实时计算需求,不妨尝试一下这款专为 AIoT 设计的数据库产品,拥抱真正面向未来的数据基础设施。


四、企业内部物联网IoT净水机业务平台方案思考:

公司企业的净水机业务就是采用了物联网IoT的设计方案,能够实时对设备的运行状态、水质状态以及滤芯状态进行全面而精确的监测。通过高效的数据传输机制,该系统实现了对设备的智能化管理,包括:

  • ①. 同步水卡消费记录、商家或设备的记录。
  • ②. 查询TDS值、CPF/DF/CF值上传。
  • ③. 远程开关机、重启机器、机器预警、调水费。
  • ④. 滤芯寿命、水温、水量、pH值、电导率、温度。

在这里插入图片描述


五、KWDB在净水机物联网IoT方案落地最佳实践:GoLang应用程序 + 香橙派Orange Pi AI Pro 开发板场景案例测试:

在实际项目中,我们通过开发语言使用数据库提供的SDK连接到KWDB数据库实例进行CURD的操作,可以看到这里分为2种场景:

  • ①. 应用程序配置连接器KWDB,可以看到官网提供了10几种不同应用程序连接器的应用开发。
  • ②. 第三方工具与KWDB数据读写同步,有分布式消息中间件、离线数据同步工具、开源指标收集工具的数据读写同步。

在这里插入图片描述


5.1 使用 pgx 驱动连接 KWDB:

KWDB 支持可以通过 pgx 驱动连接数据库,并执行创建、插入和查询操作。下面代码演示如何使用 Go 语言通过 pgx 驱动连接 KWDB。

pgx 是用 Go 语言编写的 PostgreSQL 驱动和工具包,提供了高性能的低级接口,支持用户直接利用 PostgreSQL 的特性,pgx 还包含一个适配器,与标准的数据库或 SQL 接口兼容,方便开发者进行数据库操作。

go get github.com/jackc/pgx/v5@v5.5.1

5.2 香橙派Orange Pi AI Pro 开发板:

香橙派Orange Pi AI Pro开发板凭借其硬件性能与生态适配能力,在物联网(IoT)领域展现了显著优势,开发板通过高性能AI加速能力与灵活扩展性,提供了强大的训练能力,优异的推理能力,可以满足大多数AI算法原型验证、推理应用开发的需求,可以构建智能物联网节点的理想硬件平台。

在这里插入图片描述

以下是简单的香橙派Orange Pi AI Pro 开发板相关硬件设备(电源线、开发板、TF卡),经过几分钟简单的硬件组装后,因为需要进行调试,所以,插入相关的USB和HDMI插头后,开机登陆后即可进入桌面。

在这里插入图片描述


5.3 Golang模拟测试场景实践:

在香橙派Orange Pi AI Pro 开发板上,跑一个基于Go语言开发的物联网净水器性能压测系统,用于模拟大量设备并发上传数据和请求操作的场景。

5.3.1 KWDB - 时序数据库:

在数据库管理中,KWDB的时序数据库(Time-Series Database, TSD)是一种专门用于存储和管理随时间变化的数据的数据库。这类数据库特别适用于物联网(IoT)、监控系统、日志分析、金融分析等领域,能够高效地处理大量时间序列数据。

首先我们需要新建一个测试使用的数据库,这里需要注意一下,跟平时的建表语句不同的是,需要携带一个TS的参数标识,表示是Time-Series时序数据库。

在这里插入图片描述

这里的分区时间范围比较实用,会进行定期检测删除,删除的依据就是分区中最新的数据已经超过了保存周期的话就执行删除,比较类似于Redis的“定时删除策略”,会创建一个定时事件,当时间到达时,由事件处理器自动执行 key 的删除操作相当于会维护一个进程去进行检测。

# 创建iot时序数据库成功
CREATE TS DATABASE iot RETENTIONS 50d PARTITION INTERVAL 2d;
# 查看所有数据库
show databases;
# 查看时序数据库的建库语句
show create database iot;
# 切换指定的数据库
use iot;

在这里插入图片描述

这种数据库的特点,非常适合我们的这种业务,比如在业务的设计中存在“冷热数据”,MongoDB的存在是物联网最新上传的数据,老数据会针对性的进行数据刷选备份到MySQL进行存档保存。


5.3.2 KWDB - 时序表:

KWDB时序表(TIME SERIES TABLE)是用于存储时间序列数据的数据表,在与平常接触的建表语句不太一样,而且有些数据类型、函数也是不支持的,具体支持的数据类型可以直接查看官方的文档 - 时序数据类型

在这里插入图片描述

时序表跟关系型常规的建表语句有一些差异性,这里我做了一些总结,一张表包含3种类型的列:

  • ①. 时间戳列:用于记录数据采集的时间。
  • ②. 标签列:用于记录采集对象的静态数据,比如设备编号、标识位置、设备的型号,固定不变的数据。
  • ③. 字段列:用于记录采集对象的实时数据,比如一直变化的数据,设备产生了不同的时间的收费、电流、电压。

接着创建2张时序表,一张时序表是记录净水机设备相关信息,比如这台净水机设备实时相关设备数据:TDS值、CPF/DF/CF值、pH值、水温、水量、电导率、滤芯寿命、设备状态等信息。

CREATE TABLE device_data (
    timestamp timestamptz NOT NULL,
    tds float NOT NULL,
    cpf float NOT NULL,
    df float NOT NULL,
    cf float NOT NULL,
    ph float NOT NULL,
    temperature float NOT NULL,
    water_volume float NOT NULL,
    filter_life INTEGER NOT NULL,
    conductivity float NOT NULL,
    power_status BOOLEAN NOT NULL,
    created_at timestamptz NOT NULL default now()
) TAGS (
    device_id VARCHAR(50) NOT NULL
) PRIMARY TAGS (device_id);

另外一张时序表是与消费相关的,主要记录净水机设备交易数据,比如水卡消费记录、商家/设备记录。

CREATE TABLE consumption_record (
    timestamp timestamptz NOT NULL,
    amount float NOT NULL,
    created_at timestamptz NOT NULL default now()
) TAGS (
    device_id VARCHAR(50) NOT NULL,
    card_id VARCHAR(50) NOT NULL
) PRIMARY TAGS (device_id);

5.4 Golang模拟压测脚本

上面可以看到数据库相关的准备工作已经就绪,接下来就是编写go相关代码,以下是go代码压测方案的示意图:

在这里插入图片描述

  • ①. 在香橙派Orange Pi AI Pro 开发板上运行go压测程序,支持动态并发数、测试持续时间、模拟设备数量,上传支持水卡消费记录同步和模拟设备数据指标(TDS值、CPF/DF/CF值、pH值等)。
    • 支持模拟多个设备并发上传数据
    • 模拟多种数据指标:TDS值、CPF/DF/CF值、pH值等
    • 模拟设备操作:开关机、重启、调水费等
    • 支持水卡消费记录同步
    • 实时性能监控和测试报告生成
  • ②. 我们这次压力测试的是KWDB单节点版本安全模式下进行测试,推荐在集群环境进行测试,这样会更容易贴近生产环境。
  • ③. 最后通过KWDB平台集成部署 Prometheus 和 Grafana,配置好告警规则和聚合规则配置文件,即可在Grafana中查看相关监控指标数据。

监控部署,可以直接查看官方的手册进行安装与配置(https://www.kaiwudb.com/kaiwudb_docs/#/db-monitor/os-monitor-component/deploy-monitoring.html)。

生成模拟设备数据指标(TDS值、CPF/DF/CF值、pH值等),和生成模拟支持水卡消费记录的Mock数据:

// generateDeviceData 生成模拟设备数据
func generateDeviceData(deviceID string) db.DeviceData {
	return db.DeviceData{
		DeviceID:     deviceID,
		Timestamp:    time.Now(),
		TDS:          rand.Float64() * 1000,
		CPF:          rand.Float64() * 100,
		DF:           rand.Float64() * 100,
		CF:           rand.Float64() * 100,
		PH:           rand.Float64()*6 + 1,   // pH 1-7
		Temperature:  rand.Float64()*30 + 10, // 10-40度
		WaterVolume:  rand.Float64() * 1000,
		FilterLife:   rand.Intn(100),
		Conductivity: rand.Float64() * 2000,
		PowerStatus:  rand.Intn(2) == 1,
	}
}

// generateConsumptionRecord 生成模拟消费记录
func generateConsumptionRecord(deviceID string) db.ConsumptionRecord {
	return db.ConsumptionRecord{
		CardID:    fmt.Sprintf("CARD_%d", rand.Intn(1000)),
		DeviceID:  deviceID,
		Amount:    rand.Float64() * 100,
		Timestamp: time.Now(),
	}
}

在main.go中,可以定义TestConfig结构体的参数来调整测试配置,如Concurrency(并发数)、Duration:(测试持续时间)、DeviceCount(模拟设备数量)、ReportInterval(报告输出间隔),并且通过使用goroutine池可以管理并发数量,还可以通过channel控制并发数量,使用sync.Mutex确保指标统计的准确性。

// 定期输出连接池状态
	go func() {
		ticker := time.NewTicker(time.Minute)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				stats := kwdb.GetStats()
				log.Printf("连接池状态 - 总连接数: %d, 空闲连接数: %d, 使用中连接数: %d\n",
					stats.TotalConns(), stats.IdleConns(), stats.TotalConns()-stats.IdleConns())
			}
		}
	}()

	// 测试配置
	config := TestConfig{
		Concurrency:    100,
		Duration:       1 * time.Minute,
		DeviceCount:    1000,
		ReportInterval: 5 * time.Second,
	}

	// 初始化测试指标
	metrics := &TestMetrics{}

	// 创建等待组
	var wg sync.WaitGroup

	// 开始时间
	startTime := time.Now()

	// 定期报告测试进度
	go func() {
		for {
			time.Sleep(config.ReportInterval)
			if time.Since(startTime) >= config.Duration {
				break
			}
			log.Printf("进行中 - 总请求: %d, 成功: %d, 失败: %d, 平均延迟: %v\n",
				metrics.TotalRequests,
				metrics.SuccessRequests,
				metrics.FailedRequests,
				metrics.AverageLatency)
		}
	}()

	// 主测试循环
	for time.Since(startTime) < config.Duration {
		// 控制并发数
		if metrics.TotalRequests%int64(config.Concurrency) == 0 {
			time.Sleep(100 * time.Millisecond)
		}

		wg.Add(1)
		deviceID := fmt.Sprintf("DEVICE_%d", rand.Intn(config.DeviceCount))
		go simulateDevice(deviceID, metrics, &wg, kwdb)
	}

	// 等待所有goroutine完成
	wg.Wait()

注意:时间字段去掉CURRENT_TIMESTAMP (且设置了not_null),在插入数据时创建时间是空,这里就会提示报错提示:

ERROR: null value in column "created_at" violates not-null constraint (SQLSTATE 23502)

在这里插入图片描述

另外,也在思考,如果多台设备同时运行,肯定会存在并发的问题,上面可以看到第一列是时间列,而且是默认的索引,那么会不会在同一时间段,产生多条时间一样的数据呢?这样会不会存在问题呢?会不会产生时间一样的冲突呢?带着这个问题,我们可以做以下的测试:

在这里插入图片描述

结果,可以得出结论:时间对于不同设备来说是可以重复的 ,同一个设备不行,因为同一设备不可能在同一时间产生2个值。


5.5 压测结果指标数据分析:

上面我们一共进行了4次的压力测试,可以使用 Grafana支持查看 KWDB 集群及各个节点的监控指标,包括指标概览、硬件指标、运行指标、SQL 指标、存储指标、副本指标、分布式指标、队列指标和慢查询指标。

以下不是所有指标都来查看,我们只调一些比较重要的指标来进一步分析与总结。


5.5.1概览页面指标 - SQL Queries指标:

在以下节点视图中,SQL Queries指标表示该时间序列图展示指定节点处理客户端请求的 QPS(Queries Per Second,每秒查询数)。并且支持查询的类型包括查询、更新、插入、删除。

采样值为 10 秒内的平均值。在如下集群视图中,该时间序列图展示当前集群查询负载的估计值,该估计值为每个节点最近 10 秒的活动情况的汇总值。可以在看到在以下4次压测中,在Inserts的操作最高值分别为:

在这里插入图片描述

  • ①. 第一次压测时,在时间段为2025-05-08 02:19:45时,Inserts操作达到了4.15K每秒。
  • ② 第二次压测时,在时间段为2025-05-08 02:22:15时,Inserts操作达到了2.87K每秒。
  • ③ 第三次压测时,在时间段为2025-05-08 02:42:30时,Inserts操作达到了3.29K每秒。
  • ④ 第四次压测时,在时间段为2025-05-08 02:52:45时,Inserts操作达到了3.74K每秒。

5.5.2 概览页面指标 - Service Latency: SQL 99th percentile:

在数据库管理中,服务延迟(Service Latency)指的是数据库操作(如查询、事务等)的执行时间,即集群从接收到查询请求到查询结束之间的时间,不包含将查询结果传输给客户端的时间。

特别是在高并发环境下,了解99th百分位延迟(也称为99百分位延迟或最长延迟)对于优化数据库性能至关重要。99th百分位延迟指的是在最坏情况下,有1%的请求超过了此延迟时间。

在这里插入图片描述

该时间序列图展示指定节点或者集群内所有节点的服务延迟的 99th 百分位数,即在观察时间内,百分之九十九(99%)的节点的服务延迟低于或等于这个值,这里可以看到最高的是369ms。


5.5.3 硬件页面指标 – Capacity & Memory Usage:

Capacity表示磁盘容量‌,这个指标可以显示磁盘的使用情况,包括总容量、已用容量和剩余容量等,帮助管理磁盘空间。用户可以通过监控存储容量图来判断什么时候需要为集群添加新的存储空间,比如如下,可以实时去查看时序数据库和关系型数据库磁盘空间占比,可以有针对性的进行调整。

在这里插入图片描述

Memory Usage表示内存容量,随着KWDB加载的数据源数据量增加、缓存的图表数据增多以及运行的插件功能增多,内存使用量会相应变化。这个指标用于及时发现内存使用是否超出合理范围,避免因内存耗尽导致KWDB服务中断,如果内存使用率持续上升且无合理回落,可能暗示存在内存泄漏等问题‌。

如上所示,可以看到我们实验的机器设备是8G,但是在压测的过程中,最高才使用到内存总量为2.02G,只占用了25%左右。


5.5.4 运行时页面指标 - GC Pause Time:

GC Pause Time指标指的是垃圾回收(Garbage Collection,简称GC)暂停时间,即在进行垃圾回收时,程序的工作线程被暂停的时间‌‌。
GC Pause Time指标反映了垃圾回收过程中应用程序暂停的时间长度。这个指标对于评估垃圾回收对应用程序性能的影响非常重要。较长的暂停时间会降低应用程序的响应速度和吞吐量,尤其是在交互式应用中,长时间的暂停会导致用户体验下降。因此,优化垃圾回收策略,减少暂停时间,是提高应用程序性能的关键‌。

在下面节点视图中,该时间序列图展示指定节点的 GC 阻塞时间。在集群视图中,该时间序列图展示集群中所有节点的 GC 阻塞时间总和,可以看到整个生命周期维持在2ms左右,最高是8.58ms。

在这里插入图片描述

GC Runs表示该时间序列图展示指定节点或者集群内所有节点的 GC 运行次数,可以看到平均稳定在0.5次左右,最高GC运行次数在1.27。


六、总结:

本文深入探讨了KWDB分布式多模数据库在净水机物联网IoT项目中的应用实践与压力测试。通过结合Go语言与香橙派Orange Pi AI Pro开发板,成功构建了模拟大量设备并发上传数据和请求操作的场景,验证了KWDB在处理时间序列数据方面的卓越性能。

在项目实施过程中,首先通过pgx驱动连接KWDB数据库,实现了数据的CURD操作。接着,针对净水机业务特点,设计了包含设备数据和消费记录的时序表,有效支持了设备状态监测和水卡消费记录同步等核心功能。

压力测试环节,通过模拟不同并发数、测试持续时间及模拟设备数量,全面评估了KWDB在高负载下的表现。测试结果显示,KWDB在插入操作方面表现出色,每秒查询数(QPS)达到数千级别,同时服务延迟保持在合理范围内,确保了系统的实时性和稳定性。

此外,通过Grafana监控平台,对KWDB集群及节点的各项监控指标进行了深入分析,包括SQL查询量、服务延迟、磁盘容量、内存使用及垃圾回收暂停时间等。这些指标数据为系统的优化和调整提供了有力支持,确保了KWDB在净水机物联网IoT项目中的高效稳定运行。

综上所述,KWDB分布式多模数据库凭借其强大的时间序列数据处理能力和灵活的部署方式,在物联网IoT领域展现出广阔的应用前景。通过本文的实践与压测总结,为KWDB在类似项目中的推广和应用提供了宝贵的参考经验。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐