Redis系列-第四篇持久化与事务
一、持久化
Redis是一个内存数据库,为了保证数据的持久性,它提供了两种持久化方案:
RDB方式(默认)
AOF方式
持久化功能有效地避免因进程退出造成的数据丢失问题, 当下次重启时利用之前持久化的文件即可实现数
据恢复 。
1.RDB
1.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操作 (自动)
save命令 :阻塞当前Redis服务器, 直到RDB过程完成为止, 对于内存比较大的实例会造成长时间阻塞, 线上环境不建议使用 .
bgsave命令: Redis进程执行fork操作创建子进程, RDB持久化过程由子进程负责, 完成后自动>结束。 阻塞只发生在fork阶段, 一般时间很短。
在redis.conf中设置自定义快照规则
1. RDB持久化条件
格式:save
示例:
save 900 1 : 表示15分钟(900秒钟)内至少1个键被更改则进行快照。
save 300 10 : 表示5分钟(300秒)内至少10个键被更改则进行快照。
save 60 10000 :表示1分钟内至少10000个键被更改则进行快照。
可以配置多个条件(每行配置一个条件),每个条件之间是“或”的关系。
2. 配置dir指定rdb快照文件的位置
dir ./
3. 配置dbfilename指定rdb快照文件的名称
dump.rdb
特别说明:
Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。
根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。
1.2快照的实现原理
- 快照过程
- redis使用fork函数复制一份当前进程的副本(子进程)
- 父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件。
- 当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此,一次快照操作完成。
- 注意事项
1.redis在进行快照的过程中不会修改RDB文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时 候RDB文件都是完整的。
2.这就使得我们可以通过定时备份RDB文件来实现redis数据库的备份, RDB文件是经过压缩的二进制文件,占用的空间会小于内存中的数据,更加利于传输。
1.3RDB优缺点
RDB的缺点:
- RDB方式数据没办法做到实时持久化/秒级持久化。 因为bgsave每次运行都要执行fork操作创建子进程, 属于重量级操作, 频繁执行成本过高。
- RDB文件使用特定二进制格式保存, Redis版本演进过程中有多个格式的RDB版本, 存在老版本Redis服务无法兼容新版RDB格式的问题。针对RDB不适合实时持久化的问题, Redis提供了AOF持久化方式来解决。
RDB的优点:
- RDB是一个紧凑压缩的二进制文件, 代表Redis在某个时间点上的数据快照。 非常适用于备份, 全量复制等场景。 比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中(如hdfs) , 用于灾难恢复。
- Redis加载RDB恢复数据远远快于AOF的方式。
2.AOF
2.1介绍
默认情况下Redis没有开启AOF(append only file)方式的持久化
开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件,这一过程显然会降低Redis的性能,但大部分情况下这个影响是能够接受的,另外使用较快的硬盘可以提高AOF的性能。
可以通过修改redis.conf配置文件中的appendonly参数开启
appendonly yes
- AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir ./
- 默认的文件名是appendonly.aof,可以通过appendfilename参数修改:
appendfilename appendonly.aof
2.2重写原理
Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写
重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。
整个重写操作是绝对安全的,因为Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从AOF文件切换到新AOF 文件**,并开始对新 AOF 文件进行追加操作。
重写后的AOF文件为什么可以变小 :
进程内已经超时的数据不再写入文件。
旧的AOF文件含有无效命令
多条写命令可以合并为一个
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的时候,不需要进行优化
2.3同步磁盘数据
Redis每次更改数据的时候, aof机制都会将命令记录到aof文件,但是实际上由于操作系统的缓存机制,数据并没有实时写入到硬盘,而是进入硬盘缓存。再通过硬盘缓存机制去刷新到保存到文件。
参数说明:
配置值 | 说明 |
---|---|
always | 每次执行写入都会进行同步 , 这个是最安全但是是效率比较低的方式 |
everysec | 每一秒执行 |
no | 不主动进行同步操作,由操作系统去执行,这个是最快但是最不安全的方式 |
2.4重启加载
2.5 AOF文件损坏以后如何修复
服务器可能在程序正在对 AOF 文件进行写入时停机, 如果停机造成了 AOF 文件出错(corrupt), 那么 Redis 在重启时会拒绝载入这个 AOF 文件, 从而确保数据的一致性不会被破坏。
当发生这种情况时, 可以用以下方法来修复出错的 AOF 文件:
为现有的 AOF 文件创建一个备份。
使用 Redis 附带的 redis-check-aof 程序,对原来的 AOF 文件进行修复。redis-check-aof --fix readonly.aof
重启 Redis 服务器,等待服务器载入修复后的 AOF 文件,并进行数据恢复。
2.6如何选择RDB和AOF
- 一般来说,如果对数据的安全性要求非常高的话,应该同时使用两种持久化功能。
- 如果可以承受数分钟以内的数据丢失,那么可以只使用 RDB 持久化。
- 有很多用户都只使用 AOF 持久化, 但并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快 。
- 两种持久化策略可以同时使用,也可以使用其中一种。如果同时使用的话, 那么Redis重启时,会优先使用AOF文件来还原数据
二、事务
1.Redis事务介绍
为了保证多条命令组合的原子性, Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题。事务表示一组动作, 要么全部执行, 要么全部不执行 。
- Redis的事务是通过MULTI,EXEC,DISCARD和WATCH这四个命令来完成的。
- Redis的单个命令都是原子性的,所以这里确保事务性的对象是命令集合。
- Redis将命令集合序列化并确保处于同一事务的命令集合连续且不被打断的执行
- Redis不支持回滚操作
2.基本命令
MULTI
用于标记事务块的开始。
Redis会将后续的命令逐个放入队列中,然后使用EXEC命令原子化地执行这个命令序列。
语法:multi
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set s1 11
QUEUED
127.0.0.1:6379> set s2 s2
QUEUED
可以看到set命令此时的返回结果是QUEUED, 代表命令并没有真正执行, 而是暂时保存在Redis中 .如果执行以下命令结果如下:
127.0.0.1:6379> EXISTS s1
(integer) 0
127.0.0.1:6379> get s1
(nil)
只有当exec执行后 ,才会真正添加到redis中。
EXEC
在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态
语法:exec
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set s1 11
QUEUED
127.0.0.1:6379> set s2 s2
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
因为执行了两个set命令,所以执行exec返回两条数据。
DISCARD
清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态。
语法:discard
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set s3 333
QUEUED
127.0.0.1:6379> set s4 444
QUEUED
127.0.0.1:6379> DISCARD
OK
3. 事务失败处理
3.1 Redis语法错误(可以理解为编译期错误)
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set s3 333
QUEUED
127.0.0.1:6379> set s4
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
上面执行set命令少一个value,导致事务无法提交。
3.2 Redis类型错误(可以理解为运行期错误)
这种就是运行时命令, 因为语法是正确的 。
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set s3 333
QUEUED
127.0.0.1:6379> LPUSH s3 444 555
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
从上面可以看出,redis事务是不支持回滚的。exec执行,返回了一个OK,一个异常。说明set s3 333已经执行成功了。
127.0.0.1:6379> get s3
"333"
4.监控命令
WATCH
当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的状态。
语法:watch key [key…]
注意事项:使用该命令可以实现redis的乐观锁。
UNWATCH
清除所有先前为一个事务监控的键。
语法:unwatch
有些应用场景需要在事务之前, 确保事务中的key没有被其他客户端修改过, 才执行事务, 否则不执行(类似乐观锁) 。 Redis提供了watch命令来解决这类问题 。
客户端1 | 客户端2 |
---|---|
客户端1 执行完MULTI 命令后执行 APPED s5 world命令。
然后客户端2,在在执行APPED s5 java命令。
然后客户端1,在执行APPED s5 vue命令。
然后客户端1,在执行EXEC命令。
因为客户端1 watch的值已经发生改变,所以导致事务不会提交,返回nil.
Redis提供了简单的事务, 之所以说它简单, 主要是因为它不支持事务中的回滚特性
微信公众号
Redis系列-第四篇持久化与事务相关推荐
- Redis系列(十四)、Redis6新特性之RESP3与客户端缓存(Client side caching)
Redis6引入新的RESP3协议,并以此为基础加入了客户端缓存的新特性,在此特性下,大大提高了应用程序的响应速度,并降低了数据库的压力,本篇就带大家来看一下Redis6的新特性:客户端缓存. 目录 ...
- Redis系列(四)--内存淘汰机制(含单机版内存优化建议)
每台redis的服务器的内存都是有限的,而且也不是所有的内存都用来存储信息.而且redis的实现并没有在内存这块做太多的优化,所以实现者为了防止内存过于饱和,采取了一些措施来管控内存. 文章结构: ( ...
- 深入理解javascript作用域系列第四篇——块作用域
前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...
- UR机器人装箱姿态_UR10 RG2机械臂手臂+RealsenseZR300 机器人手眼标定 系列第四篇
UR10 RG2机械臂手臂+RealsenseZR300 机器人手眼标定 系列第四篇 发布时间:2018-09-18 17:43, 浏览次数:1180 , 标签: UR RG RealsenseZR ...
- 互联网大脑的情绪,智商和梦境-互联网神经学系列第四篇
这是互联网神经学系列的第四篇文章"互联网大脑的情绪.智商和梦境,互联网神经心理学" 1.互联网神经心理学的提出 我们在互联网神经学系列的第三篇文章中详细介绍了互联网大脑的架构和运行 ...
- Redis系列教程(四):Redis为什么是单线程、及高并发快的3大原因详解
Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...
- Redis基础(四)——持久化
文章目录 持久化 1 RDB 2 AOF 3 总结 持久化 利用永久性存储介质将数据进行保存 持久化保持的方式 RDB:数据快照 AOF:记录操作过程日志 1 RDB 以数据快照形式生成.rdb文件, ...
- 18.Redis系列之AOF方式持久化
本文学习redis7两大持久化技术之一:AOF(Append Only File)日志追加方式持久化备份与还原,重写以及AOF方式的优缺点 1. AOF相关配置 首先我们先简单了解下Redis7中AO ...
- 微信商城开发系列第四篇 不写代码玩转微信公众号
本系列文章转载自:CSDN博客walkingmanc的专栏 为什么叫不写代码玩转微信公众号呢? 我们大家都知道,微信公众号有两种模式,一种是编辑模式,一种是开发模式.所谓的不写代码玩转微信公众号,其实 ...
最新文章
- 智慧树插件会被发现吗_输尿管也会得肿瘤?能早期发现吗?
- Go语言TCP网络编程(详细)
- Net基础篇_学习笔记_第十一天_面向对象(类)
- 几个免费高质量图标搜索引擎。
- docker php 乱码,如何解决docker安装zabbix5.0界面乱码
- 像搭“乐高”一样实现整合式网络安全体系
- python 把xml中含有特殊字段的部分提取出来_Python: 爬虫网页解析工具lxml.html(一)...
- http://selectorgadget.com/
- timthumb.php 2.814,苏醒主题Grace8.0最新版(免费更新)
- 多重句柄怎么处理_golang异常处理详解
- Linux下实现一个论文翻译阅读的小工具
- 第一弹app v2.30.0
- centos7 更新 Firefox 版本
- IM即时通讯开发,聊天软件APP搭建,私有云部署
- python 基础语法--print,input,open的内置函数的操作
- 生死看淡,不服就GAN(八)----WGAN的改进版本WGAN-GP
- 第19篇 基础(十九)详解QVector(数组)
- ALtera DE2开发板学习
- 提高spark任务稳定性1 - Blacklist 机制
- 【vue-router源码】十二、useRoute、useRouter、useLink源码分析
热门文章
- 置信椭圆(误差椭圆)详解
- 安装ubuntu16.04+Nvidia驱动+Cuda8.0+Cudnn5.1+Matlab R2017b+Pycharm+WPS
- 每日学一个设计模式1——迭代器模式
- 薇娅和李佳琦带货百亿奇迹背后是这些技术团队的努力
- 【Vuejs】952- 一文带你了解vue2之响应式原理
- linux模糊查询特定后缀名文件,linux中查找包含指定内容的文件
- android kill 命令杀死进程,【Android 应用开发】Android 杀进程总结 ( 杀后台进程 | 杀前台进程 | 杀其它进程 )...
- 复旦计算机科学与技术排名,“计算机科学与技术”学科评估排名,复旦无缘30强,吉大表现亮眼...
- 分享112个助理类简历模板,总有一款适合您
- python链家网爬虫_手把手教你利用Python网络爬虫获取链家网的房产信息