使用 redis 如何维护一个动态的区间和?

2022-03-17 10:31:06 +08:00
 111qqz

需求是这样: 有一个队列,队列中的元素是不断变化的,想知道这个队列中所有元素的和。

队列元素的增加: 当一个请求到来时,就往队列中添加元素。 可能同时到来上百个请求

队列元素的删除: 按照时间删除,当请求到来超过一定时间后,自动删除。

说白了就是想维护一个时间窗口,并查询窗口中元素之和。

我目前想过的两种做法:

  1. 利用 redis 的 key 过期时间进行。 但是 key 过期的时候,无法直接反应到 sum 上。 每次请求 sum 都要把队列中的元素累加一遍,可能不太合理?

  2. 队列中存储元素的时间戳,定时(比如 100ms )来根据元素的时间戳进行逐个删除,删除的同时维护区间和。 删除到第一个在时间窗口中的元素为止。 (队列从右边加入元素,从左边删除元素)

第一次使用 redis ,想问问各位大佬这个操作要如何进行比较合理?

2923 次点击
所在节点    Redis
26 条回复
git00ll
2022-03-17 14:37:37 +08:00
第二种方式没问题,resilience4j 中就有与这种做法类似的做法
111qqz
2022-03-17 18:12:48 +08:00
@git00ll #21 感谢解答
moqimoqide
2022-03-18 00:07:00 +08:00
如果 redis 的版本大于 5 ,建议使用 流 这种数据结构。

XADD 命令还提供了 MAXLEN 选项,让用户可以在添加新元素的同时删除旧元素,以此来限制流的长度:

​​​​​​​​​​XADD stream [MAXLEN len] id field value
ricky077
2022-03-18 00:53:53 +08:00
刚好我们也有这样一个物联网项目,数据量挺大,需要查固定周期内的数据来求和,感谢楼上老哥些的方法
111qqz
2022-03-19 13:17:52 +08:00
@moqimoqide #23 感谢,不过看了下和我的需要不太一样。 我窗口中元素个数其实并不会固定,在请求高峰期和低峰期会差非常多。
111qqz
2022-03-31 20:15:47 +08:00
调研到了这个 https://redis.io/docs/stack/timeseries/
感觉蛮合适

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/840956

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX