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、避免主从的读写分离,从只做备份