【问题标题】:Redis data structure design for sorting time-based values用于对基于时间的值进行排序的 Redis 数据结构设计
【发布时间】:2018-11-21 05:07:19
【问题描述】:

我正在对数据流执行一些分析并将结果发布到 Redis 通道上。消费者订阅这些频道并获得实时数据馈送。历史数据分析结果全部丢失。

现在我想在 Redis 中添加存储历史数据的功能,以便消费者可以查询这些历史数据(主要是按时间)。由于分析结果是按时间划分的,将结果存储在 Redis 中的好的设计是什么?

【问题讨论】:

  • 请注意,redis 获取密钥的性能会随着您获取的单个密钥的数量线性下降。因此,如果您存储了(大部分)连续数据的大型列表,则获取数据时间序列的单字符串表示需要 N 倍的时间。 (对于 300 个值来说这不是问题......但对于 100k 个值来说增加了几个数量级的延迟)。
  • @Nisan - 我不认为我完全理解。如果我每 30 秒存储一次日期,该方法(使用下面的 zsets)是否会产生这种性能损失。
  • 尝试填充您期望的大小的列表并测量读取它需要多长时间。现在尝试将整个列表保存为字符串(例如,作为序列化 JSON 对象,尽管肯定有更多压缩/性能选项)。以我的经验,对于同质数据类型(例如最多 K 位的整数)的非常大的列表(例如 50k-500k 元素),将整个列表存储为时间序列的字符串表示并解包大约快 1000 倍从 Redis 读取后。
  • @SoumyaSimanta 排序集是O(log(N)+M),并且不受列表的相同时间复杂度的影响;它们的效率要高得多。 @Nisan.H 我不同意您的建议,将整个列表存储为字符串可能适用于小列表,但不能扩展到非常大的列表,因为它会强制客户端在执行任何操作之前检索整个列表并解压缩它在上面;这不是一个有效的解决方案。下面概述的排序集的使用是 OP 问题的教科书解决方案。
  • @Raffian 虽然我原则上同意,但根据我的经验,Redis 从集合(列表、集合、排序集、哈希字段)中读取 N 个值与读取 N 个常规值一样长键:值对。读取单个非常大的值并不需要很长时间......这是非常具体的情况,只有当您的集合非常大并且您的读取量很大(每个读取操作有数千个值)时才会出现问题,但这是值得的意识到。

标签: database-design redis


【解决方案1】:

使用redis sorted sets

排序集基于“分数”存储数据,因此在您的情况下,只需使用以毫秒为单位的时间戳;数据将自动排序,允许您使用开始/结束日期范围检索历史项目,这是一个示例...

将项目添加到排序集...

zadd historical <timestamp> <dataValue>

..添加一些示例数据..

 zadd historical 1 data1
 zadd historical 2 data2
 zadd historical 3 data3
 zadd historical 4 data4
 zadd historical 5 data5
 zadd historical 6 data6
 zadd historical 7 data7

..使用开始/结束范围检索项目的子集...

 zrangebyscore historical 2 5

..返回...

1) "data2"
2) "data3"
3) "data4"
4) "data5"

因此,在您的情况下,如果您想检索最后一天的所有历史项目,只需执行此操作...

zrangebyscore historical <currentTimeInMillis - 86400000> <currentTimeInMillis> 

【讨论】:

  • 如果在同一毫秒内插入两条数据会怎样?
  • 虽然成员在排序集中是唯一的,但分数(在这种情况下是时间戳)可能会重复。
  • 您可以在数据之前或之后添加一些随机字符串以防止重复。
  • 感谢您的回答。我认为在您的上一个代码示例中,您希望反转范围,即zrangebyscore historical &lt;currentTimeInMillis - 86400000&gt; &lt;currentTimeInMillis&gt;,因为它看起来首先需要较低的值。
  • 这里有这个概念的详细版本:redislabs.com/redis-best-practices/time-series/…,虽然我不明白,由于上面 cmets 中提出的重复问题,为什么我们不使用 zadd historical 7 &lt;timestamp&gt;。看起来这样会更好。
猜你喜欢
  • 2019-07-14
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 2021-01-13
  • 1970-01-01
相关资源
最近更新 更多