20170918 Booboowei
过期键值清理策略
过期键值清理策略为:
- 惰性删除:碰到过期键时才会删除,scan num(触发惰性删除)
- 定期删除:每隔一段时间主动查找并删除,通过hz参数设定,默认每秒执行10次
- 加载RDB:载入时都会进行过期键值的清理,节约内存空间
- 加载AOF:载入时都会进行过期键值的清理,节约内存空间
- 重写AOF:重写时都会进行过期键值的清理,节约内存空间
- 内存溢出:内存达到设定的max值,根据清除策略进行(不论数据是否过期)
惰性删除
定期删除
加载RDB
- Redis 使用惰性删除和定期删除两种策略来删除过期的键: 惰性删除策略只在碰到过期键时才进行删除操作, 定期删除策略则每隔一段时间, 主动查找并删除过期键。
- 执行 SAVE 命令或者 BGSAVE 命令所产生的新 RDB 文件不会包含已经过期的键。
- 执行 BGREWRITEAOF 命令所产生的重写 AOF 文件不会包含已经过期的键。
- 当一个过期键被删除之后, 服务器会追加一条 DEL 命令到现有 AOF 文件的末尾, 显式地删除过期键。
- 当主服务器删除一个过期键之后, 它会向所有从服务器发送一条 DEL 命令, 显式地删除过期键。
- 从服务器即使发现过期键, 也不会自作主张地删除它, 而是等待主节点发来 DEL 命令, 这种统一、中心化的过期键删除策略可以保证主从服务器数据的一致性
加载AOF
重写AOF
内存溢出
实验1——RDB写入和载入
key |
expire |
NOW |
RDB写入 |
RDB载入 |
|
|
12:00 |
12:23 |
13:30 |
key1 |
3600s |
yes |
yes |
no |
key2 |
7200s |
yes |
yes |
yes |
key3 |
60s |
yes |
no |
no |
# 12:00 向redis服务器中更新3个key [root@mastera0 redisshell]# redis-cli -a zyadmin 127.0.0.1:6379> set key1 booboo OK 127.0.0.1:6379> set key2 tom OK 127.0.0.1:6379> set key3 jack OK 127.0.0.1:6379> EXPIRE key1 3600 (integer) 1 127.0.0.1:6379> expire key2 7200 (integer) 1 127.0.0.1:6379> expire key3 60 (integer) 1 # key3当前已经过期 127.0.0.1:6379> ttl key3 (integer) -2 127.0.0.1:6379> ttl key1 (integer) 3507 127.0.0.1:6379> ttl key2 (integer) 7117 # 12:23通过save命令将数据写入RDB文件 127.0.0.1:6379> save OK 127.0.0.1:6379> exit
# 到redis数据目录下查看rdb文件 [root@mastera0 6379]# ll -h -rw-r--r--. 1 root root 122 Sep 18 12:22 dump.rdb
# 13:30启动数据库服务器,载入RDB文件 [root@mastera0 redisshell]# ./redisctl stop 6379
# 客户端登陆查看key的情况,只有key2被还原 [root@mastera0 redisshell]# redis-cli -p 6379 127.0.0.1:6379> auth zyadmin OK 127.0.0.1:6379> keys * 1) "key2"
|
实验2——AOF写入、重写、载入
[root@mastera0 redisshell]# cat /root/test.redis set key1 booboo set key2 jack set key3 tom expire key1 10 expire key2 120 expire key3 3600
# 14:34 写入key [root@mastera0 redisshell]# redis-cli -p 6379 -a zyadmin < /root/test.redis OK OK OK (integer) 1 (integer) 1 (integer) 1
# 14:36 kye1已过期,此时的aof文件为 [root@mastera0 6379]# sed -n '/^\*/!p' appendonly.aof | grep -v '^\$' SELECT 0 set key1 booboo set key2 jack set key3 tom PEXPIREAT key1 1505716445681 PEXPIREAT key2 1505716555681 PEXPIREAT key3 1505720035681 DEL key1
# 停止服务 [root@mastera0 redisshell]# redisctl stop 6379
# 14:38 key2 已过期时,启动服务 [root@mastera0 redisshell]# redisctl start 6379
# AOF文件中自动追加delete key2 [root@mastera0 6379]# sed -n '/^\*/!p' appendonly.aof | grep -v '^\$' SELECT 0 set key1 booboo set key2 jack set key3 tom PEXPIREAT key1 1505716445681 PEXPIREAT key2 1505716555681 PEXPIREAT key3 1505720035681 DEL key1 SELECT 0 DEL key2
# 客户端查看key的情况 [root@mastera0 redisshell]# redis-cli -p 6379 -a zyadmin 127.0.0.1:6379> get key2 (nil) 127.0.0.1:6379> get key3 "tom"
|
实验3——复制
设置hz为1,每秒只执行一次删除过期值的操作,进行本次测试
[root@mastera0 redisshell]# redisctl start 6379 [root@mastera0 redisshell]# redisctl start 6380 # master 导入10万个key,并设置过期值为60s # set a1 1 # set a100000 100000 [root@mastera0 redisshell]# redis-cli -p 6379 -a zyadmin < /root/afile &> /dev/null
# 动态观察master的aof文件 [root@mastera0 6379]# tail -f appendonly.aof
# 一旦看到开始追加delete操作,立刻在slave上执行查询 # slave [root@mastera0 redisshell]# redis-cli -p 6380 -a zyadmin 127.0.0.1:6380> get a100000 "100000" 127.0.0.1:6380> get a100000 (nil)
# 虽然a100000已经过期,但是slave还是会将值返回给客户端,就像没有过期一样 # 直到master上发送delete命令,slave才会将会delete
|
总结
过期键值清理策略为:
- 惰性删除:碰到过期键时才会删除,scan num(触发惰性删除)
- 定期删除:每隔一段时间主动查找并删除,通过hz参数设定,默认每秒执行10次
- 加载RDB:载入时都会进行过期键值的清理,节约内存空间
- 加载AOF:载入时都会进行过期键值的清理,节约内存空间
- 重写AOF:重写时都会进行过期键值的清理,节约内存空间
- 内存溢出:内存达到设定的max值,根据清除策略进行(不论数据是否过期)
# volatile-lru -> LRU算法,从已经设置过过期值的数据集中挑选最近最少使用的数据淘汰 # allkeys-lru -> LRU算法,从所有的数据集中挑选最近最少值用的数据淘汰 # volatile-random -> 随即算法,从已经设置过过期值的数据集中随即挑选数据淘汰 # allkeys-random -> 随即算法,从所有数据集中随即挑选数据淘汰 # volatile-ttl -> 最少时间,从已经设置过过期值的数据集中挑选将要过期的数据淘汰 # noeviction -> 不清理,直接报错OMM # The default is: # maxmemory-policy noeviction
|