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 版本发布了,接下来的介绍和截图也就用这个版本了。
能不能不管时间精度?
传给数据库的 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 列展示,都跟时间精度没关系,时间戳都只是一个整数。
我们把这个 1、2 当做 ms 也可以,当做 us、ns 都可以。
这就是最原始的样子,没有时间精度,时间戳就是一个 long 类型的数据,数据库接收到这个 long,就存储这个 long,并且查询的时候把这个 long 返回给客户端。
所以,如果用 long 类型的时间戳跟数据库交互(凡是给数据库传输的时间戳都是 long),数据库也会返回 long,完全不用管这个参数,只需要在客户端这边把这个 long 表达的意思理清楚就行。
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 时,就是下面这种效果了。
这个时候,时间精度就开始发挥作用了。
时间戳与 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 纳秒?
时间精度开始发挥作用
也就是这个 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 位的数字。
时间精度怎么改?
回到刚开始的启动问题,因为我们要对用户写入的时间戳的解释前后一致,比如刚开始配置的是 ms,那么 1 就是 ms,这时候改成 ns,由于我们没有为每一个时间戳存储精度信息,这时候就会出现原本的 1 变成了 ns。修改前后打印出来的日期就不一致了。
为了避免这种情况,我们做了个启动检查,把 timestamp_precision 当做一个启动之后不能修改的配置项。
如果想改,正常情况我们推荐把 data/system 目录都清空,重新来过。
如果就想把老数据的时间格式改了,可以修改 iotdb-engine.properties 配置文件的同时,把 data/system/schema/ system.properties 里的 timestamp_precision 也一起改了,这时候就没人能阻止你了。
好了,关于时间戳的介绍就到这里了。
版权声明: 本文为 InfoQ 作者【Apache IoTDB】的原创文章。
原文链接:【http://xie.infoq.cn/article/d11c4970552d2f5b220610c94】。文章转载请联系作者。
评论