Redis进阶

文章目录

Redis相关问题

Redis线程模型

redis是单线程模式还是多线程模式?

不同的版本是不一样的,redis 6.x之前是真正意义上的单线程,处理客户端的连接和执行操作的命令都是由一个线程来完成的,redis 6.x之后引入多线程,接收客户端的请求是专门的线程来处理,执行命令还是单线程。

为什么是单线程模式,速度还非常快?

(1)数据是存储在内存中,读取快,cpu不是瓶颈;

(2)结构简单,key-value形式,底层是hash结构,查询操作速度为O(1);

(3)IO多路复用,非阻塞IO模型,提高连接访问速度;

(4)单线程执行命令,不存在线程切换,减少消耗,且线程是安全的。

Redis持久化

redis是如何进行数据持久化的?

RDB(Redis DataBase)和AOF(Append Only File)

(1)redis默认是RDB方式:直接将内存的数据快照。

​ 配置触发持久化的机制:

​ 1.save m n 多少秒内 多少键

​ 2.执行flushall命令

​ 3.退出

(2)AOF:以日志的形式,将写命令存储到文件

​ 还原时依次执行命令还原数据

​ 默认是不开启的:

​ appendonly no

​ 同步执行

​ appendfsync always 每秒set执行一次 消耗性能

​ appendfsync everysec 每秒记录一次 可能会丢失1s的数据(默认)

​ 重启redis生效

Redis事务

redis在执行单条命令时是原子性的(单线程的一次只能有一个线程执行命令);

事务不保证原子性(假如执行了3条命令,其中一条语法出错,那么其他2条正确的会继续执行);

redis事务本质是一组命令集合,一个事务中的所有命令都会被序列化,在事务执行过程中,按顺序执行;

redis事务没有隔离级别,所有命令都在事务中,并没有直接被执行,只有发起执行exec命令的时候才会执行。

redis事务:

​ 开启事务(multi)

​ 命令入队:命令添加进来不会立即执行,添加到一个队列

​ 执行事务(exec):执行exec命令时,才会将队列中多条命令依次执行,执行一个事务中多条命令时,其他客户端会被隔离,不会交替执行。

​ 放弃事务(discard)

主从复制

集群架构;

主从(主机和从机)复制是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。

为什么用集群?

如果只有一台redis服务,万一服务宕机,所有请求就会到达mysql,使mysql宕机。

主从复制的作用

1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

2.故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。

3.负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。

4.高可用(集群)基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是 Redis 高可用的基础。

哨兵机制

哨兵是一个独立的进程,作为进程,它会独立运行。

哨兵的作用是对集群中的多台服务进行监听,给每个服务发请求,如果没有响应,则表明出现故障,例如主机宕机,会在从机中选一台当做主机,原来的主机恢复后,又可以继续当做主机。

在这里插入图片描述

key过期策略

为key设置过到期时间,那么时间到了之后,redis如何处理过期的key?

1.立即删除(主动):到期立即执行回调函数,立即释放内存,但对redis性能有影响。立即删除能保证内存中数据的最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对 cpu 是最不友好的。因为删除操作会占用 cpu的时间。

2.惰性删除(被动):到期之后不会立即删除,到下次使用该键的时候,根据状态(设置时会记录,来决定是删除还是继续使用),缺点是浪费内存。

3.定期删除(主动):每隔一段时间对所有到期的key进行删除。每隔一段时间执行一次删除操作,并通过限制删除操作执行的时长和频率,来减少删除操作对 cpu 的影响。另一方面定时删除也有效的减少了因惰性删除带来的内存浪费。

redis 使用的过期键值删除策略是:惰性删除加上定期删除,两者配合使用。

缓存穿透、缓存击穿、缓存雪崩

缓存处理流程

前台发起请求,后台先从缓存中获取数据,获取到直接返回结果;

获取不到时从数据库中获取,数据库获取到更新缓存,并返回结果;

数据库也没获取到,那直接返回空结果。

缓存穿透

数据库没有,缓存没有。

所查询的数据在数据库中不存在,查询后也未在缓存中存,每次去访问数据库,则会导致数据库崩溃。

解决办法:

​ 1.将空对象设置到缓存里。下次再请求的时候,就可以从缓存里边获取。这种情况我们一般会将空对象设置一个较短的过期时间。

​ 2.对参数进行校验,对不合法的参数进行拦截。

缓存击穿

数据库中有数据,但某个热点key在某时间节点过期了,大量查询请求到达(查询是不加锁的),缓存过期,一起向数据库发起请求,导致数据库崩溃。

解决办法:

​ 1.设置热点key的时间,计算好何时过期合理。

​ 2.查询缓存没有后,访问数据库时加锁。(多个线程同时去查询数据库的这条数据,可以在第一个查询数据的请求上使用一个互斥锁来锁住它,其他的线程走到这一步拿不到锁就等待,等第一个线程查询到了数据,然后将数据放到 redis 缓存起来。后面的线程进来发现已经有缓存了,就直接走缓存)

缓存雪崩

大量热点key过期或redis宕机,导致大量请求到达数据库。

解决办法:

​ 1.随机设置有效时间,避免同时失效。

​ 2.把不同的热点key放在不同的redis服务上(集群)。

​ 3.设置较长的过期时间。

​ 4.在java中设置定时任务,去检查key是否过期。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值