Redis相关面试题_2024 Java面试题

一、什么是缓存穿透 ? 怎么解决 ?
缓存穿透是指,在高并发场景下,请求的数据在缓存中不存在,并且对应的数据在数据库中也不存在,导致大量请求直接穿透到数据库,从而引起数据库压力过大,甚至导致宕机的情况。缓存穿透问题不仅会影响系统性能,还可能导致数据不一致的问题。常见的缓存穿透问题场景包括:

  • 查询一个不存在的 key。
  • 查询一个已经被删除的 key。
  • 查询一个非法的 key,比如包含特殊字符、长度超出限制等。

为了避免缓存穿透问题,通常有以下几种解决方法:

  1. 布隆过滤器

布隆过滤器是一种数据结构,可以高效地检测一个元素是否存在于集合中。在缓存中使用布隆过滤器,可以在缓存命中之前先对请求参数进行过滤,如果请求参数被布隆过滤器拦截,则直接返回,不再进行后续的缓存和数据库查询操作,从而避免缓存穿透问题。

  1. 缓存空对象

在缓存中,对于不存在的数据,可以将其对应的 key 和一个空对象一起存入缓存中,这样在下一次查询时,如果缓存中存在这个 key,就直接返回空对象,避免了对数据库的查询操作。

  1. 数据预热

数据预热是指在系统启动时,预先将一些热门数据加载到缓存中。这样,在系统运行时,这些数据已经存在于缓存中,可以直接从缓存中获取,避免了对数据库的查询操作。

  1. 限流

限流是指在高并发场景下,控制请求的流量,避免大量的请求同时涌入系统,导致系统崩溃。常见的限流策略包括:漏桶算法、令牌桶算法等。通过限流,可以避免缓存穿透问题。

需要注意的是,在实际应用中,不同的场景和业务需求,可能需要选择不同的解决方案来避免缓存穿透问题,同时还需要考虑缓存的一致性和可靠性等问题。

二、你能介绍一下布隆过滤器吗?
当需要查询一个元素是否在一个集合中时,通常的做法是使用哈希表或者树等数据结构进行查询。但是,当元素的数量非常大时,这种方法的内存开销会变得非常大。布隆过滤器(Bloom Filter)是一种空间效率高、查询效率快的数据结构,可以用来判断一个元素是否在一个集合中。布隆过滤器的基本思想是,使用多个哈希函数对元素进行哈希,并将哈希值分散存储在一个比特数组中。当查询一个元素是否在集合中时,对该元素进行哈希,然后判断对应的比特数组中的值是否都为 1,如果都为 1,那么该元素很可能在集合中,如果有一个 0,那么该元素一定不在集合中。

布隆过滤器优缺点:

优点:

  1. 空间效率高:布隆过滤器只需要使用一个比特数组即可,不需要存储元素本身,因此空间效率比较高。

  2. 查询效率快:布隆过滤器只需要进行哈希计算和比特数组的查询操作,查询效率非常快。

缺点:

  1. 无法删除元素:由于布隆过滤器使用的是哈希函数和比特数组,无法删除元素。

  2. 有一定的误判率:由于哈希函数的分布和比特数组的大小等因素,布隆过滤器可能存在误判的情况,即判断一个元素在集合中,实际上并不在集合中。

  3. 无法确定一个元素是否在集合中,只能判断一个元素很可能在集合中或者一定不在集合中。

布隆过滤器应用场景:

  1. 垃圾邮件过滤:将已知的垃圾邮件的特征放入布隆过滤器中,当新的邮件到来时,对邮件的内容进行哈希,然后查询是否命中布隆过滤器,如果命中则可判定该邮件为垃圾邮件。

  2. 缓存穿透:在缓存中使用布隆过滤器,可以在缓存命中之前先对请求参数进行过滤,如果请求参数被布隆过滤器拦截,则直接返回,不再进行后续的缓存和数据库查询操作,从而避免缓存穿透问题。

  3. 爬虫重复判定:当爬虫爬取网页时,可以使用布隆过滤器来判断网页是否已经被爬取,如果已经被爬取,则可以直接跳过,避免重复爬取。

需要注意的是,在使用布隆过滤器时,需要对哈希函数的选择和比特数组的大小进行合理的设计,以保证误判率的控制和查询效率的提高。

三、什么是缓存击穿 ? 怎么解决 ?
缓存击穿是指在高并发场景下,一个热点的 key 在缓存中过期或者被删除,导致大量请求直接访问数据库,从而引起数据库压力过大,甚至导致宕机的情况。缓存击穿问题不仅会影响系统性能,还可能导致数据不一致的问题。常见的缓存击穿问题场景包括:

  • 热点数据访问频繁,缓存失效时间比较短。
  • 缓存中的某个 key 被恶意攻击删除。

为了避免缓存击穿问题,通常有以下几种解决方法:

  1. 缓存雪崩

缓存雪崩是指在高并发场景下,缓存中大量的 key 同时失效或者被删除,导致大量请求直接访问数据库,从而引起数据库压力过大,甚至导致宕机的情况。为了避免缓存雪崩问题,可以采用以下几种方法:

  • 将缓存失效时间分散开,避免大量的 key 同时失效。
  • 对于重要的数据,可以采用多级缓存的方式,这样即使一级缓存失效,也可以从二级缓存中获取数据。
  • 对于不同的 key,可以设置不同的过期时间,尽可能的减少缓存同时失效的情况。
  1. 加锁

在热点数据访问频繁的情况下,可以通过加锁的方式来避免缓存击穿问题。在缓存失效的时候,加锁操作可以防止多个请求同时访问数据库,只有一个请求可以访问数据库,其他请求等待,直到请求完成后,释放锁让其他请求继续访问。需要注意的是,加锁操作会降低系统的并发度和性能,因此需要合理地使用。

  1. 数据预热

数据预热是指在系统启动时,预先将一些热门数据加载到缓存中。这样,在系统运行时,这些数据已经存在于缓存中,可以直接从缓存中获取,避免了对数据库的查询操作。

  1. 限流

限流是指在高并发场景下,控制请求的流量,避免大量的请求同时涌入系统,导致系统崩溃。常见的限流策略包括:漏桶算法、令牌桶算法等。通过限流,可以避免缓存击穿问题。

需要注意的是,在实际应用中,不同的场景和业务需求,可能需要选择不同的解决方案来避免缓存击穿问题,同时还需要考虑缓存的一致性和可靠性等问题。

四、什么是缓存雪崩 ? 怎么解决 ?
缓存雪崩是指在高并发场景下,缓存中大量的 key 同时失效或者被删除,导致大量请求直接访问数据库,从而引起数据库压力过大,甚至导致宕机的情况。缓存雪崩问题不仅会影响系统性能,还可能导致数据不一致的问题。常见的缓存雪崩问题场景包括:

  • 缓存中的数据过期时间一致,导致在同一时间大量的 key 同时失效。
  • 缓存中的数据被恶意攻击删除,导致大量的 key 同时失效。

为了避免缓存雪崩问题,可以采用以下几种解决方法:

  1. 将缓存失效时间分散开

将缓存失效时间分散开,避免大量的 key 同时失效。对于相同类型的数据,可以使用不同的过期时间,尽可能的减小缓存雪崩的发生。

  1. 采用多级缓存

对于重要的数据,可以采用多级缓存的方式,这样即使一级缓存失效,也可以从二级缓存中获取数据。多级缓存的方式可以有效地避免缓存雪崩问题。

  1. 数据预热

在系统启动时,预先将一些热门数据加载到缓存中。这样,在系统运行时,这些数据已经存在于缓存中,可以直接从缓存中获取,避免了对数据库的查询操作。数据预热可以有效地避免缓存雪崩问题。

  1. 加锁

在缓存失效的时候,加锁操作可以防止多个请求同时访问数据库,只有一个请求可以访问数据库,其他请求等待,直到请求完成后,释放锁让其他请求继续访问。需要注意的是,加锁操作会降低系统的并发度和性能,因此需要合理地使用。

  1. 限流

通过限流,可以避免大量请求同时涌入系统,导致系统崩溃。常见的限流策略包括:漏桶算法、令牌桶算法等。通过限流,可以避免缓存雪崩问题。

需要注意的是,在实际应用中,不同的场景和业务需求,可能需要选择不同的解决方案来避免缓存雪崩问题,同时还需要考虑缓存的一致性和可靠性等问题。

五、redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)
在实际应用中,使用 Redis 作为缓存服务器时,需要考虑 MySQL 数据库和 Redis 缓存之间的数据一致性问题。通常有以下两种方式来保证 MySQL 数据库和 Redis 缓存之间的数据一致性:

  1. 双写一致性

双写一致性是指在 MySQL 数据库和 Redis 缓存中同时进行数据写入,保证数据始终一致。在实际应用中,可以使用以下两种方式来实现双写一致性:

  • 在应用程序中,同时操作 MySQL 数据库和 Redis 缓存。当应用程序需要写入数据时,先写入 MySQL 数据库,然后再写入 Redis 缓存。这种方式需要保证 MySQL 数据库和 Redis 缓存的数据一致性,如果写入 Redis 缓存失败,可以根据业务需求选择回滚 MySQL 数据库的写入操作,或者发送重试消息等方式来保证数据一致性。
  • 使用消息队列,将数据写入 MySQL 数据库和 Redis 缓存的操作封装成消息发送到消息队列中,然后由消费者从消息队列中获取消息并执行写入操作。这种方式可以将 MySQL 数据库和 Redis 缓存的写入操作解耦,提高系统的可扩展性和可维护性,同时也可以实现数据的异步更新。
  1. 延迟双删

延迟双删是指在 MySQL 数据库中进行数据删除操作时,先将 Redis 缓存中的数据标记为过期,然后再异步删除 Redis 缓存中过期的数据。在实际应用中,可以使用以下两种方式来实现延迟双删:

  • 在应用程序中,先将 MySQL 数据库中的数据删除,然后将 Redis 缓存中的数据标记为过期,再异步删除 Redis 缓存中过期的数据。这种方式需要保证 MySQL 数据库和 Redis 缓存的数据一致性,如果删除 Redis 缓存中的数据失败,可以根据业务需求选择回滚 MySQL 数据库的删除操作,或者发送重试消息等方式来保证数据一致性。
  • 使用定时任务,定期扫描 Redis 缓存中过期的数据,并从 MySQL 数据库中查询数据是否被删除。如果数据被删除,则删除 Redis 缓存中对应的数据。这种方式可以减少对 MySQL 数据库的访问次数,提高系统的性能,但是可能会出现数据不一致的情况,需要根据业务需求进行权衡。

需要注意的是,在实际应用中,双写一致性和延迟双删都需要考虑数据一致性和性能的问题,并选择合适的方式来保证 MySQL 数据库和 Redis 缓存之间的数据一致性。

六、那这个排他锁是如何保证读写、读读互斥的呢?
在并发环境下,通过使用排它锁可以保证读写、读读之间的互斥性,从而避免了并发访问的数据竞争问题。在实现排它锁时,通常有以下几种方式来保证读写、读读之间的互斥性:

  1. 读写锁

读写锁是一种特殊的锁,它允许多个读操作同时进行,但只允许一个写操作进行。在读写锁的实现中,读操作和写操作之间使用互斥的方式进行,即在写操作进行时,需要等待所有的读操作完成后才能进行写操作。读写锁常用于读多写少的环境中,可以提高系统的并发度和性能。

  1. 互斥锁

互斥锁是一种普通的锁,用于保证同一时间只有一个线程可以访问共享资源,从而避免了多个线程之间的数据竞争问题。在互斥锁的实现中,当一个线程获得锁之后,其他线程需要等待该线程释放锁后才能获得锁。互斥锁常用于读写比较平衡的环境中,可以保证读写操作之间的互斥性。

  1. 自旋锁

自旋锁是一种特殊的锁,用于避免线程进入睡眠状态,从而提高锁的性能。在自旋锁的实现中,当一个线程请求锁时,如果该锁已经被其他线程持有,那么该线程会一直等待,直到获得锁为止。自旋锁常用于锁的持有时间较短的情况下,可以提高系统的性能。

需要注意的是,在实际应用中,对于不同的场景和业务需求,需要选择合适的锁来保证读写、读读之间的互斥性,并考虑锁的性能和可扩展性等问题。同时,还需要注意锁的使用方式,避免死锁、饥饿等问题的发生。

七、redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)
在实际应用中,使用 Redis 作为缓存服务器时,需要考虑 MySQL 数据库和 Redis 缓存之间的数据一致性问题。通常有以下两种方式来保证 MySQL 数据库和 Redis 缓存之间的数据一致性:

  1. 双写一致性

双写一致性是指在 MySQL 数据库和 Redis 缓存中同时进行数据写入,保证数据始终一致。在实际应用中,可以使用以下两种方式来实现双写一致性:

  • 在应用程序中,同时操作 MySQL 数据库和 Redis 缓存。当应用程序需要写入数据时,先写入 MySQL 数据库,然后再写入 Redis 缓存。这种方式需要保证 MySQL 数据库和 Redis 缓存的数据一致性,如果写入 Redis 缓存失败,可以根据业务需求选择回滚 MySQL 数据库的写入操作,或者发送重试消息等方式来保证数据一致性。
  • 使用消息队列,将数据写入 MySQL 数据库和 Redis 缓存的操作封装成消息发送到消息队列中,然后由消费者从消息队列中获取消息并执行写入操作。这种方式可以将 MySQL 数据库和 Redis 缓存的写入操作解耦,提高系统的可扩展性和可维护性,同时也可以实现数据的异步更新。
  1. 延迟双删

延迟双删是指在 MySQL 数据库中进行数据删除操作时,先将 Redis 缓存中的数据标记为过期,然后再异步删除 Redis 缓存中过期的数据。在实际应用中,可以使用以下两种方式来实现延迟双删:

  • 在应用程序中,先将 MySQL 数据库中的数据删除,然后将 Redis 缓存中的数据标记为过期,再异步删除 Redis 缓存中过期的数据。这种方式需要保证 MySQL 数据库和 Redis 缓存的数据一致性,如果删除 Redis 缓存中的数据失败,可以根据业务需求选择回滚 MySQL 数据库的删除操作,或者发送重试消息等方式来保证数据一致性。
  • 使用定时任务,定期扫描 Redis 缓存中过期的数据,并从 MySQL 数据库中查询数据是否被删除。如果数据被删除,则删除 Redis 缓存中对应的数据。这种方式可以减少对 MySQL 数据库的访问次数,提高系统的性能,但是可能会出现数据不一致的情况,需要根据业务需求进行权衡。

需要注意的是,在实际应用中,双写一致性和延迟双删都需要考虑数据一致性和性能的问题,并选择合适的方式来保证 MySQL 数据库和 Redis 缓存之间的数据一致性。

八、redis做为缓存,数据的持久化是怎么做的?
Redis 作为一种内存数据库,通常会将数据存储在内存中,以提高数据访问速度。但是,如果 Redis 服务器意外宕机或重启,内存中的数据将会丢失,导致数据不一致的问题。为了解决这个问题,Redis 提供了多种数据持久化方式,包括 RDB 和 AOF 两种方式。

  1. RDB 持久化

RDB 持久化是指将 Redis 在内存中的数据定期保存到磁盘上的快照文件中。当 Redis 服务器重启时,可以从磁盘上加载快照文件,恢复数据。RDB 持久化的优点是效率高、恢复速度快,适合大规模数据的备份和恢复,缺点是数据的实时性较差。

  1. AOF 持久化

AOF 持久化是指将 Redis 在内存中的操作日志记录到磁盘上的 AOF 文件中。当 Redis 服务器重启时,可以通过 replay AOF 文件来恢复数据。AOF 持久化的优点是数据的实时性好,可以保证数据不丢失,缺点是效率较低,文件比较大,恢复速度较慢。

为了兼顾 RDB 和 AOF 持久化的优点,Redis 还提供了混合持久化方式。混合持久化方式可以同时使用 RDB 和 AOF 两种持久化方式,将快照和操作日志都保存到磁盘上,当 Redis 服务器重启时,可以使用快照和操作日志来恢复数据。

需要注意的是,Redis 的持久化方式可以通过配置文件进行配置。在实际应用中,需要根据业务需求和系统性能等因素,选择合适的持久化方式来保证数据的持久化和一致性。同时,还需要定期备份数据和监控 Redis 服务器的运行状态,避免数据丢失和系统故障的发生。

九、这两种方式,哪种恢复的比较快呢?
在 Redis 数据持久化方式中,RDB 恢复比 AOF 恢复快,因为恢复 RDB 数据只需要将 RDB 文件加载到 Redis 中即可,而恢复 AOF 数据则需要 replay AOF 文件中的所有操作,这个过程比较耗时。

RDB 持久化的恢复过程相对简单,通过将 RDB 文件加载到 Redis 中,就可以快速地恢复数据。但是 RDB 的恢复速度较快的同时,数据的实时性较差,如果 Redis 在生成快照文件之前宕机了,那么数据将会丢失。

而 AOF 持久化的恢复过程相对复杂,需要 replay AOF 文件中的所有操作,这个过程比较耗时。但是 AOF 的恢复速度相对较慢的同时,数据的实时性好,可以保证数据不丢失。

因此,在选择 Redis 数据持久化方式时,需要根据实际需求和业务场景来进行选择。如果需要保证数据的实时性,可以选择 AOF 持久化方式;如果数据的实时性要求不高,但是需要快速备份和恢复数据,可以选择 RDB 持久化方式。同时,也可以结合使用 RDB 和 AOF 的混合持久化方式,来兼顾数据的实时性和恢复速度。

十、Redis的数据过期策略有哪些 ?
Redis 作为一种内存数据库,通常用于缓存和高速读写的场景中。为了避免过多的数据占用内存,Redis 提供了多种数据过期策略,包括:

  1. 定时过期策略

定时过期策略是指在写入 Redis 数据时,为数据设置一个过期时间,当数据过期时,Redis 会自动将该数据删除。在 Redis 中,可以通过 EXPIRE 和 PEXPIRE 命令来设置过期时间。EXPIRE 命令用于设置以秒为单位的过期时间,PEXPIRE 命令用于设置以毫秒为单位的过期时间。

  1. 惰性过期策略

惰性过期策略是指在读取 Redis 数据时,检查数据是否过期,如果数据过期,则将该数据删除。在 Redis 中,可以通过对 key 进行访问操作来触发惰性过期策略,例如 GET 命令。

  1. 定期过期策略

定期过期策略是指定期地对 Redis 中的过期数据进行删除。在 Redis 中,定期过期策略的执行由 Redis 服务器的自身机制来触发,Redis 会随机抽取一些设置了过期时间的键,并检查它们是否过期,如果过期则删除它们。在 Redis 中,可以通过设置 maxmemory-policy 参数来控制定期过期策略的执行频率和删除策略。

需要注意的是,在 Redis 中,数据过期策略的执行由 Redis 服务器自身机制来触发,因此无法保证数据一定会在过期时间到达时立即被删除。同时,还需要根据具体的需求和系统性能等因素,选择合适的过期策略来保证数据的内存使用和系统性能。

未完待续,下期再续…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值