dot Redis 8 来了——而且是开源的

了解更多

有序集合时间序列

返回词汇表

Redis 有序集合时间序列最佳实践

使用有序集合 (zsets) 的时间序列是在 Redis 中对时间序列数据进行建模的典型方式。 有序集合由具有单个键下存储的所有分数的唯一成员组成。 将此数据类型用于有序集合意味着让分数充当某种时间指示(通常是毫秒精度的时间戳,但不总是),而成员是被记录的数据。 唯一需要注意的是,由于这是一种集合形式,因此只允许唯一成员,并且尝试记录与先前成员具有相同值的时间序列条目将只会更新分数。 为了说明这个问题,请看下面记录随时间变化的温度的例子

时间戳温度 C
151153320500121
151153320600122
151153320700121

如果您直接使用ZADD将其作为有序集合添加,您将错过一些数据点

反模式

> ZADD temperature 1511533205001 21
(integer) 1
> ZADD temperature 1511533206001 22
(integer) 1
> ZADD temperature 1511533207001 21
(integer) 0
>

ZRANGEBYSCORE

 temperature -inf +inf WITHSCORES
1) "22"
2) "1511533206001"
3) "21"
4) "1511533207001"

反模式

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

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

> ZADD temperature2 1511533205001 21:1511533205001.2583
(integer) 1
> ZADD temperature2 1511533206001 22:1511533206001.941678
(integer) 1
> ZADD temperature2 1511533207001 21:1511533207001.732015
(integer) 1
> ZRANGEBYSCORE temperature2 -inf +inf WITHSCORES
1) "21:1511533205001.2583"
2) "1511533205001"
3) "22:1511533206001.941678"
4) "1511533206001"
5) "21:1511533207001.732015"
6) "1511533207001"

正如您所看到的,所有 ZADD 都返回 1,表明添加了新条目,并且 ZRANGEBYSCORE 返回所有值。 这是一种可行的方法,但是它效率不高,浪费字节来确保唯一性,从而增加了存储开销。 对于大多数用例,唯一性将被您的应用程序丢弃。 应该注意的是,如果您的数据已经是唯一的(例如,包含 UUID 的某些数据),则显然不需要添加唯一性。

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

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