Redis系列三之持久化
一、Redis持久化
Redis是一个支持持久化的内存数据库,redis需要经常将内存中的数据同步到磁盘来保证持久化。
redis提供了不同级别的持久化方法:
- Snapshotting(快照,默认方式):能够在指定的时间间隔对你的操作进程快照存储
- Append-only file(缩写aof):记录每次对服务器写的操作,当服务器重启时会重新执行这些命令来恢复原始的数据
- 如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式
- 你也可以同时开启两种持久化方法,这种情况下,当redis重启的时候会优先载入aof原件来恢复原始数据,因为通常情况下,aof文件保存的数据集要比rdb文件保存的数据集要完整
二、快照方式(snapshotting)
默认情况下,Redis将数据库快照保存在一个dump.rdb的二进制文件中。
1、配置方式
可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置:
save 900 1 //900秒内如果超过1个key被修改,则发起快照保存
save 300 10 //300秒内容如超过10个key被修改,则发起快照保存
save 60 10000
2、工作原理
当Redis需要保存dump.rdb文件时,服务器执行以下操作:
Redis调用forks,同时拥有父进程和子进程
子进程将数据集写入到一个临时rdb文件中
当子进程完成对新rdb文件的写入时,redis用新rdb文件替换原来的rdb文件,并删除旧的rdb文件
client也可以使用save或者bgsave命令通知redis做一次快照持久化。save操作是在主线程中保存快照的,由于redis是一个主线程来处理所有client的请求,这种方式会阻塞所有client请求。
Redis启动后读取RDB快照文件,将数据从硬盘载入到内存。
通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据,这就需要开发者通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。
三、只追加操作的文件(Append-only file AOF)
快照功能并不是非常耐久,如果redis因为某些原因而造成故障停机那么服务器将丢失最近写入、且仍未保存到快照的那些数据。从1.1版本开始,redis增加了一种完全耐久的持久化方式:AOF持久化。
1、配置方式
aof比快照方式有更好的持久化性。在使用aof方式时,redis会将每一个收到的写命令都通过write函数追加到文件(默认是appendonly.aof)中。当redis重启时会通过重新执行文件中的保存的写命令来在内存中重建整个数据库的内容。
由于操作系统会在内核中缓存write做的修改,所以可能不是立即写到磁盘上,这样aof方式的持久化也还是有可能会丢失部分修改。我们可以通过配置文件告诉redis我们想要通过fsync函数强制操作系统写入到磁盘的时机,有三种方式如下(默认:每秒fsync一次):
appendonly yes #启用aof持久化方式
# appendfsync always #每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no #完全依赖os,性能最好,持久化没保证
选项分析:
1、appendfsync no
当设置appendfsync为no时,Redis不会主动调用fsync去将aof日志同步到磁盘,完全依赖于操作系统
2、appendfsync everysec
当设置为appendfsync为everysec的时候,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘。
3、appendfsync always
当设置appendfsync为always时,每一次写操作都会调用一次fsync,这时数据是最安全的,当然,由于每次都会执行fsync,所以其性能也会受到影响。
在配置文件redis.windows.conf中设置appendonly yes 后,打开redis服务器,立即会生成一个append-only.aof空文件。然后在客户端中,输入下面的命令
再查看append-only.aof文件,内容为:
2、日志重写
因为aof的运作方式是不断的将命令追加到文件的结尾,所以随着写入命令的不断增加,aof文件的体积也会变得越来越大。redis支持一种特性:可以在不打断客户端的情况下,对aof文件进行重建(rebuild),执行bgrewriteaof命令,redis将生成一个新的aof文件,这个文件将包含重建当前数据集所需的最少命令。
3、工作原理
AOF重写和rdb创建快照一样,都是巧妙的利用了写时复制机制:
- redis调用fork ,现在有父子两个进程
- 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
- 父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
- 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
- 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。
4、写数据流程
- 客户端向服务端发送写请求(数据在客户端的内存中)
- 数据库服务端接收到写请求的数据(数据在服务端的内存中)
- 服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)
- 操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓冲区中)
- 磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)
四、备份Redis数据库
我们可以在服务器运行的时候对rdb文件进行复制:rdb文件一旦被创建,就不会进行任何修改,当服务器要创建一个新的rdb文件时,它会先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使临时文件替换原来的rdb文件。
- 创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
- 确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
- 至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。
五、参考资料
1、http://www.redis.cn/topics/persistence.html
Redis系列三之持久化的更多相关文章
- Redis系列(三):Redis的持久化机制(RDB、AOF)
本篇博客是Redis系列的第3篇,主要讲解下Redis的2种持久化机制:RDB和AOF. 本系列的前2篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装. Redis系列(二): ...
- Redis系列(4)_持久化方式-RDB
一.概念 在指定的时间间隔内将内存中的数据集快照写入磁盘(满足指定时间间隔和操作次数两个条件),也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里 二.配置文件(redis.con ...
- redis系列:RDB持久化与AOF持久化
前言 什么是持久化? 持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中.XML数 ...
- Redis系列三(redis配置文件分析)
在第一篇文章中有提到过redis.conf这个文件,这个文件就是redis-server的具体配置了.要使用好redis,一定要搞清楚redis的配置文件,这样才能最大的发挥redis的性能. # B ...
- Redis系列(三)--消息队列、排行榜等
Redis命令执行生命周期: 发送命令--->排队(单线程)--->执行命令--->返回结果 慢查询: 只是针对命令执行阶段 慢查询日志通过一个固定长度的FIFO queue,这个q ...
- Redis系列三 - 缓存雪崩、击穿、穿透
前言 从学校出来,做开发工作也有一定时间了,最近有想系统地进一步深入学习,但发现基础知识不够扎实,故此来回顾基础知识,进一步巩固.加深印象. 最初开始接触编程时,总是自己跌跌撞撞.不断摸索地去学习,再 ...
- Redis系列(三)-Redis发布订阅及客户端编程
阅读目录 发布订阅模型 Redis中的发布订阅 客户端编程示例 0.3版本Hredis 发布订阅模型 在应用级其作用是为了减少依赖关系,通常也叫观察者模式.主要是把耦合点单独抽离出来作为第三方,隔离易 ...
- Redis系列三:reids常用命令
全局命令 keys * 查看所有键 dbsize 查看的是当前所在redis数据库的键总数 如果存在大量键,线上禁止使用此指令 exists key 检查键是否存在,存在返回1,不存在返回0 del ...
- Redis系列三 Redis数据类型
一 .Redis的五大数据类型 1.String(字符串) string是redis最基本的数据类型,可以理解成与 Memached一模一样的数据类型,一个key对应一个value. string 类 ...
随机推荐
- java.sql.SQLException: No suitable driver 问题解决
最近在学习java,用到c3p0数据库连接池,遇到一个很奇怪的现象,用main方法测试是可以正常连接数据库的,但是使用jsp调用代码,就会报如下图的错误! 最下面的java.sql.SQLExcept ...
- Java中main()的args的知识点浅谈
我们先来了解下Java中main()方法的默认定义格式: public static void main(String[] args){ }1.main方法是程序执行的入口,除了args这个形参变量可 ...
- Infinispan 8 中新的 Redis 缓存存储实现
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/147.html nfinispan 8 包含了一个新的在 Redis k/ ...
- MSP是什么?
本人在项目管理圈儿也算是摸爬滚打了几载,近几年真是各种压力大,看同行们各种参加培训.认证......我也不能懈怠啊,赶紧上网搜搜相关的培训和认证信息,不搜不知道一搜吓一跳.原本只知道PMP和PRINC ...
- 说说设计模式~建造者模式(Builder)
返回目录 建造者模式是我的"设计模式"里创建型模式里的最后一篇,这种模式在实现中,很多架构都用到了,如MVC,MVP,MVVM,它们都是有建造者模式的精髓的,即,创建与表现分享,我 ...
- Node.js与Sails~自定义响应体responses
回到目录 在Node.js里,你可以控制请求和响应,自己可以定义自己的响应方式,如对文本如何响应,对json如何响应,对图像流如何响应等等,而这些在Sails架构里,变得更加容易和清晰了,它位于项目的 ...
- iOS-数据持久化基础-沙盒机制
沙盒详解 1.IOS沙盒机制 IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文 ...
- iOS开发——网络使用技术OC篇&网络爬虫-使用正则表达式抓取网络数据
网络爬虫-使用正则表达式抓取网络数据 关于网络数据抓取不仅仅在iOS开发中有,其他开发中也有,也叫网络爬虫,大致分为两种方式实现 1:正则表达 2:利用其他语言的工具包:java/Python 先来看 ...
- CMD复制文件夹
CMD复制文件夹 xcopy /E/I/Y "D:\GitHub\WIP\app" "D:\GitHub\WIP_server\html\webshell"
- php基础教程-语法
PHP 脚本可放置于文档中的任何位置.PHP 脚本以 <?php 开头,以 ?> 结尾: <?php // 此处是 PHP 代码 ?> PHP 文件的默认文件扩展名是 &quo ...