当前位置: 首页 > 科技观察

你说你精通Redis,你见过持久化配置吗?

时间:2023-03-15 13:46:06 科技观察

我们之前已经介绍过Redis的五种数据类型的命令和配置文件的基本配置。今天,就让我们从理论和配置两个层面来揭开Redis持久化的神秘面纱。所谓持久化,可以简单理解为将内存中的数据保存到硬盘中存储的过程。持久化的数据在系统重启或宕机后仍然可以访问,保证数据安全。Redis有两种持久化方案,一种是快照模式(SNAPSHOTTING),简称RDB;另一种是只追加模式(APPENDONLYMODE),称为AOF。接下来,我们就来看看它们的使用方法和注意事项吧。RDBRDB是RedisDataBase的缩写,是Redis默认的持久化方案。它可以在指定的时间间隔将内存数据集快照(snapshot)写入磁盘,并在恢复时将快照文件(dump.rdb)读回内存。我们先看一下配置文件中的SNAPSHOTTING:配置文件save在给定的秒数内,如果对数据库执行的写操作次数达到设定值,就会同步数据到数据文件。支持多种条件,Redis默认配置文件提供三种条件:save9001//900s变化1次save30010//300s变化10次save6010000//60s变化10000次注意:如果不想使用RDB方案,可以打开save""的注释,把上面三个注释掉。stop-writes-on-bgsave-erroryes当bgsave发生错误时,Redis是否会停止执行写命令;如果是,当硬盘出现问题时,Redis会停止接受写操作,以便我们及时发现,避免数据noRedisbgsave如果你的Redis服务器设置了适当的监控和持久化,即其他方式发现和控制数据完整性,您可能希望禁用此功能,以便Redis仍然可以正常工作。注意:如果后台保存进程将再次开始工作,Redis将自动允许再次写入。rdbcompressionyes指定数据存储到本地数据库时是否压缩(Redis使用LZF压缩)数据,默认是yes。如果想节省CPU时间,可以关闭这个选项,但是会导致数据库文件变得巨大。rdbchecksumyes从RDBversion5开始,还可以使用CRC64算法对存储快照后的数据进行校验,CRC64校验和放在文件末尾。启用后,保存和加载RDB文件会增加10%左右的性能消耗。如果你想获得最大的性能提升,你可以关闭这个功能。Disablechecksumming会创建校验和为零的RDB文件,这会告诉加载代码跳过检查。dbfilenamedump.rdb指定本地数据库文件名,重启后会自动加载到内存中,手动执行save命令后立即生效。大坑请注意:flushall和shutdown命令会清空并提交到dump.rdbdir./指定本地数据库存放目录。理论工作方式Redisdump.rdbfork()子进程将数据集写入临时文件RDB;RDBRedisRDBRDBRDBRDB的工作方式使得Redis可以从写时复制机制中获益。如何触发RDB快照配置文件中的默认快照配置;命令save(阻塞,只保存快照,其他等待)或bgsave(异步)命令,快照也可以同时响应客户端命令;执行flushall命令清除数据库中的所有数据,意义不大;执行shutdown命令保证服务器正常关机不丢失任何数据意义不大。通过RDB文件恢复数据在实际开发中,一般会考虑到物理机硬盘的损坏,所以我们会选择备份dump.rdb文件。将备份的dump.rdb文件复制到redis安装目录的bin目录下,重启redis服务。优点RDB是一个非常紧凑的文件,非常适合数据集的备份;RDB是一个紧凑的单一文件,很容易转移到另一个远程数据中心或亚马逊的S3(可能加密),非常适合灾难恢复;Redis的主进程不进行I/O操作,保证了极高的性能;适用于大规模数据恢复,如果对数据完整性和一致性要求不高,RDB比AOF效率更高。缺点:当Redis意外宕机时,你可能会丢失几分钟的数据;RDBforkforkRedisCPUAOFforkAOF为了解决RDB方式宕机时数据丢失过多的问题,从1.1版本开始,Redis增加了持久化持久化方式:AOF。AOF是AppendOnlyFile的缩写,默认不启用。AOF以日志的形式记录每一次写操作。它只允许追加文件而不允许重写文件。当服务器重新启动时,这些命令将被重新执行以恢复原始数据。我们看一下配置文件中的APPENDONLYMODE:配置文件appendonlyno默认是关闭的,改为yes开启持久化。AOF和RDB可以同时启用而不会出现问题。appendfilename"appendonly.aof"是文件的默认名称,将在启动时创建。加载先于dump.rdb文件appendfsync同步策略:系统函数fsync()告诉操作系统将数据实际写入磁盘。Redis支持三种不同的模式appendfsyncalways//每次数据发生变化,都会立即记录到磁盘,性能较差,但数据完整性较好秒级丢失数据appendfsyncno//不同步,仅在操作系统需要时刷新数据它是文件末尾的方式,所以随着写命令的不断增加,AOF文件的体积会越来越大。为了避免这种情况,增加了一种重写机制:可以在不中断服务客户端的情况下重建AOF文件。重写触发器:通过执行bgrewriteaof命令,可以生成一个新的AOF文件,其中包含重建当前数据集所需的最少命令。Redis2.2需要手动执行该命令,而Redis2.4可以通过修改配置文件自动触发(配置见下文)。改写原理:Redis执行系统函数fork()创建子进程(与主进程完全一样);子进程开始将新的AOF文件内容写入临时文件;对于所有新执行的写入命令,父进程在将它们累积到内存缓存中的同时,将这些更改追加到现有AOF文件的末尾,这样即使在重写过程中发生关机,现有AOF文件也是安全的;当子进程完成重写工作时,向父进程发送一个信号,父进程收到信号后将内存缓存中的所有数据追加到新的AOF文件的末尾。Redis自动用新文件替换旧文件,之后所有命令都直接附加到新AOF文件的末尾。no-appendfsync-on-rewriteno当我们同时进行主进程的写操作和子进程的重写操作时,两者都会对磁盘进行操作,而重写往往会涉及到大量的磁盘操作,这会导致主进程在写aof文件时出现阻塞情况。为了解决这个问题,no-appendfsync-on-rewrite参数发挥了作用。如果这个参数设置为no,是最安全的方式,不会丢失数据,但是你要忍受阻塞的问题;yesappendfsyncnoredislinux因此,如果应用系统不能容忍延迟,可以容忍少量数据丢失,则设置为yes;如果应用系统不能容忍数据丢失,则设置为no。auto-aof-rewrite-percentage100重写百分比,默认为上次重写后aof文件大小的两倍。auto-aof-rewrite-min-size64mb重写触发器的最小值:64mb。根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。Redis会记录上次重写的AOF大小。默认配置是当AOF文件大小是上次rewrite后的两倍大小,且文件大于64M时触发。大型互联网公司一般都是3G开头的aof-load-truncatedyes。当AOF文件被截断时,即AOF文件的最后一条命令不完整。如果此时启动Redis,AOF的数据会重新加载到内存中,此时就会出现问题。.yes:加载截断的AOF,Redis服务器开始发出日志,通知用户该事件;否:服务器将因错误而中止,拒绝启动。当我们知道AOF文件报错时,我们可以使用以下方法来修复错误的AOF文件:为已有的AOF文件创建一个备份;使用Redis附带的redis-check-aof命令修复原始AOF文件;redis-check-aof–fixredis-check-aof–fixappendonly.aof修复命令,kill所有不兼容的语法(可选)使用diff-u比较修复后的AOF文件和原AOF文件的备份,并查看thetwo两个文件的区别;重启Redis服务器,等待服务器加载修复后的AOF文件,进行数据恢复。aof-use-rdb-preambleyes在重写AOF文件时,Redis可以在AOF文件中使用RDBpreamble来加速重写和恢复。启用该选项后,重写后的AOF文件由两个不同的部分组成:RDB文件,AOF尾加载Redis时,会识别AOF文件以Redis字符串开头,加载带前缀的RDB文件,然后继续加载AOF尾部。理论优势数据的完整性和一致性更高,AOF持久化采用不同的策略最多丢失1秒的数据;AOF文件是只追加的日志文件,不需要写seek;RedisAOFAOFAOF文件记录写操作以Redis协议的格式保存,便于文件的读取和分析;缺点是对于相同的数据集,AOF文件的体积通常大于RDB文件的体积;fsyncAOFRDB一般来说,每秒fsync的性能还是很高的,关闭fsync可以让AOF和RDB一样快,即使是在高负载下。但是,在处理巨大的写入负载时,RDB可以提供更有保障的最大延迟(latency)。比较总结如何选择使用哪种持久化方式?一般来说,如果要达到媲美PostgreSQL的数据安全性,应该同时使用这两种持久化功能。如果你对数据很在意,但还能忍受几分钟内数据丢失,那只能用RDB持久化了。因为AOF持久化的实时性更好,即进程意外退出时丢失的数据更少,所以AOF是目前主流的持久化方式。很多用户只使用AOF持久化,但我们不推荐这种方式:因为定期生成RDB快照(snapshots)非常方便数据库备份,而且RDB数据集的恢复速度比AOF恢复快。AOF与RDB交互在版本号大于等于2.4的Redis中,BGSAVE执行过程中不能执行BGREWRITEAOF。反之,在BGREWRITEAOF执行过程中不能执行BGSAVE。这可以防止两个Redis后台进程同时对磁盘进行大量I/O。如果正在执行BGSAVE,用户显式调用BGREWRITEAOF命令,服务器会回复一个OK状态给用户,并告知用户BGREWRITEAOF已被调度执行:一旦BGSAVE被执行,BGREWRITEAOF将正式启动。Redis启动时,如果同时开启RDB持久化和AOF持久化,程序会优先使用AOF文件恢复数据集,因为AOF文件保存的数据通常是最完整的。备份redis数据cronjobRDBRDB确保快照备份有对应的日期时间信息,每次执行周期任务脚本时使用find命令删除过期快照;至少每天一次,在你的数据中心之外备份RDB,或者至少在你运行Redis服务器的物理机器之外备份。在实际应用中,由于RDB文件只用于备份,所以建议只在slave上持久化RDB文件,每隔15分钟只需要备份一次。仅保留save9001规则。如果开启AOF,好处是在最坏的情况下,你只会丢失不超过2秒的数据。启动脚本比较简单,只需要加载自己的AOF文件即可。第一个成本是不断的IO,第二个是AOFrewrite最终将rewrite过程中产生的新数据写入到新文件中,这几乎是不可避免的。只要硬盘允许,尽量减少AOF重写的频率。AOFrewrite的basesize默认值是64M,太小了,可以设置到5G以上。当默认值超过原始大小的100%时,rewrite可以改成合适的值。如果不开启AOF,也可以只通过Master-SlaveReplication实现高可用。可以节省大量IO,减少rewrite带来的系统波动。代价是如果Master/Slave同时dump掉,十几分钟的数据会丢失。启动脚本还会比较两个Master/Slave中的RDB文件,并加载较新的一个。