面试题-Redis
[TOC]
基础
Redis是什么?
Redis是一个开源的基于内存的键值存储系统
Redis的应用场景?
- 缓存:Redis被广泛用作缓存层,可以将热门的数据缓存在内存中,以提高读取数据的速度。它可以减轻数据库负载,并节省数据库访问的时间。
- 计数器:Redis支持原子操作,可以用来实现计数器功能,如网站访问量统计、文章点赞数、粉丝数等
- 排行榜:Redis的原子操作和快速读写特性使其非常适合实现计数器和排行榜功能。比如可以用Redis来记录文章的点赞数、用户的关注数,并实时更新排名。
- 会话管理:对于需要管理用户会话的应用程序,Redis可以用来存储和跟踪会话数据。它可以轻松地存储和检索用户身份验证信息、登录状态等会话相关的数据。
- 消息队列:Redis支持发布/订阅模型,可以用作简单的消息队列系统。应用程序可以使用Redis的PUB/SUB功能进行消息的发布和订阅,实现解耦和异步通信。
- 分布式锁:Redis支持分布式锁的实现,可以用于解决多个进程或服务器之间的竞态条件问题。通过使用Redis的原子操作和过期时间设置,可以实现高效的分布式锁机制。
Redis的基本数据结构类型有哪些?
- 字符串(String):字符串是最基本的数据结构类型。可以存储文本、整数或二进制数据。
- 列表(List):列表是一个有序的元素集合,可以在列表的两端进行插入和删除操作。可以用于实现队列、栈等数据结构。
- 集合(Set):集合是一个无序的唯一元素集合。可以进行添加、删除、查找和交并补等操作。集合中的元素不重复。
- 有序集合(zSet):有序集合与集合类似,但每个元素都有一个关联的分数,用于排序。可以根据分数范围或成员获取排名。
- 哈希表(Hash):哈希表是键值对的集合,其中每个键都是唯一的。可以对单个键进行添加、删除和获取操作。
Redis为什么快?
Redis是一款高性能的内存数据库系统,具有以下几个主要原因:
- 基于内存存储:Redis将数据存储在内存中,从而实现了非常快速的数据访问。相比于传统的基于磁盘存储的数据库系统,Redis的读写速度要快得多。
- 单线程模型:Redis采用单线程模型,每个操作都是原子性的,这使得Redis在处理数据时能够避免竞态条件和线程同步的复杂性。此外,单线程模型还可以避免多线程之间的上下文切换开销,提高了执行效率。
- 高效的数据结构:Redis采用了高效的数据结构,如哈希表、跳表等,来支持不同的操作,这些数据结构在搜索、插入和删除方面具有很高的效率。
- 异步非阻塞IO:Redis使用异步I/O技术,当一个客户端发送请求后,Redis会立即返回结果并继续处理其他客户端的请求,这种非阻塞的方式可以大大提高请求处理的效率和吞吐量。
- 网络优化:Redis使用了零拷贝技术、多路复用技术等网络优化技术,以最大限度地减少网络传输的开销,提高数据传输的效率。
Redis线程安全吗?
Redis是线程安全的。所有的操作都在一个线程中完成,因此不存在多个线程相互影响的问题。
Redis是单线程吗?
Redis主要使用单个线程(即主线程)执行「
接收客户端请求——>解析请求——>进行数据读写等操作——>发送数据给客户端」的流程,因此我们常说Redis是单线程的。但这并不意味着只能处理单个连接或请求,Redis使用事件驱动模型和I/O多路复用技术(如select、epoll或kqueue),可以同时处理多个连接和请求。
缓存穿透、缓存击穿、缓存雪崩是什么?
缓存穿透、缓存雪崩和缓存击穿是在缓存系统中常见的问题
- 缓存穿透:查询一个缓存和数据库都不存在的数据,导致每次查询这条数据都会透过缓存,直接查库,最后返回空
- 缓存击穿:缓存中某个热点数据过期,恰好在此时有大量的并发请求访问这个热点数据,直接查询数据库
- 缓存雪崩:缓存中的大量数据同时失效或过期,导致大量的请求直接访问后端数据库,或者Redis直接宕机了,导致大量的查询请求全部到达数据库
缓存穿透、缓存击穿、缓存雪崩怎么解决?
缓存穿透解决方案:
- 缓存空值:当数据库查询的结果为空时,也将其缓存起来,设置一个较短的过期时间,避免重复查询。
- 布隆过滤器:在查询Redis前先查询布隆过滤器,快速判断请求的数据是否存在于缓存中,如果布隆过滤器判断数据不存在,则可以直接拒绝访问,避免对数据库的无效查询。
缓存击穿解决方案:
- 互斥锁或分布式锁:在查询热点数据之前,先尝试获取一个互斥锁或分布式锁。只有一个线程获取到锁后才能去查询数据库,其他线程在获取锁失败的情况下等待,直到获取到缓存数据为止。
- 热点数据不设置过期:对于一些非常热门且频繁访问的数据,可以选择不设置过期时间,让其一直保存在缓存中。
- 实时监控动态调整:通过实时监控系统负载和缓存命中率等指标,动态调整缓存策略
缓存雪崩解决方案:
- 随机过期时间:在缓存中设置随机的过期时间,避免大量数据在同一时刻同时失效。
- 多级缓存架构:在应用程序与缓存系统之间增加一层缓存,例如使用本地缓存(如Guava Cache)作为一级缓存,避免过多的请求直接访问主缓存层。
Redis的持久化?
RDB持久化:
记录快照方式(默认),通过快照机制将当前数据的内存状态保存到磁盘中的一个二进制文件(.rdb文件)AOF持久化:
记录日志方式,将Redis的所有写操作追加到一个日志文件中(appendonly.aof文件)。
Redis分布式锁什么时候使用?
在分布式环境下,由于每台服务器都有自己的内存空间和线程,Java的同步锁(synchronized)只能锁住单个线程或单台服务器的资源,在分布式环境下使用时,每台服务器都会有自己的一份锁,但我们希望多台服务器共用一把锁,为了在分布式环境中实现多台服务器共享一把锁的效果,可以使用Redis的SETNX命令来实现分布式锁。
Redis分布式锁如何实现?
可以使用Redis的SetNX实现分布式锁。
当一个服务器需要获取锁时,它会调用Redis的
SetNX命令尝试将一个特定的键值对写入Redis
- 如果
SetNX命令返回1(成功),那么服务器获取到了锁,并可以执行需要进行同步的操作。- 如果
SetNX命令返回0(失败),说明有其他服务器已经持有了锁,当前服务器获取锁失败。这时可以根据具体的需求选择合适的策略,比如等待一段时间后再重试获取锁,或者直接放弃任务。在操作完成后,可以通过调用Redis的
DEL命令来删除该键值对,释放锁,供其他服务器获取。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 远方の博客!
评论
GitalkValine











