redis是一个支持持久化的内存型数据库,
由于是在内存中,即使有主从,数据冗余备份,也难保数据丢失,
redis持久化就是解决这个问题。
redis持久化,是通过把内存里的数据同步到磁盘上来保证持久化。
redis有两种持久化方式
一种是快照,snapshotting,也是默认方式,还有一种是只追加文件,缩写aof(apppend-only-file)。
快照(snapshotting):将某一时刻的所有数据都写入硬盘。
只追加文件(AOF):在执行写命令时,将被执行的写命令复制到硬盘里。
snapshotting(RDB)机制
创建快照有两个命令BGSAVE,SAVE。
BGSAVE过程:
1redis通过fork产生子进程
2父进程继续处理client请求,子进程负责将快照写入硬盘
3子进程写完后,用临时文件代替原来快照文件,然后子进程退出
SAVE过程:
1redis服务器停止接受来自client请求
2在快照创建完成之前将不再响应其他命令。
SAVE和BGSAVE优缺点:
save缺点:快照操作完成之前不再响应其他命令。
save优点:在大数据量的情况下,比bgsave更快速稳定。
运用场景:SAVE一般用在机器没有足够内存执行BGSAVE
或是接收到SHUTDOWN关机命令请求时用。
比如写个脚本,在凌晨3点访问量很小的时候,执行save快照操作。
bgsave缺点:在大数据量的情况下,BGSAVE的子进程由于要把内存里的数据写入到硬盘,
子进程会耗费越来越多时间。
如果达到十几GB数据量的话,BGSAVE可能会导致系统长时间的停顿
bgsave优点:快照操作时不影响redis服务器继续接受请求,做出响应。
运用场景:非十几GB的大数据量情况下都适合。
快照snapshotting配置选项
编辑redis.conf
save 60 1000
//多久执行一次bgsave自动快照操作,当满足 60秒之内有1000次写入即触发。
save 3600 1
//该条配置可以有多个,任意一个满足一次,执行一次。一小时之内只要有一条写操作就执行快照操作
stop-writes-on-bgsave-error no
//创建快照失败后是否继续写操作
rdbcompression yes
//是否对快照文件压缩
dbfilename dump.rdb
//快照写入文件的名称
dir ./
//快照文件的指定路径
snapshotting快照持久化运用场景
快照是将某一时间点在内存里的数据进行写入操作到硬盘。
也就是说在本次快照操作完成之后,
下一次时间点快照操作到来之前的这段时间内发生系统崩溃,
或是硬件问题,这段时间内产生的数据将会丢失。
所以快照适合对小数据丢失有一定容忍的应用和场景。
1购物车(查询简单|经常变更|数据量级不大|弱化事务|安全级别低)
2促销活动规则(存储) | 抢购 缓冲队列
3和钱无关,支付,银行
append-only-file(AOF)机制
AOF持久化会将被执行的写命令追加到原来的AOF文件末尾,
因此redis只要重新执行一遍AOF文件包含的所有写命令
即可恢复AOF文件所记录的数据集。
1redis产生fork子进程。
2父进程继续处理client请求,子进程把aof内容写入缓冲区。
3子进程写完退出,父进程接受退出消息,将缓冲区内容写入AOF文件。
AOF配置选项
编辑redis.conf
appendonly no
//是否启用aof方式
appendfsync everysec|always|no
//aof文件同步频率 everysec 每秒执行同步一次,显示的将多个命令同步到硬盘,也是redis推荐的一
//个。always每个redis写命令都要同步写入到硬盘,io操作频繁影响到redis速度。但是数据最安全的一
//个。no让操作系统来决定何时该同步。
no-appendfsync-on-rewite no
//再对aof进行压缩的时候是否执行同步操作
auto-aof-rewrite-percentage 50
//当aof文件大于80MB时并且AOF文件比
auto-aof-rewrite-min-size 80mb
//上次重写之后体积大了50%,redis将自动执行BGREWRITEAOF命令,
AOF缺陷--aof文件体积问题
表面上看,aof方式既可以把数据丢失降低到1秒(设置成appendfsync everysec),又可以极短时间完成持久化操作,无疑是最好的方式,但是aof有文件过大的问题。随着redis不断运行,执行的写操作越来越多,aof文件不断追加命令,aof文件将越来越大,极端情况可以用完整个硬盘。另一方面,如果系统崩溃了,在机器重启后需要执行aof文件来恢复丢失数据,aof文件过大,导致,执行时间会很长。
为了解决这个问题,就不得不说BGREWRITEAOF命令,
该命令可以移除原有aof文件里冗余的写操作重写aof文件。但是BGREWRITEAOF命令又出现了快照方式BGSAVE问题,执行BGREWRITEAOF,redis会创建子进程,子进程负责文件重写,由此带来的子进程的性能和时间问题同样存在。
无论使用aof方式还是快照方式来实现持久化都是各有利弊,选用时要因地制宜。
如果有不同见解欢迎大家一起来讨论,共同进步@[email protected]。
观点有参考Josiah L,carlson 所著redis in action。