Redis
1. 为什么要用 redis ?为什么要用缓存?主要从"高性能"和“高并发”这两点来描述这个问题。
高性能:
-
内存存储:Redis将数据存储在内存中,相比磁盘存储,内存访问速度极快,从而显著提升了数据访问的性能。
-
数据结构丰富:Redis支持多种数据结构,如字符串、列表、集合、哈希等,能够更高效地处理各种复杂场景下的数据操作。
-
避免数据库瓶颈:通过将热点数据存储在Redis中,减少了对后端数据库的访问次数,避免了数据库成为性能瓶颈。
高并发:
-
扩展性强:Redis支持主从复制和集群模式,可以轻松实现水平扩展,从而处理更高的并发请求。
-
缓解数据库压力:在高并发场景下,Redis作为缓存层可以承接大量读请求,减轻数据库压力。
-
分布式锁和限流:Redis支持分布式锁和限流策略,有助于在高并发环境中控制对共享资源的访问和防止系统过载。
2. redis和memcached 的区别
-
数据结构:Redis支持更丰富的数据结构,如list、set、sorted set、hash等,而Memcached主要支持简单的key-value存储。
-
内存管理:Redis支持数据的持久化和复制功能,而Memcached采用Slab Allocation机制,预分配内存块并根据对象大小存储,当内存不足时采用LRU算法淘汰旧数据。
-
扩展性:Redis支持主从复制和集群模式,具有更好的水平扩展性,而Memcached的每个进程间不通信,需要客户端提供分布式算法。
-
特性:Redis具有更丰富的功能,如键过期、发布订阅、Lua脚本支持等,而Memcached则更注重于简单的key-value存储和缓存功能。
3.redis 常见数据结构以及使用场景分析
数据结构:
-
String(字符串):用于存储字符串类型的数据,是最常用的数据类型,可以接受任何格式的数据。
-
Hash(哈希):类似于字典或Map,用于存储键值对,适用于存储结构化数据。
-
List(列表):有序的字符串列表,支持双向操作(如插入、删除),适用于实现消息队列、任务队列等。
-
Set(集合):无序且不重复的字符串集合,适用于需要快速查找、判断元素是否存在的场景。
-
ZSet(有序集合):每个元素都关联一个分数,按分数进行排序,适用于排行榜、计数器等场景。
使用场景:
-
缓存:将热点数据存储在Redis中,减少数据库访问次数,提高系统性能。
-
分布式锁:利用Redis的原子操作实现高效可靠的分布式锁。
-
消息队列:利用List或Stream实现消息队列,生产者向队列中添加消息,消费者从队列中取出消息进行处理。
-
计数器:利用ZSet的有序特性实现计数器功能,如网站访问量统计、用户点赞数等。
-
会话管理:将用户会话信息存储在Redis中,实现跨服务器共享会话。
-
地理位置服务:利用Redis的geohash算法支持存储和查询地理位置信息。
-
Web集群Session共享:在Web集群中,使用Redis存储和共享Session信息,确保用户在不同服务器间切换时Session信息保持一致。
4.请描述 redis 设置过期时间的含义和作用
Redis设置过期时间的含义是为一个key设置一个时间窗口,在这个时间窗口内,该key可以被访问和使用,到达时间窗口后,Redis会自动删除过期的key。
作用主要包括:
-
内存管理:自动清理不再需要的数据,避免数据无限期地占用内存资源,从而有效管理内存资源,防止内存泄漏和溢出。
-
数据新鲜度:对于时效性强的数据,设置过期时间可以确保缓存中的数据保持最新状态。过期后,Redis会自动删除过期数据,应用程序可以重新从原始数据源获取最新数据并重新缓存。
-
防止缓存问题:
-
缓存雪崩:通过设置过期时间的随机性,分散缓存的过期时间,避免大量缓存同时失效,减轻数据库的压力。
-
缓存击穿:当热点数据过期后,由于设置了较短的过期时间,Redis可以迅速重新加载数据到缓存中,减少数据库压力。
-
-
实现特定功能:如通过Redis的过期时间实现分布式锁、限流等常见应用场景。
总的来说,设置过期时间有助于Redis更好地管理和利用内存资源,同时保证数据的时效性和系统的稳定性。
5.redis 内存淘汰机制(MySQL里有 2000w数据,Redis 中只存 20w 的数据,如何保证 Redis 中的数据都是热点数据?)
Redis 的内存淘汰机制是为了在内存达到上限时,自动淘汰一些数据以释放空间。为了确保 Redis 中只存储热点数据,可以采取以下策略:
-
设置TTL(Time To Live):为 Redis 中的数据设置合理的过期时间,使不常访问的数据自动过期。这有助于保持 Redis 中的数据都是近期的热点数据。
-
使用淘汰策略:
-
allkeys-lru
:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key。 -
volatile-lru
:根据 LRU 算法移除设置了过期时间的 key。 -
考虑到 MySQL 中有 2000w 数据,而 Redis 中只存 20w 数据,可能更倾向于使用
volatile-lru
或与 LRU 相关的策略,因为这样可以确保那些最近被访问且设置了过期时间的 key 被保留。
-
-
数据预热:在系统启动或特定时间点,将预期的热点数据预先加载到 Redis 中,确保这些数据在需要时能被快速访问。
-
监控与分析:使用 Redis 的监控工具(如 Redis Insight)和分析技术来跟踪哪些数据是热点数据,哪些数据不常被访问。根据这些信息,可以调整数据的 TTL 和淘汰策略。
-
容量规划:根据业务需求和数据增长趋势,合理规划 Redis 的容量。如果 Redis 的容量不足以存储所有热点数据,可能需要考虑增加内存、使用 Redis 集群或优化数据结构以减少内存使用。
简写总结:
-
设置 TTL,确保数据不过期。
-
使用 LRU 淘汰策略,保留热点数据。
-
数据预热,预先加载热点数据。
-
监控分析,调整策略以适应数据变化。
-
合理规划 Redis 容量,确保足够存储热点数据。
6.redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)
Redis的持久化机制主要保证在Redis挂掉之后重启时数据可以进行恢复。它提供了两种主要的持久化方式:
-
RDB(Redis DataBase):RDB是按照一定的时间间隔将内存中的数据集快照写入磁盘,生成一个dump.rdb文件。当Redis重启时,可以从这个文件中恢复数据。RDB是Redis的默认持久化方式,它提供了较快的恢复速度。
-
AOF(Append Only File):AOF则是将Redis执行的所有写命令记录到日志文件中。当Redis重启时,它会重放AOF文件中的写命令来恢复数据。AOF提供了更高的数据安全性,但通常AOF文件较大,加载速度较慢。
7.请描述 redis 的 事务是如何实现的 ?
Redis的事务实现包含三个步骤:
-
开始事务:客户端使用
MULTI
命令来开启一个事务。 -
命令入队:客户端将事务中要执行的具体操作(如GET、SET等)发送给服务器。这些命令会被Redis暂存到一个命令队列中,并不会立即执行。
-
执行事务:客户端使用
EXEC
命令来提交事务,使Redis实际执行队列中的命令。如果服务器收到EXEC
命令,则会按照命令队列中的顺序执行这些命令,并返回结果。
Redis的事务机制能保证命令的原子性,即要么全部执行,要么全部不执行,但不能保证像关系型数据库那样的ACID(原子性、一致性、隔离性、持久性)属性。
8.Redis 缓存使用过程当中,关于缓存穿透、缓存雪崩、缓存预热以及缓存降级这四点常见问题如何解决 ?
-
缓存穿透:
-
布隆过滤器:在查询缓存之前,使用布隆过滤器快速判断数据是否存在于缓存中,避免直接访问数据库。
-
空值缓存:对于不存在的数据,也在缓存中保存一个空值或特殊标记,但设置较短的过期时间。
-
-
缓存雪崩:
-
缓存过期时间分散:避免大量缓存同时过期,将过期时间设置得随机一些。
-
互斥锁:在缓存失效后,使用互斥锁或分布式锁保证只有一个线程去数据库加载数据,其他线程等待。
-
异步加载:使用后台线程或队列来异步加载缓存,避免大量请求直接打到数据库。
-
-
缓存预热:
-
提前加载:在系统启动或低峰期时,将热点数据提前加载到缓存中。
-
脚本工具:使用脚本或定时任务定期或按需加载数据到缓存。
-
-
缓存降级:
-
熔断机制:当缓存服务出现问题时,快速失败并降级到备用方案,如读取数据库或返回默认数据。
-
限流降级:使用限流策略,如令牌桶或漏桶算法,控制对缓存的请求量,防止系统过载。
-
关闭部分缓存:根据业务需要,关闭部分非关键的缓存功能,以减轻系统压力。
-
这些策略可以根据具体的业务场景和需求进行选择和组合使用。
9.请介绍“分布式锁"以及“分布式自增 ID"常见的应用场景
分布式锁:
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。常见的应用场景包括:
-
临界区互斥访问:防止多个节点同时修改共享数据,确保数据的一致性。
-
分布式环境同步访问:在分布式环境中同步访问共享资源,如分布式任务调度、分布式事务等。
分布式自增 ID:
分布式ID是指在分布式环境下可用于对数据进行标识且易存储的全局唯一的ID标识。常见的应用场景包括:
-
订单号生成:在高并发的电商平台中,为了保证订单号的唯一性和顺序递增,使用分布式ID作为订单号。
-
数据库主键生成:在数据库分库分表后,为了避免多个节点插入相同的主键值,使用分布式ID生成不重复的主键。
-
数据消息队列的幂等性:在数据消息队列中,使用分布式ID确保多次消费同一条消息不会产生副作用。
这些应用场景都依赖于分布式锁和分布式ID来保证数据的一致性和唯一性。
10.请描述一下 Redis 的几种集群模式
-
主从复制模式(Master-Slave):
-
原理:一个Redis实例作为主节点(Master),其他实例作为从节点(Slave)。主节点负责处理写操作,从节点负责处理读操作或作为主节点的备份。
-
优点:读写分离,分担主节点的读写压力;方便容灾恢复。
-
缺点:每台Redis服务器存储的数据相同,浪费内存;不具备自动容错和恢复功能,需人工介入;较难支持在线扩容。
-
-
哨兵模式(Sentinel):
-
原理:哨兵是一个独立的进程,负责监控Redis主从节点的运行状态。当主节点宕机时,哨兵会自动将从节点中的一个提升为主节点,确保系统的高可用性。
-
优点:自动故障转移,提供高可用性;支持在线扩容。
-
缺点:相对复杂,需要部署和管理哨兵节点。
-
-
集群模式(Cluster):
-
原理:将数据分散存储到多个Redis节点上,每个节点只存储一部分数据。每个节点都保存了数据和其他节点的映射关系,当访问数据时,会先查询映射关系,然后到相应的节点上获取数据。
-
优点:支持在线扩容,数据分散存储,提高系统的扩展性和容错性。
-
缺点:相对复杂,需要管理和维护多个节点;需要手动或自动进行数据的分片。
-
Spring/SpringMVC
1.Spring 事务如果失效了,可能是哪几种原因?
-
方法修饰符问题&#