thheller / timed-counter

simple Counters in redis

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Extremly simplistic time-based Counters in Redis

redis = Redis.connect

counter = TimedCounter.new(redis)

counter.reset!(:test)
counter.incr(:test, 1)

# get the last 5 minutes
# returns [0, 0, 0, 0, 1]
p counter.minutes(:test, 5.minutes.ago, 5)

# get the last 60 minutes
p counter.minutes(:test, 1.hour.ago, 60)

# get the last 30 days
p counter.days(:test, 30.days.ago, 30)


Data is kept in Hashes in Redis (mostly to cut down on key sizes)

per Key you'll get:

- one total value
- one years hash with a field per year eg. { 2010: value, 2011: value }
- one hash per years with a field per month { 01: value, ...}
- one hash per month with a field per day
- one hash per day with a field per hour
- one hash per hour with a field per minute

Key Layout is: $tc:<key>:<timestamp part>

Keys given may be arrays and will be joined with "/". eg. [:user, 1, :clicks] == "user/1/clicks"

Currently does not set any expires, probably should add some depending on the amount of counts kept. Might be sensible to delete the hour hashes after a few days. Performs all increments atomically instead of relying on rollups and other services. No Idea how well this scales, but should be able to increment a couple thousand counters per second.

Redis Monitor Log:

1299922276.799784 "multi"
1299922276.800636 "incrby" "$tc:test:1:total" "1"
1299922276.800728 "hincrby" "$tc:test:1:years" "2011" "1"
1299922276.800762 "hincrby" "$tc:test:1:2011" "03" "1"
1299922276.800789 "hincrby" "$tc:test:1:201103" "12" "1"
1299922276.800817 "hincrby" "$tc:test:1:20110312" "10" "1"
1299922276.800837 "hincrby" "$tc:test:1:2011031210" "31" "1"
1299922276.800899 "exec"

A hopefully accurate set of all counters keys is kept in "$tc_list" ("SMEMBERS $tc_list").

About

simple Counters in redis

License:MIT License


Languages

Language:Ruby 100.0%