时间序列数据的写入特点就是插入数据块,读操作特点就是既有单条的记录查询,也有范围查询,还有聚合查询;针对写特点 Redis 的高性能保证写操作,针对读特点,Redis 提供了保存数据的两种方案,基于Hash 和 Sorted Set 实现,以及RedisTimeSeries 模块的实现
基于 Hash 和 Sorted Set 保存时间序列的数据
- 稳定性由 Redis 自身性能保证
- Hash 用于单键的快速查询,Sorted Set 用于对数据范围的查询
- 通过 MULTI 和 EXEC 包含保证数据存储Hash 和 Sorted Set 的原子操作
- 聚合操作只能返回到客户端进行计算,但是大量的数据在Redis实例和客户端之间传输,占用网络资源,导致其他操作变慢
- 单值查询
HGET device:temperature 202008030905
"25.1"
HMGET device:temperature 202008030905 202008030907 202008030908
1) "25.1"
2) "25.9"
3) "24.9"
- 范围查询
ZRANGEBYSCORE device:temperature 202008030907 202008030910
1) "25.9"
2) "24.9"
3) "25.3"
4) "25.2"
- 保证原子操作
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> HSET device:temperature 202008030911 26.8
QUEUED
127.0.0.1:6379> ZADD device:temperature 202008030911 26.8
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 1
2) (integer) 1
基于 RedisTimeSeries 模块保存时间序列的数据
RedisTimeSeries 是Redis 的一个扩展模块,他专门面向时间序列数据提供的数据类型和访问接口,并支持在Redis 实例上直接对数据进行按时间范围的聚合操作
- 操作: 下载源码 编译成redistimeseries.so 然后使用 loadmodule 加载
loadmodule redistimeseries.so
- 命令
- TS.CREATE 创建时间序列数据集合
- TS.ADD 插入数据
- TS.GET 读取最新数据
- TS.MGET 按标签过滤查询结果
- TS.RANGE 支持聚合计算的范围查询
实例
- 创建一个时间序列数据集合
TS.CREATE device:temperature RETENTION 600000 LABELS device_id 1
OK
- 插入数据,读取最新数据
TS.ADD device:temperature 1596416700 25.1
1596416700
TS.GET device:temperature
25.1
- 按标签过滤查询数据集合
TS.MGET FILTER device_id!=2
1) 1) "device:temperature:1"
2) (empty list or set)
3) 1) (integer) 1596417000
2) "25.3"
2) 1) "device:temperature:3"
2) (empty list or set)
3) 1) (integer) 1596417000
2) "29.5"
3) 1) "device:temperature:4"
2) (empty list or set)
3) 1) (integer) 1596417000
2) "30.1"
- 聚合计算的范围查询
TS.RANGE device:temperature 1596416700 1596417120 AGGREGATION avg 180000
1) 1) (integer) 1596416700
2) "25.6"
2) 1) (integer) 1596416880
2) "25.8"
3) 1) (integer) 1596417060
2) "26.1"
