我已经搜索并做了一些阅读,但是找不到答案。我相信我可能对缓存实现有错误的想法。
我有一组历史和当前的金融股票数据,我想将它们缓存起来以便快速访问 API,这些数据遵循以下格式:
id: uuid
timestamp: unix_timestamp
data: {...}
Run Code Online (Sandbox Code Playgroud)
目的是允许用户请求缓存提供的数据,但是我希望用户能够提供一个时间范围,例如 1483142400 - 1493510400
秒的形式(例如 300、900 、1800、3600、86400)。
我现在在如何处理这个问题上进退两难,我最初的想法是将所有时间戳存储zadd
在每个股票的单个排序集中,然后使用zrange
. 然而,这将是昂贵的,因为我会查询太多不必要的数据,除非 Redis 能够在一段时间内“逐步”通过(如果我可以提供所有密钥,因为它们遵循非随机的一致格式)。
我的第二个想法是改用单独的密钥,因为我的财务数据是针对股票 XYZ 的:
ZADD XYZ_300 1501200300 'data' 1501200600 'data'
ZADD XYZ_900 1501200900 'data' 1501201800 'data'
ZADD XYZ_1800 1501201800 'data' 1501203600 'data'
ZADD XYZ_3600 1501203600 'data' 1501207200 'data'
Run Code Online (Sandbox Code Playgroud)
然而,这意味着我有一些冗余数据正在进行,因为所有集合都将包含在 300 秒表中也可用的数据。
此外,我可能有一些股票,例如XYZ
、ABC
和DEF
。我希望能够每小时查询 3 天前到 2 天前的所有上述所有股票的数据,我不确定是否应该使用某种ZUNIONSTORE
或某种管道来有效地执行此操作一次查询多个范围。
现在唯一的保证是我确切地知道我的密钥是什么,因为它们总是四舍五入到最接近的 00:00、05:00、15:00 和 30:00 分钟 unix 时间戳。正在从运行 Django(存储 json)的 Python 中设置/查询缓存本身。可能我最好将其存储在文件而不是缓存中(因为我使用的是 AWS,我可以利用新的 EFS 存储系统让多个服务器共享相同的底层“硬盘/卷”)
小智 5
据我了解,您有 2 个基本要求:1. 能够在任何随机时间范围内进行查询 2. 按时间跨度查询结果聚合
ZRANGE 基本上是一个排序集,具有(非常)高效的查询运行时。从Redis手册:
O(log(N)+M) 其中 N 是排序集中的元素数,M 是返回的元素数。
许多人的一个常见用例是将时间序列数据保存在一个排序集中:
关于性能,我们需要同时查看插入和读取:
关于要求 #2:在 redis 中没有简单的方法进行聚合。
总而言之,时间序列没有最佳的数据结构,您可以使用 ZSET(很多人都这样做)它可以工作,但不是非常优化,也没有空间效率。
您可以通过以下方式改进:
或者您可以尝试使用我编写和维护的模块:https : //github.com/danni-m/redis-timeseries。特点是: