Redis 从库key值过期不失效问题 3.2版本以下 - Wangxiaoman/tech-note GitHub Wiki
现象
之前在一个服务上用到了3.0以下低版本的redis,主从服务,写主读多从。发现在redis主上设置key值得expire时间,当该key值的实效时间已经到达的时候,从上仍然能够获取到该key值,从而引发了查询判断上的bug。
分析
redis的过期策略,可以从之前的文章Redis的数据过期策略了解
代码分析
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);
}```
从源码可以看出,通过server.masterhost来判断,如果是redis的从库,那么不走下面的删除部分。
## 解决方案
1、升级Redis版本
2、获取到key值之后,通过ttl判断该值是否过期
3、避免主从的读写分离,从只做备份