我们现在就是Redis

了解更多

Redis最佳实践

排序集时间序列

时间序列排序集(zsets)是Redis中建模时间序列数据的典型方法。Sorted set由惟一的成员组成,其得分都存储在单个键下。对Sorted Sets使用这种数据类型意味着让分数充当时间的某种指示(通常是毫秒级的精确时间戳,尽管并不总是如此),成员是记录的数据。唯一的问题是,因为这是Set的一种形式,所以只允许唯一的成员,并且尝试用与前一个成员相同的值记录时间序列条目将只导致更新分数。为了说明这个问题,我们以以下记录温度随时间变化的例子为例:

时间戳 温度C
1511533205001 21
1511533206001 22
1511533207001 21

如果您只是使用扎德,则会丢失一些数据点:

反模式

>ZADD温度1511533205001 21(整数)1>ZADD温度1511533206001 22(整数)1>ZADD温度1511533207001 21(整数)0>

ZRANGEBYSCORE

温度-inf+inf 1)“22”2)“1511533206001”3)“21”4)“1511533207001”

反模式

请注意第三个ZADD如何返回0–这表示未将新成员添加到排序集。然后,在ZRANGEBYSCORE中,我们可以看到排序集只有两个条目,…7001和…6001,缺少…5001。为什么?在这种情况下,因为…7001和…5001共享同一个成员(21),我们只更新了该成员的分数。不好的!

有几种方法可以解决这个问题。第一种是包含某种具有足够熵的随机数据,以确保唯一性。让我们检查一下这个方法。首先,我们将创建一个介于0(包含)和1(排除)之间的伪随机浮点数,然后将其添加到时间戳中。对于我们的示例,为了便于阅读,我们将其保留为十进制形式(在实际工作负载中,将其转换回原始8字节以节省存储空间是明智的做法)。

>ZADD温度2 1511533205001 21:1511533205001.2583(整数)1>ZADD温度2 1511533206001 22:1511533206001.941678(整数)1>ZADD温度2 1511533207001 21:1511533207001.732015(整数)1>ZRANGEBYSCORE温度2-inf+inf带磁芯1) "21:1511533205001.2583"2) "1511533205001"3) "22:1511533206001.941678"4) "1511533206001"5) "21:1511533207001.732015"6) "1511533207001"

如您所见,所有ZADD都返回1s,表示新添加的内容,ZRANGEBYSCORE返回所有值。这是一种可行的方法,但是对于浪费的字节,它并不能非常有效地确保唯一性,这会增加存储开销。对于大多数用例,唯一性将被应用程序丢弃。应该注意的是,如果您的数据已经是唯一的(例如,一些包含UUID的数据),则显然不需要添加唯一性。

使用此方法,您可以访问所有排序集方法,以便进行分析和操作:

  • ZRANGEBYSCORE允许您在两个时间戳之间获取特定的切片
    (ZREVRANGEBYSCORE用于降序)
  • ZREMRANGEBYSCORE允许删除特定范围的时间戳
  • ZCOUNT一系列时间戳之间的项目数
  • 锌店‡允许您将两个时间序列数据集相交,并将其保存在新的密钥中
  • 遵宁斯特‡允许您组合两个时间序列数据集,并将其保存在新密钥中。它还可用于复制已排序集。

‡ZINTERSTORE和ZUNIONSTORE是多键操作。在分片环境中工作时应注意确保新密钥最终位于同一分片上,否则这些命令将以错误告终。

Baidu