zoukankan      html  css  js  c++  java
  • Redis持久化

    Redis持久化

    • RDB持久化(以时间间隔做数据集的快照)
    • AOF持久化(记录服务接收到的每个写操作,当服务启动的时候,会再次执行这些写操作,是为了构造原来的数据集。当AOF文件变得很大时,Redis会以后端进程重写log)
    • 你也可以禁止持久化,如果你希望你的数据仅仅服务运行的时候存在
    • 你也可以在同一个实例中结合AOF和RDB,在这种情况下,当Redis重启的时候,AOF文件主要用来构造原来的数据集,因为AOF保证数据的完整性

    RDB和AOF的对比

    RDB的优点:

    • RDB是一个数据集的快照。RDB非常适合备份。例如,你想每个小时备份RDB文件。在这种情况下,当灾难发生时,你可以恢复数据集的不同版本
    • RDB非常适合灾难恢复
    • RDB最大化Redis性能,当需要持久化的时候,是父进程启动一个子进程,剩下的事情由子进程来说。
    • RDB对比AOF来说,伴随着大数据来说,能更快启动

    RDB缺点:

    • 当Redis停止工作的时候,为了最小化数据的丢失,RDB并不是很好。通常你会设置每五分钟创建快照,当Redis非正常关闭的时候,这样你最多丢失五分钟的数据。
    • RDB为了持久化,需要fork(),但是如果数据集比较大的话,Fork()是消耗时间的。会导致Redis大概几百毫秒不能接收客户端的请求

    AOF优点:

    • 使用AOF,Redis会更耐用,你可以选择不同的fsync策略:no fsync,  fsync every second, fsync at every  query。默认的策略是fsync every second,写性能也非常好,并且你最多丢失一秒的写数据。
    • 有可能AOF文件中包含写一半的命令,会导致Redis启动不起来,你可以使用redis-check-aof工具来解决这个问题
    • 当AOF文件变大的时候,Redis会自动重写AOF文件。并且重写也是非常安全的
    • AOF文件以一种容易理解好解析的格式的存储所有的操作。你可以导出AOF文件

    AOF缺点:

    • 相同数据集来说,AOF比RDB更大
    • 如果选择精确的fsync策略,AOF比RDB更慢。通常设置为fsync every second的策略有很高的性能。如果禁止fsync,在高负载下,和RDB一样的快
    • 有一些操作,可能会导致不能恢复成原始数据,但是这种情况非常罕见。

    我们应该选择哪一个?

    通常,如果你想要更深度的数据安全,你应该同时使用这两种方法

    如果你更多的关注数据,但是同时能够忍受几分钟数据的丢失,你可以仅仅使用RDB

    但是有许多用户仅仅使用AOF,但是我们并不鼓励这样,因为RDB快照能够很好的做数据库备份,能够快速重启,能够避免AOF引擎的一些bugs

    快照

    默认Redis保存数据集的快照到磁盘上,以名叫dump.rdb的文件名保存。它是一个二进制文件,例如,如果每60秒,至少有1000个keys改变,那么让Redis自动执行快照

    save 60 1000

    工作流程:

    当Redis需要做快照的时候,Redis forks,会有一个子进程和父进程。子进程开始写数据集到一个临时的RDB文件。当子进程完成后,新的文件会替换老的文件

    Append-only file

    快照并不是很耐用,如果你的计算机停止Redis运行或者你kill -9实例,最新写到Redis的数据会丢失。对一些应用来说,这并不是理想的选择。为了更好的耐用,你可以选择append-only file,在配置文件中

    appendonly yes

    当设置完成后,每一次修改数据集的操作将会添加到AOF中,当你重启Redis的时候,会重新应用AOF来构建数据集

    Log重写

    AOF会越来越大,例如,你修改一个key的值100次,你的数据集会存储最终的值,但是在AOF中会有100条记录,99条记录对于重构数据集是不需要的。

    Redis支持一个特性:Redis会以守护进程重新构建AOF,而且并不会影响客户端的服务。当你执行BGREWRITEAOF,Redis会写最简短的命令,来构建数据集。如果Redis版本是2.2,你需要时常运行BGREWRITEAOF命令。Redis 2.4会自动触发log重写

    append only file怎么耐用

    你可以配置Redis同步数据到磁盘的频率,有3个不同的选择

    • fsync(每次都添加新的命令到AOF中,是非常慢的,但是非常安全)
    • fsync evry second(非常快,如果有灾难发生,你仅仅丢失一秒的数据)
    • Never fsync(仅仅放你的数据到内存,是非常快的,但是不安全)

    推荐的策略是fsync every second,这也是默认的策略。因为它是相当快并且安全。always策略在实践中是非常慢的。

    如果我的AOF文件损害了,我应该做什么?

    当写AOF文件的时候,服务崩溃。这样使得Redis无法加载AOF文件。当这个发生的时候,你可以使用下面的流程来解决问题

    • 做一下你的AOF文件的备份
    • 使用redis-check-aof --fix来解决AOF文件的损害
    • 可选,使用diff -u来对比两个AOF文件的不同
    • 用修复后的AOF文件来启动服务

    Log重写的工作流程

    Log重写使用和快照一样的copy-on-write方式,下面是工作流程

    • Redis forks,我们会有子进程和父进程
    • 子进程会以临时文件的形式写新的AOF文件
    • 父进程积累新的改变到内存缓存中,但是同时一会添加新的改变到老的AOF文件中,如果我们重写失败了,那么我们是安全的。
    • 当子进程完成重写文件后,父进程得到通知,添加内存缓存中的内容到新的AOF文件中
    • Redis会命令命名老的AOF名字到新的文件名字,开始添加新的数据到新的文件

    如果现在在使用dump.rdb快照,怎么切换成AOF?

    Redis >= 2.2

    • 备份下最新的dump.rdb文件
    • 传输这个备份文件到安全的地方
    • 执行下面的命令
      redis-cli config set appendonly yes
      redis-cli config set save ""

    Redis2.0

    • 备份下最新的dump.rdb文件
    • 传输备份文件到安全的地方
    • 停止所有对数据库的写操作
    • 执行redis-cli bgewriteaof命令,会创建一个appendonly文件
    • 当Redis完成AOF dump,停止redis服务。
    • 编辑redis.conf文件,开启append only file持久化
    • 重启Redis服务

    AOF和RDB持久化的互动

    Redis>2.4会避免当RDB快照正在执行的过程中,来触发AOF重写。当AOF重写正在执行的过程中,来执行BGSAVE。这样做是为了避免两个守护进程带来高强度的磁盘IO

    当快照正在执行过程中,用户明确使用BGREWRITEAOF命令来请求log重写操作,服务会返回OK,但是只有当快照执行完成后,才开始执行log重写

    当AOF和RDB持久化都开启的时候,Redis重启的时候,AOF文件用来构造数据集,来保证数据的完整性。

    备份Redis数据

    如果数据不备份,会导致数据的丢失。Redis有非常友好的数据备份。当数据库在运行的时候,你可以复制RDB文件。RDB文件只要生成,并不会修改了。这样意味着复制RDB文件是安全的。下面是我的建议:

    • 创建定时任务,在一个目录做每小时的快照,在另一个目录中做每天的快照
    • 当cron脚本在运行的时候,使用find命令确保老的快照已被删除。
    • 至少保证每天传输RDB快照到数据中心之外护着其他的物理主机

    灾难恢复

    类似于数据备份,通过传输RDB快照到其他的机器上,然后通过一些验证方法来验证数据的正确性。当数据丢失了,可以使用这些备份文件恢复。

  • 相关阅读:
    Java并发编程的艺术(二)——volatile、原子性
    Java并发编程的艺术(一)——并发编程的注意问题
    算法——朋友圈(并查集)
    算法——汉诺塔问题
    算法——接雨水
    算法——n皇后问题
    深入理解Java虚拟机(八)——类加载机制
    深入理解Java虚拟机(七)——类文件结构
    转-项目管理5阶段|一位高级项目经理的4年项目经验分享
    什么是信息系统项目管理师(高级项目经理)
  • 原文地址:https://www.cnblogs.com/yandufeng/p/6526339.html
Copyright © 2011-2022 走看看