Redis 保存时间序列的数据

2021/01/26 posted in  实践

时间序列数据的写入特点就是插入数据块,读操作特点就是既有单条的记录查询,也有范围查询,还有聚合查询;针对写特点 Redis 的高性能保证写操作,针对读特点,Redis 提供了保存数据的两种方案,基于Hash 和 Sorted Set 实现,以及RedisTimeSeries 模块的实现

基于 Hash 和 Sorted Set 保存时间序列的数据

  1. 稳定性由 Redis 自身性能保证
  2. Hash 用于单键的快速查询,Sorted Set 用于对数据范围的查询
  3. 通过 MULTI 和 EXEC 包含保证数据存储Hash 和 Sorted Set 的原子操作
  4. 聚合操作只能返回到客户端进行计算,但是大量的数据在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"