Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possibility of Hash/Set/List fields expiration #242

Closed
kalondar opened this issue Dec 9, 2011 · 3 comments
Closed

Possibility of Hash/Set/List fields expiration #242

kalondar opened this issue Dec 9, 2011 · 3 comments

Comments

@kalondar
Copy link

kalondar commented Dec 9, 2011

Now it's possible to set expiration only for keys to main objects, not for collecion elements.
I have design problem with that.

Let's imagine we store session properties in the hash.
Session expires after some time, but we have to know how many sessions are still alive.
So... | created another collection to store active session list, where:
token (key), and key to session hash (value).

Now, when my session expires, it's token in active collection is still present,
and I have no posiibility to remove them.

Solutions:

  1. Possibility of Hash/Set/List fields expiration. I wille simply set expiration of session token, the same like main session hash

  2. Expiration triggers - when key expires, some command group wille be executed (Maybe Lua script)

  3. Publish expiration message to earlier defined channel, containing expired key. Using drivers I could implements my own triggers

@antirez
Copy link
Contributor

antirez commented Jan 16, 2012

Hi, this will not be implemented by original design:

  • No nested types in keys.
  • No complex features in single fields of aggregate data types.

The reasoning is much more complex and is a lot biased by personal feelings, preference and sensibility so there is no objective way I can show you this is better ;)

Closing. Thanks for reporting.

@antirez antirez closed this as completed Jan 16, 2012
@rkh
Copy link

rkh commented Jun 18, 2012

Is there a best practice for approaching this?

@Tectract
Copy link

I have come up with a pretty good work-around solution for this "expire redis hash values by key" problem.

Essentially you just store the entries with the timestamps as the keys, or embedded into the keys. Note that redis wants strings as keys so you'll have to .toString() / parseInt() the keys to do compares. Using this scheme, you just make a bunch of hash tables with your relevant variables in the names of the hash tables, and each one has timestamp/value pairs.

For example, in nodejs:

var Redis = require('then-redis')
var _ = require("underscore");
var redClient = Redis.createClient('tcp://localhost:6379');
var now = new Date();
var nowSeconds = parseFloat( Math.round(now.getTime() / 1000)); 
var nowSecondString = nowSeconds.toString();
thisEntry[nowSecondString] = myReleventValueAtThisTime;
var myHashTableName = thisCategory + ":" + thisSubcategory + ":" + thisFrame;    
// add newest entry to hash
redClient.hmset(myHashTableName,thisEntry).then(function () {
    // get all entries from hash
    redClient.hgetall(myHashTableName).then(function (result) { 
        console.log("got existing entries from : " + myHashTableName + " hashTable.")
        var myCurrentValidValues = [];
        if (result) {
            for (var i in result) {
                // test entries for being too old in seconds
                if (parseFloat(i) < nowSeconds - 180) { 
                    // this entry is > 3 minutes old, mark for deletion
                    redClient.hdel(myHashTableName,i) // delete old entries here
                } else {
                    var thisValidKeyValPair = {}
                    // our values happen to be floats
                    thisValidKeyValPair[i] = parseFloat(result[i]);
                    myCurrentValidValues.push(thisValidKeyValPair) 
                }
            }
            // now do stuff with your value array, which doesn't including "stale" entries
            // example sort by value descending
            myCurrentValidValues.sort(function(a,b){ 
                return( _.values(a) - _.values(b));
            })
            // example sort by timestamp, oldest to newest, ascending
            myCurrentValidValues.sort(function(a,b){ 
                return( parseFloat(_.keys(a)) - parseFloat(_.keys(b)));
            })
        }
    })
})

Note that just deleting the old entries before you do any critical analysis on the values, as you go, is far more efficient, computationally, than having redis actually check timeout values on every key in every redis hash in every DB every second. So, it's not a bad solution.

PatKamin added a commit to PatKamin/redis that referenced this issue Oct 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants