一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 这篇文章是关于Java面试中可能会遇到的五个问题,包括MySQL索引类型及其对数据库性能的影响、Redis的RDB和AOF持久化机制、Redis的过期键删除策略、Redis的单线程模型为何高效,以及缓存雪崩、缓存穿透和缓存击穿的概念及其解决方案。

这里是参考B站上的大佬做的面试题笔记。大家也可以去看视频讲解!!!

文章目录

  • 1、简述MySQL中索引类型对数据库的性能的影响
  • 2、RDB和AOF机制
  • 3、Redis的过期键的删除策略
  • 4、Redis线程模型,单线程为什么这么快
  • 5、缓存雪崩、缓存穿透、缓存击穿

1、简述MySQL中索引类型对数据库的性能的影响

  • 普通索引:允许被索引的数据列包含重复的数据

  • 唯一索引:可以保证数据记录的唯一性

  • 主键:是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字primary key来创建。

  • 联合索引:索引可以覆盖多个数据列,如像INDEX(columnA,columnB)索引。

  • 全文索引:通过建立倒排索引,可以极大的提升检索效率,解决判断字段是否包含的问题,是目前搜索引擎使用的一种关键技术。可以通过ALTER TABLE table_name ADD FULLTEXT(column);创建全文索引

优点:

  • 索引可以极大的提高数据的查询速度。

  • 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

缺点:

  • 但是会减低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件
  • 索引需要占用物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大,如果非聚簇索引很多,一旦聚簇索引改变,那么所有非聚集索引都会跟着变。

2、RDB和AOF机制

RDB:Redis DataBase

在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程就是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

优点:

  • 1、整个Redis数据库只包含一个文件dump.rdb,方便持久化
  • 2、容灾性好,方便备份
  • 3、性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能。
  • 4、相对于数据集大时,比AOF的启动效率更高

缺点:

  • 1、数据安全性低。RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)
  • 2、由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是一秒钟。

AOF:Append Only File

以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

优点

  • 1、数据安全,Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统发生宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立刻记录到磁盘中。
  • 2、通过append模式写文件,即使中途服务器宕机也不会破坏已经存在的内容,可以通过redis-check-aof工具解决数据一致性问题。
  • AOF机制的rewrite模式。定期对AOF文件进行重写,以达到压缩的目的。

缺点

  • 1、AOF文件比RDB文件大,且恢复速度慢
  • 2、数据集大的时候,比rdb启动效率低
  • 3、运行效率没有RDB高

AOF文件比RDB更新频率高,优先使用AOF还原数据
AOF比RDB更安全也更大
RDB性能比AOF好
如果两个都配置了优先加载AOF

3、Redis的过期键的删除策略

Redis是key-value数据库,我们可以设置Redis中缓存的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理。

  • 惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况肯可能出现大量的过期key没有被访问,从而不会被清除,占用大量内存
  • 定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是改键的毫秒精度的UNIX时间戳表示过期的时间。键空间是指该Redis集群中保存的所有的键。)

Redis中同时使用了惰性过期和定期过期两种过期策略。

4、Redis线程模型,单线程为什么这么快

Redis基于Reactor模式开发了网路事件处理器,这个处理器叫做文件事件处理器 file event handler。这个文件事件处理器,它是单线程的,所以Redis才叫做单线程的模型,它采用IO多路复用机制来同时监听多个Socket,根据Socket上的事件类型来选择对应的事件处理器来处理这个事件。可以实现高性能网络通信模型,又可以跟内部其他单线程的模块进行对接,保证了Redis内部的线程模型的简单性。

文件事件处理器的结构包含4个部分:多个Socket、IO多路复用程序、文件事件分配器以及事件处理器(命令请求处理器、命令回复处理器、连接应答处理器等)。
多个Socket可能并发的产生不同的操作,每个操作对应不同的文件事件,但是IO多路复用程序会监听多个Socket,会将Socket放入一个队列中排队,每次从队列中取出一个Socket给事件分派器,事件分派器把Socket给对应的事件处理器。
然后一个Socket的事件处理完之后,IO多路复用程序会将队列中的下一个Socket给事件分派器。文件事件分派器会根据每个Socket当前产生的事件,来选择对应的事件处理器来处理。

单线程快的原因:

  • 1、纯内存操作
  • 2、核心是基于非阻塞的IO多路复用机制
  • 3、单线程反而避免了多线程的频繁上下文切换带来的性能问题

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

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

缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方案:

  • 1、缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  • 2、给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存标记失效,则更新数据缓存
  • 3、缓存预热
  • 4、互斥锁

缓存穿透是指缓存和数据库中都没有的数据,会导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决方法:

  • 1、接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  • 2、从缓存取不到数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样就可以防止攻击用户反复用同一个id暴力攻击
  • 3、采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩式不同数据都过期了,很多数据都查不到从而查数据库。

解决方法:

  • 设置热点数据永远不过期
  • 加互斥锁
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
12月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
10月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
257 4
|
9月前
|
安全 Java 编译器
Java类型提升与类型转换详解
本文详解Java中的类型提升与类型转换机制,涵盖类型提升规则、自动类型转换(隐式转换)和强制类型转换(显式转换)的使用场景与注意事项。内容包括类型提升在表达式运算中的作用、自动转换的类型兼容性规则,以及强制转换可能引发的数据丢失和运行时错误。同时提供多个代码示例,帮助理解byte、short、char等类型在运算时的自动提升行为,以及浮点数和整型之间的转换技巧。最后总结了类型转换的最佳实践,如避免不必要的转换、使用显式转换提高可读性、金融计算中使用BigDecimal等,帮助开发者写出更安全、高效的Java代码。
492 0
|
9月前
|
安全 IDE Java
Java记录类型(Record):简化数据载体类
Java记录类型(Record):简化数据载体类
616 143
|
9月前
|
Java 测试技术
Java浮点类型详解:使用与区别
Java中的浮点类型主要包括float和double,它们在内存占用、精度范围和使用场景上有显著差异。float占用4字节,提供约6-7位有效数字;double占用8字节,提供约15-16位有效数字。float适合内存敏感或精度要求不高的场景,而double精度更高,是Java默认的浮点类型,推荐在大多数情况下使用。两者都存在精度限制,不能用于需要精确计算的金融领域。比较浮点数时应使用误差范围或BigDecimal类。科学计算和工程计算通常使用double,而金融计算应使用BigDecimal。
3279 102
|
10月前
|
缓存 数据库连接 数据库
缓存三剑客(穿透、击穿、雪崩)
缓存穿透指查询数据库和缓存中都不存在的数据,导致请求直接冲击数据库。解决方案包括缓存空对象和布隆过滤器。缓存击穿是大量请求访问同一个失效的热点数据,使数据库瞬间压力剧增,解决方法有提前预热、设置永不过期、加锁限流等。缓存雪崩是大量key同时失效,导致所有请求直达数据库,可通过引入随机过期时间缓解。三者分别对应单点爆破、全面崩塌等问题,需根据场景选择合适策略优化系统性能与稳定性。
532 0
|
7月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
198 7
|
8月前
|
Java 开发者
Java 函数式编程全解析:静态方法引用、实例方法引用、特定类型方法引用与构造器引用实战教程
本文介绍Java 8函数式编程中的四种方法引用:静态、实例、特定类型及构造器引用,通过简洁示例演示其用法,帮助开发者提升代码可读性与简洁性。
|
9月前
|
安全 算法 Java
Java泛型编程:类型安全与擦除机制
Java泛型详解:从基础语法到类型擦除机制,深入解析通配符与PECS原则,探讨运行时类型获取技巧及最佳实践,助你掌握泛型精髓,写出更安全、灵活的代码。
|
10月前
|
缓存 数据库
如何解决缓存穿透?
对请求增加校验机制,如ID格式和位数校验,避免无效请求;缓存空值或特殊值防止缓存穿透;使用布隆过滤器拦截不存在的请求,减轻数据库压力。
185 0

推荐镜像

更多