目录
一.配置Redis
1.配置application.properties
2. 配置Config
3.测试连接redis
二、Redis持久化
持久化方案
RDB:
1、RDB基础认识
1、具体流程如下:
3、小结:
3、Fork&Copy-On-Write
4、RDB的配置
5、默认快照的配置
6、save VS bgsave
7、flushall
8、save
9、stop-writes-on-bgsave-error
10、rdbcompression
11、rdbchecksum
12、动态停止RDB
2、RDB备份和恢复:
3、RDB小结
2、AOF
1、开启AOF
2、修复和恢复
3、同步频率设置
4、rewrite压缩
5、AOF小结
3、选择RDB还是AOF?
一.配置Redis
1.配置application.properties
# Redis 服务器地址
spring.redis.host=127.0.0.1
# Redis 服务器连接端口
spring.redis.port=6379
# Redis 密码(如果没有密码,直接删除这一行)
spring.redis.password=
# Redis 数据库索引(默认 0)
spring.redis.database=2
# 连接超时时间(毫秒)
spring.redis.timeout=1800000
# 连接池最大连接数(使用负数表示无限制)
spring.redis.lettuce.pool.max-active=20
# 最大阻塞等待时间(负数表示无限制)
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
# 连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
2. 配置Config
里面包含两个方法
1.redisTemplate
2.CacheManager
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template =new RedisTemplate<>();System.out.println("template=>" + template);//这里可以验证..RedisSerializer<String> redisSerializer =new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL,JsonTypeInfo.As.WRAPPER_ARRAY);jackson2JsonRedisSerializer.setObjectMapper(om);template.setConnectionFactory(factory);//key序列化方式template.setKeySerializer(redisSerializer);//value序列化template.setValueSerializer(jackson2JsonRedisSerializer);//value hashmap序列化template.setHashValueSerializer(jackson2JsonRedisSerializer);return template;}@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer =new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);//解决查询缓存转换异常的问题ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL,JsonTypeInfo.As.WRAPPER_ARRAY);jackson2JsonRedisSerializer.setObjectMapper(om);// 配置序列化(解决乱码的问题),过期时间600秒RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}
}
3.测试连接redis
@RestController
@RequestMapping("/redisTest")
public class RedisTestController {//装配RedisTemplate@Resourceprivate RedisTemplate redisTemplate;//编写第一个测试方法//演示设置数据和获取数据@GetMapping("/t1")public String t1() {//设置值到redisredisTemplate.opsForValue().set("book", "天龙八部~");//从redis获取值String book = (String) redisTemplate.opsForValue().get("book");return book;}
通过上面的api来访问,就会得到:
以及
这样我们就测试成功了
注意:
如果是通过客户端添加的数据,我们用redisTemplate的时候也会做反序列化,但是客户端set是不会做序列化的,所以会报错
解决方案就是用服务端的程序重新set一下就好了
二、Redis持久化
Redis 持久化是指 将内存中的数据保存到磁盘,确保即使 Redis 服务重启或崩溃,数据也不会丢失。由于 Redis 是 内存数据库(数据默认存储在内存中),持久化机制可以防止数据因断电、宕机等情况而丢失。
在线文档 :https://redis.io/topics/persistence
持久化方案
RDB和AOP
RDB:
1、RDB基础认识
在指定时间内将内存的数据集快照写入磁盘中,也就是Snapshot快照,恢复时将快照文件读到内存
RDB 持久化是通过生成数据快照来实现的
流程图:
1、具体流程如下:
1、redis 客户端执行bgsave命令或者自动触发bgsave命令;
2、主进程判断当前是否已经存在正在执行的子进程,如果存在,那么主进程直接返回;
3、如果不存在正在执行的子进程,那么就fork一个新的子进程进行持久化数据,fork过程是阻塞的,fork操作完成后主进程即可执行其他操作;
4、子进程先将数据写入到临时的rdb文件中,待快照数据写入完成后再原子替换旧的rdb文件;
5、同时发送信号给主进程,通知主进程rdb持久化完成,主进程更新相关的统计信息
3、小结:
1.整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 。
2.如果需要进行大规模数据的恢复, 且对于数据恢复的完整性不是非常敏感,那RDB方式 要比AOF方式更加的高效 。
3.RDB 的缺点是最后一次持久化后的数据可能丢失:如果你是正常关闭Redis,也就是正常shutdown时仍然会进行持久化, 不会造成数据丢失。如果是Redis 异常终止/宕机, 就可能造成数据丢失,具体流程如下:
- 收到
SHUTDOWN
命令。 - Redis 立即执行一次 阻塞式
SAVE
(确保数据完整)。 - 将最新数据写入
dump.rdb
。 - 关闭进程。
默认是SAVE
3、Fork&Copy-On-Write
1、Fork 的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、 程序计数器等) 数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程
2、在Linux 程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会 exec 系统调用,出于效率考虑,Linux中引入了"写时复制技术 即:copy-on-write", 有兴 韩顺平Java 工程师 趣的参考:https://blog.csdn.net/Code_beeps/article/details/92838520
3、一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程,也就是说:
当我用父进程操作一块物理内存,fork了一个子进程,此时父进程和子进程都在同一块物理内存,因为数据是一致的,当父进程对物理内存进行操作了,就会创建一个新的物理内存,此时父线程就到新的内存区域了,子线程在旧的内存区域。
4、RDB的配置
在redis.conf中配置文件名称,默认为dump.rdb,可以自定义
如何配置:
1、默认为Redis启动时命令行所在的目录下
进入到/usr/local/bin 目录下, 启动 Redis, 这个 ./ 就是 /usr/local/bin , 如果你在 /root/ 目录下启动 Redis, 那么 ./ 就是 /root/ 下了。如果之前在root目录下启动的redis,数据自动保存在这个目录下的dump.rdb,当年第二天打开,数据也从这个目录下的dump.rdb里恢复回来,也就是说,如果你从其他目录打开是没有数据的,因为没有对应的dump.rdb
2、rdb 文件的保存路径, 也可以修改, 比如: dir"/root/"
把dit ./改成dir /root/ ,这样一来无论从哪打开redis都会统一走同一个持久化文件
5、默认快照的配置
这是后台机制
1.
2.注意理解这个时间段的概念:
时间是独立的一段一段时间,下一个60秒会刷新统计
3.如果我们没有开启save注释,那么在退出Redis的时候也会再进行备份,更新dump.rdb(执行一次 阻塞式 SAVE
)
4.如果再规定时间内没有达到指定的key值变化,那么30秒后不做持久化
例子:save 30 10:
如果再规定时间内没有达到指定的key值变化,那么30秒后不做持久化,但是时间是独立的一段一段时间,下一个30秒会刷新统计,那我上一个30秒修改的key不做保存,就丢失了。除非shutdown
6、save VS bgsave
1、save :save时只管保存,其它不管,全部阻塞。手动保存, 不建议。
2、bgsave:Redis 会在后台异步进行快照操作, 快照同时还可以响应客户端请求。
3、可以通过lastsave 命令获取最后一次成功执行快照的时间(unix时间戳), 可以使用工具转换时间戳(Unix timestamp)转换工具 - 在线工具
7、flushall
1、执行flushall 命令,会把内存的数据全部拿掉,同时把数据再次持久化,所以dump.rdb文件数据为空.
2、Redis Flushall 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key)
内存92相当于是初始化的内存大小
8、save
save 秒钟 写操作次数
禁用: 给save传入空字符串
RDB是整个内存的压缩过的Snapshot,RDB的数据结构,可以配置复合的快照触发条
9、stop-writes-on-bgsave-error
当Redis无法写入磁盘的话(比如磁盘满了), 直接关掉Redis的写操作。推荐yes
10、rdbcompression
1、对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用 LZF 算法进行压缩。
2、如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能, 默认yes
11、rdbchecksum
1、在存储快照后, 还可以让redis使用CRC64算法来进行数据校验,保证文件是完整的
2、但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭 此功能, 推荐yes
12、动态停止RDB
1、动态停止RDB:redis-cli config set save"",不需要重启redis
2、说明:save后给空值,表示禁用保存策略
2、RDB备份和恢复:
1、Redis可以充当缓存, 对项目进行优化, 因此重要/敏感的数据建议在Mysql 要保存一份
2、从设计层面来说,Redis的内存数据, 都是可以重新获取的(可能来自程序, 也可能来自 Mysql)
3、因此我们这里说的备份&恢复主要是给大家说明一下 Redis启动时, 初始化数据是从 dump.rdb 来的, 这个机制.
config get dir 查询 rdb 文件的目录
将dump.rdb 进行备份, 如果有必要可以写shell脚本来定时备份 网课: https://www.bilibili.com/video/BV1Sv411r7vd?p=105
参考韩顺平老师的演示:
最终结果:
3、RDB小结
优势:
1、适合大规模的数据恢复
2、对数据完整性和一致性要求不高更适合使用
3、节省磁盘空间
4、恢复速度快
劣势:
1、虽然Redis在fork时使用了写时拷贝技术(Copy-On-Write), 但是如果数据庞大时还是比较消耗性能。
2、在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话(如果正常 关闭Redis, 仍然会进行RDB备份, 不会丢失数据), 就会丢失最后一次快照后的所有修改
2、AOF
官方资料 在线文档 :https://redis.io/topics/persistence
1、AOF(Append Only File)
2、以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(比 如 set/del 操作会记录, 读操作get不记录)
3、只许追加文件但不可以改写文件
4、redis 启动之初会读取该文件重新构建数据
5、redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
持久化流程图
1) 客户端的请求写命令会被append追加到AOF缓冲区内
2) AOF 缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中
3) AOF 文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量
4) Redis 服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的
1、开启AOF
1、在redis.conf 中配置文件名称,默认为 appendonly.aof
2、AOF文件的保存路径,同RDB的路径一致。
3、AOF和RDB同时开启,系统默认取AOF的数据
4、老韩实验, 当开启AOF后,Redis从AOF文件取数据.
后续:
当我们开启AOF之后再去写操作,这时候appendonly.aof就有数据了
2、修复和恢复
AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样, 都是拷贝备份文件, 需要恢复时再拷贝到Redis工作目录下,启动系统即加载
一、正常恢复
1、修改默认的appendonlyno,改为yes
2、将有数据的aof文件定时备份, 需要恢复时, 复制一份保存到对应目录(查看目录:config get dir)
3、恢复:重启redis然后重新加载
4、和前面RDB备份/恢复机制类似 .bak
二、异常恢复
1、如遇到AOF文件损坏,通过/usr/local/bin/redis-check-aof --fix appendonly.aof 进行恢复
2、建议先: 备份被写坏的AOF文件
3、恢复:重启redis,然后重新加载
可能会造成数据丢失,但是总比没有好,而且当文件损坏之后是连接不上了,根本就没有redis服务
开始修复文件:
成功了
3、同步频率设置
AOF 缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中,其中[always,everysec,no]就是同步频率设置
1.配置位置
1) appendfsync always 始终同步,每次Redis的写入都会立刻记入日志;性能较差但数据完整性比较好
2) appendfsync everysec 每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
3) appendfsync no redis不主动进行同步,把同步时机交给操作系统 https://baijiahao.baidu.com/s?id=1740774723808931509&wfr=spider&for=pc
4、rewrite压缩
一、rewrite 重写介绍
1) AOF 文件越来越大,需要定期对AOF文件进行重写达到压缩
2) 旧的AOF文件含有无效命令会被忽略,保留最新的数据命令 , 比如 :set a a1 ; set a b1; set a c1; 保留最后一条指令就可以了
3) 多条写命令可以合并为一个 , 比如把上面的指令改成: set a c1 b b1 c c1
4) AOF 重写降低了文件占用空间
5) 更小的AOF文件可以更快的被redis加载
二、重写触发配置
1) 手动触发 直接调用bgrewriteaof 命令
2) 自动触发
auto-aof-rewrite-min-size: AOF 文件最小重写大小, 只有当 AOF 文件大小大于该值时候才能 auto-aof-rewrite-percentage, 默认配置64MB
auto-aof-rewrite-percentage: 当前 AOF 文件大小和最后一次重写后的大小之间的比率等于或者大于指定的增长百分比,如100代表当前AOF文件是上次重写的两倍时候才重写
系统载入时或者上次重写完毕时,Redis会记录此时AOF大小,设为 base_size。
如果Redis的AOF当前大小>=base_size+base_size*100%(默认) 且 当前 大小>=64mb(默认)的情况下,Redis会对AOF进行重写。比如base_size是64m,那么下一次就是128m,没有到达128就不会重写。
5、AOF小结
优势:
1、备份机制更稳健,丢失数据概率更低,数据一致性比RDB好。
2、可读的日志文本,通过操作AOF稳健,可以处理误操作
劣势:
1、比起RDB占用更多的磁盘空间
只记录有哪些key
2、恢复备份速度要慢
因为记录的全是一些写指令,要重新执行一遍
3、每次读写都同步的话,有一定的性能压力
3、选择RDB还是AOF?
官方文档地址:https://redis.io/topics/persistence
官方推荐两个都启用
如果只做缓存:如果你只希望你的数据在服务器运行的时候存在, 你也可以不使用任何持久化方式