排序集中特定范围内过去 24 小时分数的总和 (Redis)



有没有办法计算 24 小时内保存的分数总和,尊重 Redis 服务器的性能?(每天添加约 100 万行(

使用什么格式来存储使用排序集的用户的时间戳和分数?

实际上我正在使用以下命令:

ZADD allscores 1570658561 20

作为分数,这是以秒为单位的实际时间...等字段才是真正的分数。

但是,这里有一个问题!当另一个用户获得相同的分数 (20( 时,不会添加它,因为它已经存在 - 这个问题有什么解决方案吗?

我正在考虑使用 LUA 脚本,但有 2 个令人头疼的问题:

  • LUA 脚本将阻止其他命令工作,直到完成作业(对于我的情况来说,这不是一个好的做法,因为脚本必须 24/24 7/7 工作,同时许多用户必须同时从 Redis 缓存服务器获取数据,如用户分数、历史信息等。 - 另外,LUA脚本每次都必须处理每天保存在特定键中的许多记录 - 所以, 当Lua脚本工作时,用户无法获取数据...知道 Lua 脚本将始终循环工作。

  • 其次,它与第一个问题有关,如果我在命令中使用时间戳作为分数,则不允许我存储相同的分数,以便我可以返回 24 小时数据。

如果你是我的情况,你将如何处理这个问题?谢谢

考虑到过去 24 小时(滑动窗口(需要数据,可能的行数为 100 万。我们不能使用排序集数据结构来计算高性能的总和。

高性能设计,并解决您的重复分数问题:

相反,只需对准确性做出一点决定,您就可以通过在窗口中处理数据来拥有一个高性能的系统。

示例输入数据: 输入 1:用户 1 要添加 时间:11:10:01 分数:20 输入 2:用户 2 想要添加 时间:11:11:02 分数:20 输入 3:用户 1 想要添加 时间:11:17:04 分数:50

您可以有 1 分钟、5 分钟或 1 小时的准确性,并据此决定窗口。


如果您接受近似 1 小时的数据,则可以在插入时获得此数据, 对于输入 1 :

INCRBY SCORES_11_hour 20

对于输入 2:

INCRBY SCORES_11_hour 20

对于输入 3:

INCRBY SCORES_11_hour 20

若要获取过去 24 小时的数据,只需汇总 24 小时键。

MGET SCORES_previous_day_12_hour SCORES_previous_day_13_hour SCORES_previous_day_14_hour ....SCORES_current_day_10_hour SCORES_current_day_11_hour


如果您接受近似值 5 分钟,则可以在插入时执行此操作,同时增加每小时键,您需要存储 5 分钟的窗口数据。

对于输入 1 :

INCRBY SCORES_11_hour 20

INCRBY SCORES_11_hour_00_minutes 20

对于输入 2:

INCRBY SCORES_11_hour 20

INCRBY SCORES_11_hour_00_minutes 20

对于输入 3:

INCRBY SCORES_11_hour 20

INCRBY SCORES_11_hour_05_minutes 20

要获取过去 24 小时的数据,您只需汇总 23 小时键(整小时数据(+ 12 个五分钟窗口键


如果添加的时间基于当前时间,则可以进一步优化它。(假设如果是第 11 小时,并且第 10 小时、第 9 小时和前几个小时的数据根本不会改变(。

正如您所说,它将是 24/7,我们也可以使用以前迭代中的一些计算值。

假设它是在第 11 小时计算的,您将获得过去 24 小时的值。 如果在第 12 小时再次计算,则可以在数据不变的 22 个中间小时内重复使用总和,并且仅从 redis 获取缺失的 2 小时数据。

同样,可以根据您的需要应用进一步的优化。

最新更新