清除redis缓存命令_Redis面试必备(十)

fa0e9e687d551baf48bb4c7cef6af93c.png

33ef1c8008ec142a2552e342fbe716cd.gif

Redis

Redis数据类型

  • String:key-value
  • list:有序列表
  • set:无序列表并且去重
  • zset:有序列表去重
  • hash:哈希表接口

Redis键过期时间

Redis是存储在内存中的,我们内存空间是有限的,所以我们需要定时的去清理Redis数据,这个时候就用到了Redis过期时间清除

过期策略

根据上面所讲的我们知道当redis过期的是会删除,但是什么时候删除呢?redis有三种过期策略

  • 定时删除:到时间就把所有过期键进行删除
  • 惰性删除:每次从键空间取键的时候都会判断一下该键是否过期,如果过期则删除
  • 定期删除:每隔一段时间就去删除过期键


Redis默认是采用惰性删除和定期删除两种策略,所以当redis键过期的时候不会立刻去删除。

内存淘汰策略

刚刚我们说redis使用惰性删除和定期删除,所以当使用惰性删除的时候,其实我们有很多过期数据是没有被删除的,停留在Redis内存中,这样也会导致Redis内存耗尽,所以我们制定了内存淘汰策略,但是redis内存不够的时候触发内存淘汰策略,总共有6种内存淘汰策略

  • lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
  • ttl:从已设置过期时间的数据集中挑选将要过期的数据进行淘汰
  • random:从已设置过期时间的数据集中随机挑选数据进行淘汰
  • allkeys-lru:从所有数据集中挑选最近最少使用的数据淘汰,当为了提供缓冲命中率可以使用、
  • allkeys-random:从所有数据集中挑选任意数据
  • noeviction:禁止驱逐数据

Redis持久化

由于Redis是基于内存的,所以为了保证数据不丢失,Redis的数据必须保留在硬盘上,Redis保留数据在硬盘上有两种方式:1AOF:当Redis执行写命令的时候会把数据写到AOF文件中,2 RDB:基于快照,将某一时刻的数据快照保存到RDB文件中

  • RDB

RDB文件触发保存有两种方式,1 SAVE命令,这个命令会阻塞Redis服务进程,2BGSAVe命令,这个命令不会阻塞,是因为他创建子进程去创建RDB文件,Redis服务器可以继续接受请求。

  • AOF

aof是通过保存写命令来记录到数据库中。1 首先命令会写入aof_buf缓冲区中 2 缓冲区中的文件写入到AOF文件中3文件同步内存缓冲区数据写入到硬盘
aof还有一个重要概念是AOF重写,指的是多条指令可以合并成一条指令,这样还节约了空间,aof文件体积也变小了

RDB和AOF优缺点

RDB载入数据非常快,到时容易丢失数据
AOF丢失数据非常少,恢复数据比较慢,因为文件体积比较大。

为什么Redis是单线程却这么快

  • 利用IO多路复用优点:操作系统为你提供了一个功能,当你的某个socket可读或者可写的时候,它可以给你一个通知。这样当配合非阻塞的socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据而不做纯返回-1和EAGAIN的无用功,多路指的是多个socket,复用指的是一个线程
  • 内存操作
  • 避免多线程频繁的上下文切换

Redis主从架构

主从架构的优点

  • 主服务器负责接收写请求
  • 从服务器负责接收读请求
  • 提高并发量
  • 高可用,主挂了还有从接收请求。

主从如何保证数据一致

既然设置了主从,那么一定要保证数据的一致性,避免出现脏数据,在Redis中可以通过命令SALVEOF命令,复制有两部操作,1同步,2命令传播

主服务挂了

主服务器是接收写请求的,Redis提供了哨兵机制,如果主服务器挂了则把从服务器升为主服务器
哨兵工作

  • 检测服务器状况
  • redis有故障发送给管理员
  • 主服务器挂了,则从服务器升级为主
  • 提供当前主服务器配置信息

如何判断主服务挂了

  • 1 主观下线:哨兵会每秒主动给各个服务发送ping命令,如果ping命令判断是否下线
  • 2 客观下线:如果其中一个哨兵发现主服务挂了,则会通知其他哨兵,如果一半以上的哨兵都ping不通则进行故障转移操作。

Redis缓存雪崩

  • 1 加入所有缓存都过期失效了
  • 2 加入缓存挂掉了


以上两种情况可能导致所有所有请求都跑到我们MySQL数据中执行,如果大量的请求打数据库压力会非常大,可能造成极端情况,数据库被打垮,导致真个系统崩溃
解决方法:

  • 1 Redis使用主从+哨兵模式提高可用性,高可用
  • 2 本地缓存+限流方式实现
  • 3 恢复数据,利用redis持久化AOF文件,恢复缓存数据

缓存穿透

缓存穿透指的是缓存中没有数据,数据库中也没有数据,所有每次查询都查询的是不存在的数据,缓存失去意义。
解决方法

  • 1 使用过滤器把请求不合法的数据阻挡在外面
  • 2 如果数据库为null则存储到redis中,这样避免每次都走数据库

缓存与数据库不一致

读数据


在读数据的时候,首先会判断缓存中是否存在,如果存在则直接使用,如果不存在则去数据库中读取,然后存储到Redis缓存中

修改数据流程

  • 先删除缓存再更新数据库
  1. 线程A删除缓存
  2. 线程B发现缓存为空,数据库旧值
  3. 线程A更新数据
  4. 线程B把旧值更新到redis

这个时候缓存与数据库就不一致了,通过分布式锁来解决这个问题。

  • 先更新库在删除缓存
  1. 缓存失效
  2. 线程AB读取缓存
  3. 先A把数据写入数据,在删除Redis缓存
  4. 先B把旧数据写入缓存

这种几率一般不高,缓存要同时失效

  • mysql的binlog日志更新到redis中
    推荐使用最后一种方法。

Redis有哪些适合的场景

  • session共享
  • 队列
  • 排行榜
  • 发布/订阅

Redis锁

  • setnx
  • redlock
  • redisson

setnx

setnx表示当获取key的时候不存在则赋值,返回1,存在则返回0

  • 进程Asetnx发现没有数据则获取锁
  • 线程Bsetnx发现有数据则阻塞等待
  • 进程A执行完,则del锁
  • 进程B获取锁执行


以上是正常情况,下面描述的是不正常的情况

  • 问题1

假如进程A获取锁不释放则会一直持有锁,导致进程B获取不到锁,所以需要设置超时时间,但超时超时时间则释放错,避免死锁现象

  • 问题2

假如进程A设置了超时时间并且执行时间超过超时时间,这样就会导致,当进程A超过超时超时间,另一个进程会获取锁,等线程A执行完之后执行finally删除锁的时候,删除的是另一个进程,另一个进程过来则获取锁
Redis有一个GetSet  命令,表示赋值之后,把旧值返回。

  • A获取锁,之后超时
  • BC读取发现A超时,B检测到A超时,比较当前时间和redis中的时间发现超时
  • B执行GetSet命令设置时间戳,通过比较旧值是否小于当前时间,判断进程是否获取锁,这时候B已经获取锁
  • C执行GetSet命令发现时间大于当前时间,则等待。

所以在释放锁的时候,需要判断锁是否过期,如果过期是否会删除其他线程的锁。

5bbe5e1f620eb989a5409587837cca32.png                                                     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值