网站优化与seo的区别,网站建设 域名,钻磊云主机,网站注册好域名怎么办Redis 持久化
redis 提供了两种持久化的方式#xff0c;分别是RDB#xff08;Redis DataBase#xff09;和AOF#xff08;Append Only File#xff09;。
RDB#xff0c;简而言之#xff0c;就是在不同的时间点#xff0c;将 redis 存储的数据生成快照并存储到磁盘等…Redis 持久化
redis 提供了两种持久化的方式分别是RDBRedis DataBase和AOFAppend Only File。
RDB简而言之就是在不同的时间点将 redis 存储的数据生成快照并存储到磁盘等介质上
AOF则是换了一个角度来实现持久化那就是将 redis 执行过的所有写指令记录下来在下次 redis 重新启动时只要把这些写指令从前到后再重复执行一遍就可以实现数据恢复了。
其实 RDB 和 AOF 两种方式也可以同时使用在这种情况下如果 redis 重启的话则会优先采用 AOF 方式来进行数据恢复这是因为 AOF 方式的数据恢复完整度更高。
如果你没有数据持久化的需求也完全可以关闭 RDB 和 AOF 方式这样的话redis 将变成一个纯内存数据库就像 memcache 一样。
redis持久化RDB
RDB 方式是将 redis 某一时刻的数据持久化到磁盘中是一种快照式的持久化方法。
redis 在进行数据持久化的过程中会先将数据写入到一个临时文件中待持久化过程都结束了才会用这个临时文件替换上次持久化好的文件。正是这种特性让我们可以随时来进行备份因为快照文件总是完整可用的。
对于 RDB 方式redis 会单独创建fork一个子进程来进行持久化而主进程是不会进行任何 IO 操作的这样就确保了 redis 极高的性能。
如果需要进行大规模数据的恢复且对于数据恢复的完整性不是非常敏感那 RDB 方式要比 AOF 方式更加的高效。
虽然 RDB 有不少优点但它的缺点也是不容忽视的。如果你对数据的完整性非常敏感那么 RDB 方式就不太适合你因为即使你每 5 分钟都持久化一次当 redis 故障时仍然会有近 5 分钟的数据丢失。所以redis 还提供了另一种持久化方式那就是 AOF。
redis持久化 AOF
AOF英文是 Append Only File即只允许追加不允许改写的文件。
如前面介绍的AOF 方式是将执行过的写指令记录下来在数据恢复时按照从前到后的顺序再将指令都执行一遍就这么简单。
我们通过配置 redis.conf 中的 appendonly yes 就可以打开 AOF 功能。如果有写操作如 SET 等redis 就会被追加到 AOF 文件的末尾。
默认的 AOF 持久化策略是每秒钟 fsync 一次fsync 是指把缓存中的写指令记录到磁盘中因为在这种情况下redis 仍然可以保持很好的处理性能即使 redis 故障也只会丢失最近 1 秒钟的数据。
如果在追加日志时恰好遇到磁盘空间满、inode 满或断电等情况导致日志写入不完整也没有关系redis 提供了 redis-check-aof 工具可以用来进行日志修复。
因为采用了追加方式如果不做任何处理的话AOF 文件会变得越来越大为此redis 提供了 AOF 文件重写rewrite机制即当 AOF 文件的大小超过所设定的阈值时redis 就会启动 AOF 文件的内容压缩只保留可以恢复数据的最小指令集。举个例子或许更形象假如我们调用了 100 次 INCR 指令在 AOF 文件中就要存储 100 条指令但这明显是很低效的完全可以把这 100 条指令合并成一条 SET 指令这就是重写机制的原理。
在进行 AOF 重写时仍然是采用先写临时文件全部完成后再替换的流程所以断电、磁盘满等问题都不会影响 AOF 文件的可用性这点大家可以放心。
AOF 方式的另一个好处我们通过一个“场景再现”来说明。某同学在操作 redis 时不小心执行了 FLUSHALL导致 redis 内存中的数据全部被清空了这是很悲剧的事情。不过这也不是世界末日只要 redis 配置了 AOF 持久化方式且 AOF 文件还没有被重写rewrite我们就可以用最快的速度暂停 redis 并编辑 AOF 文件将最后一行的 FLUSHALL 命令删除然后重启 redis就可以恢复 redis 的所有数据到 FLUSHALL 之前的状态了。是不是很神奇这就是 AOF 持久化方式的好处之一。但是如果 AOF 文件已经被重写了那就无法通过这种方法来恢复数据了。
虽然优点多多但 AOF 方式也同样存在缺陷比如在同样数据规模的情况下AOF 文件要比 RDB 文件的体积大。而且AOF 方式的恢复速度也要慢于 RDB 方式。
如果你直接执行 BGREWRITEAOF 命令那么 redis 会生成一个全新的 AOF 文件其中便包括了可以恢复现有数据的最少的命令集。
如果运气比较差AOF 文件出现了被写坏的情况也不必过分担忧redis 并不会贸然加载这个有问题的 AOF 文件而是报错退出。这时可以通过以下步骤来修复出错的文件
1.备份被写坏的 AOF 文件\ 2.运行 redis-check-aof –fix 进行修复\ 3.用 diff -u 来看下两个文件的差异确认问题点\ 4.重启 redis加载修复后的 AOF 文件
redis持久化 – AOF重写
AOF 重写的内部运行原理我们有必要了解一下。
在重写即将开始之际redis 会创建fork一个“重写子进程”这个子进程会首先读取现有的 AOF 文件并将其包含的指令进行分析压缩并写入到一个临时文件中。
与此同时主工作进程会将新接收到的写指令一边累积到内存缓冲区中一边继续写入到原有的 AOF 文件中这样做是保证原有的 AOF 文件的可用性避免在重写过程中出现意外。
当“重写子进程”完成重写工作后它会给父进程发一个信号父进程收到信号后就会将内存中缓存的写指令追加到新 AOF 文件中。
当追加结束后redis 就会用新 AOF 文件来代替旧 AOF 文件之后再有新的写指令就都会追加到新的 AOF 文件中了。
RDB 和 AOF ,我应该用哪一个
一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性 你应该同时使用两种持久化功能。
如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失 那么你可以只使用 RDB 持久化。
有很多用户单独使用AOF但是我们并不鼓励这样因为时常进行RDB快照非常方便于数据库备份启动速度也较之快还避免了AOF引擎的bug。
注意基于这些原因将来我们可能会统一AOF和RDB为一种单一的持久化模型(长远计划)。
下面的部分将介绍两种持久化模型等多的细节。
RDB 快照
默认情况下Redis保存数据集快照到磁盘名为dump.rdb的二进制文件。你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集或者你也可以手动调用SAVE或者BGSAVE命令。
例如这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘 save 60 1000 这种策略被称为快照。
快照的运作方式:
当 Redis 需要保存 dump.rdb 文件时 服务器执行以下操作
Redis 调用 fork() 同时拥有父进程和子进程。子进程将数据集写入到一个临时 RDB 文件中。当子进程完成对新 RDB 文件的写入时Redis 用新 RDB 文件替换原来的 RDB 文件并删除旧的 RDB 文件。
这种工作方式使得 Redis 可以从写时复制copy-on-write机制中获益。
只追加文件 AOF
快照功能并不是非常耐久durable 如果 Redis 因为某些原因而造成故障停机 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。尽管对于某些程序来说 数据的耐久性并不是最重要的考虑因素 但是对于那些追求完全耐久能力full durability的程序来说 快照功能就不太适用了。
从 1.1 版本开始 Redis 增加了一种完全耐久的持久化方式 AOF 持久化。
你可以通过修改配置文件来打开 AOF 功能
appendonly yes
从现在开始 每当 Redis 执行一个改变数据集的命令时比如 SET 这个命令就会被追加到 AOF 文件的末尾。 当 Redis 重新启时 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。
日志重写
你可以猜得到写操作不断执行的时候AOF文件会越来越大。例如如果你增加一个计数器100次你的数据集里只会有一个键存储这最终值但是却有100条记录在AOF中。其中99条记录在重建当前状态时是不需要的。
于是Redis支持一个有趣的特性在后台重建AOF而不影响服务客户端。每当你发送BGREWRITEAOF时Redis将会写入一个新的AOF文件包含重建当前内存中数据集所需的最短命令序列。如果你使用的是Redis 2.2的AOF你需要不时的运行BGREWRITEAOF命令。Redis 2.4可以自动触发日志重写(查看Redis 2.4中的示例配置文件以获得更多信息)。
AOF持久性如何
你可以配置 Redis 多久才将数据 fsync 到磁盘一次。有三个选项
每次有新命令追加到 AOF 文件时就执行一次 fsync 非常慢也非常安全。每秒 fsync 一次足够快和使用 RDB 持久化差不多并且在故障时只会丢失 1 秒钟的数据。从不 fsync 将数据交给操作系统来处理。更快也更不安全的选择。
推荐并且也是默认的措施为每秒 fsync 一次 这种 fsync 策略可以兼顾速度和安全性。 总是 fsync 的策略在实际使用中非常慢 即使在 Redis 2.0 对相关的程序进行了改进之后仍是如此 ------ 频繁调用 fsync 注定了这种策略不可能快得起来。
如果 AOF 文件出错了怎么办
服务器可能在程序正在对 AOF 文件进行写入时崩溃这个不应该破坏数据的一致性 Redis不会装载已破坏的AOF文件。当发生这种情况时 可以用以下方法来修复出错的 AOF 文件
为现有的 AOF 文件创建一个备份。使用 Redis 附带的 redis-check-aof 程序对原来的 AOF 文件进行修复。\$ redis-check-aof --fix可选使用 diff -u 对比修复后的 AOF 文件和原始 AOF 文件的备份查看两个文件之间的不同之处。重启 Redis 服务器等待服务器载入修复后的 AOF 文件并进行数据恢复。
如何工作
日志重写采用了和快照一样的写时复制机制。下面是过程
Redis调用fork()。于是我们有了父子两个进程。子进程开始向一个临时文件中写AOF。父进程在一个内存缓冲区中积累新的变更(同时将新的变更写入旧的AOF文件所以即使重写失败我们也安全)。当子进程完成重写文件父进程收到一个信号追加内存缓冲区到子进程创建的文件末尾。搞定现在Redis原子性地重命名旧文件为新的然后开始追加新数据到新文件。
如何由RDB持久化转换到AOF持久化
Redis 2.0 和 Redis 2.2 处理流程不一样可以很简单猜测到 Redis 2.2 处理流程更简单并且不需要重启。
Redis 2.2 时
创建最近的RDB文件的备份。将备份保存在安全的位置。发起如下命令。\$redis-cli config set appendonly yes。\$redis-cli config set save 。确认数据库包含相同的keys。确认write操作被正确追加到了AOF文件。
第一个CONFIG命令开启AOF。Redis会阻塞以生成初始转储文件然后打开文件准备写开始追加写操作。
第二个CONFIG命令用于关闭快照持久化。这一步是可选的如果你想同时开启这两种持久化方法。
重要记得编辑你的redis.conf文件来开启AOF否则当你重启服务器时你的配置修改将会丢失服务器又会使用旧的配置。
Redis2.0时
创建最近的RDB文件的备份将备份存放在安全的位置停止数据库上的所有写操作发起 redis-cli bgrewriteaof命令创建AOF文件当AOF文件生成后停止Redis Server编辑redis.conf开启AOF持久化重启Redis Server确认数据库包含相同的keys确认write操作被正确追加到了AOF文件。
AOF与RDB之间的相互作用
Redis2.4以上的版本会确保在RDB快照创建时不触发AOF重写或者在AOF重写时不允许BGSAVE操作以避免Redis后台进程同时做繁重的磁盘I/O操作。
当创建RDB快照时对于用户使用BGREWRITEAOF明确发起的日志重写操作server会立刻回应一个ok状态码告知用户操作将回被执行当且仅当快照创建完成后重写操作开始被执行。
在同时使用了AOF和RDB方式的情况下Redis重启后会优先使用AOF文件来重构原始数据集。
**
备份Redis 数据**
开始这一部分之前请务必牢记一定要备份你的数据库。磁盘损坏云中实例丢失等等没有备份意味着丢失数据的巨大风险。
Redis对数据备份非常友好因为你可以在数据库运行时拷贝RDB文件RDB文件一旦生成就不会被修改文件生成到一个临时文件中当新的快照完成后将原子性地使用rename(2)修改文件名为目标文件。
这意味着在服务器运行时拷贝RDB文件是完全安全的。以下是我们的建议
创建一个定时任务(cron job)每隔一个小时创建一个RDB快照到一个目录每天的快照放在不同目录。每次定时脚本运行时务必使用find命令来删除旧的快照例如你可以保存最近48小时内的每小时快照一到两个月的内的每天快照。注意命名快照时加上日期时间信息。至少每天一次将你的RDB快照传输到你的数据中心之外或者至少传输到运行你的Redis实例的物理机之外。
灾难恢复
在Redis中灾难恢复和数据备份基本上是同样的过程并且灾难恢复会将这些备份传输到外部的多个数据中心。这样即使一些灾难性的事件影响到运行Redis和生成快照的主数据中心数据也是安全的。
由于许多Redis用户都处于启动阶段没有太多预算我们会介绍一些最有意思的灾难恢复技术而不用太多的花销。
Amazon S3和一些类似的服务是帮助你灾难恢复系统的一个好办法。很简单只需要将你的每日或每小时的RDB快照以加密的方式传输到S3。你可以使用 gpg -c 来加密你的数据(以对称加密模式)。确保将你的密码保存在不同的安全地方(例如给一份到你的组织中的最重要的人)。推荐使用多个存储服务以提升数据安全。使用SCP(SSH的组成部分)来传输你的快照到远程服务器。这是一种相当简单和安全的方式在远离你的位置获得一个小的VPS安装ssh生成一个无口令的ssh客户端key并将其添加到你的VPS上的authorized_keys文件中译者注这是SSH互信在Linux系统中可以使用ssh-keygen命令生成公私钥。你就可以自动的传输备份文件了无需输入密码。为了达到更好的效果最好是至少从不同的提供商那搞两个VPS。
要知道这种系统如果没有正确的处理会很容易失败。至少一定要确保传输完成后验证文件的大小(要匹配你拷贝的文件)如果你使用VPS的话可以使用 SHA1 数字签名。
你还需要一个独立的告警系统在某些原因导致传输备份过程失败时告警。
来自Redis 持久化