Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design 基于时间值排序的Redis数据结构设计_Database Design_Redis - Fatal编程技术网

Database design 基于时间值排序的Redis数据结构设计

Database design 基于时间值排序的Redis数据结构设计,database-design,redis,Database Design,Redis,我正在对数据流执行一些分析,并将结果发布到Redis频道上。消费者订阅这些频道并获得实时数据源。所有历史数据分析结果都将丢失 现在我想添加在Redis中存储历史数据的功能,以便消费者可以查询这些历史数据(主要是按时间)。既然分析结果是按时间划分的,那么在Redis中存储结果的好设计是什么 使用redis 排序集根据“分数”存储数据,因此在您的情况下,只需使用毫秒的时间戳;数据将自动排序,允许您使用开始/结束日期范围检索历史项目,下面是一个示例 将项目添加到已排序的集合 zadd historic

我正在对数据流执行一些分析,并将结果发布到Redis频道上。消费者订阅这些频道并获得实时数据源。所有历史数据分析结果都将丢失

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

使用redis

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

将项目添加到已排序的集合

zadd historical <timestamp> <dataValue>
…使用开始/结束范围检索项目的子集

 zrangebyscore historical 2 5
…返回

1) "data2"
2) "data3"
3) "data4"
4) "data5"
因此,在您的情况下,如果您想检索最后一天的所有历史项目,只需执行以下操作

zrangebyscore historical <currentTimeInMillis - 86400000> <currentTimeInMillis> 
zrangebyscore历史记录

请注意,redis密钥获取性能会随着您获取的单个密钥的数量线性下降。因此,如果存储了大量(大部分)连续数据,则获取数据时间序列的单个字符串表示形式所需的时间将是获取数据时间序列的N倍。(对于300个值来说,这不是一个问题……但是对于100k值来说,增加了几个数量级的延迟)。@Nisan-我不认为我完全理解。如果我每30秒存储一次日期,那么这种方法(使用下面的zsets)会有这样的性能损失吗?请尝试填充一个您期望的列表,并测量从中读取数据所需的时间。现在,通过将整个列表保存为字符串(例如,作为序列化的JSON对象,当然还有更多的压缩/性能选项)来尝试同样的方法。根据我的经验,对于同质数据类型的非常大的列表(例如50k-500k个元素)(例如最多有K位的整数),将整个列表存储为时间序列的字符串表示形式并在从Redis读取后将其解包大约快1000倍。@SoumyaSimanta排序集是
O(log(N)+M)
,并且不受清单同时复杂性的影响;它们的效率要高得多@Nisan.H我不同意你的建议,将整个列表存储为字符串可能适用于小列表,但不能扩展到非常大的列表,因为它迫使客户端在对其执行任何操作之前检索整个列表并将其解压缩;这不是一个有效的解决办法。下面概述的使用排序集是解决OP问题的教科书解决方案。@Raffian虽然我原则上同意,但根据我的经验,Redis从集合(列表、集合、排序集、hashfield)中读取N个值的时间与读取N个常规键:值对的时间差不多。只要读取一个非常大的值,就不会花费太长时间。。。这是一个非常具体的问题,仅当您的集合非常大且读取量很大(每个读取操作有数千个值)时才会出现,但值得注意。如果在同一毫秒内插入两个数据会怎么样?虽然成员在排序集中是唯一的,但分数(在本例中为时间戳)可能会重复。您可以在数据之前或之后添加一些随机字符串,以避免重复。谢谢您的回答。我认为在上一个代码示例中,您可能希望反转范围,即
zrangebyscore historical
,因为它似乎首先期望较低的值。这里有这个概念的详细版本:,尽管我不明白,上面的评论中提出了重复问题,为什么我们不改为
zadd historical 7
。看起来这样会更好。
zrangebyscore historical <currentTimeInMillis - 86400000> <currentTimeInMillis>