redis 127.0.0.1:6379> TTL KEY_NAME
redis 127.0.0.1:6379> EXPIRE runooobkey 60
(integer) 1
127.0.0.1:6379> PEXPIRE k2 10000000
(integer) 1
127.0.0.1:6379> SETEX k1 100 v1
OK
127.0.0.1:6379> ttl k1
(integer) 92
127.0.0.1:6379> get k1
"v1"
//TTL命令
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> ttl key
(integer) -2
127.0.0.1:6379> set key value
OK
127.0.0.1:6379> ttl key
(integer) -1
//expire命令
127.0.0.1:6379> expire key 10
(integer) 1
127.0.0.1:6379> ttl key
(integer) 7
127.0.0.1:6379> ttl key
(integer) 3
127.0.0.1:6379> ttl key
(integer) -2
//PEXPIRE命令
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> PEXPIRE k2 10000000
(integer) 1
127.0.0.1:6379> ttl k2
(integer) 9994
//PERSIST 命令
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> EXPIRE k1 100
(integer) 1
127.0.0.1:6379> ttl k1
(integer) 86
127.0.0.1:6379> PERSIST k1
(integer) 1
127.0.0.1:6379> ttl k1
(integer) -1
@Autowired
private JedisPool jedisPool;
Jedis jedis = jedisPool.getResource();
System.out.println("判断key是否存在:"+shardedJedis.exists("key"));
// 设置 key001的过期时间
System.out.println("设置 key的过期时间为5秒:"+jedis.expire("key", 5));
// 查看某个key的剩余生存时间,单位【秒】.永久生存或者不存在的都返回-1
System.out.println("查看key的剩余生存时间:"+jedis.ttl("key"));
// 移除某个key的生存时间
System.out.println("移除key的生存时间:"+jedis.persist("key"));
System.out.println("查看key的剩余生存时间:"+jedis.ttl("key"));
// 查看key所储存的值的类型
System.out.println("查看key所储存的值的类型:"+jedis.type("key"));
timelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;
if (dbs_per_call > server.dbnum || timelimit_exit)
dbs_per_call = server.dbnum;
for (j = 0; j int expired;
redisDb *db = server.db+(current_db % server.dbnum);
current_db++;
do {
...
/* If there is nothing to expire try next DB ASAP. */
if ((num = dictSize(db->expires)) == 0) {
...
}
slots = dictSlots(db->expires);
now = mstime();
if (num && slots > DICT_HT_INITIAL_SIZE &&
(num*100/slots <1)) break;
...
if (num > ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP)
num = ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP;
while (num--) {
...
}
/* Update the average TTL stats for this database. */
if (ttl_samples) {
...
}
iteration++;
if ((iteration & 0xf) == 0) { /* check once every 16 iterations. */
...
}
if (timelimit_exit) return;
} while (expired > ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP/4);
while (num--) {
dictEntry *de;
long long ttl;
if ((de = dictGetRandomKey(db->expires)) == NULL) break;
ttl = dictGetSignedIntegerVal(de)-now;
if (activeExpireCycleTryExpire(db,de,now)) expired++;
if (ttl <0) ttl = 0;
ttl_sum += ttl;
ttl_samples++;
}
int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) {
long long t = dictGetSignedIntegerVal(de);
if (now > t) {
sds key = dictGetKey(de);
robj *keyobj = createStringObject(key,sdslen(key));
propagateExpire(db,keyobj);
dbDelete(db,keyobj);
notifyKeyspaceEvent(REDIS_NOTIFY_EXPIRED,
"expired",keyobj,db->id);
decrRefCount(keyobj);
server.stat_expiredkeys++;
return 1;
} else {
return 0;
}
}
/* We can‘t block forever here even if there are many keys to
* expire. So after a given amount of milliseconds return to the
* caller waiting for the other active expire cycle. */
iteration++;
if ((iteration & 0xf) == 0) { /* check once every 16 iterations. */
long long elapsed = ustime()-start;
latencyAddSampleIfNeeded("expire-cycle",elapsed/1000);
if (elapsed > timelimit) timelimit_exit = 1;
}
if (timelimit_exit) return;
int expireIfNeeded(redisDb *db, robj *key) {
mstime_t when = getExpire(db,key);
mstime_t now;
if (when <0) return 0; /* No expire for this key */
/* Don‘t expire anything while loading. It will be done later. */
if (server.loading) return 0;
/* If we are in the context of a Lua script, we claim that time is
* blocked to when the Lua script started. This way a key can expire
* only the first time it is accessed and not in the middle of the
* script execution, making propagation to slaves / AOF consistent.
* See issue #1525 on Github for more information. */
now = server.lua_caller ? server.lua_time_start : mstime();
/* If we are running in the context of a slave, return ASAP:
* the slave key expiration is controlled by the master that will
* send us synthesized DEL operations for expired keys.
*
* Still we try to return the right information to the caller,
* that is, 0 if we think the key should be still valid, 1 if
* we think the key is expired at this time. */
/*如果我们正在slaves上执行读写命令,就直接返回,
*因为slaves上的过期是由master来发送删除命令同步给slaves删除的,
*slaves不会自主删除*/
if (server.masterhost != NULL) return now > when;
/*只是回了一个判断键是否过期的值,0表示没有过期,1表示过期
*但是并没有做其他与键值过期相关的操作*/
/* Return when this key has not expired */
/*如果没有过期,就返回当前键*/
if (now <= when) return 0;
/* Delete the key */
/*增加过期键个数*/
server.stat_expiredkeys++;
/*传播键过期的消息*/
propagateExpire(db,key);
notifyKeyspaceEvent(REDIS_NOTIFY_EXPIRED,"expired",key,db->id);
/*删除过期键*/
return dbDelete(db,key);
}
//加进redis时,设置生存时间
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String string = jedis.set(key, value);
jedis.expire(key,5);
System.out.println("key : "+key);
System.out.println("查看key的剩余生存时间:"+jedis.ttl(key));
jedis.close();
return string;
}
//从redis获取时
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String string = jedis.get(key);
jedis.expire(key,5);//每次访问刷新时间
jedis.close();
return string;
}
Redis系列(三)--过期策略