最新消息:

Redis专题二、过期时间、内存逐出和数据持久化

IT技术 ipcpu 5209浏览

Redis专题二、过期时间、内存逐出和数据持久化.md

KEY的过期时间

Redis可以设置键(KEY)的超时时间。命令是expire,查看超时时间的命令是ttl。如下

127.0.0.1:6379> set ipcpu:001 abcdefg
OK
127.0.0.1:6379> EXPIRE ipcpu:001 600
(integer) 1
127.0.0.1:6379> ttl ipcpu:001
(integer) 590
127.0.0.1:6379> ttl ipcpu:001
(integer) 582

Redis使用最大内存和驱逐算法

在redis中,允许用户设置最大使用内存大小maxmemory(需要配合maxmemory-policy使用),设置为0表示不限制(默认配置)。
生产环境中需要设置此值,最好不超过内存60%-70%。
当redis内存数据集快到达maxmemory时,redis会实行数据淘汰策略。Redis提供6种数据淘汰策略:

volatile-lru -> remove the key with an expire set using an LRU algorithm
#@按照LRU算法逐出原有数据,但仅逐出设置了过期时间的数据
allkeys-lru -> remove any key according to the LRU algorithm
#@按照LRU算法逐出原有数据
volatile-random -> remove a random key with an expire set
#@随机逐出原有数据,但仅逐出设置了过期时间的数据
allkeys-random -> remove a random key, any key
#@随机逐出原有数据
volatile-ttl -> remove the key with the nearest expire time (minor TTL)
#@仅逐出设置了过期时间的数据,并且是按照TTL有小到大的顺序进行逐出
noeviction -> don't expire at all, just return an error on write operations
#@不逐出任何数据,新数据的写入会得到一个错误信息

在redis2.8中默认策略是volatile-lru
在redis 3.2和redis4.0中默认策略是noeviction

当内存不足时,Redis会返回OOM的错误信息

(error) OOM command not allowed when used memory > 'maxmemory'.

Redis中的LRU不是严格意义上的LRU算法实现,是一种近似的LRU实现,主要是为了节约内存占用以及提升性能。Redis有这样一个配置——maxmemory-samples,Redis的LRU是取出配置的数目的key,然后从中选择一个最近最不经常使用的key进行置换,默认是5。可以通过调整样本数量来取得LRU置换算法的速度或是精确性方面的优势。

redis用作缓存服务器

经过上述分析,如果想将Redis作为缓存服务器使用,最好将内存驱逐算法改成allkeys-lru。
因为开发人员很可能根本就不给KEY加上expire时间,默认配置情况下,内存耗尽后会报错。

redis数据持久化

redis有两种方式支持持久化,分别是RDB和AOF。

RDB即redis database,它是redis默认采用支持持久化的方式。RDB通过快照实现持久化的支持,当满足一定条件时,RDB将对内存中的所有数据生成快照,并存放到硬盘中,默认存放在当前执行redis服务的根目录的dump.rdb中。

AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。 AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

RDB

RDB持久化是把当前进程数据生成快照保存到硬盘的过程, 触发RDB持久化过程分为手动触发和自动触发。
手动触发分别对应save和bgsave命令:

save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。
bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。

除了手动触发以外,还可以使用save命令自动触发

###SNAPSHOTTING###
save 900 1
save 300 10
save 60 10000
#@当900秒内有1个key被修改;
#@或者当300秒内有10个key被修改;
#@或者当60秒内有10000个key被修改,都会触发快照的生成。

在redis.conf文件中,还有如下配置项:

stop-writes-on-bgsave-error yes:当后台最后一次保存出错,停止redis的写操作。
rdbcompression yes:当进行持久化时,是否对数据使用LZF算法进行压缩。
rdbchecksum yes:在存储快照后,是否使用CRC64算法进行数据校验。
dbfilename dump.rdb:指定生成的快照文件名为dump.rdb。
dir /var/lib/redis:存储快照文件的路径。

禁用RBD

#@注释其他save选项
save ""

AOF

AOF即append only file,在AOF模式下,redis会将每一个收到的写命令(包括flushall命令)都通过write函数追加到文件appendonly.aof中。默认情况下redis并没有开启AOF,AOF的配置在redis.conf中注释为APPEND ONLY MODE的模块里,如果要开启AOF,需要将appendonly no改为appendonly yes。

工作流程

(1)所有写命令会被追加aof_buf(缓冲区)中
(2)AOF缓冲区根据对应的策略向硬盘做同步操作
(3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的
(4)当 redis服务器进行重启时,可以加在AOF文件进行数据恢复

Redis提供了多种AOF缓冲区同步文件策略,由参数appendfsync控制。
apendfsync参数的选项如下:

always:命令写入AOF缓冲区后调用系统fsync操作同步到AOF文件中,fsync完成后线程返回
everysec(默认配置):命令写入AOF缓冲区后调用系统write操作,write完成后线程返回。fsync同步文件操作由专门线程每秒调用一次。Everysec是建议的同步策略。理论上只有在系统突然宕机的情况下丢失1秒的数据。
no:命令写入AOF缓冲区后调用系统write操作,write完成后线程后线程返回,不对AOF文件作fsync同步,同步硬盘操作由操作系统负责,通常同步周期最长30秒。

随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入AOF重写机制压缩文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。

AOF重写过程可以手动触发和自动触发:

手动触发:直接调用bgrewriteaof命令。
自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。

提示:
Redis的持久化是可以禁用的,两种方式的持久化是可以同时存在的,但是当Redis重启时,AOF文件会被优先用于重建数据。

参考资料

http://www.h3399.cn/201701/34618.html

https://lanjingling.github.io/2015/11/16/redis-chijiuhua/

转载请注明:IPCPU-网络之路 » Redis专题二、过期时间、内存逐出和数据持久化