TL; DR我正在寻找一种按分钟存储,增加和检索事件计数范围的方法。
我正在寻找在redis中创建递增时间序列的解决方案。我希望将分数存储到分钟。我的目标是能够查找时间范围并获得值。因此,如果特定键的事件每30分钟发生一次,则为instnace。我想做像zrange这样的事情,并获得他们的关键价值观。我也希望使用像zincrby这样的东西来增加价值。我当然看了一个有条不紊的装置,看起来像是一个完美的装,直到我意识到我只能对得分进行范围扫描,而不是值。最佳解决方案是使用分钟数作为分数,然后使用排序集中的值作为该分钟的事件数。我遇到的问题是,锌只会增加分数而不是值。我无法找到一种原子地增加值的方法。我还使用当前分钟作为键和事件计数作为值来查看散列映射。我能够使用hincrby增加值,但问题是它不支持获取一系列键。
任何帮助都将不胜感激。
答案 0 :(得分:3)
你知道,问题已经有了答案。你已经说过redis解决问题的方法了:
为什么只有这种情况 - 因为只有这种结构(ZSET,HSET和string keys)才有原子方法来增加值。
所以实际上:
第一个问题的答案是记忆和表现之间的妥协。根据您的问题,如果排序这样排序的集合不是最佳解决方案,则不需要任何类型 - 消耗大量内存并且ZINCRBY时间复杂度为 O(log(N))而不是HINCRBY和INCRBY O(1)。所以我们应该选择哈希和字符串键。请查看关于redis中正确内存优化的question and answer - 据此我认为您应该使用哈希作为解决方案的数据类型。
第二个问题对于任何类型的数据结构都是通用的,因为它们的所有类型都不包含select by name
特征或它们的类似物。我们可能会使用HMGET或LUA scripting来解决此问题。在任何情况下,该解决方案都具有时间复杂度 O(n)。
以下是Jedis的示例(我不是Java程序员,对可能的错误感到抱歉):
int fromMinute = 1;
int toMinute = 10;
List<String> list = new ArrayList<String>();
for(int i = fromMinute ; i < toMinute ; i++) {
list.add(i.toString());
}
Jedis jedis = new Jedis("localhost");
List<String> values = jedis.hmget("your_set_name", list);
此解决方案原子,快速,具有时间复杂度 O(n)并且在redis中尽可能少地消耗内存。