美文网首页
redis 过期数据清理机制

redis 过期数据清理机制

作者: _oenday | 来源:发表于2020-04-08 14:49 被阅读0次

    Redis 使用一个 HashTable 存储数据的过期时间,把数据的 key 与过期时间相关联,这样就可以通过 key 来查询数据的过期时间了。

    但 Redis 并不会每时每刻去检查数据是否过期,因为这样做效率太低。Redis 清除过期数据分两个阶段进行,第一个阶段在定时器中进行(serverCron),第二个阶段在用户获取数据时进行。

    在 Redis 的定时器中,每隔 100 毫秒便会调用 src/redis.c 的 activeExpireCycle 函数清理过期数据。
    activeExpireCycle 函数随机获取一些数据的过期时间,如果当前时间大于数据设定的过期时间,就把此数据从内存中删除。Redis 每次随机获取 10 个数据的过期时间,如果这 10 个数据中有超过 25% 的数据到达过期时间(也就是大于等于 3 个),这个清理过程会一直进行下去。目地是可能删除更多的过期数据,节省内存的空间。

    用户使用 get、hget 等命令获取数据时,Redis 调用 expireIfNeeded 函数删除过期的数据(但仅限于当前获取的数据)。该函数判断当前获取的数据是否过期,如果已经过期,调用 dbDelete 函数把它从数据库中删除。dbDelete函数除了删除数据外,还会把数据的过期时间信息删除。

    因为在定时器中只是随机删除一些过期数据,不可能把所有的过期数据完全删除。所以在获取数据时还需要对数据进行过期判断。

    当内存达到 maxmemory 配置时候,也会触发 Key 的删除操作。
    ———————————————————————————————————

    总结

    如果 Redis 中每天过期大量 Key(比如几千万),那么必须得考虑过期 Key 的清理:
    增加 Redis 主动清理的频率(通过调大hz参数);
    手动清理过期 Key,最简单的方法是进行 scan 操作,scan 操作会触发第一种被动删除,scan 操作时候别忘了加 count;
    dbsize 命令返回的 Key 数量,包含了过期 Key;
    randomkey 命令返回的 Key,不包含过期 Key;
    scan 命令返回的 Key,包含过期 Key;
    info 命令返回的# Keyspace:
    db6:keys=1034937352,expires=994731489,avg_ttl=507838502
    keys 对应的 Key 数量等同于 dbsize;(因为 Redis的特性单线程, keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令,scan 指令可以无阻塞的提取出指定模式的key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。)
    expires 指的是设置了过期时间的 Key 数量;
    avg_ttl 指设置了过期时间的 Key 的平均过期时间(单位:毫秒);

    ———————————————————————————————————


    image.png

    最后再附上一些参考文章:
    http://lxw1234.com/archives/2017/07/874.htm

    相关文章

      网友评论

          本文标题:redis 过期数据清理机制

          本文链接:https://www.haomeiwen.com/subject/zjnzphtx.html