Redis主从之从Redis服务器Key不失效
2016-09-14 18:10
603 查看
大家在使用redis的时候,经常会用expire来设置key的过期时间,以为某个key到期就会马上清除。如果只是在单个redis(即一个主redis)下是没有问题的。但是如果为了实现读写分离,搭建了主从服务器,那么就会遇上从库Key不失效的问题了。(使用Redis3.2以后版本的同学请忽略,3.2之后的版本已不存在以下问题)
场景重现:
主: setex name 20 Johny
从:
get name >> Johny
ttl name >> 18
// 过了一分钟...
// 发现name这个key已经失效了
ttl name >> -1
get name >> Johny // 仍然能获取到key的值
主:get name >> nil // 主Redis服务器上获取不到
从:get name >> nil // 此时,从Redis服务器上也获取不到了
Redis key的三种过期策略
惰性删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key,很明显,这是被动的!
定期删除:由于惰性删除策略无法保证冷数据被及时删掉,所以 redis 会定期主动淘汰一批已过期的key。(在第二节中会具体说明)
主动删除:当前已用内存超过maxMemory限定时,触发主动清理策略。主动设置的前提是设置了maxMemory的值
Redis删除过期Key的源码
所以说,在从库执行主动删除操作,或者通过惰性删除的方式触发删除key的操作,最终都不会执行成功。原因就在上面的第16行代码。
参考:https://github.com/antirez/redis/issues/1768
http://www.cnblogs.com/bridger/archive/2012/11/07/2758734.html http://www.tuicool.com/articles/INRZFr
场景重现:
主: setex name 20 Johny
从:
get name >> Johny
ttl name >> 18
// 过了一分钟...
// 发现name这个key已经失效了
ttl name >> -1
get name >> Johny // 仍然能获取到key的值
主:get name >> nil // 主Redis服务器上获取不到
从:get name >> nil // 此时,从Redis服务器上也获取不到了
Redis key的三种过期策略
惰性删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key,很明显,这是被动的!
定期删除:由于惰性删除策略无法保证冷数据被及时删掉,所以 redis 会定期主动淘汰一批已过期的key。(在第二节中会具体说明)
主动删除:当前已用内存超过maxMemory限定时,触发主动清理策略。主动设置的前提是设置了maxMemory的值
Redis删除过期Key的源码
int expireIfNeeded(redisDb *db, robj *key) { time_t when = getExpire(db,key); 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 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. */ if (server.masterhost != NULL) { return time(NULL) > when; } /* Return when this key has not expired */ if (time(NULL) <= when) return 0; /* Delete the key */ server.stat_expiredkeys++; propagateExpire(db,key); return dbDelete(db,key); }通过以上源码发现,4行:没有设置超时时间,则不删;7行:在"loading"时不删;16行:非主库不删;21行未到期不删。25行同步从库和文件。
所以说,在从库执行主动删除操作,或者通过惰性删除的方式触发删除key的操作,最终都不会执行成功。原因就在上面的第16行代码。
参考:https://github.com/antirez/redis/issues/1768
http://www.cnblogs.com/bridger/archive/2012/11/07/2758734.html http://www.tuicool.com/articles/INRZFr
相关文章推荐
- 在多台服务器上简单实现Redis的数据主从复制
- 在多台服务器上简单实现Redis的数据主从复制
- redis主从服务器的配置(入门)
- Redis主从备份以及key的过期时间配置
- 在多台服务器上简单实现Redis的数据主从复制
- Redis配置-主从服务器-phpredis-phpRedisAdmin-php调用 推荐
- windows下用一台机器配置分布式redis(主从服务器)
- redis:高性能key-value数据库,安装及主从配置(何志雄)
- 俩台服务器搭建redis主从的问题
- redis 配置主从(master-slave)服务器
- redis 多服务器, 主从配置
- redis源码分析:主从模式中从服务器同步策略
- Redis 笔记与总结5 Redis 常用命令之 键值命令 和 服务器命令 && 高级应用之 安全性 和 主从复制
- redis主从服务器配置
- 在多台服务器上简单实现Redis的数据主从复制
- 在多台服务器上简单实现Redis的数据主从复制(3)(转载)
- windows下用一台机器配置分布式redis(主从服务器)
- 在多台服务器上简单实现Redis的数据主从复制