Redis
事务
Redis事务的本质:一组命令的集合!一个事务中所有命令都会被序列化,在事务执行过程中,会按照顺序执行!
Redis的单挑命令是保持原子性的,但是事务不保证原子性!
编译型异常(代码有问题!命令有错误!),事务中所有命令都不会执行!
运行时异常(1/0),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的
悲观锁 乐观锁
悲观锁:
- 很悲观,什么时候都会出问题,无论什么时候都会加锁!
乐观锁:
- 很乐观,认为什么时候都不会出问题,所以不会上锁!更新数据的时候去判断一下,在此期间是否有人修改过这个数据。
- 获取version
- 更新的时候比较version
测试多线程修改值,使用watch可以当成redis的乐观锁操作!
1.如果发现事务执行失败,就先解锁
2.获取最新的值,再次监视,select version
3.比对监视的值是否发生了变化,如果没有变化,那么可以执行成功,如果变化了,执行失败。
jedis
什么是Jedis
是Redis官方推荐的java连接开发工具!使用Java操作Redis中间件!如果你要使用java操作redis,那么一定要对jedis十分熟悉!
SpirngBoot整合
说明:在Springboot2.x之后,原来使用的jedis被替换为了lettuce
jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool连接池!更像DIO模式。
letture:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数量,更像NIO模式。
配置文件 快照
持久化,在规定时间内,执行了多少次操作,则会持久化到文件 .rdb .aof
redis是内存数据库,如果没有持久化,那么数据断电及去!
# 如果900s内,如果至少有一个1 key进行了修改,我们及进行持久化操作
save 900 1
# 如果300s内,如果至少有一个10 key进行了修改,我们及进行持久化操作
save 300 10
# 如果60s内,如果至少有一个10000 key进行了修改,我们及进行持久化操作
save 60 10000
dir ./ #rdb 文件保存的目录
APPEND ONLY 模式 aof配置
appendonly no #默认是不开启aof模式的,默认是使用rdb方式持久化的,在大部分所有情况下,rdb完全够用!
appendfilename “appendonly.aof” #持久化文件的名字 .rdb
Redis持久化
Redis是内存数据库,如果不将内存中的数据库保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以redis提供持久化功能!
RDB(Redis Datebase)
什么是RDB
在主从复制中,rdb就是备用了!从机上面!
在指定的时间间隔内,将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读取到内存里。
Redis会单独创建(fork)一个子进程进行持久化,会将数据写入到一个临时文件中,待持久化过程结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的。这就确保了极高的性能。如果需要进行大规模数据恢复,且对于数据恢复的完整性不是非常的敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
我们默认就是RDB,一般情况下不需要修改这个配置。
有时候在生产环境我们会将这个文件备份
== rdb保存的文件是dump.rdb ==
触发机制
- save的规则满足的情况下,会自动触发rdb规则
- 执行flushall命令,也会出发我们的rdb规则
- 退出redis,也会产生rdb文件
- 备份就自动生成一个dump.rdb
如何恢复rdb文件呢?
- 只需要将rdb文件放在我们redis启动目录就可以了,redis启动的时候会自动检查dump.rdb 恢复其中的数据!(全自动)
- 查看需要存在的位置
192.168.148.128:6379> config get dir
1) "dir"
2) "/" # 如果在这个目录下存在dump.rdb 文件,启动就会自动恢复其中的数据
192.168.148.128:6379>
几乎自己默认的配置就够了
优点:
- 适合大规模的数据恢复!
- 对数据的完整性要求不高
缺点:
1.需要一定的时间间隔进行操作! 如果redis意外宕机了,这个最后一次修改数据就没有了!
2.fork进程的时候,会占用一定的内容空间!
AOF (Append Only File)
将我们所用命令都记录下来,history,恢复的时候就把这个文件全部再执行一遍!
什么是AOF
以日志的形式来记录每一个写操作,将redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之redis重启的话就是根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
== AOF保存的是appendonly.aof 文件 ==
默认不开启,需要手动配置 只需要将appendonly改为yes就开启了aof!
重启,redis就可以生效了!
如果这个aof文件有错误,这个时候redis是启动不起来的吗,我们需要修复这个aof文件
redis给我们提供了一个工具 redis-check-aof -- fix
优点:
- 每一次修改都同步,文件的完整性会更加好!
- 每秒同步一次,可能会丢失1秒的数据
- 从不同步,效率最高
缺点: - 相对于数据文件来说,aof远远大于rdb,修复的速度也比rdb慢!
- aof运行效率也要比rdb慢,所以我们redis默认的配置就是redis持久化!
Redis发布订阅
Redis发布订阅(pub/sub)是一种消息通信模式:发布者(pub)发送消息,订阅者(sub)接收消息。微博,微信,关注系统!
Redis客户端可以订阅任意数量的频道。
订阅/发布消息图:
使用场景:
实时消息系统
实时聊天
Redis主从复制
概念
主从复制,是将一台Redis服务器的数据,复制到其他Redis服务器。前者称为主节点,后者称为从节点,数据的复制是单向的,只能由主节点到从节点
。Master以写为主,Slave以读为主。
主从复制的作用:
一主二从:
主从复制,读写分离!80%的情况下都在进行读操作,减缓服务器的压力!架构中经常使用!一主二从!
环境配置
只配置从库,不配置主库!
info replication #查看当前库信息
复制3个配置文件,然后修改对应信息
1.端口
2.pid
3.log文件名字
4.dump.rdb文件名字
一主二从
默认情况下,每一台Redis服务器都是主节点;
一般情况下只用配从机就好。
一主(79)二从(8081)
127.0.0.1:6381> slaveof 127.0.0.1 6379 # 认老大
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1699860010
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:bc2b75ba4d8f93b04517f5501a783cfd10f98ba9
真实的主从配置在配置文件中配置,这样的话是永久的。
使用命令配置是暂时的。
细节
主机可以写,从机不能写只能读!主机中所有的信息和数据,都会自动被从机保存!
主机断开连接,从机依旧连接到主机,但是没有写操作,这个时候,主机如果回来了,从机依旧可以直接获取到主机写的信息!
如果是使用命令行,来配置主从,这个时候如果重启了,就会变回主机!只要变为从机,立马就会从主机中获取值!
复制原理
谋权篡位
如果主机断开了连接,我们可以使用
SLAVEOF no one
让自己变成主机!其他的节点就可以手动连接到最新的这个主节点(手动)如果这个时候老大修复了,那就重新连接!
Redis哨兵模式
概述
主从切换技术的方法:当主服务器宕机后,需要手动把一台服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多的时候,我们优先考虑哨兵模式。Redis从2.8开始正式提供了Sentinel(哨兵)架构来解决这个问题。
谋权篡位的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。
哨兵模式执行过程:
如果主机此时回来了,只能当从机!
优缺点
Redis缓存穿透与雪崩(高可用问题)
Redis缓存的使用,极大的提示了应用程序的性能和效率,特别是数据查询方面。但同时,它也带来了一些问题。其中,最要害的问题就是数据一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。
另外一些典型的问题就是,缓存穿透,缓存雪崩,缓存击穿。目前,业界也都有比较流行的解决方案。
缓存穿透(缓存查不到)
概念
缓存穿透的概念很简单,用户想要查询一个数据,发现redis内存数据库没有,也就缓存没有命中,于是向持久层数据库查询。发现也没有,于是本次查询失败。
当用户很多的时候,缓存都没有命中,于是都去请持久层数据库。这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。
解决方案
布隆过滤器
布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力;
缓存空对象
当存储层不命中后,即使返回空对象也将其缓存起来,同时设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源;
缓存击穿(量太大)
例如微博热搜!
概述
这里需要注意和缓存击穿的区别,缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中这个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开一个洞。
当某个key在过期的瞬间,有大量的请求并发访问,这类数据一般是热点数据,由于缓存过期,会同时访问数据库来查询最新数据,并且回写缓存,会导致数据库压力瞬间增大。
解决方案
设置热点数据永不过期
加互斥锁
缓存雪崩
解决方案