Redis(三)了解持久化与事务

一、Redis事务(似乎不常用)

1、Redis事务介绍

为了保证多条命令组合的原子性, Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题。事务表示一组动作, 要么全部执行, 要么全部不执行 。

  • Redis的事务是通过MULTIEXECDISCARDWATCH这四个命令来完成的。
  • Redis的单个命令都是原子性的,所以这里确保事务性的对象是命令集合。
  • Redis将命令集合序列化并确保处于同一事务的命令集合连续且不被打断的执行
  • Redis不支持回滚操作

Redis对事务的支持比较简单,或者说它的事务是有缺陷的。它只能保证一个Client发起的事务中的命令可以连续执行,中间不会插入其它client端的命令。缺陷在于,如果一个client将两条命令放到一个事务了,执行的时候第二条命令发送错误,但此时Redis的事务不会回滚第一条命令。

如下图

 从上面可以看出,redis事务是不支持回滚的

exec执行,返回了一个31,一个异常。说明 incr age 已经执行成功了

2、基本命令

注意:Redis中是没有回滚的,事务只是将多个命令先放入一个队列,之后再同时执行,或者清空队列中的命令

中间命令出错并不会回滚所有执行的命令数据

命令 描述
multi

Redis会将后续的命令逐个放入队列中,然后使用EXEC命令原子化地执行这个命令序列

用于标记事务块的开始,开启事务

exec

(执行)在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态

扫描二维码关注公众号,回复: 9415330 查看本文章
discard

(清除)清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态

WATCH、UNWATCH

监控命令

WATCH:当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的状态

语法:watch key [key…]

UNWATCH:清除所有先前为一个事务监控的键

语法:unwatch

3、Redis事务的执行原理

当client端发起multi命令时,这个连接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个缓冲队列中,当执行exec命令时,Redis会依次执行队列中所有命令

开启 / 执行事务(multi / exec)

取消事务(discard)

二、Redis持久化(RDB默认持久化)

Redis是一个内存数据库,为了保证数据的持久性,它提供了两种持久化方案:

  • RDB方式(默认)
  • AOF方式

持久化功能有效地避免因进程退出造成的数据丢失问题, 当下次重启时利用之前持久化的文件即可实现数据恢复

1、介绍及默认配置

  • RDB是Redis默认采用的持久化方式。
  • RDB方式是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。
  • Redis会在指定的情况下触发快照(分为手动触发自动触发
  1.  符合自定义配置的快照规则(自动,在redis.conf中配置的规则)
  2.  执行save或者bgsave命令(手动)
  3. 执行flushall命令(手动)
  4. 如果从节点执行全量复制操作, 主节点自动执行bgsave生成RDB并发送给从节点(自动)
  5. 默认情况下执行shutdown命令时, 如果没有开启AOF持久化功能则自动执行bgsave(自动)
  6. 执行debug reload命令重新加载Redis时, 也会自动触发save操作 (自动)

snapshotting(快照)默认方式:将内存中以快照的方式写入到二进制文件中,默认为 dump.rdb

可以通过配置设置自动做快照持久化的方式。可以配置 redis 在 n 秒内如果超过 m 个 key 则修改就自动做快照。

下图为Redis conf 文件的默认参数:

​ 格式:save

​ 示例:

  • save 900 1 : 表示15分钟(900秒钟)内至少1个键被更改则进行快照。
  • save 300 10 : 表示5分钟(300秒)内至少10个键被更改则进行快照。
  • save 60 10000 :表示1分钟内至少10000个键被更改则进行快照。

特别说明:

  • Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。
  • 根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。

2、快照的实现原理

快照过程

  1. redis使用fork函数复制一份当前进程的副本(子进程)
  2. 父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件。
  3. 当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此,一次快照操作完成。

注意事项

  1. redis在进行快照的过程中不会修改RDB文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时 候RDB文件都是完整的。
  2. 这就使得我们可以通过定时备份RDB文件来实现redis数据库的备份, RDB文件是经过压缩的二进制文件,占用的空间会小于内存中的数据,更加利于传输。
     

3、RDB优缺点

RDB的缺点:

  • RDB方式数据没办法做到实时持久化/秒级持久化。 因为bgsave每次运行都要执行fork操作创建子进程, 属于重量级操作, 频繁执行成本过高。
  • RDB文件使用特定二进制格式保存, Redis版本演进过程中有多个格式的RDB版本, 存在老版本Redis服务无法兼容新版RDB格式的问题。针对RDB不适合实时持久化的问题, Redis提供了AOF持久化方式来解决。

RDB的优点:

  • RDB是一个紧凑压缩的二进制文件, 代表Redis在某个时间点上的数据快照。 非常适用于备份, 全量复制等场景。 比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中(如hdfs) , 用于灾难恢复。
  • Redis加载RDB恢复数据远远快于AOF的方式。
     

三、Redis持久化(AOF)

1、介绍

  • 默认情况下Redis没有开启AOF(append only file)方式的持久化
  • 开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件,这一过程显然会降低Redis的性能,但大部分情况下这个影响是能够接受的,另外使用较快的硬盘可以提高AOF的性能。
  • 可以通过修改 redis.conf 配置文件中的 appendonly 参数开启
  • AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
  • 默认的文件名是 appendonly.aof,可以通过 appendfilename 参数修改

2、重写原理

(1)Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写

(2)重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合

(3)整个重写操作是绝对安全的,因为Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从AOF文件切换到新AOF 文件**,并开始对新 AOF 文件进行追加操作。

(4)重写后的AOF文件为什么可以变小 :

  • 进程内已经超时的数据不再写入文件。
  • 旧的AOF文件含有无效命令
  • 多条写命令可以合并为一个

(5)AOF重写过程可以手动触发和自动触发:

  • 手动触发: 直接调用 bgrewriteaof 命令。
  • 自动触发: 根据 auto-aof-rewrite-min-size auto-aof-rewrite-percentage 参数确定自动触发时机。

参数说明

auto-aof-rewrite-percentage 100 表示当前aof文件大小超过上一次aof文件大小的百分之多少的时候会进行重写。如果之前没有重写过,以启动时aof文件大小为准

auto-aof-rewrite-min-size 64mb 限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化
 

3、同步磁盘数据

Redis每次更改数据的时候, aof机制都会将命令记录到aof文件,但是实际上由于操作系统的缓存机制数据并没有实时写入到硬盘,而是进入硬盘缓存。再通过硬盘缓存机制去刷新到保存到文件

参数说明:

配置值 说明
always 每次执行写入都会进行同步 , 这个是最安全但是是效率比较低的方式
everysec 每一秒执行
no 不主动进行同步操作,由操作系统去执行,这个是最快但是最不安全的方式

4、重启加载顺序

四、RDB和AOF的区别

1、区别

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

2、优缺点

RDB存在哪些优势呢?

  1.  一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
  2.  对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
  3.  性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
  4. 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。

RDB又存在哪些劣势呢?

  1.  如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
  2. 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

AOF的优势有哪些呢?

  1. 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。
  2. 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
  3. 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
  4.  AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。

AOF的劣势有哪些呢?

  1. 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
  2. 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。

二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 eventually consistent的意思了。不过生产环境其实更多都是二者结合使用的。

3、常用配置

RDB持久化配置

Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开6379.conf文件之后,我们搜索save,可以看到下面的配置信息:

save 900 1              #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。

save 300 10            #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。

save 60 10000        #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。

AOF持久化配置

在Redis的配置文件中存在三种同步方式,它们分别是:

appendfsync always     #每次有数据修改发生时都会写入AOF文件。

appendfsync everysec  #每秒钟同步一次,该策略为AOF的缺省策略。

appendfsync no          #从不同步。高效但是数据不会被持久化。

发布了69 篇原创文章 · 获赞 43 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/fox_bert/article/details/100825148