I want to use redis timeseries to store item count. i.e
Monitoring many companies and Company A has an account where they have added employees... When an employee adds an item I want to update their count of today, thisweek and thismonth and also increment the company A's account items today, this week and this month.
Is RedisTimeSeries the best technology and how can it be done to monitor multiple companies and their employees ?
If you don't need the history of items over time, One option is to just use counters (integers, Redis Strings) in either a multi exec block or a Lua script.
I tagged the company name (A) so that all keys reside on the same shard. 123 denotes the employee id
MULTI
SADD {A}:123:items newItem
INCR {A}:123:total
INCR {A}:123:2021
INCR {A}:123:2021:month:07
INCR {A}:123:2021:week:32
EXEC
Alternatively, you could keep all the counts per user in a single hash and use HINCRBY
Either solution might need some clean up for longer running periods.
Related
How can I store collection with key-value pairs in Redis? For example, I want to log time when user tried to login, to some collection. Every user have id, so I want to use it as a key. But I want to store it separatly from other elements, in separate collection
For each user you can have a sorted set. You can use the user id in the name of the sorted set. Just use 1 as the value since you don't need to store something there and use the timestamp as the score.
zadd 'user:' + uid +':logins' currentTimestamp 1
With this you can run queries to grab how many times a user tried to login during certain periods with zcount etc.
I use awesome Redis sorted sets to score users and, then, quickly get user rating by score. Also, my score has "weight", so that one score can give 5 points to user, and another vote can give 2 points, etc. Now if somebody votes for user, I call
ZINCRBY user:votes <vote_weight> <userId>
but now I need to calculate users ratings for the last week, month, year from the current timestamp (like 'moving window')
What is the best way to do it in Redis?
Your current approach would only work if you're interested in counting all votes from the beginning of time until this instant..
Lets focus on the problem of doing this for today - this could be easily addressed by adding a new sorted, e.g. votes:today, and doing the ZINCR on its elements.
What happens when today becomes tomorrow? Simple - either RENAME the key, e.g. to votes:yesterday, or just use the timestamp to begin with so you'll always be updating today's vote key, i.e. votes:<timestamp day value>
If you use the timestamp approach, after a week you'll end up with 7 keys - on for each day - with scores-per-user. Getting the results for the last week is a simple matter of getting these 7 keys' members and summing up their scores. You could even do it on the fly. The same goes for 1m0, 3mo, 6mo, 12mo and so forth... but.
But, if you want to do it for 12mo (~= 365 keys), you'll need more RAM (for storing these keys in Redis) and it will take longer to complete the aggregation, naturally. You can combat this by combining Redis' key expiry capabilities (e.g. set the TTL of a day's key to 12mo to keep only one year of history) and keeping running aggregates that are updated either on the fly (i.e. with every vote) or periodically (daily, weekly, monthly, etc...). Note that the same scripts can do housekeeping and delete/archive old data, potentially solving the need to expire it explicitly.
mayby I am doin something completely useless to create my datasets at all. I incr keys to a user-tracking with
incr('userhit-by-day:20131118') //for the day
incr('userhit-by-day-and-userid:20131118:foobar123') //for the day and userid
How can I get a hit counter like top 10 users by from today, this week and a special date?
make use of "Sorted set" as per above comment.
here is documentation
Create a set for every day,
In that set, key should be UserId and its value should be count of hits.
Use ZINCRBY key increment member to update user's hit count.
Using ZREVRANGE key start stop [WITHSCORES] you can get list of all players who hit that day.
Using ZSCORE key member you can get particular users hit count.
In a rails find...how do I sum all the values from multiple records that have a matching key?
For example, I have a flight and duty log where users store times they have flown or worked. I am storing these k/v pairs using hstore. One duty log will be created each day. If a user logs time in the same aircraft day after day...I need to be able to do something like this:
Dutylog.where(user_id: current_user).where("(properties -> '206B')::float > 0.0")
# properties is the hstore hash
This finds all the correct records...but, I am having trouble summing all the values whos key is "206B".
How would you do this?
Its in the docs...but the docs are not easy to understand...at least for me. Here is a solution:
Dutylog.where("(properties -> '206B')::float > 0.0").sum("(properties -> '206B')::float")
Node.js & Redis:
I have a LIST (users:waiting) storing a queue of users waiting to join games.
I have SORTED SET (games:waiting) of games waiting for users. This is updated by the servers every 30s with a new date. This way I can ensure if a server crashes, the game is no longer used. If the server is running and fills up, it'll remove itself from the sorted set.
Each game has a SET (game:id:users) containing the users that are in it. Each game can accept no more than 6 players.
Multiple servers are using BRPOP to pick up users from the LIST (users:waiting).
Once a server has a user id, it gets the waiting games ids, then proceeds to run SCARD on their game:id:users SET. If the result of this is less than 6, it adds them to the set.
The problem:
If multiple servers are doing this at once, we could end up with more than 6 users being added to a set at a time. For example if one server requests SCARD and immediately after another runs SADD, the number in the set will have increased but the first server won't know.
Is there anyway of preventing this?
You need transactions, which redis supports: http://redis.io/topics/transactions
in your case in particular, you want to pay attention to the watch command: http://redis.io/topics/transactions#cas