TL;DR I am looking for a way to store, increment and retrieve ranges of event counts by minute.
I am looking for a solution to creating an incrementing timeseries in redis. I am looking to store counts to the minute. My goal is to be able to look up a time range and get the values. So for instnace if an event occurred for a specific key 30 times a minute. I would want to do something like zrange and get their key values. I also am hoping to use something like zincrby to increment the value. I have of course looked at a sorted set which would have seemed like a perfect fit until I realized that I can only do a range scan on the score and not the value. The optimal solution would be to use the number of minutes as the score and then use the value in the sorted set as the number of events for that minute. The problem I ran into is the zincrby only increments the score and not the value. I was unable to find a way to increment the value atomically. I also looked into a hashmap using the current minute as the key and event count as the value. I was able to increment the value using hincrby but the problem is that it doesn't support fetching a range of keys.
Any help would be appreciated.
In Redis, sorted sets are a data type similar to sets in that both are non repeating groups of strings. The difference is that each member of a sorted set is associated with a score, allowing them to be sorted from the smallest score to the largest.
Redis sorted sets use a double 64-bit floating point number to represent the score. In all the architectures we support, this is represented as an IEEE 754 floating point number, that is able to represent precisely integer numbers between -(2^53) and +(2^53) included.
Redis INCR command is used to increment the integer value of a key by one. If the key does not exist, it is set to 0 before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that cannot be represented as an integer.
Redis - Sorted Set Zinterstore Command Redis ZINTERSTORE command computes the intersection of numkeys sorted sets given by the specified keys, and stores the result in the destination. It is mandatory to provide the number of input keys (numkeys) before passing the input keys and the other (optional) arguments.
You know, right a question already has an answer. And you already says about redis way to solve your problem:
Why only this cases - becouse of only this structures (ZSET, HSET and string keys) has atomic methods to increment values.
So actualy:
The first question answer is compromise between memory and perfomance. From your question you do not need to have any types if sorting so sorted sets is not a best solution - consume lot of memory and ZINCRBY time complexity is O(log(N)) rather HINCRBY and INCRBY is O(1). So we should choose betweeh hashes and string keys. Please look at question and answer about right memory optimization in redis - according this i think you should use hashes as a data type for your solution.
The second question is common for any types of data structures becouse of all types of them do not contains select by name
features or they analogs. And we may use HMGET or LUA scripting to solve this problem. In any case this solution would have time complexity O(n).
Here is sample with Jedis (i`m not an Java programmer, sorry for possible errors):
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);
This solution is atomic, fast, has time complexity O(n) and consume memory as little as possible in redis.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With