【面试题】Redis面试题及答案总结

Redis支持的数据类型?

Redis 支持以下五种主要数据类型:

  • 字符串(String):
    字符串是 Redis 中最基本的数据类型,它可以存储任何类型的二进制数据或文本数据。
    常见操作包括设置值(SET)、获取值(GET)、自增/自减(INCR/DECR)、追加(APPEND)等。

  • 列表(List):
    列表是一个有序的序列,可以存储多个字符串,并且允许重复元素。
    操作包括从头部或尾部插入(LPUSH/RPUSH)、弹出元素(LPOP/RPOP)、获取范围内的元素(LRANGE)、移除指定值(LREM)等。

  • 哈希(Hash):
    哈希是一种键值对集合,其中每个字段都有一个关联值。
    常用操作有添加、删除和查找字段及其对应的值(HSET/HGET/HDEL),获取整个哈希的所有字段和值(HGETALL)等。

  • 集合(Set):
    集合包含不重复的字符串成员,它们是无序的。
    支持的操作包括添加成员(SADD)、获取集合所有成员(SMEMBERS)、检查成员是否存在(SISMEMBER)、交集、并集、差集运算(SDIFF/SINTER/SUNION)等。

  • 有序集合(Sorted Set):
    有序集合与集合类似,但每个成员都有一个分数与之关联,使得集合中的元素能够按分数排序。
    提供了与集合类似的增删查功能,此外还包括根据分数排名进行范围查询(ZRANGE/ZREVRANGE)、计算成员分数(ZSCORE)、按分数增量更新(ZINCRBY)等操作。

  • HyperLogLog:
    HyperLogLog提供不精确的唯一计数功能,它使用极小的空间(以字节为单位)来估算集合中的唯一元素数量。
    虽然不是Redis 6新增,但它是在较早的Redis版本(例如:2.8.9版本)中引入的。

  • Bitmaps:
    Bitmaps并不是Redis内置的数据类型,而是通过操作字符串类型实现位级别的操作的一种用法,例如SETBIT和GETBIT命令可用于处理位数组。
    这些命令早在Redis支持字符串数据类型时就已经存在,Redis提供了丰富的位操作命令集来模拟位图功能。

  • Geospatial(地理空间索引):
    Redis支持地理空间索引功能,可以存储地理位置信息并进行距离排序和周边查询等操作。
    地理位置相关的命令如GEOADD、GEODIST、GEORADIUS等在Redis 3.2版本中被引入。


使用Redis有哪些好处?常见的使用场景?

使用Redis有以下多个显著的好处:

  • 内存存储,高速访问:Redis将数据存储在内存中,提供了亚毫秒级别的读写速度,适合对性能要求极高的场景。
  • 丰富数据结构:Redis支持多种数据类型,包括字符串(String)、列表(List)、哈希(Hash)、集合(Set)和有序集合(Sorted Set),这使得它能够灵活地处理各种复杂的数据模型和业务需求。
  • 持久化选项:Redis 提供了两种持久化策略:RDB(快照)和AOF(追加式日志),可以在保证高性能的同时,实现数据的持久保存。
  • 事务支持:Redis 支持多条命令的原子性执行,确保在事务中的操作要么全部成功,要么全部失败。
  • 高可用与分布式扩展:Redis可以通过主从复制、哨兵模式或集群模式实现高可用性和水平扩展能力。
  • 过期机制:可以为键设置过期时间,到期后自动删除,非常适合缓存系统的设计。
  • 消息队列:利用列表数据结构可以实现简单的消息队列功能,例如发布/订阅(Pub/Sub)模式,用于异步任务和消息传递。
  • 实时排行与计数:有序集合可用于实现排行榜,同时Redis的incr/decr等命令可以轻松完成计数统计,如微博点赞数、粉丝数统计等。

应用场景举例:

  • 缓存系统:减少数据库压力,提高整体系统的响应速度。
  • 会话存储:存储网站用户会话信息,减轻服务器负担并提供快速的会话管理。
  • 实时分析与监控:作为实时分析系统的数据缓冲区,收集统计数据,进行实时计算。
  • 排行榜与计数器:网络游戏的积分排名榜,社交网络的动态点赞数统计等。
  • 消息队列与通知系统:通过发布/订阅机制实现实时的消息推送服务。
  • 地理位置服务:利用地理空间索引进行附近地点查询等地理信息服务。

Redis相比Memcached有哪些优势?

Redis相比Memcached有以下显著优势:

  • 数据类型丰富:
    Redis支持多种数据结构,包括字符串(String)、列表(List)、集合(Set)、有序集合(Sorted Set)和哈希(Hash),这使得Redis能够处理更复杂的业务场景,如计数、排行榜、消息队列等。
    相比之下,Memcached只支持简单的键值对存储,所有值都是字节串。
  • 持久化选项:
    Redis提供了两种持久化机制:RDB(Redis Database)和AOF(Append Only File),可以在一定程度上保证即使在服务器重启后也能恢复数据。Memcached则不支持持久化,一旦服务器关闭或重启,缓存中的数据就会丢失。
  • 事务支持:
    Redis支持多条命令的原子性执行,即事务,确保一系列操作的完整性。Memcached不支持事务,无法实现多个操作的原子提交。
  • 主从复制与高可用:
    Redis可以配置主从复制以实现数据备份和故障切换,通过哨兵模式或集群模式可以构建出高可用的服务架构。
    Memcached原生并不直接支持主从复制,要实现高可用需要依赖于外部工具或服务发现机制。
  • 过期策略:
    Redis除了设置键的过期时间外,还支持更加灵活的TTL控制和LRU/LFU淘汰策略。
    Memcached也支持设置键的过期时间,但其淘汰策略相对简单。

区别总结如下:

  • 数据模型:Redis的数据模型复杂且多样,而Memcached仅提供简单的键值对模型。
  • 持久化:Redis提供持久化选项,Memcached不提供。
  • 事务支持:Redis支持事务操作,Memcached则不支持。
  • 高可用和分布式:Redis内置了较为完善的主从复制和集群功能,Memcached在这方面功能较弱,需要借助其他工具来实现。

redis使用单线程,为何如此高效?

Redis利用I/O多路复用技术实现高效的网络通信,具体来说是通过以下方式:

  • 单线程模型与文件事件处理器:
    Redis运行在一个主线程中,所有客户端请求均在该线程中顺序执行。
    Redis内部设计了文件事件处理器(File Event Handler),它负责监听和处理多个socket连接上的各种网络事件。
  • I/O多路复用机制:
    文件事件处理器使用操作系统提供的I/O多路复用API,如Linux系统中的epoll、kqueue(BSD系统)或select/poll(早期的Unix/Linux系统)等。这些API允许Redis在单个线程中同时监听多个套接字(socket),并能够识别哪些套接字已经准备好进行读写操作,而不需要为每个套接字循环等待和检查。
  • 事件分发与回调函数:
    当有网络事件发生时(例如:客户端发送了一个命令请求或者服务器需要向客户端回复数据),文件事件处理器会根据不同的事件类型调用相应的处理函数来执行对应的操作。对于每个socket,Redis预先关联一个或多个事件处理器(handler),当I/O就绪时,对应的处理器会被触发执行相应逻辑。
  • 高效并发处理:
    通过这种方式,Redis可以在不引入额外线程开销的前提下,有效管理数千甚至数万个并发连接,并且在空闲时将线程阻塞,避免无效轮询造成的CPU资源浪费。尽管是单线程处理,但由于采用了非阻塞I/O和多路复用技术,Redis能够在高并发场景下保持较高的吞吐量和低延迟。

Redis的持久化机制是什么?各自的优缺点?

Redis提供了两种主要的持久化机制:RDB(Redis Database)和AOF(Append-Only File)。
RDB持久化
RDB持久化是将Redis在某一时刻的数据生成一个或多个数据文件,这些文件包含了整个数据库的数据。它是通过周期性地创建数据库的快照来实现的。
优点:

  • 紧凑且易于备份:RDB文件是一个二进制文件,存储占用空间小,适合进行全量备份。
  • 恢复速度快:由于RDB文件是直接加载到内存中的,所以在Redis重启时,如果只有RDB文件,恢复速度相对较快。
  • 对性能影响较小:RDB持久化可以在空闲时间执行,例如在服务器负载较低时,通过fork子进程进行快照生成,不影响主线程处理客户端请求。

缺点:

  • 可能丢失数据:如果Redis在两次快照之间发生故障,最后一次持久化后的数据会丢失。
  • 实时性差:对于需要高实时性的场景,因为RDB是定时或者满足一定条件触发的,所以数据一致性相对较低。

AOF持久化
AOF持久化则是将所有写命令以追加的方式记录到磁盘上的日志文件中,当Redis重启时,会重新执行AOF文件中的所有命令来重建数据集。
优点:

  • 数据完整性好:AOF模式下,只要append操作成功,即使Redis服务异常退出,也不会丢失数据,因为所有的写命令都会被记录下来。
  • 实时性较高:AOF可以根据配置选择不同的同步策略,从而实现近乎实时的数据持久化。

缺点:

  • 文件较大:随着写入操作的增多,AOF文件大小会不断增长,比RDB文件大很多。
  • 恢复速度较慢:相比于RDB,AOF在重启时需要重放整个日志文件中的命令,因此恢复数据的速度取决于文件的大小和内容复杂度。
  • 额外的资源消耗:AOF开启后,尤其是启用每条命令都fsync到磁盘的模式,可能会对性能产生一定的影响。

综合考虑,用户通常会选择结合使用RDB和AOF,利用它们各自的优点,并通过合理配置来达到数据安全性和性能之间的平衡。


Redis常见性能问题和解决方案

Redis常见性能问题和解决方案如下:

  • 性能瓶颈:
    问题:Redis服务器的CPU、内存或磁盘I/O使用率过高,导致性能下降。
    解决方案:优化查询语句、增加缓存命中率、扩容硬件资源或采用分布式架构。
  • 内存溢出:
    问题:Redis内存占用超过预设上限,导致服务不可用。
    解决方案:限制Redis实例的内存使用量、定期清理无用数据、优化数据结构或采用集群模式分散内存压力。
  • 网络延迟:
    问题:网络通信延迟导致Redis响应变慢。
    解决方案:检查网络设备和链路、优化网络拓扑结构、缩短网络传输距离或采用高性能网络设备。
  • 慢查询:
    问题:某些查询语句执行时间过长,影响整体性能。
    解决方案:使用Redis的慢日志功能定位慢查询语句,优化查询语句、增加索引或采用异步处理方式。
  • 高并发访问:
    问题:大量并发请求导致Redis性能下降。
    解决方案:优化查询语句、采用分布式锁机制、增加Redis实例数量或采用读写分离架构。
  • 数据一致性:
    问题:数据更新频繁,导致数据一致性问题。
    解决方案:使用事务处理、采用分布式锁机制或采用复制和持久化机制保证数据一致性。
  • 磁盘碎片:
    问题:Redis数据文件占用磁盘空间过大,导致磁盘碎片增加。
    解决方案:定期进行磁盘碎片整理、优化数据结构或采用压缩技术减少磁盘空间占用。
  • 命令阻塞:
    问题:某些命令执行时间过长,阻塞了其他命令的执行。
    解决方案:使用异步处理方式、限制命令执行时间或采用分布式架构分散命令执行压力。
  • 资源争抢:
    问题:多个客户端同时访问Redis,导致资源争抢。
    解决方案:优化客户端访问策略、采用分布式锁机制或采用高性能的硬件资源。
  • 数据备份与恢复:
    问题:数据备份和恢复时间过长,影响服务可用性。
    解决方案:采用增量备份和恢复策略、优化备份和恢复过程、采用分布式架构分散备份和恢复压力。

redis过期键的删除策略?

Redis过期键的删除策略主要包括以下三种机制:

  • 定时删除(Timed deletion):
    Redis在为键设置过期时间的同时,会创建一个定时器。当键的过期时间到达时,由定时器负责立即执行删除操作。
    实际上,Redis为了防止定时器过多导致CPU过度消耗,并没有采用严格意义上的定时删除。因为每个键都创建定时器是不切实际且资源消耗巨大的。
  • 惰性删除(Lazy deletion / Lazy expiration):
    惰性删除是指Redis不会主动去检查和删除已过期的键,而是在客户端访问某个键时,服务器才检查该键是否已经过期。
    如果键已经过期,那么返回空值并删除这个键;如果未过期,则正常返回键的值。
  • 定期删除(Periodic deletion / Active expiration):
    为了避免大量过期键堆积而导致内存浪费,Redis采用了定期删除策略,即每隔一段时间随机抽取一些数据库中的键进行检查。
    Redis会根据当前服务器负载、内存大小等因素来决定在这次周期内检查并删除多少个可能已过期的键,从而平衡了内存使用和CPU性能之间的关系。

综合来说,Redis结合了惰性和定期两种策略,在实际运行中以一种更为高效和灵活的方式管理过期键。这样既可以避免在某一刻集中处理大量过期键造成阻塞,也能保证长期运行过程中内存的有效利用。


Redis的回收策略(淘汰策略) ?

Redis的内存回收策略,也就是淘汰策略(Eviction Policy),用于在内存使用达到最大限制时,决定哪些数据应当优先被删除以释放空间。Redis提供了多种不同的淘汰策略供用户根据场景需求选择:

  • volatile-lru:只对设置了过期时间(TTL)的键进行淘汰。
    按照最近最少使用(Least Recently Used, LRU)的原则来选择要删除的键,即当内存不足时,从已设置过期时间的数据集中找出最近最少使用的键删除。
  • allkeys-lru:不区分键是否设置过期时间,对所有键按照LRU原则淘汰。
    当内存不足以容纳新写入的数据时,将整个数据集中最近最少使用的键移除。
  • volatile-random:仅针对已设置过期时间的键执行随机淘汰。
    当需要腾出内存时,从已设置过期时间的数据集中随机选择一个键进行删除。
  • allkeys-random:对所有键(不论是否有过期时间)执行随机淘汰。
    在内存不足时,从整个数据集中随机选择一个键进行删除。
  • volatile-ttl:根据键的剩余生存时间(Time To Live, TTL)来淘汰键。
    优先删除剩余生存时间最短(即将过期)的键,但只针对设置了过期时间的键。
  • noeviction:禁止驱逐(淘汰)任何键。
    如果内存达到上限且客户端尝试写入新的数据,会返回错误信息,并拒绝写入操作,以避免丢失现有数据。
    开发者可以根据实际业务需求和缓存使用模式来选择合适的淘汰策略,以保证系统在高负载或资源受限情况下仍能保持合理运行。

为什么Redis需要把所有数据放到内存中?

Redis将所有数据存储在内存中主要有以下几个原因:

  • 性能优势:内存的访问速度远高于磁盘。将数据保存在内存中,使得Redis能够实现亚毫秒级的读写操作响应时间,满足高并发、高性能场景的需求。Redis被设计为一个高速缓存和键值存储系统,内存中的数据结构可以直接被CPU访问和处理,避免了磁盘I/O带来的延迟。
  • 实时性要求:许多应用场景需要近乎实时的数据访问,例如排行榜、会话管理、消息队列等。将数据保留在内存中可以提供低延迟的数据更新和检索服务。
  • 数据结构丰富:Redis支持多种复杂的数据结构(如字符串、哈希、列表、集合和有序集合),这些数据结构都是为了高效地在内存中进行操作而设计的。
  • 持久化方案:尽管Redis把数据放在内存中,但它也提供了RDB和AOF两种持久化机制来定期或实时地将数据同步到磁盘上,从而在系统重启时恢复内存中的数据。这样既可以保证数据的快速访问,又能实现一定程度的数据安全性。
  • 设计初衷与定位:Redis从设计之初就定位为内存数据库,它的核心竞争力在于其高性能和丰富的数据类型,而不是像传统的关系型数据库那样侧重于事务性和完整性。

综上所述,Redis选择将所有数据放置在内存中是为了最大化性能并满足特定应用领域对数据访问速度的要求,同时通过持久化机制平衡了数据的安全性需求。


Redis的同步机制了解么?

Redis集群是一种分布式缓存解决方案,它通过将数据分散存储在多个节点上,实现高可用性、水平扩展以及负载均衡。
Redis集群原理

  • 数据分片(Sharding):Redis集群采用虚拟槽分区(Virtual Slot Sharding)的方式对数据进行分片,一共预设了16384个槽位。
    每个键会被哈希到一个槽位上,不同的槽位被分配给集群中的不同节点来负责。
  • 客户端路由:客户端发送命令时,需要知道哪个节点负责处理特定的键。
    Redis Cluster实现了客户端库与服务器之间的智能路由,使得客户端能够根据请求的键自动定位到正确的节点。
  • 节点间通信:集群内的节点之间通过Gossip协议(节点间消息传递)进行通信,维护集群配置信息如节点状态、槽分布等。
    节点间可以相互发现对方的存在和变化,并自动调整整个集群的状态。
  • 故障转移与主从复制:在集群中,每个槽位都有一个主节点和零个或多个从节点。
    当主节点发生故障时,集群会通过选举过程选出新的主节点以保证服务连续性和数据可用性。
    主节点和从节点之间采用主从复制机制同步数据,确保从节点的数据是最新的。

Redis集群同步机制

  • 主从复制同步:主节点通过持久化策略生成RDB文件或写入AOF日志,然后将其发送给从节点进行全量同步或增量同步。
    主节点在执行写操作的同时,也会把命令传播到所有从节点,从节点执行相同的命令完成数据更新,保持数据一致性。
  • 节点间数据迁移:在集群动态调整过程中,例如新增或移除节点、重新分配槽位时,需要进行数据迁移。
    迁移过程中,源节点会将指定槽位上的键值对批量发送给目标节点,直到所有槽位数据迁移完毕。

总之,Redis集群通过巧妙的数据分片方式和高效的主从复制机制,不仅实现了数据的分布式存储,还保证了在节点增删及故障恢复时数据的一致性和完整性


Pipeline有什么好处,为什么要用pipeline?

Redis Pipeline(管道)机制的主要好处和使用原因如下:

  • 减少网络往返时间:在没有Pipeline的情况下,客户端每次向Redis服务器发送命令都需要等待服务器响应后才能发送下一个命令。Pipeline允许客户端一次性将多个命令批量发送给服务器,然后一次性接收所有命令的执行结果。
    这样极大地减少了客户端与服务器之间的网络通信次数,从而显著降低了由于网络延迟导致的总体执行时间。
  • 提升吞吐量:通过批处理命令,Pipeline能够提高Redis数据库的处理速度,尤其是在进行大量数据操作时,比如批量写入或读取数据,可以极大提升系统的整体性能。
  • 保持命令顺序性:即使是批量执行,Redis也会按照Pipeline中命令的发送顺序来执行它们,确保了命令的执行逻辑不会因为并行化而被打乱。
  • 优化资源利用率:
    Pipeline减少了系统调用次数,使得CPU、内存和网络带宽等资源得到更高效的利用。
  • 简化客户端编程模型:
    对于某些复杂的多步操作,使用Pipeline可以让客户端代码更加简洁,一次性组装和发送多个命令,无需关心每一步操作的具体执行细节。

综上所述,Pipeline机制在高并发场景下尤其重要,它不仅提高了Redis服务端的处理效率,同时也优化了客户端与服务器间的交互效率,是实现高性能Redis应用的重要手段之一。


说说Redis哈希槽的概念?

Redis Cluster使用哈希槽(Hash Slot)来实现数据的分布式存储。哈希槽是一种将数据按照一定的规则划分成固定数量的分区方法,每个分区被称为一个哈希槽。

在Redis Cluster中,总共有16384个哈希槽。当需要在集群中添加或移动数据时,Redis使用CRC16校验算法对键进行哈希计算,然后将计算结果对16384取余数,得到的值就是该键对应的哈希槽。通过这种方式,Redis可以将键均匀地分布在集群的各个节点上,从而实现数据的分布式存储。

哈希槽的概念使得Redis Cluster能够更加灵活地处理数据的分布和迁移。当集群需要进行扩容或缩容时,只需要将部分哈希槽从一个节点迁移到另一个节点,而不需要重新分布所有的键值对,这样可以大大降低对集群服务的影响。

哈希槽的使用还简化了Redis Cluster的路由机制。客户端只需要将键发送给集群中的任意一个节点,节点会根据键的哈希值将请求转发给正确的节点进行处理。这样可以减轻客户端的路由负担,提高集群的可扩展性


Redis事务相关的命令有哪几个?

Redis事务相关的命令有以下几个:

  • MULTI:标记一个事务的开始。在执行该命令后,客户端发送的命令会被放入一个队列中,直到执行EXEC命令才会被执行。
  • EXEC:执行事务队列中的所有命令。在执行该命令之前,可以使用DISCARD命令取消事务。
  • DISCARD:取消事务,清除事务队列中的所有命令。
  • WATCH:监视一个或多个键,当这些键被修改时,事务将被取消。该命令通常在实现乐观锁时使用。
  • UNWATCH:取消对键的监视。
  • DEBUG OBJECT:用于查看键对应的值的具体信息,包括对象类型、创建时间和序列化大小等。该命令在事务中也可以使用,但与事务本身无直接关系。

以上命令中,MULTI、EXEC、DISCARD、WATCH和UNWATCH是与Redis事务直接相关的命令,而DEBUG OBJECT虽然在事务中也可以使用,但其主要用于查看键值对的详细信息,与事务的控制和执行无关。


Redis如何做内存优化?

Redis内存优化可以从以下几个方面进行:

  • 选择合适的数据结构:根据实际业务需求和数据特点,选用最适合的数据结构。例如,如果只需要存储简单的键值对且不需要排序或集合操作,可以选择字符串(String)类型;如果需要存储结构化的对象并减少重复数据,可以使用哈希(Hash)类型;对于列表、集合、有序集合等复杂场景,根据具体需求来决定。
  • 设置合理的过期时间:为不再需要的缓存数据设置适当的过期时间,使得Redis能自动删除过期的键值对,释放内存空间。可以通过EXPIRE或者TTL命令实现。
  • 内存碎片整理:Redis会定期执行内存碎片整理,但也可以通过手动触发BGREWRITEAOF命令(在开启AOF的情况下),间接引发内存碎片整理,从而减少内存浪费。
  • 使用较小的数据编码:Redis内部会对数据结构采用不同的编码方式以节省内存。例如,整数集合(IntSet)会根据元素大小自动选择最优的编码格式。
  • 禁用不必要的持久化机制:如果不需要长期持久化数据,可考虑关闭RDB或AOF中的一个或两个持久化方法,以减少内存和磁盘资源消耗。
  • 限制最大内存使用量:设置maxmemory配置参数限制Redis实例的最大内存占用,配合合适的淘汰策略(如LRU、LFU、volatile-lru等),当达到内存上限时自动移除不常用的数据。
  • 监控与清理:定期监控Redis内存使用情况,并及时清理无用数据,例如使用MEMORY USAGE命令查看特定键的内存消耗,以及使用KEYS结合DEL命令清理不再需要的键(但请注意,KEYS命令在大型数据库中可能会阻塞服务器,应谨慎使用或结合SCAN命令分批次处理)。
  • 合理规划集群容量:在集群环境中,确保每个节点有足够的内存,并合理分配数据到各个节点,避免单个节点内存压力过大。
  • 使用Link Pack协议压缩:对于客户端与Redis之间的网络通信,可以考虑启用RESP3协议,支持数据压缩传输,从而降低内存消耗(尤其是在带宽受限的场景下)。但这主要影响的是网络传输效率而非Redis本身的内存使用。

综合以上策略,结合具体的业务场景和数据模型进行针对性优化,能够有效提升Redis内存使用的效率。


redis是如何保证事务的ACID特性的

Redis事务并不完全符合ACID(原子性、一致性、隔离性和持久性)特性中所有标准的定义,特别是在分布式环境下的强一致性方面。但Redis通过其特有的机制在一定程度上支持了部分ACID特性:

  • 原子性(Atomicity):Redis中的事务虽然不能像传统数据库那样执行复杂的SQL事务,但它确实保证了事务内的命令序列会作为一个整体执行,要么全部执行成功,要么一个都不执行。客户端通过MULTI命令开启事务,然后将多个命令放入队列,在调用EXEC命令时一次性提交执行这些命令。如果在EXEC之前连接断开或发生错误,Redis会拒绝执行事务。
  • 一致性(Consistency):Redis的“一致性”主要是指数据结构操作的一致性规则,例如增删改查等操作后,数据状态保持逻辑上的正确。但是,由于Redis不支持跨多条命令的约束检查,所以要实现业务层面的一致性需要由应用程序开发者确保每个命令本身满足业务规则。
  • 隔离性(Isolation):Redis事务的隔离级别相对较低,它采用的是简单乐观锁模型,即通过WATCH命令监视某些键,如果在执行EXEC前被监视的键被其他客户端修改,则整个事务会被取消(回滚)。这种机制实现了某种程度的事务并发控制,但并不能阻止脏读、不可重复读和幻读等问题。
  • 持久性(Durability):在Redis事务中,持久化主要取决于Redis本身的持久化策略,如RDB快照和AOF日志,并非事务本身提供的功能。在事务执行完毕后,即使服务器崩溃重启,只要相应的持久化策略生效,数据更改依然能够保存下来。

因此,Redis的事务处理更偏向于批处理命令而不是严格意义上的ACID事务,它提供了一种有限的事务支持方式来提升操作效率,并通过WATCH命令提供了简单的并发控制能力。在实际应用中,若需要更强的事务保障,可能需要结合具体业务场景使用额外的机制来确保数据的一致性和完整性。


Redis中的缓存雪崩和缓存穿透什么情况会发生 如何解决

缓存雪崩是指在某个时间段内,大量Redis缓存数据集中过期失效或者Redis服务器出现故障导致无法提供服务的情况。这种情况下,原本应该由缓存承载的请求会全部涌入后端数据库,造成数据库短时间内承受极高并发访问的压力,可能会导致系统崩溃。

发生场景

  • 所有缓存数据使用相同的过期时间,当这些数据同时过期时,大量请求直达数据库。
  • Redis集群中多个节点同时宕机或网络中断,导致整个缓存层不可用。

解决办法:

  • 分散过期时间:为不同的缓存设置随机的过期时间,避免大量缓存在同一时刻失效。
  • 热点数据永不过期:对于重要的热点数据,可以设置其永不过期,或者通过定期刷新机制更新缓存,而不是等待自然过期。
  • 限流降级:对到达数据库的请求进行限流,防止过多请求压垮数据库,在压力过大时采用降级策略。
  • 高可用集群:搭建Redis高可用集群,包括主从复制、哨兵模式或Redis Cluster等方案,保证单点故障时能自动切换到其他正常节点继续提供服务。
  • 熔断与重试:在客户端实现熔断和重试机制,当检测到Redis服务异常时,暂时阻止请求直接访问数据库,并在一段时间后再尝试连接Redis。

缓存穿透是指查询一个一定不存在的数据时,由于缓存中没有该数据且数据库中也没有,每次请求都会直接打到数据库,从而使得大量的无效请求绕过缓存直击数据库,给数据库带来巨大压力。

发生场景:

  • 查询不存在的数据并被恶意攻击。
  • 系统设计不当,未对空结果也做缓存处理。

解决办法:

  • 缓存空值:即使查询结果为空,也将空值缓存起来,但要注意设置合理的过期时间以防止内存被大量无效键占用。
  • 布隆过滤器:在请求到达Redis之前,先经过一个布隆过滤器,过滤掉那些肯定不存在于数据库中的请求,从而避免直接查询数据库。
  • 预加载热门或默认数据:对于某些常用查询,即使实际数据为空,也可以预先加载一些默认值到缓存中。
  • 权限控制与认证:如果是恶意攻击行为,则需要在前端或API层面上增加权限控制和认证机制,限制非法请求的产生。
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1、什么是 Redis? 2、Redis 相比 memcached 有哪些优势? 3、Redis 支持哪几种数据类型? 4、Redis 主要消耗什么物理资源? 5、Redis 的全称是什么? 6、Redis 有哪几种数据淘汰策略? 7、Redis 官方为什么不提供 Windows 版本? 8、一个字符串类型的值能存储最大容量是多少? 9、为什么 Redis 需要把所有数据放到内存中? 10、Redis 集群方案应该怎么做?都有哪些方案? 11、Redis 集群方案什么情况下会导致整个集群不可用? 12、MySQL 里有 2000w 数据,Redis 中只存 20w 的数据, 如何保证 Redis 中的数据都是热点数据? 13、Redis 有哪些适合的场景? 14、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个? 15、RedisRedisson 有什么关系? 16、Jedis 与 Redisson 对比有什么优缺点? 17、Redis 如何设置密码及验证密码? 18、说说 Redis 哈希槽的概念? 19、Redis 集群的主从复制模型是怎样的? 20、Redis 集群会有写操作丢失吗?为什么? 21、Redis 集群之间是如何复制的? 22、Redis 集群最大节点个数是多少? 23、Redis 集群如何选择数据库? 24、怎么测试 Redis 的连通性? 25、Redis 中的管道有什么用? 26、怎么理解 Redis 事务? 27、Redis 事务相关的命令有哪几个? 28、Redis key 的过期时间和永久有效分别怎么设置? 29、Redis 如何做内存优化? 30、Redis 回收进程如何工作的? 31、Redis 回收使用的是什么算法? 32、Redis 如何做大量数据插入? 33、为什么要做 Redis 分区? 34、你知道有哪些 Redis 分区实现方案? 35、Redis 分区有什么缺点? 36、Redis 持久化数据和缓存怎么做扩容? 37、分布式 Redis 是前期做还是后期规模上来了再做好?为 什么? 38、Twemproxy 是什么? 39、支持一致性哈希的客户端有哪些? 40、Redis 与其他 key-value 存储有什么不同? 41、Redis 的内存占用情况怎么样? 42、都有哪些办法可以降低 Redis 的内存使用情况呢? 43、查看 Redis 使用情况及状态信息用什么命令? 44、Redis 的内存用完了会发生什么? 45、Redis 是单线程的,如何提高多核 CPU 的利用率? 46、一个 Redis 实例最多能存放多少的 keys?List、Set、 Sorted Set 他们最多能存放多少元素? 47、Redis 常见性能问题和解决方案? 48、Redis 提供了哪几种持久化方式? 49、如何选择合适的持久化方式? 50、修改配置不重启 Redis 会实时生效吗?
关于Java和Redis面试题,你可以参考以下资源: 1. "Java基础教程(入门篇)"这本书中可能包含与Java和Redis相关的基础知识点,例如如何连接和操作Redis以及在Java中使用Redis的常见场景。 2. "java面试大集合"这本书中可能包含Java和Redis面试题,涵盖了Java技术栈以及与Redis相关的问题。你可以浏览这本书中的相关章节以寻找你感兴趣的Java和Redis面试题。 3. "Java基础教程(进阶篇)"这本书可能包含更深入的Java和Redis面试题,例如Java高并发和如何在Java中使用Redis进行缓存。 这些资源可能会给你提供一些有关Java和Redis面试题的参考。你可以根据自己的需求和兴趣选择适合的资源进行学习。希望这些资源能帮助到你。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [redis面试题总结(附答案)](https://blog.csdn.net/guorui_java/article/details/117194603)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [java面试大集合一共485页](https://download.csdn.net/download/wm9028/88268176)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泽济天下

你的鼓励是我最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值