Apache IoTDB 中的时间精度 | 铁头乔分享

从启动说起

有一个timestamp_precision的配置项文件名在IoTDB的配置文件里,默认是ms。但是大多数用户在使用IoTDB储存数据时,对这个配置项timestamp_precision不关注,而通过System.currentTime Millis在Java客户端拿到一个long类型的时间戳,刚好就是毫秒级别的,很合适。


所以大多数用户对这个都无感,但是也有一些场景,数据采集频率大于1000了,这时候大家就开始想着改这个参数了,比如改成ns。

然后就会遇到一个启动问题:

ConfigurationException:

Parameter timestamp_precision can not be ns, please set to: ms。

大家可能就蒙了,为啥不让改?

正好 0.13.1 版本发布了,接下来的介绍和截图也就用这个版本了。

a6c69aef1f9eeb11ac16e934dcf54c32.gif

91ec0e87108bb09118ec1a1c31826b34.gif

能不能不管时间精度?

传给数据库的 Time 都是数字格式的时间戳,就不用管这个参数。

我们先启动一个 CLI,加一个参数:

./sbin/start-cli.sh -disableISO8601

然后执行下列 SQL:

insert into root.sg.d(time,s1) values(1,520)

insert into root.sg.d(time,s1) values(2,520)

select s1 from root.sg.d where time<10

接下来,我们会看到下面这种结果,从写入的SQL,到查询出的结果的Time列展示,都跟时间精度没关系,时间戳都只是一个整数。

836f2394e309ca5f9e1bc28074b52047.png

我们把这个 1、2 当做ms也可以,当做us、ns都可以。

这就是最原始的样子,没有时间精度,时间戳就是一个long类型的数据,数据库接收到这个long,就存储这个long,并且查询的时候把这个long返回给客户端。

所以,如果用long类型的时间戳跟数据库交互(凡是给数据库传输的时间戳都是long),数据库也会返回 long,完全不用管这个参数,只需要在客户端这边把这个long表达的意思理清楚就行。

d6f437ba39d34c8fb3f8ff8e29e681a5.gif

CLI 打印时间

注意一下,我们刚才启动 CLI 的时候加了一个参数 -disableISO8601,这是干啥的?

这个参数的功能是 关闭 ISO 8601 格式打印,ISO 8601 是一种日期和时间的表示方法。

比如北京时间2021年5月21日下午2点22分22秒,ISO 8601 格式就是 :

2021-05-21T14:22:22+08:00

为啥要加这个呢,刚才我们查出来的数据时间是1和2,这是啥玩意,就很不好理解,大家还是喜欢看是哪年哪月哪天的。

所以,为了让CLI查出来的数据更直观,我们把这个 long 类型的时间戳,转成ISO8601格式的字符串来打印了。因此,不加任何参数启动CLI时,就是下面这种效果了。

这个时候,时间精度就开始发挥作用了。

0808b1ad7fda0f0578496c0a113b5451.png

454f19b718ba467476454c63e2d5e696.gif

时间戳与1970

时间戳是指格林威治时间1970年01月01日00时00分00秒到当前经过的时间。因此1970年01月01日00时00分00秒就是时间戳0。

更具体一点,0时间戳也是1970年01月01日00时00分00秒000毫秒000微秒000纳秒。

时间戳0没什么歧义,那1呢?是1970年01月01日00时00分01秒?还是00秒001毫秒?还是00秒000毫秒001微秒?亦或是00秒000毫秒000微秒001纳秒?

171772924c8f84e7d56afbeccd7f8063.gif

时间精度开始发挥作用

也就是这个1个时间单位,到底代表多长的时间,这就是时间精度要管的。

如果配置里的timestamp_precision =ms,那么1就表示1970年01月01日00时00分00秒001毫秒。

如果我们配置的是纳秒,那么写入的1打印出来的就是:

1970-01-01T08:00:00.000000001+08:00

总结一下:凡是涉及到整数的时间戳和字符串格式的日期的相互转换时,就是时间精度发挥作用的时刻。时间戳有负的吗,有的,1970年之前的时刻,比如1969年用时间戳表示就是小于0了。1970年只是坐标轴的原点,这个时间的坐标轴可正可负。只不过现在一般用不到负数了。

如果我们写入一个now(),在这时候系统内部就会使用 System.currentTime Millis() 获取当前ms级别的时间戳,一般就是这么一个16开头的13位的数字。

81885de2111c3745dc4cf8f5bc076316.png

0be201622251dcb2e1997fcba714e512.gif

时间精度怎么改?

回到刚开始的启动问题,因为我们要对用户写入的时间戳的解释前后一致,比如刚开始配置的是ms,那么1就是ms,这时候改成ns,由于我们没有为每一个时间戳存储精度信息,这时候就会出现原本的1变成了 ns。修改前后打印出来的日期就不一致了。

为了避免这种情况,我们做了个启动检查,把 timestamp_precision 当做一个启动之后不能修改的配置项。

如果想改,正常情况我们推荐把data/system目录都清空,重新来过。

如果就想把老数据的时间格式改了,可以修改iotdb-engine.properties配置文件的同时,把data/system/schema/ system.properties 里的 timestamp_precision 也一起改了,这时候就没人能阻止你了。

好了,关于时间戳的介绍就到这里了。

1cfbddd1df9f852c62ea7ff93dcdbc6c.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值