fundamentals.md

·interview-questions

Q:你在项目中使用 Redis 做了什么缓存?能举例说明使用 Redis 带来的性能提升幅度吗?是否做过基准测试或压测?

A:

Q:说一下热点 key 和大 key

A:热点 key 主要是在高并发场景下被频繁读写的同一个 redis key,短时间内 QPS 极高,单点压力过高导致 redis 性能下降,甚至会击穿后端,大 key 则是指 redis 中存储的单个 key 占用内存过大,可能会阻塞 redis 主线程或导致内存溢出、慢查询等问题,解决方法的话可以将单个热点 key 拆成多个子 key,然后对同一 key 并发请求做请求合并,只发一次真实请求,其他请求等待结果复用,也可以把主从节点做读写分离;大 key 的话可以拆分成小 key,然后渐进式迭代访问,分批读取,使用哈希结构这样每次广播可以只做差量更新

Q:为什么学 redis?是否了解其他分布式缓存技术?

A:嗯因为 redis 本身是一个性能非常高的内存数据库,有丰富的数据结构,功能也非常强大,既能做缓存也能做消息队列、分布式锁等,使用起来也很方便,正好在项目中也有这方面功能实现的需求,所以我就选择了 redis,目前只是简单学了一下它的使用,底层我还在学习中,现在主要是用它来做项目里的房间状态缓存和游戏事件的快速推送;另外我也了解过其他的分布式缓存技术,比如说 Memcached,它是一个高性能的分布式内存对象缓存系统,主要用于加速动态 Web 应用程序,通过减轻数据库负担来提高性能 ,但它不支持数据持久化和复杂的数据结构,只适合简单的请求缓存

Q:讲一下 redis 的缓存雪崩,击穿和穿透以及解决方法

A:缓存穿透是指用户频繁请求不存在的数据,每次都无法在缓存中命中,又直接打到了数据库,这个主要是要对请求参数做合法校验,比如用布隆过滤器,或者直接存一个空值并设置较短的 TTL,这样就可以缓解数据库压力;缓存击穿主要是指某个热点 key 恰好在高并发时刻过期,导致大量并发请求无法命中缓存,同时击穿到数据库做查询或写入,瞬间击垮后端,这个主要要设置热点 key 的过期时间为随机值,也可以使用互斥锁来加锁,只有一个请求能去查询数据库,其他请求等待结果,或后续并发复用同一个结果;缓存雪崩就是指大量缓存,比如整个 redis 实例或大批 key 在同一时间点集中到期,或 redis 整体不可用,导致所有请求都到数据库,形成雪崩式的流量冲击,这个主要是要设置不同的过期时间,避免同一时间点集中到期,同时也可以使用多级缓存,比如在业务进程内做一层 LRU,让热点数据优先走本地,或采用 redis 集群和限流降级

Q:redis 的 QPS,单机顶不住,该怎么办

A:当我发现单机 redis 达到 QPS 瓶颈后,首先会在实例内排查慢命令,避免全表扫描并使用批量写入、单条原子增量命令代替多条写入,同时在应用层加进程级本地缓存来减少对 redis 的打击,如果单机硬件已升级到极限,就要使用主从复制和读写分离,把写请求集中到主节点,读请求分给多个从节点,然后做自动路由,随着业务继续扩张的话就要考虑部署 redis cluster,把数据分片到多个主节点,每个再配从节点做高可用,Cluster 模式下节点宕机能自动故障切换,扩缩容也更灵活

Q:经常用 redis 的哪几种类型

A:我最常用的是 String、哈希、List、Set、Sorted Set 和 Pub/Sub,String 是用来做验证码、分布式锁、计数器,哈希是用来存储用户会话、房间状态等对象,List 是用来做消息队列、任务队列,Set 和 Sorted Set 是用来做排行榜、标签等,Pub/Sub 是用来做实时消息推送和事件通知等,另外根据不同场景我也会用 Stream 做可靠消息流,HyperLogLog 做大数据量的去重,Geo 做地理位置相关的查询等

Q:有过使用分布式锁的经验吗,分布式锁底层用的是哪两个命令

A:我在项目里主要是用 redis 做分布式锁,底层主要是用 SETNX 抢锁,然后再用 EXPIRE 给锁设置 TTL,释放时会先用一段 Lua 脚本来校验锁的持有者标识,只有匹配才会执行 DEL,避免误删锁

Q:redis 集群是什么,你的 redis 是什么集群,主 redis 宕机了库存还能做吗

A:redis 集群是一种分布式部署方案,通过主从、分片和故障自动转移来实现高可用,在我的项目中我用的是 redis cluster 模式,一共三主三从,16384 个哈希槽自动分片,如果主节点宕机,集群会自动触发 failover 把从节点提升为主节点来继续处理请求,不影响业务,如果用 redis 做库存,那在设计上会配合主从复制、幂等扣减、数据库兜底等机制,确保即使 redis 出故障也不会出现库存丢失或订单错误