java面试 - redis


redis数据类型

string,list,set,zset,hash

redis为什么这么快1.基于内存

2.数据结构简单
3.单线程
4.多路复用的IO,使用非阻塞式的IO

redis持久化

RDB和AOF方式
RDB: 每天定时全量复制,优点是恢复速度比AOF快,缺点是没办法做到实时的持久化。
AOF:每次操作都以日志的方式记录到文件,优点是持久化快,兼容性好,缺点是文件大,恢复速度慢,影响性能


redis分布式锁原理

先拿setnx来争抢锁,再用expire给锁加一个过期时间用来释放锁

redis内存淘汰策略

redis内存淘汰策略是指redis用于缓存是内存不足,怎么处理需要写入且需要申请额外空间的数据
分两种方式处理全局的键
全局键选择性移除:内存不足时新写入的操作会报错,内存不足时移除使用率较少的key,内存不足是随机删除key
设置过期时间的键选择性移除:内存不足时移除最近使用最少的key,内存不足时随机移除key,内存不足时移除时间较早的key


redis集群方式

主从模式,哨兵模式和集群模式
主从模式:部署的时候”一主多从“,主服务器负责写并将数据复制到其它从节点,从节点复制读
哨兵模式:通过哨兵监控redis实例,如果发现master挂掉了就会选择slave顶上,如果发现某个slave宕机哨兵就会通知管理员
集群模式:多台实例部署时相互指向双方


redis缓存雪崩,缓存穿透,缓存击穿

雪崩:是指缓存同一时间大面积的失效,导致后续请求落到数据库造成数据库处理大量请求而奔溃。
解决方案:缓存数据的过期时间设置随机数避免同一时间大量数据过期
穿透:是指缓存和数据库中都没有数据,导致后续请求落到数据库造成数据库处理大量请求而奔溃。
解决方案:请求层增加数据校验,设置空的数据,使用布隆过滤器
击穿:是指某一个key在缓存中没有,和雪崩的区别是雪崩是大量的key不存在,击穿是某一个key不存在
解决方案:设置热点数据永不过期,加互斥锁

redis缓存数据和数据库数据不一致问题

什么情况下会产生缓存数据不一致问题:
1.读数据的时候会自动把数据库的数据写到缓存,因此不会产生不一致
2.更新数据时数据库更新了,删除缓存失败了
3.删除数据时,删除缓存失败

解决办法:

1.延迟双删:先删除缓存,再更新数据库,当更新数据后休眠一段时间再删除一次缓存。

        实现方案:

        ①:项目整合quartz等定时任务框架,去实现延时3–5s再去执行最后一步任务 。(推荐使用)
        ②:创建线程池,线程池中拿一个线程,线程体中延时3-5s再去执行最后一步任务(不能忘了启动线程)

2.异步更新缓存(基于订阅binlog的同步机制)

        热数据基本都在Redis写MySQL,增删改都是操作MySQL更新Redis数据:MySQ的数据操作binlog,来更新到Redis:

        实现方案:

        ①:数据操作主要分为两大块:一个是全量(将全部数据一次写入到redis)一个是增量(实时更新)。这里说的是增量,指的是mysql的update、insert、delate变更数据。
        ②:读取binlog后分析 ,利用消息队列,推送更新各台的redis缓存数据。

分布式锁的特点:

1.互斥性:在任意时刻只能有一个进程有锁
2.放死锁:即使一个进程持有锁期间奔溃,要有其它方式释放锁
3.加锁和解锁必须是同一个进程


redisson分布式锁原理

1.加锁机制,线程去获取锁如果获取成功就会执行lua脚本保存数据到redis中,如果获取失败则会一直去舱室获取
2.watch dog自动延期机制:某个线程执行时间超过了设置的过期时间时后台就会启动一个watch dog线程不断的延长锁key的时间

redis锁的数据类型是Hash类型,key的值包含了当前线程信息


缺点:客户端对master节点加锁时如果此时master宕机了,会选取新的master节点,若此时再来一个线程是可以再次加锁的
这就出现了多个客户端对同一个分布式锁进行了加锁,就会产生脏数据

Redis跳表

跳表是在双向链表之上加多层索引构成,相对于双向链表支持快速查找,更新,删除。在查找某一个数据时,先在索引里面查找出一个大范围,然后再下降到原始链表中精确查找,因为加上一层索引后查找一个节点需要遍历的次数减少了,所以查找效率大大提升。
有点像hashMap,在jdk1.7下hashMap底层也是数组 + 链表。


跳表主要应用在Redis中实现有序集合(ZSet)


redis跳表为什么不用B+数?
因为B+数叶子节点保存索引和数据,非叶子节点保存索引值,每次读取磁盘就会读取一整个节点,没个叶子节点还有指向、前后节点的指针,为的是降低磁盘的IO。
然后redis是基于内存读取数据,不涉及IO,从内存中读取数据耗费时间是从磁盘中IO读取的百万分之一,因此使用跳表利用空间换时间的方式,实现简单,且能提高查询效率。

redis使用场景

1.作为队列使用,(因为是基于内存、一般不会作为消费队列、作为循环队列必要适用。
2.模拟类似于token这种需要设置过期时间的场景,登录失效。
3.分布式缓存,避免大量请求底层关系型数据库,大大降低数据库压力。
4.分布式锁;基于 bitmap 实现布隆过滤器。
5.排行榜-基于zset(有序集合数据类型)。
6.计数器-对于浏览量、播放量等并发较高,使用 redis incr 实现计数器功能。
7.分布式会话;消息系统。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值