文档章节

Redis的两种持久化方式及原理

Vegetable
 Vegetable
发布于 2017/08/18 00:22
字数 1521
阅读 119
收藏 1

精选30+云产品,助力企业轻松上云!>>>

Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)

1.RDB方法

(1)第一种方法filesnapshotting:默认redis是会以快照的形式将数据持久化到磁盘的(一个二进 制文件,dump.rdb,这个文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之内,redis至少发生M次修改则redis抓快照到磁盘。当然我们也可以手动执行save或者bgsave(异步)做快照。

(2)工作原理简单介绍一下:当redis需要做持久化时,redis会fork一个子进程;子进程将数据写到磁盘上一个临时RDB文件中;当子进程完成写临时文件后,将原来的RDB替换掉,这样的好处就是可以copy-on-write还有一种持久化方法是Append-only:filesnapshotting方法在redis异常死掉时, 最近的数据会丢失(丢失数据的多少视你save策略的配置),所以这是它最大的缺点,当业务量很大时,丢失的数据是很多的。

(3)详细过程

1.redis调用fork,现在有了子进程和父进程。

2. 父进程继续处理client请求,子进程负责将内存内容写入到临时文件。由于os的写时复制机制(copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程的地址空间内的数 据是fork时刻整个数据库的一个快照。

3.当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,然后子进程退出。

client 也可以使用save或者bgsave命令通知redis做一次快照持久化。save操作是在主线程中保存快照的,由于redis是用一个主线程来处理所有 client的请求,这种方式会阻塞所有client请求。所以不推荐使用。另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并不 是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。

另外由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof持久化方式。下面介绍

2.AOF持久化

Append-only file方法可以做到全部数据不丢失,但redis的性能就要差些。AOF就可以做到全程持久化,只需要在配置文件中开启(默认是no),appendonly yes开启AOF之后,redis每执行一个修改数据的命令,都会把它添加到aof文件中,当redis重启时,将会读取AOF文件进行“重放”以恢复到 redis关闭前的最后时刻。

当然由于os会在内核中缓存 write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。不过我们可以通过配置文件告诉redis我们想要 通过fsync函数强制os写入到磁盘的时机。有三种方式如下(默认是:每秒fsync一次)

appendonly yes              //启用aof持久化方式
# appendfsync always      //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec     //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no    //完全依赖os,性能最好,持久化没保证

aof 的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis将使用与快照类似的方式将内存中的数据 以命令的方式保存到临时文件中,最后替换原来的文件。具体过程如下

1. redis调用fork ,现在有父子两个进程
2. 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
3.父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
4.当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
5.现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。

需要注意到是重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。

 

参考文献

redis持久化方法对比分析

redis 的两种持久化方式及原理

Vegetable
粉丝 20
博文 49
码字总数 48342
作品 0
杭州
私信 提问
加载中
请先登录后再评论。
Redis02——Redis内存数据如何保存到磁盘

在前一篇文章中,已经介绍了Redis的基础数据结构,这篇文章将继续介绍Redis的持久化原理。 简介 众所周知Redis的所有数据都存在于内存之中,这就会存在因内存问题而导致的数据丢失,为了避免...

osc_43of92sp
03/11
2
0
Redis数据库操作、持久化详解及内存管理基础概览

Redis数据库操作、持久化详解及内存管理基础概览 前言 上篇主要介绍了redis的编译安装流程以及redis常用的两个命令工具,本文主要讲述redis的数据库相关操作:增删改查等等,以及简述理解red...

wx5d8a17c45cb5b
03/23
0
0
Redis原理说明

Redis有string、hash、list、set、sorted set共5种数据类型;而Redis内部则使用一个redis Object对象(包含类型type、编码方式encoding等属性)来表示所有的key和value;其中类型type 表示v...

tinder_boy
2018/10/31
14
0
redis持久化

[TOC] Redis为持久化提供了两种方式: RDB:在指定的时间间隔能对你的数据进行快照存储。 AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。 本文将通...

osc_yjcc5pir
01/02
1
0
两种Redis持久化原理的详解

Redis为持久化提供了两种方式: RDB:在指定的时间间隔能对你的数据进行快照存储。 AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。 本文将通过下面...

osc_9wny6wso
2019/09/16
5
0

没有更多内容

加载失败,请刷新页面

加载更多

要求jQuery在执行某些操作之前等待所有图像加载的官方方式

问题: In jQuery when you do this: 在jQuery中,当您执行以下操作时: $(function() { alert("DOM is loaded, but images not necessarily all loaded");}); It waits for the DOM t......

法国红酒甜
昨天
11
0
实现Map按值排序

Map按照值排序,需要自定义比较器,实现Comparator接口,实现compare方法。 public class SortByVlue {public static void main(String[] args) {Map<String, Long> map = new HashMap<......

游人未归
昨天
16
0
定天气爬虫加定时发送天气邮件

今天无聊,在家研究个爬虫玩玩 主要用到以下几个库: request 请求资源 iconv-lite转码,有的网站html格式不是utf-8 cheerio类似jq,操作html,获取相关爬虫数据 nodemailer 发送邮件,例如q...

莫西摩西
昨天
14
0
还在为大屏分辨率困扰?图扑提供响应式(自适应)可视化大屏

前言 数据可视化在当下信息时代已经成为炙手可热的话题,而 B/S 化趋势,也使得许多大屏应用上在网页端出现,今天给大家分享一套不一样风格的大屏页面,与传统深蓝色不同,这次采用了暗红色设...

xhload3d
昨天
30
0
如何妙用Spring 数据绑定机制

前言 在剖析完 Spring Boot 返回统一数据格式是怎样实现的?文章之后,一直觉得有必要说明一下 Spring's Data Binding Mechanism 「Spring 数据绑定机制」。 默认情况下,Spring 只知道如何转...

码农小胖哥
2019/12/27
25
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部