redis 如何保证exipre操作幂等性

之前在微信群讨论一个问题:redis启动时load aof文件会不存在因exipre 操作把key删除了?答案是不会的
因为redis设计aof并用之恢复数据时,需要保证exipre等时间操作的幂等性(idempotent)。

1、为什么时间相操作不存在幂等性的可能?

redis中,把expire操作执行成功后写入aof中时,相对时间(多少s后过期)转化成unix timestamp时间戳。当使用aof文件恢复数据时,这个key可能过期了,也有可能没有过期。如果过期了(相对当前的时间戳),理论上replay aof会删除这个key, 后续的操作(比如incr)会得到不一致的数据。

2、redis 启动机制保证expire操作的幂等性

redis启动时如果使用aof恢复数据,expire操作做了一些过滤机制。即server处于loading状态,即使key达到了过期时间,也不做其它的任何操作。
首先通过src/server.c中的rediCommandTable中的flag为‘wF’,就可以看出expire不允许loading过程中执行。

{"expire",expireCommand,3,"wF",0,NULL,1,1,1,0,0},

src/db.c中执行expire时,会判断server是否处于loading状态。

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;
    ....
}

3、主从数据的过期时间
redis只在主库上执行expire操作,通过del命令传播到从库完成过期数据的删除。

/* Propagate expires into slaves and the AOF file.
 * When a key expires in the master, a DEL operation for this key is sent
 * to all the slaves and the AOF file if enabled.
 *
 * This way the key expiry is centralized in one place, and since both
 * AOF and the master->slave link guarantee operation ordering, everything
 * will be consistent even if we allow write operations against expiring
 * keys. */
void propagateExpire(redisDb *db, robj *key) {
    robj *argv[2];

    argv[0] = shared.del;
    argv[1] = key;
    incrRefCount(argv[0]);
    incrRefCount(argv[1]);

    if (server.aof_state != AOF_OFF)
        feedAppendOnlyFile(server.delCommand,db->id,argv,2);
    replicationFeedSlaves(server.slaves,db->id,argv,2);

    decrRefCount(argv[0]);
    decrRefCount(argv[1]);
}
此条目发表在redis分类目录,贴了, 标签。将固定链接加入收藏夹。

redis 如何保证exipre操作幂等性》有 1 条评论

  1. Forever说:

    It’s good to get a fresh way of looknig at it.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>