Redis学习总结(1)——数据持久化

  以前研究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 100
#当前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)部分!

时间: 2024-10-14 02:23:40

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

Unity游戏开发学习之路——数据持久化

数据持久化 谈到数据持久化,在Unity的游戏开发中十分重要的,不管是是在本地和服务器端,数据持久化都是我们学习的难点,数据持久化的技术有很多种,这里只选取几种,目前也是我所学到的,在接下来的时间里会陆续整理到这里. Part1:PlayerPrefs类 这是unity圣典中给出的, PlayerPrefs 游戏存档 Description 描述 在游戏会话中储存和访问游戏存档.这个是持久化数据储存,比如保存游戏记录. Editor/Standalone 编辑器 / 桌面平台 Mac OS 在M

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

一点技术.技术乐享!!! 如果有人问你:Redis这么快,他的“多线程模式”你了解吗? 请回答他:您是想问Redis这么快,为什么还是单线程模式吗? redis是什么 简单来说redis是C语言开发的一个开源的(遵从BSD协议)高性能键值对(key-value)的内存数据库,可以用作数据库.缓存.消息中间件等. 性能优秀,数据在内存中,读写速度非常快,支持并发10W QPS. 单进程单线程,是线程安全的,采用Io多路复用机制. 丰富的数据类型,支持字符串(string).散列(hash).列表(

Snail—OC学习之本地数据持久化(plist)

plist文件的格式 plist是一种数据持久化的文件 1.最外层通常为数组或者字典 2.plist里面的数据 只局限于数组.字典.逻辑值(BOOL).NSNumber.NSData.NSDate.字符串等数据类型 3.无法存储自定义类型的对象 plist作用 1.不适用它作为缓存 无法存储自定义类型的对象 2.通常存储长时间不容易发生变化的数据.国家.省市区.汽车品牌.项目的info.plist工程的设置信息 3.占用内存小 #import <Foundation/Foundation.h>

ios学习笔记-数据持久化

沙盒 沙盒是一种数据安全策略,只允许自己的应用访问目录.可以使用NSHomeDirectory()获取. ios沙盒下有三个子目录: 1.Documents目录:用于存储比较大的文件活着需要频发女更新的数据,需要持久化的数据.获取代码: NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 2.Library目录:

Redis学习笔记2--Redis数据存储优化机制

1.zipmap优化hash: 前面谈到将一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象.省内存的原因是新建一个hash对象时开始是用zipmap来存储的.这个zipmap其实并不是hash table,但是zipmap相比正常的hash实现可以节省不少hash本身需要的一些元数据存储开销.尽管zipmap的添加,删除,查找都是O(n),但是由于一般对象的field数量都不太多.所以使用zipmap也是很快的,也就是说添加删除平均还是O(1).如果field或者val

Redis学习(三) —— 持久化

参考文档 [1]: Redis官方文档 持久化(persistence) [2]: 一个经典面试题:如何保证缓存与数据库的双写一致性? 原文地址:https://www.cnblogs.com/fonxian/p/10931979.html

Snail—OC学习之本地数据持久化(归档)

#import <Foundation/Foundation.h> #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { NSString * filePath = @"/Users/student/Desktop/snail/array.data"; //对官方类创建的对象进行存储 NSArray * array = @[@"one"

redis学习——数据持久化

一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的.所以,我们需要将内存中的数据持久化!典型的需要持久化数据的场景如下: 将Redis作为数据库使用: 将Redis作为缓存服务器使用,但是缓存miss后会对性能造成很大影响,所有缓存同时失效时会造成服务雪崩,无法响应. 本文介绍Redis所支持的两种数据持久化方式. 二.Redis数据持久化 Redis支持两种数据持久化方式:RDB

redis学习大全

http://blog.csdn.net/menergy/article/details/17577985 http://blog.sina.com.cn/s/blog_64008ed70102uya3.html 池化使用jedis (1)新建redis.properties文件,内容如下 #最大分配的对象数 redis.pool.maxActive=1024 #最大能够保持idel状态的对象数 redis.pool.maxIdle=200 #当池内没有返回对象时,最大等待时间 redis.po