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

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

1、Redis事务介绍

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

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

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

如下图
Redis(三)了解持久化与事务_第1张图片

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

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

 

2、基本命令

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

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

命令 描述
multi

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

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

exec

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

discard

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

WATCH、UNWATCH

监控命令

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

语法:watch key [key…]

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

语法:unwatch

3、Redis事务的执行原理

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

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

Redis(三)了解持久化与事务_第2张图片

取消事务(discard)

Redis(三)了解持久化与事务_第3张图片

 

 

二、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.db

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

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

Redis(三)了解持久化与事务_第4张图片

​ 格式: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、重启加载顺序

Redis(三)了解持久化与事务_第5张图片

 

你可能感兴趣的:(分布式,微服务系列)