时序数据库之TDengine
物联网、工业互联网的数据特点
物联网、工业互联网的数据是流式数据,像视频流,而且单个数据点的价值很低,甚至丢失一小段时间的数据也不影响分析的结论,也不影响系统的正常运行。但看似简单的事情,由于数据记录条数巨大,导致数据的实时写入成为瓶颈,查询分析极为 缓慢,成为新的技术挑战。传统的关系型数据库、NoSQL 数据库以及流式计算引擎由于没有充分利用物联网数据的特点,性能提升极为有限,只能依靠集群技术,投入更多的计算资源 和存储资源来处理,系统的运营维护成本急剧上升。
面对这一高速增长的物联网数据市场,近几年出现一批专注时序数据处理的公司,比如美国的InfluxData,其融资已经超过1.3亿美元,其产品InfluxDB在IT运维监测方面有相当的市场占有率。在工业控制领域老牌实时数据库公司OSIsoft在2017年5月获得软银12亿美元的投资,期望成为新兴的物联网领域的数据库的领头羊。开源社区也十分活跃,比如基于HBase开发的OpenTSDB。中国国内,阿里、百度、华为都有基于OpenTSDB的产品。
2017年成立的北京涛思数据科技有限公司看好这一市场,不依赖任何第三方软件或开源软件,在吸取众多传统关系型数据库、NoSQL 数据库、流式计算引擎、消息队列等软件的优点之后自主开发了TDengine Database,一个完整的时序大数据处理引擎。TDengine Database的性能远超InfluxDB, 而且其安装、部署、维护简单,使用SQL接口,学习成本几乎为零,有望成为时序数据处理市场的一匹黑马。
各种类型数据库特点
从数据库的定义来说,数据库就是一个数据管理系统,是用来存放数据文件的一个软件,支持用户的添加,修改,删除,查询等操作。所以从定义上讲,时序数据库和关系 / 非关系数据库是一样的,都是用来存放数据的。只是存储的数据特点不同,应用的场景也不尽相同:
- 关系型数据库 ( SQL ):主要用来存储结构化数据,使用实物保证数据一致性,使用SQL语言来进行查询操作,。典型代表主要有 MySQL, Oracle, SQL Server 等。
- 非关系型数据库 ( NoSQL ): 主要用来存储非结构化数据,数据可以不通过验证进行存储,使用 JSON 数据对象进行查询操作。典型代表主要有 MongoDB, Redis 等。
而时序数据库主要存储实时数据,最明显的特点就是每条数据都会带有时间戳属性。在电力、石化、冶金、智能汽车、监控等领域应用比较广泛。典型代表主要有 influxDB,TimescaleDB. 另外不得不推荐一下 TDengine (http://mtw.so/5ZNoHA),从个人的使用情况来看,功能强大,性能远远超出预期。
能否用关系/非关系型数据库代替时序数据库?
一方面如果数据采集频率少,数据量不大的话,使用关系/非关系型数据库代替时序数据库是完全没有问题的。
另一方面,从时序数据的特点(采集频率高、数据量大)来看,关系/非关系型数据库很难满足这样高的性能需求。在大数据场景下,如果性能达不到要求,数据没有办法被有效存储的话,那么这样的数据库是无法代替时序数据库的。
举一个简单的例子,在相同的测试环境(16 核 64G 内存)拿 MySQL 和 TDengine 做一下 benchmark 的对比测试 :
分别使用 MySQL 自带的 benchmark 工具 mysqlslap 和 TDengine 自带的 benchmark 工具taosbenchmark,使用16个线程,写入单表10万条记录,表结构为1个timestamp类型,2个int类型,2个字符串类型,测试结果如下:
1 | mysqlslap -uroot -p1234 --concurrency=16 --number-of-queries=100000 --create-sc hema=tests --query= "INSERT INTO meters(c0, c1, c2, c3) VALUES (RAND() * 100, RAND() * 100, uuid(), uuid())" |
TDengine
taosBenchmark -b int,int,binary\(128\),binary\(128\) -n 100000 -t 1 -T 16
同样写入 10 万条记录的情况下,MySQL 使用自带的 mysqlslap 工具需要 75 秒完成,而 TDengine 使用自带的 taosBenchmark 只需要不到 1 秒。在差距如此巨大的情况下可以看到使用 MySQL 代替时序数据库处理时序数据是比较困难的。当然由于测试工具不同,这里只是做一个示例,测试本身算不上严谨。
TDengine
TDengine 是一个具有 SQL 支持的高性能、可扩展的时间序列数据库。其包含集群功能的代码在GNU AGPL v3.0下是开源的。除了数据库,它还提供缓存、流处理、数据订阅等功能,以降低开发和运营的复杂性和成本。TDengine 区别于其他 TSDB 具有以下优势。
-
高性能:TDengine 在数据摄取和查询方面优于其他时间序列数据库,同时通过创新设计和专用存储引擎显着降低存储成本和计算成本。
-
可扩展性:TDengine 通过其原生分布式设计提供开箱即用的可扩展性和高可用性。可以通过简单的配置添加节点,以实现更大的数据处理能力。此外,此功能是开源的。
-
SQL 支持:TDengine 使用 SQL 作为查询语言,从而降低学习和迁移成本,同时增加 SQL 扩展以更好地处理时序数据,并支持方便灵活的无模式数据摄取。
-
All in One:TDengine内置缓存、流处理和数据订阅功能,部分场景不再需要集成Kafka/Redis/HBase/Spark等软件。它使系统架构更加简单和易于维护。
-
无缝集成:TDengine无需一行代码,提供与Telegraf、Grafana、EMQX、Prometheus、StatsD、collectd等第三方工具的无缝集成。更多的将被集成。
-
零管理:安装和集群设置可以在几秒钟内完成。数据分区和分片是自动执行的。可以通过 Grafana 或其他 DevOps 工具监控 TDengine 的运行状态。
-
零学习成本:以 SQL 作为查询语言,支持 Python、Java、C/C++、Go、Rust、Node.js 连接器等无处不在的工具,学习成本为零。
-
交互式控制台:TDengine 提供对数据库的便捷控制台访问,以运行即席查询、维护数据库或管理集群,无需任何编程。
TDengine可广泛应用于物联网(IoT)、车联网、工业物联网、DevOps、能源、金融等诸多场景。
用户手册、系统设计与架构、工程博客,详见TDengine文档(中文版请点击这里)。
从 TDengine shell 运行 SQL 命令很容易,这与其他 SQL 数据库相同。
CREATE DATABASE demo;
USE demo;
CREATE TABLE t (ts TIMESTAMP, speed INT);
INSERT INTO t VALUES('2019-07-15 00:00:00', 10);
INSERT INTO t VALUES('2019-07-15 01:00:00', 20);
SELECT * FROM t;
ts | speed |
===================================
19-07-15 00:00:00.000| 10|
19-07-15 01:00:00.000| 20|
Query OK, 2 row(s) in set (0.001700s)
IoTSharp.Data.Taos 是一个采用TDengine的原生动态库构建的ADO.Net提供程序。 它将允许你通过.Net Core 访问TDengine 数据库。
IoTSharp.EntityFrameworkCore.Taos 是一个Entity Framework Core 的提供器, 基于IoTSharp.Data.Taos实现。 (原名称为 Maikebing.EntityFrameworkCore.Taos)
NuGet 名称 | 版本 | 下载量 | 说明 |
---|---|---|---|
IoTSharp.Data.Taos | ADO.Net Core 基础组件 | ||
IoTSharp.EntityFrameworkCore.Taos | 供EF Core使用的组件 | ||
IoTSharp.HealthChecks.Taos | 供Asp.Net Core 使用的健康检查组件 |
TDengine技术开放日 — 从技术创新和设计思想,认识TDengine
如何使用?
例子:
///Specify the name of the database string database = "db_" + DateTime.Now.ToString("yyyyMMddHHmmss"); string database = "db_" + DateTime.Now.ToString("yyyyMMddHHmmss"); var builder = new TaosConnectionStringBuilder() { DataSource = "127.0.0.1", DataBase = database, Username = "root", Password = "kissme", Port=6060 }; //Example for ADO.Net using (var connection = new TaosConnection(builder.ConnectionString)) { connection.Open(); Console.WriteLine("create {0} {1}", database, connection.CreateCommand($"create database {database};").ExecuteNonQuery()); Console.WriteLine("create table t {0} {1}", database, connection.CreateCommand($"create table {database}.t (ts timestamp, cdata int);").ExecuteNonQuery()); Console.WriteLine("insert into t values {0} ", connection.CreateCommand($"insert into {database}.t values ('{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ms")}', 10);").ExecuteNonQuery()); Console.WriteLine("insert into t values {0} ", connection.CreateCommand($"insert into {database}.t values ('{DateTime.Now.AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss.ms")}', 20);").ExecuteNonQuery()); var cmd_select = connection.CreateCommand(); cmd_select.CommandText = $"select * from {database}.t"; var reader = cmd_select.ExecuteReader(); Console.WriteLine(cmd_select.CommandText); Console.WriteLine(""); ConsoleTableBuilder.From(reader.ToDataTable()).WithFormat(ConsoleTableBuilderFormat.MarkDown).ExportAndWriteLine(); Console.WriteLine(""); Console.WriteLine("DROP TABLE {0} {1}", database, connection.CreateCommand($"DROP TABLE {database}.t;").ExecuteNonQuery()); Console.WriteLine("DROP DATABASE {0} {1}", database, connection.CreateCommand($"DROP DATABASE {database};").ExecuteNonQuery()); connection.Close(); } //Example for Entity Framework Core using (var context = new TaosContext(new DbContextOptionsBuilder() .UseTaos(builder.ConnectionString).Options)) { Console.WriteLine("EnsureCreated"); context.Database.EnsureCreated(); for (int i = 0; i < 10; i++) { var rd = new Random(); context.sensor.Add(new sensor() { ts = DateTime.Now.AddMilliseconds(i), degree = rd.NextDouble(), pm25 = rd.Next(0, 1000) }); } Console.WriteLine("Saveing"); context.SaveChanges(); Console.WriteLine(""); Console.WriteLine("from s in context.sensor where s.pm25 > 0 select s "); Console.WriteLine(""); var f = from s in context.sensor where s.pm25 > 0 select s; var ary = f.ToArray(); ConsoleTableBuilder.From(ary.ToList()).WithFormat(ConsoleTableBuilderFormat.MarkDown).ExportAndWriteLine(); context.Database.EnsureDeleted(); } Console.WriteLine(""); Console.WriteLine("Pass any key to exit...."); Console.ReadKey();
用于物联网的超级表示例:
IoTSharp/Storage/TaosStorage.cs
鸣谢:
https://www.zhihu.com/question/408178021/answer/2400714433
https://www.taosdata.com/engineering/105.html
https://github.com/taosdata/TDengine
https://github.com/IoTSharp/EntityFrameworkCore.Taos
本文来自博客园,作者:{春光牛牛,yak},转载请注明原文链接:https://www.cnblogs.com/yakniu/p/16437015.html
欢迎各位大佬们评论指正
QQ讨论群:610129902
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!