Redis --------从节点过期还能读到

0 从节点必须等主节点同步删除命令才会删除

如果一个键过期了,可以有下面3个过期删除策略:

①定时删除(Redis不支持)
②惰性删除
③定期删除

1 使用TTL命令

使用TTL key可以访问key的生存时间。

时间复杂度:

O(1)

返回值:

当 key 不存在时,返回 -2 。

当 key 存在但没有设置剩余生存时间时,返回 -1 。

否则,以秒为单位,返回 key 的剩余生存时间

2 使用Redis3.2以上

Redis3.2以上,已经做出了优化:对于在从库中已经过期的键,在从库发起读取的时候,Redis会判断这个键是否已经过期,如果已经过期,那么将返回nil;但是对于这个过期的键,从库仍然不会自己采取清理措施,而是需要等主库发起对这个过期键的清理,然后同步DEL操作过来,从库才应用DEL操作对过期键进行删除。
所以Redis3.2以上的优化总结来说,是屏蔽了从库中已经过期的键

 * Note: this function also returns NULL is the key is logically expired
 * but still existing, in case this is a slave, since this API is called only
 * for read operations. Even if the key expiry is master-driven, we can
 * correctly report a key is expired on slaves even if the master is lagging
 * expiring our key via DELs in the replication link. */
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) {
     
    robj *val;

    if (expireIfNeeded(db,key) == 1) {
     
        /* Key expired. If we are in the context of a master, expireIfNeeded()
         * returns 0 only when the key does not exist at all, so it's safe
         * to return NULL ASAP. */
        if (server.masterhost == NULL) return NULL;

        /* However if we are in the context of a slave, expireIfNeeded() will
         * not really try to expire the key, it only returns information
         * about the "logical" status of the key: key expiring is up to the
         * master in order to have a consistent view of master's data set.
         *
         * However, if the command caller is not the master, and as additional
         * safety measure, the command invoked is a read-only command, we can
         * safely return NULL here, and provide a more consistent behavior
         * to clients accessign expired values in a read-only fashion, that
         * will say the key as non exisitng.
         *
         * Notably this covers GETs when slaves are used to scale reads. */
        if (server.current_client &&
            server.current_client != server.master &&           /*如果当前实例不是master*/
            server.current_client->cmd &&
            server.current_client->cmd->flags & CMD_READONLY)
        {
     
            return NULL;                    /*返回NULL,前端即nil*/
        }
    }



expireIfNeeded(db,key) == ·1 代表已经被过期了,从节点直接返回空。

你可能感兴趣的:(Redis)