以前研究Redis的时候,很多东西都不太明白,理解得也不太深,现在有时间重新拾起来看看,将一些心得记录下来,希望和大家一起探讨。

一、简介

  Redis是一个单线程高可用的Key-Value存储系统,和Memcached类似,但是实际使用上最大的区别有两方面:

  1. Redis支持多种数据结构类型的value,比如string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型);
  2. Memcached在出现系统瘫痪的情况下,无法实现系统恢复,而Redis支持两种数据持久化的方式(RDB和AOF),并且在此基础上实现了master-slave同步,从而体现了其自身高可用的特点;

二、Redis的持久化方式介绍(注:为了省事,相关配置直接贴的是网上的)

  1. RDB(默认):即snapshot(快照),从字面意思上理解,就像将其进行的一些命令操作以照片方式记录下来,那么,有人肯定会存在以下几个疑问:

  • Redis在持续写入的过程,通过来进行快照的?答:Redis借助了fork命令的copy on write机制(私有内存非共享内存)。在生成快照时,将当前进程fork出一个子进程(主进程继续接受客户端的请求操作),然后在子进程中循环所有的数据,将数据写成为RDB文件。(注:由于os的写时复制机制父子进程会共享相同的物理页面(内存区),当父进程处理写请求时os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程的地址空间内的数据是fork时刻整个数据库的一个快照。)
  • 如何配置策略写入RDB答:在redis.conf文件中,可以配置 save M N ,意思是在M秒内,进行N次操作,比如:save 300 10 即当300秒内有10条Keys数据被改变时,则进行快照,生成RDB;(注:如果不配置任何的save规则,即默认不开启快照功能)
################################ SNAPSHOTTING  #################################
# Save the DB on disk:
# 设置sedis进行数据库镜像的频率。
# 900秒(15分钟)内至少1个key值改变(则进行数据库保存--持久化)。
# 300秒(5分钟)内至少10个key值改变(则进行数据库保存--持久化)。
# 60秒(1分钟)内至少10000个key值改变(则进行数据库保存--持久化)。
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
# 在进行镜像备份时,是否进行压缩。yes:压缩,但是需要一些cpu的消耗。no:不压缩,需要更多的磁盘空间。
rdbcompression yes
# 一个CRC64的校验就被放在了文件末尾,当存储或者加载rbd文件的时候会有一个10%左右的性能下降,为了达到性能的最大化,你可以关掉这个配置项。
rdbchecksum yes
# 快照的文件名
dbfilename dump.rdb
# 存放快照的目录
dir /var/lib/redis
  • Redis快照持久化写入哪些数据?:答:每次快照持久化都是将内存数据完整写入到磁盘一次(达到save条件的时,保存该时间点的内存数据),并不是增量的只同步RDB文件中不存在的数据。在数据量大并且写操作较多的情况下,会引起大量的磁盘io操作,可能会严重影响性能。
  • Redis的RDB文件不会坏掉?答:因为其写操作是在一个新进程中进行的。当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,然后通过原子性rename系统调用将临时文件重命名为RDB文件。这样在任何时候出现故障,Redis的RDB文件都总是可用的。
  • Redis的RDB持久化方式有什么不足?答:如果主机down机的话,那么有可能造成数据丢失,比如上次快照到down机这段时间内的数据可能丢失,因为还没有到达那个触发快照的条件(配置的save机制),为了解决这个问题,请看第二种持久化方式。

  2. AOF:即Append Only File,该种持久化解决了上面提到的数据丢失问题,但是同样,可能有人会存在以下几个疑问:

  • AOF是如何来进行的呢?答:和快照一样,也是fork出一个子进程,将内存中的数据写入到AOF文件中;
  • 有哪几种模式?答:在redis.conf文件,如下面配置中,appendfsync的值即为写入AOF文件的模式;
############################## APPEND ONLY MODE ###############################
# 是否开启AOF,默认关闭(no)
appendonly yes
# 指定 AOF 文件名
appendfilename appendonly.aof
# Redis支持三种不同的刷写模式:
# appendfsync always #每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。
appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。
# appendfsync no #完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。 #在日志重写时,不进行命令追加操作,而只是将其放在缓冲区里,避免与命令的追加造成DISK IO上的冲突。
#设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes
no-appendfsync-on-rewrite yes
#当前AOF文件大小是上次日志重写得到AOF文件大小的二倍时,自动启动新的日志重写过程。
auto-aof-rewrite-percentage
#当前AOF文件启动新的日志重写过程的最小值,避免刚刚启动Reids时由于文件尺寸较小导致频繁的重写。
auto-aof-rewrite-min-size 64mb
  • AOF存在什么问题呢?答:1⃣由于写入AOF文件的频率远大于快照,那么势必会出现一种问题,就是在高并发操作下,内存很快就会爆满,那怎么办?AOF提供一种重写(Rewrite,使用bgrewriteaof命令)的机制。创建一个新的AOF文件来替代已有文件,新文件中不存在一些冗余的命令,比如连续的set a 1,set a 2,其实这个压缩后只会保留set a 2。2⃣数据一致性问题(见下一个);
  • 数据一致性问题?答:子进程在重写期间,如果有新的命令对现有的数据做出更改的操作,那么会出现所谓的内存中数据和AOF不一致问题。Redis提供了一个AOF重写缓冲区,该缓冲区是在fork出子进程的时候创建,当父进程进行一些操作时,在子进程重写新文件的过程中,父的所有的写操作日志还是会写到原来老的AOF文件中(为了防止写入AOF时发生故障系统也没有影响),同时还会将这些命令发送到缓冲区中。子进程写入AOF结束后,会像父进程发送一个信号,父进程会进行两个操作:1⃣将缓冲区的内容写入AOF文件末尾;2⃣rename方法对AOF文件改名,覆盖现有的AOF文件。
  • 纯粹的日志追加,如果包含了未写入完整的命令怎么办?答:可能某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途主机崩溃等等), 可以使用redis-check-aof 工具修复这种问;

三、总结

  今天主要介绍Redis的两种持久化机制,在现实系统中应用时该如何选择,那么不能一定说哪个好!比如,如果系统能够容忍数据部分丢失的情况下,则使用RDB,如果不能则使用AOF;但是AOF频繁写入文件,也会带来一定的性能损耗。有些时候也会混合使用,在这种情况下,Redis crash后,通过加载AOF文件来恢复数据。

  以后会再列出Redis的高可用(master-slave)部分!

Redis学习总结(1)——数据持久化的更多相关文章

  1. 老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化

    引言 今天周末,我在家坐着掐指一算,马上又要到一年一度的金九银十招聘季了,国内今年上半年受到 YQ 冲击,金三银四泡汤了,这就直接导致很多今年毕业的同学会和明年毕业的同学一起参加今年下半年的秋招,这个 ...

  2. Redis学习笔记六:持久化实验(AOF,RDB)

    作者:Grey 原文地址:Redis学习笔记六:持久化实验(AOF,RDB) Redis几种持久化方案介绍和对比 AOF方式:https://blog.csdn.net/ctwctw/article/ ...

  3. Android开发学习之路--数据持久化之初体验

    上班第一天,虽然工作上处于酱油模式,但是学习上依旧不能拉下,接着学习android开发吧,这里学习数据持久化的 知识. 其实数据持久化就是数据可以保存起来,一般我们保存数据都是以文件,或者数据库的形式 ...

  4. Redis(2)---数据持久化

    数据持久化 Redis有两种持久化的方式:快照(RDB文件)和追加式文件(AOF文件) (1)RDB持久化方式是在一个特定的间隔保存某个时间点的一个数据快照.(默认模式) (2)以日志的形式来记录每个 ...

  5. Redis基本数据类型、数据持久化、过期策略及淘汰机制

    一点技术.技术乐享!!! 如果有人问你:Redis这么快,他的“多线程模式”你了解吗? 请回答他:您是想问Redis这么快,为什么还是单线程模式吗? redis是什么 简单来说redis是C语言开发的 ...

  6. Redis基础—了解Redis是如何做数据持久化的

    之前的文章介绍了Redis的简单数据结构的相关使用和底层原理,这篇文章我们就来聊一下Redis应该如何保证高可用. 数据持久化 我们知道虽然单机的Redis虽然性能十分的出色, 单机能够扛住10w的Q ...

  7. .Net Redis实战——事务和数据持久化

    Redis事务 Redis事务可以让一个客户端在不被其他客户端打断的情况下执行多个命令,和关系数据库那种可以在执行的过程中进行回滚(rollback)的事务不同,在Redis里面,被MULTI命令和E ...

  8. Redis系列2:数据持久化提高可用性

    1 介绍 从上一篇的 <深刻理解高性能Redis的本质> 中可以知道, 我们经常在数据库层上加一层缓存(如Redis),来保证数据的访问效率. 这样性能确实也有了大幅度的提升,但是本身Re ...

  9. scrapy 学习笔记2 数据持久化

    前情提要:校花网爬取,并进行数据持久化 数据持久化操作 --编码流程: 1:数据解析 2:封装item 类 3: 将解析的数据存储到实例化好的item 对象中 4:提交item 5:管道接收item然 ...

随机推荐

  1. 笔记:程序内存管理 .bss .data .rodata .text stack heap

    1.未初始化的全局变量(.bss段) bss段用来存放 没有被初始化 和 已经被初始化为0 的全局变量.如下例代码: #include<stdio.h> int bss_array[102 ...

  2. [从产品角度学EXCEL 02]-EXCEL里的树形结构

    这是<从产品角度学EXCEL>系列第三篇. 前言请看: 0 为什么要关注EXCEL的本质 1 excel是怎样运作的 或者你可以去微信公众号@尾巴说数 获得连载目录. 本文仅由尾巴本人发布 ...

  3. AVPlayer

    AVPlayer     AVPlayerLayer是CALayer的一个子类,由于AVPlayer这个播放器只能安置在AVPlayerLayer 这个图层之上,所以我们需要实例化一个UIView,并 ...

  4. Azure上的那些IP

    相信第一次接触Azure的读者都会碰到这样一个问题,就是Azure的IP地址,笔者第一次接触Azure也是被搞懵逼了,一会儿VIP,不知道的还以为是会员的意思呢,一会儿又是DIP,后来又来了个PIP, ...

  5. HTML5 图片本地压缩上传插件「localResizeIMG」

    移动应用中用户往往需要上传照片,但是用户上传的照片尺寸通常很大,而手机的流量却很有限,所以在上传前对图像进行压缩是很有必要的. 原生应用可以直接对文件进行处理,网页应用就没有这个优势了.不过 canv ...

  6. TBitmapSurface.StretchFrom

    procedure TBitmapSurface.StretchFrom(const Source: TBitmapSurface; const NewWidth, NewHeight: Intege ...

  7. html5 历史管理onhashchange和state

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. powershell批量设置权限

    批量设置权限 $acl=get-acl .\demo Get-ChildItem .\Documents -Recurse -Force|Set-Acl -AclObject $acl

  9. jquery.validate不用submit而用js提交的例子

    $("#form").validate(); $("#btn).click(function(){ if($("#form").valid()){ $ ...

  10. ACM/ICPC 之 Dinic+枚举最小割点集(可做模板)(POJ1815)

    最小割的好题,可用作模板. //Dinic+枚举字典序最小的最小割点集 //Time:1032Ms Memory:1492K #include<iostream> #include< ...