高频缓存面试题及答案_第1页
高频缓存面试题及答案_第2页
高频缓存面试题及答案_第3页
高频缓存面试题及答案_第4页
高频缓存面试题及答案_第5页
已阅读5页,还剩14页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

高频缓存面试题及答案1.缓存穿透的定义、产生原因及解决方案?缓存穿透指查询一个数据库和缓存中都不存在的数据,导致请求直接打到数据库。产生原因通常是恶意攻击(如伪造不存在的key)或业务逻辑错误(如查询条件错误)。解决方案包括:布隆过滤器:在缓存层前使用布隆过滤器,预先存储所有可能的有效key。查询时先检查布隆过滤器,若不存在则直接返回,避免数据库压力。需注意布隆过滤器存在误判率(即可能将不存在的key判断为存在),需结合业务场景调整哈希函数和位数组大小。空值缓存:当数据库查询结果为空时,仍将空值(如null)写入缓存,并设置较短的过期时间(如5-10分钟)。后续相同查询会直接从缓存返回空值,避免重复查库。但需注意空值缓存可能占用内存,需评估无效key的数量。接口校验:在API入口对请求参数进行合法性校验(如ID格式、范围),过滤明显无效的请求(如负数ID、超长字符串)。2.缓存击穿的定义、典型场景及解决方法?缓存击穿指热点key在缓存中突然失效(如过期),导致大量并发请求同时打到数据库。典型场景是秒杀活动中的商品信息、热门文章详情等高频访问的key过期。解决方法包括:互斥锁(锁机制):当发现缓存失效时,先尝试获取分布式锁(如Redis的SETNX)。只有获取锁的线程查询数据库并更新缓存,其他线程等待缓存更新后重新查询。需注意锁的超时时间设置(避免死锁)和锁的粒度(细粒度锁减少竞争)。提前更新:对热点key设置“逻辑过期时间”(如在缓存中存储实际过期时间戳),在业务线程访问时,若发现当前时间超过逻辑过期时间但未真正过期,异步触发缓存更新,避免实际过期。热点数据永不过期:对长期稳定的热点数据(如配置信息、字典数据)设置不过期,通过后台任务定时更新缓存,或在数据库更新时主动刷新缓存。3.缓存雪崩的定义、触发条件及应对策略?缓存雪崩指缓存层大规模失效(如大量key同时过期、缓存服务宕机),导致所有请求涌入数据库,可能引发数据库宕机甚至整个系统崩溃。触发条件包括:批量key设置相同过期时间(如活动结束后所有商品缓存同时失效);缓存服务器集群宕机(如Redis主从全挂)。应对策略包括:分散过期时间:为key的过期时间添加随机偏移量(如基础时间+0-5分钟随机值),避免批量失效。例如,原过期时间30分钟,调整为30+random(0,5)分钟。二级缓存:使用两层缓存(如本地缓存+分布式缓存)。第一层本地缓存(如Caffeine)设置较短过期时间,第二层分布式缓存(如Redis)设置较长过期时间。当分布式缓存失效时,本地缓存仍可短暂支撑流量。限流降级:在缓存失效时,通过限流组件(如Sentinel)限制数据库的访问频率,或对非核心业务降级(如返回默认值、提示稍后重试)。持久化与快速恢复:缓存服务启用持久化(如Redis的RDB+AOF),宕机时可快速从快照恢复数据;同时部署集群(如RedisCluster),避免单点故障。4.如何保证缓存与数据库的一致性?缓存与数据库的一致性是指两者数据在任意时刻的差异不超过可接受范围。常见策略及优缺点如下:Cache-Aside(旁路缓存)模式:读:先读缓存,命中则返回;未命中则读数据库,将结果写入缓存后返回。写:先更新数据库,再删除缓存(而非更新缓存)。优点:实现简单,避免缓存与数据库的强同步;缺点:更新后可能存在短暂不一致(删除缓存后,新请求会读取旧数据并重新写入缓存)。ReadThrough(读穿)模式:读操作由缓存层代理,缓存未命中时由缓存层负责加载数据库数据并更新缓存,应用层只需调用缓存接口。写操作通常结合WriteThrough模式。WriteThrough(写穿)模式:写操作时,先更新缓存,缓存层同步更新数据库(或异步批量更新)。应用层只需操作缓存,由缓存层保证最终一致性。优点:强一致性;缺点:写入延迟高(同步写库),适用于对一致性要求高的场景(如账户余额)。WriteBehind(写回)模式:写操作时仅更新缓存,缓存层异步批量更新数据库(如按时间或数量阈值)。优点:写入性能高;缺点:存在数据丢失风险(缓存未刷盘时宕机),适用于允许短暂不一致的场景(如日志记录)。补充策略:异步消息队列:更新数据库后,发送消息到队列,由消费者删除或更新缓存,解决主从库延迟导致的不一致(如主库更新后,从库未同步时缓存可能读取旧数据)。分布式锁:在高并发写场景中,使用分布式锁(如RedisRedlock)保证同一key的更新操作串行执行,避免脏数据。5.Redis作为分布式缓存的常见数据结构及适用场景?Redis支持多种数据结构,需根据业务场景选择:String(字符串):最基础类型,存储序列化后的对象(如JSON)、计数器(如UV/PV统计)、分布式锁(SETkeyvalueNXPX)。Hash(哈希):存储对象属性(如用户信息的name、age、email),避免序列化整个对象,支持部分字段更新(HSET/HGET)。List(列表):实现队列(LPUSH/RPOP)或栈(LPUSH/LPOP),如消息队列的待处理任务;支持按索引范围查询(LRANGE),适用于分页场景(如朋友圈动态列表)。Set(集合):存储唯一元素,支持交集(SINTER)、并集(SUNION)、差集(SDIFF)操作,适用于共同好友、标签去重等场景。SortedSet(有序集合):通过score排序,支持按分数范围查询(ZRANGEBYSCORE),适用于排行榜(如积分排名、热搜榜单)。Bitmap(位图):通过位操作存储布尔值,节省内存(1字节=8位),适用于签到统计(用户ID对应位标记是否签到)、在线状态(百万用户仅需约122KB)。HyperLogLog(基数统计):近似统计集合的基数(去重元素数量),误差率约0.81%,适用于UV统计(如日活用户数)。6.Redis的持久化机制有哪些?各自优缺点及选择建议?Redis提供RDB(快照)和AOF(追加日志)两种持久化方式,可组合使用。RDB(RedisDatabaseBackup):原理:定期(如配置save9001)将内存数据快照写入磁盘(默认文件dump.rdb)。支持手动触发(SAVE/BGSAVE),BGSAVE通过fork子进程执行,避免阻塞主进程。优点:文件紧凑(二进制格式),恢复速度快(直接加载快照);适合全量备份和容灾。缺点:数据完整性依赖快照间隔(如每5分钟快照,故障时可能丢失5分钟数据);fork子进程在内存大时可能耗时,导致主进程短暂阻塞。AOF(AppendOnlyFile):原理:记录所有写操作命令(如SET、HSET),追加到AOF文件(默认appendonly.aof)。支持配置同步策略(appendfsync):always(每条命令同步,最安全但最慢)、everysec(每秒同步,平衡安全与性能)、no(由操作系统决定,最快但可能丢失较多数据)。优点:数据完整性高(everysec策略最多丢失1秒数据);AOF文件可读性高(文本格式),可手动修复(如使用redis-check-aof工具)。缺点:文件体积大(记录所有写操作),恢复速度慢(需重放所有命令);长期运行可能因大量写操作导致AOF文件过大,需通过BGREWRITEAOF重写(合并重复命令,如多次SET同一key仅保留最后一次)。选择建议:对数据完整性要求高的场景(如支付、账户):启用AOF(everysec)+RDB,兼顾备份与恢复;对性能要求高、允许少量数据丢失的场景(如缓存热点数据):仅启用RDB,或AOF设置为no;生产环境通常建议同时启用两种持久化,RDB用于快速恢复,AOF用于保证数据完整性。7.Redis的内存淘汰策略有哪些?如何选择?当Redis内存达到maxmemory限制时,会根据配置的淘汰策略删除数据。Redis4.0+支持8种策略(旧版本6种):LRU相关:allkeys-lru:所有key中移除最近最少使用(LeastRecentlyUsed)的key;volatile-lru:仅在设置了过期时间的key中移除LRU的key;LFU相关(Redis4.0+):allkeys-lfu:所有key中移除最不经常使用(LeastFrequentlyUsed)的key;volatile-lfu:仅在设置了过期时间的key中移除LFU的key;随机淘汰:allkeys-random:所有key中随机移除;volatile-random:仅在设置了过期时间的key中随机移除;TTL淘汰:volatile-ttl:仅在设置了过期时间的key中移除即将过期的(TTL最小的);不淘汰:noeviction(默认):内存不足时拒绝写操作(读操作仍正常),适用于不能丢失数据的场景(如持久化存储)。选择建议:缓存场景(允许淘汰):优先allkeys-lru(假设大部分key访问频率相似)或allkeys-lfu(存在热点key时,LFU更高效,因考虑访问次数);混合存储(部分key需持久化):使用volatile-lru或volatile-lfu,仅淘汰设置了过期时间的key;测试或对数据无要求:allkeys-random;需优先淘汰快过期的key(如限时活动):volatile-ttl。8.Redis集群方案对比(主从复制、哨兵、Cluster)?主从复制(Master-Slave):架构:一个主节点(写),多个从节点(读)。主节点同步数据到从节点(全量同步+增量同步)。优点:实现简单,支持读写分离(降低主节点压力);缺点:主节点宕机后需手动切换,无法自动故障转移;无法水平扩容(内存受限于单节点)。哨兵(Sentinel):架构:在主从基础上增加哨兵集群(至少3个节点),监控主节点状态。当主节点宕机时,哨兵自动选举新主节点,并更新从节点指向新主。优点:自动故障转移,提升高可用性;缺点:仍无法水平扩容(数据分片需手动管理);主节点内存瓶颈未解决。RedisCluster(集群):架构:采用分片(Sharding)机制,数据通过哈希槽(16384个)分布在多个节点(每个节点负责部分哈希槽)。支持自动故障转移(多数节点认为某节点宕机时,从其从节点选举新主)。优点:水平扩容(增加节点可扩展内存和性能);自动分片与故障转移;缺点:实现复杂(客户端需支持路由);跨节点操作(如多key的MSET)需注意哈希槽分布(需相同哈希槽或使用{}强制哈希)。选择建议:数据量小(单节点内存足够)、需高可用:哨兵;数据量大(需分片)、需高可用和扩展性:RedisCluster;简单读写分离(无高可用需求):主从复制。9.本地缓存与分布式缓存的区别及适用场景?本地缓存:存储在应用进程内存中(如Java的Caffeine、GuavaCache)。优点:访问速度极快(内存级),无网络开销;缺点:各应用实例缓存独立,数据不一致(如分布式系统中,实例A更新缓存,实例B可能仍读取旧值);内存受限于单实例(无法横向扩展)。适用场景:高频访问、数据量小、允许短暂不一致的场景(如配置信息、字典数据);减少对分布式缓存的访问压力。分布式缓存:独立部署的缓存服务(如Redis、Memcached),所有应用实例共享。优点:数据集中管理,一致性高;可水平扩容(通过集群);缺点:存在网络开销(RTT约1-10ms);单点故障需高可用方案(如哨兵、Cluster)。适用场景:分布式系统中共享的热点数据(如商品详情、用户会话);数据量较大需分片存储。10.缓存设计时的关键考虑点有哪些?缓存键设计:避免重复和冲突,使用统一前缀(如"user:info:{userId}"),保证可读性和可维护性;避免过长键(浪费内存),但需包含足够标识信息(如区分不同业务的key)。缓存粒度:细粒度缓存(如用户的单个属性)可减少冗余,但增加缓存数量;粗粒度缓存(如整个用户对象)减少缓存数量,但更新时可能浪费(如仅更新一个属性需淘汰整个对象)。需根据业务更新频率权衡。过期时间:避免所有key同一过期时间(防雪崩);结合业务场景设置合理过期时间(如实时性要求高的5分钟,静态数据1天);对热点key可动态延长过期时间(如访问时刷新TTL)。缓存预热:系统启动时主动加载热点数据到缓存(如从数据库批量查询并写入),避免启动后缓存未命中导致数据库压力。缓存降级:当缓存服务不可用时,降级处理(如直接访问数据库、返回默认值、记录异常),避免级联故障。监控与报警:监控缓存命中率(理想>90%,低则需检查缓存策略)、内存使用(防淘汰)、QPS(防流量突增)、延迟(网络或节点故障);设置阈值报警(如内存使用率>80%、命中率<70%)。11.如何处理Redis大key问题?大key指单个key的value过大(如String类型>10MB,Hash类型字段数>1000),会导致:网络传输延迟(读取/删除大key耗时);内存分布不均(集群中某节点内存压力大);持久化时阻塞(RDB/AOF写大key耗时)。处理方法:拆分大key:将大对象拆分为多个小key(如用户订单按时间分片为"order:user1:202401"、"order:user1:202402");压缩数据:对String类型的大value使用压缩算法(如gzip),存储压缩后的数据(需权衡压缩/解压缩耗时与网络传输时间);异步处理:删除大key时使用UNLINK命令(异步删除,避免主线程阻塞);监控大key:通过redis-cli--bigkeys扫描大key,定期清理无效大key(如过期数据)。12.缓存命中率低的可能原因及优化方法?可能原因:缓存策略不合理(如过期时间过短,热点数据频繁失效);缓存粒度过粗(存储大量不常用数据);业务访问模式变化(如突发冷门数据访问);缓存穿透(大量无效key导致未命中)。优化方法:调整过期时间(对热点key延长TTL,或设置永不过期+定时更新);细化缓存粒度(仅缓存高频访问的字段,而非整个对象);分析访问日志(通过Redis慢日志或监控工具),识别高频访问的key,调整缓存策略;解决缓存穿透(如布隆过滤器、空值缓存)。13.Redis的事务机制及局限性?Redis事务通过MULTI(开启事务)、EXEC(执行事务)、DISCARD(取消事务)实现。事务内的命令会被放入队列,EXEC时按顺序执行,中途不会被其他客户端命令打断。局限性:不支持回滚(仅支持“要么全执行,要么全不执行”,但执行中某条命令失败(如类型错误),其他命令仍会执行);不支持跨节点事务(RedisCluster中,事务涉及的key需在同一节点);弱一致性(事务执行期间,其他客户端可修改数据,因Redis不支持行锁,仅通过WATCH实现乐观锁)。适用场景:需批量执行多个命令且要求原子性的场景(如账户转账的扣减与增加),但需结合WATCH监控关键key(如WATCHbalance后,若balance被修改,事务会失败)。14.如何用Redis实现分布式锁?需注意哪些问题?常见实现(基于SETNX+EXPIRE原子操作):```java//获取锁:SETkeyvalueNXPX30000(NX表示仅当key不存在时设置,PX设置过期时间30秒)//释放锁:Lua脚本(保证原子性)StringunlockScript="ifredis.call('get',KEYS[1])==ARGV[1]thenreturnredis.call('del',KEYS[1])elsereturn0end";```需注意

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论