面试—Redis

目录

对Redis的了解

Redis的数据类型

Redis的事务

Redis的事务冲突

Redis的持久化

Redis主从复制

三大招式

哨兵模式

集群

缓存问题

缓存穿透

缓存击穿

缓存雪崩

分布式锁


对Redis的了解

  • Redis是非关系型数据库,不依赖业务逻辑存储,以简单的key---value形式存储,基于内存存储

  • Redis采用单线程+多路IO复用技术

    • Redis采用单线程模式,无需进行线程切换,减少消耗一定的CPU时间和内存资源,处理请求更加高效

    • Redis主要是基于内存,单线程可以更好的利用CPU缓存。由于数据的访问和操作具有局部性,利用CPU缓存能提高内存访问速度

    • 多路IO复用技术可以同时监听多个连接,当一个连接准备就绪时,就可以进行相应的操作

    • Redis在等待IO操作的过程中,将CPU资源用于执行其他任务 ,如数据处理和存储,充分利用资源

    • 实现非阻塞IO ,当一个客户端的IO操作不可用时,Redis可以立即切换其他就绪的连接进行操作

Redis的数据类型

  1. 字符串(String)

    • Redis最基本的数据类型,一个Key对应一个Value
  2. 列表(List)

    • 单键多值,底层是一个双向链表

    • 对两端的操作性能高,中间查询性能低

  3. 集合(Set)

    • 与List相似,多一个自动排重的功能

    • 是一个无序集合,存储不重复元素

  4. 哈希(Hash)

    • 是一个string类型的fieldvalue的映射表

    • 适合存储对象,类似Java里的Map<String,Object>

  5. 有序集合(Zset)

    • sorted ser 与set相似,是没有重复元素的字符串集合

    • 每一个成员都关联了一个评分,评分用来排序

  6. Bitmaps

    • 本身是一个字符串类型,但是可以实现位操作

    • 可以把Bitmaps当作一个数组,每个元素只能存储0和1 ,数组的下标称为偏移量

    • 主要存储活跃用户,如某一时间段访问网址的用户,将用户id作为偏移量

  7. HyperLogLog

    • 用来做基数统计的数据结构,统计不重复元素

    • 可以去重,添加时相同的元素,无法添加

  8. Geospatital

    • 提供经纬度设置、查询、范围查询、距离查询、经纬度Hash等

Redis的事务

  • Redis事务是一个单独的隔离操作,所有的命令被序列化,按顺序执行

  • 事务主要分为两个部分

    • 组队阶段

      输入Milit命令开始组队阶段,将命令依次放入组队队列里面

    • 执行阶段

      输入Exec命令开始执行组队队列里面的代码

    • 在组队结束后可以输入discard放弃组队

  • 在组队阶段,如果命令出现错误,整个队列里面的命令全部都不会被执行

  • 在执行阶段,命令出现错误,只有出现错误的命令不会执行,不影响其他命令执行

Redis的事务冲突

  • 由于事务的单独隔离操作,当其他客户端发送请求后,会导致对同一个键值对进行操作,导致结果不同

  • 这时采用锁机制进行预防

  1. 悲观锁

    当一个客户端拿到数据后就会进行上锁,直到锁释放才会被其他客户端操作 效率较低

  2. 乐观锁

    采用版本号机制,每次拿到数据后会进行判断,判断别的客户端是否修改过版本(是否为数据进行过修改)

  • Redis中如果两个事务同时要对一个key进行操作,在组队阶段会先拿到键的版本号,当一个事务进入执行阶段执行后,另一个事务会在执行之前对键进行版本号校验,版本不同,事务就会被终止

Redis的持久化

  • 将内存中的数据写入到磁盘,就是持久化
  1. RDB

    在一定的时间间隔内,将内存中的数据集快照写入磁盘

    过程(写时复制技术

    1. 先复制创建一个**子线程(Fork)**来进行持久化

    2. 将数据写入到一个临时文件中

    3. 等持久化的过程结束,将临时文件替换会持久化文件

      • 由于直接创建持久化文件,当进程断开的时候,数据会丢失

      • 缺点:最后一次持久化的数据可能会丢失

        在durmp.rdb配置文件中,save 20 3意味着在20秒内当3个key发生变化时,进行持久化

  2. AOF

    AOF是以日志的形式记录写操作(增删改),将Redis执行过程中的指令记录下来,当Redis重启会重构数据

    过程

    1. 客户端的命令会被append追加到AOF的缓存区

    2. AOF缓存区会根据持久化策略(每次操作都立即写入日志、每隔一秒同步一次、不主动同步,由操作系统同步)将操作同步到磁盘中的appendonly.aof文件中

    3. AOF根据文件大小执行重写策略(文件大于64M的100%---128M)的时候,用写时复制技术将文件的指令进行压缩

    4. 当Redis重启时,会加载文件重构数据

  3. 备份

    先将.rdb和.aof配置文件复制下来,当Redis重启时会自动加载配置文件,以达到备份的功能

    当RDB和AOF同时开启,默认读取的是AOF的数据

Redis主从复制

  • Redis主从复制是将一台Redis服务器的数据复制到其他Redis服务器

  • 主服务器用来实现写的功能,从服务器实现读的功能,提高系统的并发性能

  • 当主服务器故障时,从服务器可以升级为主服务器,不会操作系统停滞

原理

  1. 当从服务器连接上主服务器后,会主动发送数据同步的消息

  2. 主服务器收到消息后,进行数据持久化,并将RDB文件发送给从服务器

  3. 从服务器收到RDB文件后进行读取,实现数据同步

  4. 当主服务器写的时候,会主动的和从服务器进行数据同步

三大招式

  1. 一主两仆

    • 当从服务器断开后,重写连接会变成单独的主服务器

    • 当主服务器断开后,从服务器不会篡位

  2. 新火相传

    • 从服务器可以组为主服务器(小组长),下面挂多个从服务器

    • 当主服务器断开后,依旧遵循一主两仆,不会篡位

    • 缺点:小组长从服务器断开后,下面的数据不会同步

  3. 反客为主

    • 当主服务器断开后,从服务器会晋升为主服务器

哨兵模式

  • 哨兵模式主要是检测Redis主从服务器的故障,当主服务器发送故障时,自动将从服务器升为主服务器,确保Redis服务的运行
  1. 配置sentinel.config文件,启动哨兵

  2. 哨兵会不断监控主从服务器的运行状态,包括时候在线、是否正常同步等

  3. 哨兵会定期的向主从服务器发送PING命令,如果主服务器在一定时间内没有响应,则认为出现故障

  4. 当检测主服务器故障时,会在从服务器中选择一个合适的服务器作为新的主服务器

  5. 哨兵会向其他服务器发送命令,让新的主服务器与其他服务器同步

  6. 最后将旧的主服务器重新配置为从服务器

  • 选举规则

    1. 优先级靠前的

      在redis.conf中默认配置:slave-priority 100 / replica-priority 100(值越小优先级越高)

    2. 偏移量大的

      与主句数据同步值最高的

    3. runid最小的从服务器

      Redis启动后自动生成的40位的runid

集群

  • Redis集群就是对Redis的水平扩容,将数据分布存储在多个节点上

  • 一个集群至少要有三个主节点

  • 无中心化集群:任何一个节点都可以作为集群的入口,各个节点之间是相互连通的

  1. 客户端可以连接到集群的任意一个节点上

  2. 当执行命令时,会根据键的哈希值对 16384 取模计算出槽位

  3. 每个节点都负责自己范围的键的存储和查询操作

缓存问题

缓存穿透

  • 主要是服务器被恶意攻击,大量的url访问服务器

解决方案

  1. 对空值缓存,如果查询数据库返回的时空值,对这个数据也存入缓存中,避免这个url一直访问服务器

  2. 设置白名单,利用Bitmaps类型作一个可访问名单,id作为偏移量,每次访问的时候与Bitmaps中的值进行比较(1表示用户访问过,无需在对服务器进行查询)

  3. 实时监控,当Redis命中率开始急速下降时,排查访问对象和访问数据,与运维人员配合处理

缓存击穿

  • 主要是某个时间段内的热点新闻

  • 在一点时间内,某一个key过期了,但是由大量返回去查询这个键,这是会去服务器中查询

  • 数据库无法将数据存入缓存中,造成击穿

解决方案

  1. 预先设置热门数据,增加key的过期时间

  2. 实时调整,及时的监控热门数据,增加过期时间

  3. 使用锁机制

缓存雪崩

  • 在某个时间内,大量的key过期,一直去数据库中查找,导致服务器奔溃

解决方案:

  1. 构建多级缓存架构

  2. 使用锁或队列,保证不会有大量的线程对数据库进行读写操作

    缺点:不适合高并发

  3. 设置过期标志更新缓存,记录缓存数据是否过期,如果快过期就会触发通知,让其他线程进行更新

  4. 将缓存失效时间分散开,在失效时间设置随机数,保证不会有大量ket同时失效

分布式锁

  • 对服务器加锁,加锁后,这个集群中的服务器都得加这个锁

  • 锁的四个条件

  1. 互斥性,在任意时间,只有一个客户端持有锁

  2. 不会发送死锁

    设置锁的过期时间,确保服务器断开后锁一直不被释放的问题

  3. 加锁和解锁必须是同一个客户端

    设置uuid,避免a服务器在执行过程中锁过期自动释放后,a服务器执行完释放锁,造成正在使用这个锁的b服务器被释放

  4. 原子性

    使用LUA脚本,确保在服务器执行操作的过程中别的客户端干扰

相关推荐
IT大白鼠2 天前
Redis 系列 · 第 01 篇——认知入门:Redis 是什么
redis·nosql
彧azz2 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
lbb 小魔仙2 天前
OpenClaw + cpolar 实战:远程 NAS、分享小游戏、RDP,再配置公网 AI 入口
数据库·人工智能·redis·oracle·prometheus
夕除2 天前
redis--018
redis
两锭子2 天前
Redis基础
redis
烟沙九洲2 天前
Redis 缓存穿透、缓存击穿、缓存雪崩
数据库·redis
字节探索2 天前
Redis 只会当缓存用?这 10 大实战场景,让你的系统快到飞起
redis·后端
于樱花森上飞舞2 天前
【Redis】哨兵详解
java·开发语言·数据库·redis
Rain的Java大神之路2 天前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog2 天前
Java 接入Redis: 通用命令与键管理
java·服务器·redis