JAVA面试实战-xx云(1.redis篇)

背景

今天去xx云面试,回答的不是很好,不过感觉问的很好,这里我分为几次记录下来,每天进步亿点点

实战面试题(redis篇)
  1. redis如何保证所有数据都是热点数据?

redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略

  • voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  • allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  • no-enviction(驱逐):禁止驱逐数据
  1. redis常见的性能问题有哪些?
  1. Master写内存快照(RDB),save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能的影响非常大,会间断性暂停服务,所以Master最好不要写内存快照
  2. Master AOF 持久化,如果不重写AOF文件,那么这个方式对性能影响是很小的,但是AOF不断增大,AOF文件过大会影响Master的重启恢复速度。Master最好不要做任何持久化的工作,包括RDB和AOF。如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次
  3. Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内
  1. redis中有1000W数据,其中有20W是以 XX_ 开头的,如何获取到它们?
  1. 可以通过keys pattern来获取,如:keys* xx_

    image-20200729092412978.png

    不过这种方式是以停止insert为代价的,所以在生产环境中不能使用

  2. 通过scan cursor [MATCH pattern] [COUNT count] [TYPE type]来获取,如:scan 0 match xx_* count 5

    image-20200729103912395.png

    其中:

    1. scan是基于游标的迭代器,执行scan后会返回下一次的游标
    2. 0表示开始一次新的迭代
    3. 3表示返回的数量,但是查询出的结果却不可控,只是大概率符合count参数
    4. 返回结果不保证与之前的数据不重复,需要在客户端自行去重
  1. 分布式锁如何用redis实现?有什么问题吗?

实现思路:redis分布式锁实现是基于命令setnx key value,意思是:若该键不存在则创建键,这就保证了redis中该键的唯一性,所以在多个线程同时执行该命令时,谁执行成功了,谁就获取了锁;然后业务逻辑执行完毕则需要使用del key删除键,表示释放锁;
问题1:如果一个线程逻辑执行完毕,程序出现异常,则锁会一直存在,没有得到释放,其它应用就会无法获得锁,此时就会造成死锁
改进方式:拿到锁之后,给锁加上一个过期时间,也就是 expire key seconds 指令;此时避免了死锁问题,但是由于业务逻辑执行的时间不同,过期的时间设置也是一个问题,故通常分布式锁不能应用于业务逻辑执行较长的程序
问题2:由于redis 每条指令都是原子性操作,但由于setnx 和 expire 是2两条指令,如果在执行setnx后程序出现问题expire指令未得到执行就会造成死锁问题;
改进方式:redis2.8版本之后引入了指令 set key value [EX seconds] [PX milliseconds] [NX|XX],该指令可以同时执行 setnx 和 expire ,于是解决了死锁问题;
问题3
①线程1获取锁,直到锁超时都未能执行完代码并释放锁。② 线程2此时获取到锁。 ③ 线程1执行完毕,释放了线程2持有的锁,出现问题
处理思路
setnx的时候,同一把锁key必须为同名,但是value可以设置为uuid,这样可以保证谁去获取的锁,只能由自己释放;
接上一个问题
4、此时线程3来了,轻松地获取到了锁,那么这时出现了多个线程并发操作,锁失效
处理思路
究其出现的根本原因,是业务执行时间超过了redis中key的失效时间,我们可以通过给获得锁的线程开启一个守护线程,用来给快要过期的锁“续航”
其实这个锁最大的缺点就是它加锁时只作用在一个Redis节点上,即使Redis通过sentinel保证高可用,如果这个master节点由于某些原因发生了主从切换,那么就会出现锁丢失的情况;所以这个时候就要考虑用RedLock——一个作用与多个节点的锁

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值