Redis进阶
Redis线程模型
1.概述
在redis6.x版本之前,监听客户端连接,读写数据操作,都是由一个单线程来完成的
在redis6.x版本之后,引入了多线程,将客户端网络请求由一些线程来负责完成,数据读写操作仍由单线程进行操作,保证操作的原子性
2.为什么设计为单线程模型速度也很快
1.Redis是基于内存操作的
2.底层是一个hash表结构,对数据的操作时间复杂度为o(1)
3.io多路复用和非阻塞IO
4.单线程避免了线程间的切换
全局hash
hash 可以在 O(1)的时间内计算出 hash 值并且找到对应的 entry 位置,entry
里面是一个一个 key 指针和 value 指针,其实还有其他信息。这也是 redis 之所
以性能高的原因之一
Redis持久化
方式一:RDB
定期将数据快照保存在一个dump.rdb文件中,是Redis中默认的持久化方式,不需要配置开启。
里面有触发rdb保存快照的条件:
save 900 1 :表示 900 秒钟内至少 1 个键被更改则进行快照。
save 300 10 :表示 300 秒内至少 10 个键被更改则进行快照。
save 60 10000 :表示 60 秒内至少 10000 个键被更改则进行快照。
在redis客户端模式中,使用shutdown save 命令在关闭redis服务时,保存快照
重新启动redis服务时,把dump.rdb文件内容还原回来.
方式二:AOF
使用记录日志的方式来记录写操作的命令,需要手动开启
appendfsync always #每次修改都会 sync 消耗性能
appendfsync everysec #每秒执行一次 sync,可能会丢失这1s 的数据(默认)
开启方式
修改 redis.conf 配置文件,开启 AOF 机制
appendon1y no
#默认是不开启 aof 模式的,改为 yes 开启.
Redis事务
将多条命令放在同一个队列中,保证多条命令在同一个事务中进行,不受其他客户端的影响,但是不会保证同一事物多条命令执行的原子性,即使有错也会被添加到队列中,出错也不会影响同一个事务中其他命令的执行
操作方法:
multi 开启事务
命令1
命令2
命令3 把命令加入到一个队列中,并没有立即执行
exec 执行事务
主从复制
在大型项目中,为了保证系统的稳定性,有一台服务作为主机,有多台服务器作为从机,主机负责写数据,将数据同步到多台从机,由从机负责读操作,从而实现读写分离。
在此期间,如果有一台服务器出现问题,其他服务器也可以正常工作,有问题的服务器故障排除后,可以继续在集群中工作
即使是主机出现故障,也可以通过哨兵机制选出一台服务器作为主机
主从复制的作用主要包括:
1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
2.故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢
复;实际上是一种服务的冗余。
3.负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,
由从节点提供读服务(即写 Redis 数据时应用连接主节点,读 Redis 数据时应
用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节
点分担读负载,可以大大提高 Redis 服务器的并发量。
4.高可用(集群)基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是 Redis 高可用的基础。
哨兵机制
哨兵机制是一个独立的任务,独立运行,定期的向集群中的redis发送消息,如果收不到回应就表明Redis服务有问题,通过一套选举机制,就会从多台从机中选取一台作为主机,当主机故障恢复后,临时主机又变为从机
key过期策略
在设置key的时候,可以为key设置一个有效的时间,当时间到了以后Redis有一套机制可以用来删除过期的key
1.立即删除
在设置key的时候,创建一个回调函数,在时间到达以后立即执行回调函数进行删除,不浪费内存空间,但是如果大量的key同时到期,会导致cpu荷载高
2.惰性删除
到期后不立即删除,会等待下一次调用时判断是否过期,到期就进行删除,会浪费内存空间
3.定时删除
将过期的key记录下来,定期的对过期的key进行删除
Redis使用的策略是惰性删除和定时删除配合使用
缓存穿透
查询一个数据时,该数据在数据库中本身都没有,那么在Redis中也不会有,每次请求都会到达MySQL数据库
解决办法:
1.将该空对象也存储到Redis中,下次查询时会直接从Redis中查询到
2.对参数进行校验,拦截不合法参数的请求
缓存穿击
查询数据时,在数据库中存在,但是在Redis中某个热点key过期了,刚好有大量的请求到达,查询Redis中没有后,都会向MySQL数据库进行查询,导致数据库被压垮
解决办法:
1.合理设置热点key的过期时间
2.如果Redis为空,就加锁,第一个请求将数据写到缓存中后,其他请求就会直接从缓存中拿到数据
缓存雪崩
查询数据时,大量的key过期或者缓存出现了故障,导致大量的请求到达MySQL
解决办法:
1.设置随机过期时间
2.把热点key,放在不同的从机中
3.将热点key设置为不过期
4.设置定时任务,将快过期的Key,重新放入到缓存中