Test script to check how redis expire registration works.
Run with npm run
.
const redis = require('redis'), | |
subscriber = redis.createClient(6379, 'localhost'), | |
writer = redis.createClient(6379, 'localhost'), | |
keys = new Map(); | |
// config | |
const keyCount = 10000, | |
delay = 10, // expire delay in seconds | |
listenDelay = 5, // how many seconds to listen after last timeout | |
batchDelay = 1, // how many seconds between a batch | |
batches = 20; // In how many batches to execute | |
subscriber.on('pmessage', (pattern, channel, message) => { | |
if (message == 'expired') { | |
const parts = channel.split(':'), | |
key = Number(parts[2]), | |
keyData = keys.get(key); | |
keyData.unset = Date.now(); | |
keyData.delay = keyData.unset - keyData.set - delay * 1000; | |
} | |
}); | |
function setExpiringBatch(start, count, cb) { | |
for (let i = 0; i < count; i += 1) { | |
const key = i + start; | |
writer.setex(`expire-test:${key}`, delay, Date.now()); | |
keys.set(key, { set: Date.now(), unset: undefined, delay: 0 }); | |
} | |
console.log(`Added ${count} test keys with ${delay}s expire time.`); | |
cb(start + count); | |
} | |
subscriber.on('psubscribe', (channel, count) => { | |
console.log("Subscribed to keychange events."); | |
const more = (last) => { | |
if (last < keyCount) { | |
console.log('Sleeping for', batchDelay, 's') | |
setTimeout(() => { | |
setExpiringBatch(last + 1, keyCount / batches, more); | |
}, batchDelay * 1000); | |
} else { | |
setTimeout(() => { | |
console.log(`Listened for ${listenDelay + delay}s, shutting down.`); | |
subscriber.punsubscribe("__keyspace@0__:*"); | |
subscriber.quit(); | |
writer.quit(); | |
const keyValues = keys.values(); | |
let unexpiredCount = 0, | |
biggestDelay = 0, | |
delays = []; | |
for (let keyData of keyValues) { | |
if (!keyData.unset) | |
unexpiredCount += 1; | |
else | |
if (keyData.delay > biggestDelay) | |
biggestDelay = keyData.delay; | |
delays.push(keyData.delay); | |
} | |
delays.sort(); | |
console.log("Results for expire test:"); | |
console.log("Created", keyCount, "expiring keys with", delay, "s expire time in", batches, "batches with", batchDelay, "s between each batch."); | |
console.log("Keys that did not expire: ", unexpiredCount); | |
console.log("Biggest delay was:", biggestDelay, "ms"); | |
console.log("Median delay was: ", delays[Math.floor(delays.length / 2)], "ms"); | |
console.log("Mean delay was: ", Math.floor(delays.reduce((memo, count) => { return memo + count; }, 0) / delays.length), "ms"); | |
}, (listenDelay + delay) * 1000); | |
} | |
} | |
setExpiringBatch(0, keyCount / batches, more); | |
}); | |
writer.keys("expire-test:*", (err, keys) => { | |
console.log(`Found ${keys.length} existing keys.`); | |
if (keys.length > 0) { | |
console.log("Deleting existing keys."); | |
writer.del(...keys); | |
} | |
subscriber.config("SET", "notify-keyspace-events", "Kx"); | |
subscriber.psubscribe("__keyspace@0__:*"); | |
}); |
{ | |
"name": "redis-expire-test", | |
"version": "0.0.1", | |
"description": "Test redis key expiration", | |
"main": "index.js", | |
"scripts": { | |
"test": "./node_modules/.bin/babel-node index.es6" | |
}, | |
"author": "Otto Vehvilainen", | |
"license": "MIT", | |
"dependencies": { | |
"babel": "^4.5.5", | |
"hiredis": "^0.2.0", | |
"redis": "^0.12.1" | |
} | |
} |