时序数据库TDengine写入查询的问题分析

目录
  • 写入问题
    • 必须为每个Tag组合起一个表名
    • Tag支撑与管理
    • 不支持乱序写入
  • 查询问题
    • 求topN的group
    • downsampling和aggregation
    • 查询聚合架构

写入问题

必须为每个Tag组合起一个表名

付出的代价:

  • 用户必须要保证每个Tag组合起的表名唯一,并且一旦Tag组合数过多用户很难记住每个Tag组合对应的表名,在查询时基本都是靠超级表STable来查询。所以对用户来说这个表名几乎没用到却让用户来花代价来起名

这样设计的最终目的是为了将相同Tag组合的数据放到一起,但是系统设计时完全可以自己内部针对这个Tag组合记录一个唯一id或者唯一字符串来作为内部隐藏的表名,来替换让用户自己起表名的操作,对用户只需要呈现一个超级表STable即可,减轻用户负担。

其实可以看到上述其实是将系统内部判断唯一的负担转交给用户,麻烦了用户。假如系统内部自动判断Tag组合是否唯一,则在数据写入过程中一直需要判断当前Tag组合是否存在以及查找对应的底层唯一id或者唯一字符串,而让用户起表名则省去了上述代价,因为用户起的表名就是一个唯一的字符串,所以写入性能自然好一些

Tag支撑与管理

  • 最多支持6个Tag,如果想要支持更多就要重新源码编译
  • 超级表STable对Tag组合的索引是全内存的,终将会遇到瓶颈的,InfluxDB已经走过这条路了,从之前的全内存到后面的tsi
  • 超级表STable对Tag组合的索引仅仅是对第一个Tag作为key来构建一个skiplist,也就是说当你的查询用到第一个tag时可以利用下上述索引,当你的查询没用到第一个tag时,那就是暴力全扫,所以这种在Tag组合数过多的时候过滤查询能力还是很有限的。而像其他时序数据库InfluxDB、Druid都在写入过程中针对Tag组合构建了倒排索引来应对任意维度的过滤,写入性能比TDengine自然就会差一些
  • 对于不再使用的Tag组合的过期目前也是个麻烦的事情

不支持乱序写入

每张表会记录该表目前写入的最大时间,一旦后续的写入时间小于该时间则不允许写入。假如你不小心向某张表写入2021-07-24 00:00:00时间的数据,那么该时间之前的数据都无法写入了

这样做带来的好处,简化了写入过程,写入过程永远是append操作。举个简单例子,比如用数组来存放内存数据,数组中的数据是按时间排序的,如果后来的数据的时间不是递增,那么就需要将数据插入到数组中间的某个位置,并且需要将该位置之后的数据全部后移。假如后来的数据的时间都是递增的,那么直接往数组的最后面放即可,所以不支持乱序写入即以牺牲用户使用为代价来简化写入过程提高写入性能

不支持乱序写入还省去的一个麻烦就是:LSM中常见的compact。如果允许乱序写入,那么就会存在2个文件中时间范围是有重叠的,那么就需要像RocksDB那样来进行compact来消灭重叠,进而减少查询时要查询的文件个数,所以你就会发现HBase、RocksDB、InfluxDB等等辛辛苦苦设计的compact在TDengine中基本不存在

总结一下就是:不支持乱序写入是以牺牲用户的使用为代价来提高写入性能以及简化设计

查询问题

求topN的group

order by只能对时间、以及tag进行排序。top或者bottom只能对某个field求topN

时序领域非常常见的topN的group,比如求CPU利用率最大的3台机器,目前也无法满足

downsampling和aggregation

downsampling:将同一根时间线上1s粒度的数据聚合成10s粒度的数据

aggregation:将同一时刻多根时间线聚合成1根时间线

比如每个appId有多台机器,每台机器每秒都会记录该机器的连接数,目前想画出每个appId的总连接数的曲线

假如使用标准SQL则可能表示如下:

select sum(avg_host_conn),appid,new_time from (
		select avg(connection) as avg_host_conn,
				appid,host,time/10 as new_time
		from t1 group by appid,host,time/10
) as t2 group by appid, new_time

内部的子查询会先将每个appid的host 10s内的connection求平均值,即downsampling,外部的查询将每个appid下的host的上述平均值求和,即aggregation

由于这类需求在时序查询中太常见了,使用上述SQL书写非常麻烦,有些系统就通过函数嵌套的方式来简化这类查询的书写

目前TDengine的聚合函数要么只能是downsampling要么只能是aggregation,也不支持子查询,那么是无法满足上述需求的

查询聚合架构

查询分2阶段:第一阶段请求管理节点,获取符合tag过滤的所有表的meta信息(包含每个表在哪个数据节点上),假如满足条件的表有上百万个,这这个阶段的查询基本也吃不消,第二阶段向数据节点查询聚合每个表的数据,返回给客户端,客户端再做最终的聚合。

这种查询方案终究还是会面临客户端聚合瓶颈的,还是要上多机协调的分布式查询方案比如类似Presto、Impala等等

以上就是时序数据库TDengine写入问题分析的详细内容,更多关于时序数据库TDengine写入的资料请关注我们其它相关文章!

(0)

相关推荐

  • ASP.NET Core2读写InfluxDB时序数据库的方法教程

    前言 在我们很多应用中会遇到有一种基于一系列时间的数据需要处理,通过时间的顺序可以将这些数据点连成线,再通过数据统计后可以做成多纬度的报表,也可通过机器学习来实现数据的预测告警.而时序数据库就是用于存放管理这种有着时间顺序数据的,时序数据库一般都支持时序数据的快速写入.持久化.多纬度的聚合查询等基本功能. InfluxDB简介 InfluxDB是一个基于时间序列数据而开发的高性能数据存储平台,它可以对时序数据进行高吞吐量的摄取.压缩和实时查询.InfluxDB是用Go语言编写的,它会编译成一个没

  • Springboot使用influxDB时序数据库的实现

    目录 引入依赖 配置 构建实体类 保存数据 查询数据 项目中需要存放大量设备日志,且需要对其进行简单的数据分析,信息提取工作. 结合众多考量因素,项目决定使用时序数据库中的领头羊InfluxDB. 引入依赖 项目中使用influxdb-java,在pom文件中添加如下依赖(github地址:https://github.com/influxdata/influxdb-java): <dependency> <groupId>org.influxdb</groupId>

  • 时序数据库TDengine写入查询的问题分析

    目录 写入问题 必须为每个Tag组合起一个表名 Tag支撑与管理 不支持乱序写入 查询问题 求topN的group downsampling和aggregation 查询聚合架构 写入问题 必须为每个Tag组合起一个表名 付出的代价: 用户必须要保证每个Tag组合起的表名唯一,并且一旦Tag组合数过多用户很难记住每个Tag组合对应的表名,在查询时基本都是靠超级表STable来查询.所以对用户来说这个表名几乎没用到却让用户来花代价来起名 这样设计的最终目的是为了将相同Tag组合的数据放到一起,但是

  • 系统高吞吐量下的数据库重复写入问题分析解决

    目录 问题分析 数据库上解决 从程序上保证数据不重复 总结 问题分析 为了提高系统的吞吐量,很多环节下对于数据库的写入是多线程,甚至是多进程的.为了保证写入成功,在很多情况下需要多次重试.这就会带来一个问题,数据重复,同一条数据会被记录多次.有些情况下数据重复无伤大雅,但是很多情况系统是无法容忍数据重复的.因此这个问题需要解决.我个人觉得解决这一问题有两个方向:第一,从数据库上保证数据不重复,第二,从程序上保证数据不重复. 数据库上解决 主要包括:主键,唯一性索引,甚至是临时表.程序上解决无非就

  • laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析

    本文实例讲述了laravel框架数据库操作.查询构建器.Eloquent ORM操作.分享给大家供大家参考,具体如下: 1.连接数据库 laravel连接数据库的配置文件位于config/database.php中,在其中connection字段中包含laravel所支持的数据库的配置信息,可以看到其中有主机.端口.数据库.用户名.密码等信息: 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'),

  • 总结12个MySQL慢查询的原因分析

    目录 1. SQL 没加索引 2. SQL 索引不生效 2.1 隐式的类型转换,索引失效 2.2 查询条件包含 or,可能导致索引失效 2.3. like 通配符可能导致索引失效 2.5 在索引列上使用 mysql 的内置函数 2.6 对索引进行列运算(如,+.-.*./), 索引不生效 2.7 索引字段上使用(!= 或者 < >),索引可能失效 2.8 索引字段上使用 is null, is not null,索引可能失效 2.9 左右连接,关联的字段编码格式不一样 2.10 优化器选错了索

  • hibernate查询缓存详细分析

     一.查询缓存配置 1.在hibernate.cfg.xml中加入查询缓存的策略,  <propertyname="hibernate.cache.use_query_cache">true</property>      启用查询缓存的策略,默认是false. 二.关闭二级缓存,采用query.list()查询普通属性 代码如下所示. public voidtestCache1() { Session session = null; try { session

  • 优化MySQL数据库中的查询语句详解

    很多时候基于php+MySQL建立的网站所出现的系统性能瓶颈往往是出在MySQL上,而MySQL中用的最多的语句就是查询语句,因此,针对MySQL数据库查询语句的优化就显得至关重要!本文就此问题做出详细分析如下: 1.判断是否向MySQL数据库请求了不需要的数据,如下列情况: (1).查询不需要的数据,例如你需要10条数据,但是你选出了100条数据加了limit做限制. (2).多表关联时返回全部列 (3).总是取出全部列select*......取出全部列,会让优化器无法完成索引覆盖扫描这类优

  • 对MySQL慢查询日志进行分析的基本教程

    0.首先查看当前是否开启慢查询: (1)快速办法,运行sql语句 show VARIABLES like "%slow%" (2)直接去my.conf中查看. my.conf中的配置(放在[mysqld]下的下方加入) [mysqld] log-slow-queries = /usr/local/mysql/var/slowquery.log long_query_time = 1 #单位是秒 log-queries-not-using-indexes 使用sql语句来修改:不能按照m

  • MySQL慢查询之pt-query-digest分析慢查询日志

    一.简介 pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdump抓取的MySQL协议数据来进行分析.可以把分析结果输出到文件中,分析过程是先对查询语句的条件进行参数化,然后对参数化以后的查询进行分组统计,统计出各查询的执行时间.次数.占比等,可以借助分析结果找出问题进行优化. 二.安装pt-query-digest 1.下载页面:https://www.pe

  • PHP数据库操作三:redis用法分析

    本文实例讲述了PHP数据库操作redis用法.分享给大家供大家参考,具体如下: memcache虽然好用,解决了数据库遇到高并发时的IO问题,但还有很多问题丞待解决: 1.数据持久性问题,memcache用内存进行存储,一旦memcache服务器宕机,那么所存储的数据全部丢失. 2.memcache存储的数据类型单一,只支持key-value型的数据,要存储复杂类型的数据,必然需要PHP脚本的大量逻辑操作. redis基本介绍 redis也是一个内存非关系型数据库,它拥有memcache在数据存

随机推荐