目录
第二步,移动压缩包到/usr/java目录,如果没有该目录就创建,创建指令:
第六步,安装(在解压的目录中执行,同样是redis-5.0.0目录):
第七步,切换到redis.conf文件默认执行路径目录(未进行任何更改的话就是这个路径)
第九步,在/usr/local/bin目录修改redis.conf
注意:需要远程连接的话得关闭虚拟机防火墙,以下为防火墙指令:
六、Redis可视化客户端(Redis Desktop Manager ):
一:Redis简介:
Redis是一款高性能的NOSQL系列的非关系型数据库.
Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
Redis优势:
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
Redis的缺点包括:
内存限制:Redis的数据存储在内存中,因此受到内存大小的限制,不能存储过大的数据。
数据持久化成本较高:Redis的持久化机制会带来一定的性能损失和存储成本,需要在性能和数据安全之间做出平衡。
不支持复杂查询:Redis不支持复杂的查询操作,例如关系型数据库中的join操作。
不能作为全局锁:Redis的锁机制只能作用于单个Redis实例,不能作为全局锁使用。
Redis作用:将数据存储于缓存(内存)之中,方便查询。(热点数据加速查询)
• 缓存(数据查询、短连接、新闻内容、商品内容等等)
• 聊天室的在线好友列表
• 任务队列。(秒杀、抢购、12306等等)
• 应用排行榜
• 网站访问统计
• 数据过期处理(可以精确到毫秒
• 分布式集群架构中的session分离
注意:
redis实现缓存只是在你项目跑起来时可以更加快速访问,一但你的服务器关闭,那么数据也没有保存,下次还是要先在mysql中获得数据后存到redis中来实现一个缓存,然后才能实现快速查询。
Redis持久化
1.redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
2.redis持久化机制:
1. RDB:默认方式,不需要进行配置,默认就使用这种机制
* 在一定的间隔时间中,检测key的变化情况,然后持久化数据
1. 编辑redis.windwos.conf文件
# after 900 sec (15 min) if at least 1 key changed
save 900 1
# after 300 sec (5 min) if at least 10 keys changed
save 300 10
# after 60 sec if at least 10000 keys changed
save 60 10000
2. 重新启动redis服务器,并指定配置文件名称
D:\JavaWeb2018\day23_redis\资料\redis\windows-64\redis-2.8.9>redis-server.exe redis.windows.conf
2.AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
1. 编辑redis.windwos.conf文件
appendonly no(关闭aof) --> appendonly yes (开启aof)
# appendfsync always : 每一次操作都进行持久化
appendfsync everysec : 每隔一秒进行一次持久化
# appendfsync no : 不进行持久化
理解:
Java中普遍使用jedis连接数据库(不能直接连接,如果直接使用 Jedis
链接Redis会造成频繁的Jedis对象创建和销毁,对性能会有很大的影响,所以我们会选择使用连接池来链接性能。原理同Mysql连接池);相当于Mybatis连接MySQL。
Linux中的Redis命令:
- redis-server 服务器启动命令
- redis-cil 客户端启动命令
- redis.conf redis核心配置文件
- redis-check -dump RDB文件检查工具(快照持久化文件)
- redis-check -aof AOF文件修复工具
二、Redis的安装和配置(虚拟机中):
第一步,打开虚拟机终端,下载Redis压缩包,输入:
wget http://download.redis.io/releases/redis-5.0.0.tar.gz
安装失败的话是因为没有wget依赖,输入该指令再重试:
yum install -y gcc
如果还是失败,输入该指令再重试第一步指令:
yum install -y wget
第二步,移动压缩包到/usr/java目录,如果没有该目录就创建,创建指令:
mkdir /usr/java
移动到该目录下:
mv redis-5.0.0.tar.gz /usr/java
第三步,先切换到java目录,输入:
cd /usr/java
解压压缩包:
tar –xvf redis-5.0.0.tar.gz
如果解压失败,输入这个指令:
tar –zxvf redis-5.0.0.tar.gz
第四步,cd到解压目录,输入:
cd redis-5.0.0
第五步,编译,输入:
make
第六步,安装(在解压的目录中执行,同样是redis-5.0.0目录):
make install
第七步,切换到redis.conf文件默认执行路径目录(未进行任何更改的话就是这个路径)
cd /usr/local/bin
第八步,将Redis的配置文件复制到当前目录
cp /usr/java/redis-5.0.0/redis.conf ./
第九步,在/usr/local/bin目录修改redis.conf
vi redis.conf
1.将bind 127.0.0.1改为bind 0.0.0.0或者将其注释掉(使用#)
2.将daemonize no改为daemonize yes(将redis服务改为可以后台启动)
3.设置redis客户端访问密码,添加一段代码:requirepass yourpassword(yourpassword为你自己设置的密码)
然后按esc,再按:wq保存并退出编译。
第十步,启动Redis客户端和服务器(安装及配置完成)
启动服务器:
./reids-server redis.conf
启动客户端:
redis-cli
注意:需要远程连接的话得关闭虚拟机防火墙,以下为防火墙指令:
#查看防火墙状态
systemctl status firewalld
#关闭防火墙
systemctl stop firewalld
#禁止开机启动防火墙
systemctl disable firewalld
#开启防火墙
systemctl start firewalld
三、Redis数据类型操作(在redis客户端进行):
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合,比较少用)。
一、String类型操作:
添加/修改数据添加/修改数据
set key value
获取数据
get key
删除数据
del key
判定性添加数据(该key如果没有数据就添加value值,并返回1;该key如果有数就不添加value值,并返回0)
setnx key value
添加/修改多个数据
mset key1 value1 key2 value2 …
获取多个数据
mget key1 key2 …
获取数据字符个数(字符串长度)
strlen key
追加信息到原始信息后部(如果原始信息存在就追加,否则新建)
append key value
String扩展操作:
string的扩展操作,分成两大块:一块是对数字进行操作的,第二块是对我们的key的时间进行操作的。
设置数值数据增加指定范围的值(相当于i++)
//key的value每次执行此操作自动+1 incr key //key的value值每次执行此操作自动+increment incrby key increment //为 key 中所储存的值加上指定的浮点数增量值(原有基础上增加increment浮点数) incrbyfloat key increment
设置数值数据减少指定范围的值(相当于i--)
//key的value每次执行此操作自动-1 decr key //key的value值每次执行此操作自动-increment decrby key increment
设置数据具有指定的生命周期
//设置key值存活seconds秒的value值,主要用于验证码的限时有效 setex key seconds value //设置key值存活milliseconds毫秒秒的value值,主要用于验证码的限时有效 psetex key milliseconds value
string 类型数据操作的注意事项:
(1)数据操作不成功的反馈与数据正常操作之间的差异
表示运行结果是否成功
(integer) 0 → false 失败
(integer) 1 → true 成功
表示运行结果值
(integer) 3 → 3 3个
(integer) 1 → 1 1个
(2)数据未获取到时,对应的数据为(nil),等同于null
(3)数据最大存储量:512MB
(4)string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算
(5)按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis 数值上限范围,将报错 9223372036854775807(java中Long型数据最大值,Long.MAX_VALUE)
(6)redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响.
数据库中的热点数据key命名惯例(中间用":"连接)
表名 | 主键名 | 主键值 | 字段名 | |
---|---|---|---|---|
eg1: | order | id | 29437595 | name |
eg2: | equip | id | 390472345 | type |
eg3: | news | id | 202004150 | title |
例如: user:id:852562:name:张三 (其中user是表名,id是主键名,852562是主键值,name是字段名,张三是存入的value值)
二、hash类型操作:
如上图所示,这种结构叫做hash,左边一个key,对右边一个存储空间。这里要明确一点,右边这块儿存储空间叫hash,也就是说hash是指的一个数据类型,他指的不是一个数据,是这里边的一堆数据,那么它底层呢,是用hash表的结构来实现的。
hash类型基本操作:
添加/修改数据
//添加key的filed字段的value值 hset key field value
获取数据
//获取key的filed字段的value值 hget key field //获取全部key的数据 hgetall key
删除数据
//删除key的filed1字段的value值 hdel key field1 [field2]eg:hdel user:123 age
设置field的值,如果该field存在则不做任何操作
hsetnx key field value
添加/修改多个数据
hmset key field1 value1 field2 value2 …
获取多个数据
hmget key field1 field2 …
获取哈希表中字段的数量
//查看hash表中有几组key-value值 hlen key
获取哈希表中是否存在指定的字段
hexists key field
hash 类型数据扩展操作:
获取哈希表中所有的字段名或字段值
//获取key的所有key数据 hkeys key //获取key是所有value值 hvals key
设置指定字段的数值数据增加指定范围的值
//key的filed字段自动增长increment大小 hincrby key field increment //key的filed字段自动减少increment大小 hincrbyfloat key field increment
hash类型数据操作的注意事项
(1)hash类型中value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到,对应的值为(nil)。
(2)每个 hash 可以存储 232 - 1 个键值对 hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计 的,切记不可滥用,更不可以将hash作为对象列表使用。
(3)hgetall 操作可以获取全部属性,如果内部field过多,遍历整体数据效率就很会低,有可能成为数据访问瓶颈。
三、List类型操作(最后存入的索引为0)
list类型:保存多个数据,底层使用双向链表存储结构实现
List类型基本操作:
添加/修改数据
//给key添加value1[value2]...值 lpush key value1 [value2] …… //给key增加value1[value2]...值 rpush key value1 [value2] ……
获取数据
//获取key的从start到stop索引上的值 lrange key start stop //获取key的index索引位置上的数据 lindex key index //获取key里面数据的长度 llen key
获取并移除数据
//获取key的第一个值并删除 lpop key //获取key的最后一个值并删除 rpop key
list扩展操作:
移除指定数据
//删除key中count数量的value值(value值可能存在重复) lrem key count value
规定时间内获取并移除数据
//在timeout秒内将key的最后一个存入(索引为0)的数据取出来并删除(若多个key值,则每执行一次只取一个value值) //当 BLPOP 被调用时,如果给定key内至少有一个非空列表,那么弹出遇到的第一个非空列表的头元素,并和被弹出元素所属的列表的名字一起,组成结果返回给调用者。 blpop key1 [key2] timeout //在timeout秒内将key的第一个存入(索引最大的)的数据取出来并删除(若多个key值,则每执行一次只取一个value值) brpop key1 [key2] timeout //将source里面的最后一个元素(索引最大的元素)取出放入destination的表头(0号索引)位置(在timeout秒内) brpoplpush source destination timeout
list 类型数据操作注意事项
(1)list中保存的数据都是string类型的,数据总容量是有限的,最多232 - 1 个元素(4294967295)。
(2)list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作
(3)获取全部数据操作结束索引设置为-1
(4)list可以对数据进行分页操作,通常第一页的信息来自于list,第2页及更多的信息通过数据库的形式加载
四、set类型操作
set类型:与hash存储结构完全相同,仅存储键,不存储值(nil),并且值是不允许重复的
整个结构:
set类型数据的基本操作
添加数据
//给key添加数据member1[member2] sadd key member1 [member2]
获取全部数据
//获取key的全部数据 smembers key
删除数据
//删除key中的member1[member2]这些数据 srem key member1 [member2]
获取集合数据总量
//获取key的value值的数量 scard key
判断集合中是否包含指定数据
//判断key中是否含有member这个值 sismember key member
随机获取集合中指定数量的数据
//随机获取key中[count数量]的数据 srandmember key [count]
随机获取集中的某个数据并将该数据移除集合
//随机获取key中[count数量]的数据并移除 spop key [count]
set 类型数据的扩展操作
交并差图示
求两个集合的交、并、差集
//求key1[key2]的交集 sinter key1 [key2 …] //求key1[key2]的并集 sunion key1 [key2 …] //求key1[key2]的补集 sdiff key1 [key2 …]
求两个集合的交、并、差集并存储到指定集合中
//将key1 key2的交集存储到destination中 sinterstore destination key1 key2 … //将key1 key2的并集存储到destination中 sunionstore destination key1 key2 … //将key1 key2的差集存储到destination中 sdiffstore destination key1 key2 …
将指定数据从原始集合中移动到目标集合中
//将source中的member移动到destination集合中 smove source destination member
set 类型数据操作的注意事项:
set 类型不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份。
set 虽然与hash的存储结构相同,但是无法启用hash中存储值的空间。
四、Redis常用指令(在redis客户端进行)
一、key指令:
key 基本操作:
删除指定key
del key
获取key是否存在
exists key
获取key的类型
type key
3.1.3 拓展操作
排序
//对数字进行排序 sort key //对字母进行排序 sort key alpha
改名
rename key newkey //判断是否存在该key,若存在便改为newkey,不存在则不改(具有安全性) renamenx key newkey
key 扩展操作(时效性控制)
为指定key设置有效期
//将key设置为seconds秒有效 expire key seconds //将key设置为milliseconds毫秒有效 pexpire key milliseconds //将key改为具有时效性(timestamp秒)的数据 expireat key timestamp //将key改为具有时效性(milliseconds-timestamp毫秒)的数据 pexpireat key milliseconds-timestamp
获取key的有效时间
//获取key的有效时间(秒) ttl key //获取key的有效时间(毫秒) pttl key
切换key从时效性转换为永久性
persist key
key 扩展操作(查询模式)
查询key
keys pattern
查询模式规则
*匹配任意数量的任意符号 ? 配合一个任意符号 [] 匹配一个指定符号
keys * 查询所有 keys it* 查询所有以it开头 keys *h 查询所有以h结尾 keys ??h 查询所有前面两个字符任意,后面以h结尾 查询所有以 keys user:? user:开头,最后一个字符任意 keys u[st]er:1 查询所有以u开头,以er:1结尾,中间包含一个字母,s或t
二、数据库常用指令(DB指令):
redis在使用过程中,伴随着操作数据量的增加,会出现大量的数据以及对应的key。
假如说你们十个人同时操作redis,会不会出现key名字命名冲突的问题。
为了解决这个问题,数据库指令油然而生
解决方案:
redis为每个服务提供有16个数据库(默认16个,需要改的话就得到配置文件中修改了),编号从0到15。每个数据库之间的数据相互独立
在对应的数据库中划出一块区域,说他就是几,你就用几那块,同时,其他的这些都可以进行定义,一共是16个,这里边需要注意一点,他们这16个共用redis的内存。没有说谁大谁小,也就是说数字只是代表了一块儿区域,区域具体多大未知。这是数据库的一个分区的一个策略!
Redis数据库的基本操作:
切换数据库
//index为数据库编号 select index
其他操作
//测定服务器是否连通 ping
数据库扩展操作:
数据移动
//将key移动到1号数据库 move key 1
数据总量(在当前数据库下执行)
//测定当前库里的内容条数 dbsize
数据清除
//清除当前库的数据 flushdb //清除所有库的数据 flushall
五、Jedis(提供java与Redis的连接服务)
准备工作
(1)jar包导入
下载地址:https://mvnrepository.com/artifact/redis.clients/jedis
基于maven
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
(2)客户端连接redis
连接redis,localhost需要虚拟机终端通过 ip addr进行查询
Jedis jedis = new Jedis("localhost", 6379);
操作redis
jedis.set("name", "itheima"); jedis.get("name");
关闭redis连接
jedis.close();
代码实现
创建:com.JedisTest
public class JedisTest {
public static void main(String[] args) {
//1.获取连接对象
Jedis jedis = new Jedis("192.168.40.130",6379);
//2.执行操作
jedis.set("age","39");
String hello = jedis.get("hello");
System.out.println(hello);
jedis.lpush("list1","a","b","c","d");
List<String> list1 = jedis.lrange("list1", 0, -1);
for (String s:list1 ) {
System.out.println(s);
}
jedis.sadd("set1","abc","abc","def","poi","cba");
Long len = jedis.scard("set1");
System.out.println(len);
//3.关闭连接
jedis.close();
}
}
六、Redis可视化客户端(Redis Desktop Manager ):
以下是我个人使用的安装工具:
redis可视化工具安装包 https://www.aliyundrive.com/s/CGwXHpFB2j7 提取码: 81mr 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
七、Redis持久化
一、什么是持久化
(1)什么是持久化
利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化。
持久化用于防止数据的意外丢失,确保数据安全性。
(2)持久化过程保存什么?
我们知道一点,计算机中的数据全部都是二进制,如果现在我要你给我保存一组数据的话,你有什么样的方式呢,其实最简单的就是现在长什么样,我就记下来就行了,那么这种是记录纯粹的数据,也叫做快照存储,也就是它保存的是某一时刻的数据状态。
还有一种形式,它不记录你的数据,它记录你所有的操作过程,比如说大家用idea的时候,有没有遇到过写错了ctrl+z撤销,然后ctrl+y还能恢复,这个地方它也是在记录,但是记录的是你所有的操作过程,那我想问一下,操作过程,我都给你留下来了,你说数据还会丢吗?肯定不会丢,因为你所有的操作过程我都保存了。这种保存操作过程的存储,用专业术语来说可以说是日志,这是两种不同的保存数据的形式啊。
总结一下:
第一种:将当前数据状态进行保存,快照形式,存储数据结果,存储格式简单,关注点在数据。
第二种:将数据的操作过程进行保存,日志形式,存储操作过程,存储格式复杂,关注点在数据的操作过程。
二、RDB
1.save指令
手动执行一次保存操作
save
save指令相关配置
设置本地数据库文件名,默认值为 dump.rdb,通常设置为dump-端口号.rdb
dbfilename filename
设置存储.rdb文件的路径,通常设置成存储空间较大的目录中,目录名称data
dir path
设置存储至本地数据库时是否压缩数据,默认yes,设置为no,节省 CPU 运行时间,但存储文件变大
rdbcompression yes|no
设置读写文件过程是否进行RDB格式校验,默认yes,设置为no,节约读写10%时间消耗,单存在数据损坏的风险
rdbchecksum yes|no
save指令工作原理
redis是个单线程的工作模式,它会创建一个任务队列,所有的命令都会进到这个队列里边,在这儿排队执行,执行完一个消失一个,当所有的命令都执行完了,OK,结果达到了。
但是如果现在我们执行的时候save指令保存的数据量很大会是什么现象呢?
他会非常耗时,以至于影响到它在执行的时候,后面的指令都要等,所以说这种模式是不友好的,这是save指令对应的一个问题,当cpu执行的时候会阻塞redis服务器,直到他执行完毕,所以说我们不建议大家在线上环境用save指令。
bgsave指令
之前我们讲到了当save指令的数据量过大时,单线程执行方式造成效率过低,那应该如何处理?
此时我们可以使用:bgsave指令,bg其实是background的意思,后台执行的意思
手动启动后台保存操作,但不是立即执行
bgsave
bgsave指令相关配置
后台存储过程中如果出现错误现象,是否停止保存操作,默认yes
stop-writes-on-bgsave-error yes|no
其 他
dbfilename filename dir path rdbcompression yes|no rdbchecksum yes|no
bgsave指令工作原理
save配置自动执行
设置自动持久化的条件,满足限定时间范围内key的变化数量达到指定数量即进行持久化
save second changes
参数
second:监控时间范围
changes:监控key的变化量
范例:
save 900 1 save 300 10 save 60 10000
其他相关配置:
dbfilename filename dir path rdbcompression yes|no rdbchecksum yes|no stop-writes-on-bgsave-error yes|no
save配置工作原理 :
RDB三种启动方式对比
方式 | save指令 | bgsave指令 |
---|---|---|
读写 | 同步 | 异步 |
阻塞客户端指令 | 是 | 否 |
额外内存消耗 | 否 | 是 |
启动新进程 | 否 | 是 |
RDB特殊启动形式
服务器运行过程中重启
debug reload
关闭服务器时指定保存数据
shutdown save
RDB优点:
-
RDB是一个紧凑压缩的二进制文件,存储效率较高
-
RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
-
RDB恢复数据的速度要比AOF快很多
-
应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复。
RDB缺点
-
RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据
-
bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能
-
Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象
三、AOF
为什么要有AOF,这得从RDB的存储的弊端说起:
-
存储数据量较大,效率较低,基于快照思想,每次读写都是全部数据,当数据量巨大时,效率非常低
-
大数据量下的IO性能较低
-
基于fork创建子进程,内存产生额外消耗
-
宕机带来的数据丢失风险
那解决的思路是什么呢?
-
不写全数据,仅记录部分数据
-
降低区分数据是否改变的难度,改记录数据为记录操作过程
-
对所有操作均进行记录,排除丢失数据的风险
AOF概念
AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令 达到恢复数据的目的。与RDB相比可以简单理解为由记录数据改为记录数据产生的变化
AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式
启动AOF相关配置(在redis.conf中配置)
开启AOF持久化功能,默认no,即不开启状态
appendonly yes|no
AOF持久化文件名,默认文件名为appendonly.aof,建议配置为appendonly-端口号.aof
appendfilename filename
AOF持久化文件保存路径,与RDB持久化文件保持一致即可
dir
AOF写数据策略,默认为everysec
appendfsync always|everysec|no
AOF执行策略
AOF写数据三种策略(appendfsync)
-
always(每次):每次写入操作均同步到AOF文件中数据零误差,性能较低,不建议使用。
-
everysec(每秒):每秒将缓冲区中的指令同步到AOF文件中,在系统突然宕机的情况下丢失1秒内的数据 数据准确性较高,性能较高,建议使用,也是默认配置
-
no(系统控制):由操作系统控制每次同步到AOF文件的周期,整体过程不可控
AOF重写
场景:AOF写数据遇到的问题,如果连续执行如下指令该如何处理
什么叫AOF重写?
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积。AOF文件重 写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结 果转化成最终结果数据对应的指令进行记录。
AOF重写作用
-
降低磁盘占用量,提高磁盘利用率
-
提高持久化效率,降低持久化写时间,提高IO性能
-
降低数据恢复用时,提高数据恢复效率
AOF重写规则
-
进程内具有时效性的数据,并且数据已超时将不再写入文件
-
非写入类的无效指令将被忽略,只保留最终数据的写入命令
如del key1、 hdel key2、srem key3、set key4 111、set key4 222等
如select指令虽然不更改数据,但是更改了数据的存储位置,此类命令同样需要记录
-
对同一数据的多条写命令合并为一条命令
如lpushlist1 a、lpush list1 b、lpush list1 c可以转化为:lpush list1 a b c。
为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素
AOF重写方式(客户端输入)
-
手动重写
bgrewriteaof
手动重写原理分析:
自动重写
auto-aof-rewrite-min-size size auto-aof-rewrite-percentage percentage
自动重写触发条件设置
//操作达到指定大小自动重写(kb,mb) auto-aof-rewrite-min-size size //操作量达到占用存储百分之precent就重写 auto-aof-rewrite-percentage percent
自动重写触发比对参数( 运行指令info Persistence获取具体信息 )
//aof基础尺寸大小 aof_current_size //aof当前尺寸大小 aof_base_size
自动重写触发条件公式:
AOF工作流程及重写流程
RDB与AOF区别
RDB与AOF对比(优缺点)
持久化方式 | RDB | AOF |
---|---|---|
占用存储空间 | 小(数据级:压缩) | 大(指令级:重写) |
存储速度 | 慢 | 快 |
恢复速度 | 快 | 慢 |
数据安全性 | 会丢失数据 | 依据策略决定 |
资源消耗 | 高/重量级 | 低/轻量级 |
启动优先级 | 低 | 高 |
RDB与AOF应用场景
RDB与AOF的选择之惑
-
对数据非常敏感,建议使用默认的AOF持久化方案
AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出 现问题时,最多丢失0-1秒内的数据。
注意:由于AOF文件存储体积较大,且恢复速度较慢
-
数据呈现阶段有效性,建议使用RDB持久化方案
数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段 点数据恢复通常采用RDB方案
注意:利用RDB实现紧凑的数据持久化会使Redis降的很低,慎重总结:
综合比对
-
RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊
-
如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF
-
如能承受数分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB
-
灾难恢复选用RDB
-
双保险策略,同时开启 RDB和 AOF,重启后,Redis优先使用 AOF 来恢复数据,降低丢失数据的量