Redis实战笔记2026:部署、数据类型与生产排障全攻略
发布时间:2026/9/28 23:18:48 作者:尧图编辑部 阅读量:1,286

不用怀疑标题这套Redis笔记确实是我压箱底的东西。从2018年第一次在生产环境部署Redis到现在中间踩过的坑、查过的源码、整理过的应急预案零零散散记了七八年。2026年这版不是简单换个年份我把过时的命令、废弃的配置项、已经改版的客户端工具全部重新过了一遍同时补齐了阿里云环境下的RDS托管、云服务器部署、Docker容器化、Maven仓库配置等实操内容顺手把面试高频题和线上故障排查方法整理成了速查表。内容不追新但一定够用适合正在学Redis的人、马上要背面试题的人以及想把生产环境里的缓存问题彻底搞清楚的人。1. 为什么Redis值得花时间吃透以及这套笔记的核心思路1.1 Redis到底解决了什么问题我说点实际的Redis是个内存型数据库处理的是“热数据”的读写问题。很多人在初学阶段把它当成一个“高级点的HashMap”这没错但只看到了表面。如果你把应用想象成一家餐厅MySQL是后厨的大仓库所有食材、半成品都存在里面但每次招待客人都要跑大仓库翻一遍速度跟不上。Redis就是前台那张登记台客流高峰前你把这些客人最常用的菜品信息、库存余量、会员余额摆到前台服务员一抬手就能拿到不用再往后厨跑。但Redis能做的事远不止缓存。它支持字符串、哈希、列表、集合、有序集合这些基础类型还有Bitmap、HyperLogLog、Geo这几种高级结构能做分布式锁、延迟队列、排行榜、UV统计、附近的人。再加上Redis Cluster、哨兵、主从复制这套高可用体系它基本成了一个独立的基础设施而不是某个应用里的附属组件。这套笔记不是为了让你记住几条命令而是帮你建立一套完整的使用框架什么场景该用哪种结构、部署的时候选什么形态、出了问题怎么排查。我见过太多人把Redis用成“缓存分布式锁”其实还有很多玩法没发挥出来。2026版我在内容上做了几处调整删掉了已经过时的配置和旧版客户端写法的示例补上了Docker、RDS、云服务器这三种部署形态的对比增加了大量线上故障的真实案例。1.2 2026版重写了哪些内容适合谁看这套笔记的主体分四块环境搭建、数据类型、工程实战、运维排障。每一块都是围绕“实际能用”这个标准来写的。环境搭建部分覆盖了Windows本机、Linux服务器、Docker容器、阿里云RDS四种部署方式数据类型部分用真实的业务场景串讲而不是罗列命令工程实战部分包含Java接入方式、序列化方案、Maven阿里云仓库配置、分布式锁和缓存治理运维排障部分包括日志分析、慢查询定位、连接数排查和常见问题速查表。不同人拿到的价值不一样。如果你是个完全没接触过Redis的新手按顺序读就行前面环境搭建部分足够把你带到能跑起来的程度后面案例部分相当于提前帮你趟一遍雷。如果你有两年左右工作经验重点看第三部分的缓存治理和第四部分的排障思路这两块是最靠经验积累的也是面试最容易深挖的地方。如果你正在准备面试最后一章整理过的高频题和答案方向可以直接拿来复习。2. 环境准备从零装好Redis并配上一套顺手的可视化工具2.1 Windows本机安装别在这上面浪费太多时间很多教程喜欢在Windows上用官方MSI安装包但我更推荐下载ZIP压缩包解压即用理由只有一个干净。官方Windows安装包会把Redis注册成Windows服务还会改注册表卸载起来很麻烦。ZIP包下载下来解压到一个固定目录比如D:\redis接下来就完事了。# 启动服务端 D:\redis\redis-server.exe D:\redis\redis.windows.conf # 另开一个窗口启动命令行客户端 D:\redis\redis-cli.exe -h 127.0.0.1 -p 6379启动之后先在客户端里输入ping返回PONG说明通了。Windows版本有几个注意点一是这个版本本质是微软维护的移植版版本号通常落后于Linux官方版本只适合本地学习别用在生产环境二是配置文件里默认protected-mode yes如果后面想从其他机器连接只改bind和protected-mode还不够还要配置requirepass否则按默认配置你是连不上的。本地学习阶段有个常见误区非要在Windows上把Redis Cluster跑起来。我劝你别折腾Windows版对Cluster的支持不够好报错都不太一样。本地只练单机命令就够了分布式相关的内容上Docker或者云服务器后面第三部分会讲到。2.2 Linux安装并交给systemd托管这才是标准姿势Linux下安装Redis其实简单到让人意外但很多人栽在一个细节上直接用redis-server 把进程丢后台完事。这种用法的问题在于进程和终端会话绑在一起一旦SSH断开Redis就可能跟着没了。正确做法是把Redis交给systemd托管让系统负责拉起和守护。以CentOS类的系统为例# 方式一包管理器安装 yum install redis # 方式二源码编译安装可自定义版本 wget https://download.redis.io/releases/redis-7.2.4.tar.gz tar xzf redis-7.2.4.tar.gz cd redis-7.2.4 make make install老一点的系统可能会遇到yum install redis装不上或者报源失效我之前在低版本系统上就吃过这个亏。解决办法是先换一套可用的软件源排在里面的阿里云镜像源节点在国内访问速度很好非阿里云ECS也可以直接用。换源之后再安装就不会报Error: Failed to download metadata之类的错误了。装完之后改Redis配置并创建systemd服务。关键配置项先用一组自己验过的# redis.conf 核心配置 bind 0.0.0.0 protected-mode yes port 6379 requirepass your_strong_password daemonize no logfile /var/log/redis/redis.log dir /var/lib/redis maxmemory 2gb maxmemory-policy allkeys-lru appendonly yes appendfsync everysec这里有个原则很多人不清楚配置里不要写daemonize yes。因为一旦交给systemd托管systemd期望前台进程被管理daemonize yes会让systemd误判服务状态出现“明明Redis活着但systemctl status显示失败”的诡异情况。Redis官方很早就明确推荐用supervised systemd systemd管理而不是自己daemonize。# /etc/systemd/system/redis.service [Unit] DescriptionRedis Server Afternetwork.target [Service] ExecStart/usr/local/bin/redis-server /etc/redis/redis.conf ExecStop/usr/local/bin/redis-cli shutdown Restartalways Userredis Groupredis [Install] WantedBymulti-user.target写完执行systemctl daemon-reload然后systemctl enable --now redis。启动后用redis-cli -a your_password ping验证。平时看日志、重启、看状态都走systemctl不要手动kill进程。2.3 用Docker跑主从复制一只文件帮你搭完整套高可用本地学习阶段我强烈建议用Docker跑一个最小化的主从复制环境。好处是干净、可重复、拆了重建只需一条命令不会把你自己的系统环境搞乱。先创建个目录放编排文件内容如下# docker-compose.yml version: 3.8 services: redis-master: image: redis:7.2-alpine container_name: redis-master command: redis-server --appendonly yes --requirepass masterpass ports: - 6379:6379 volumes: - ./master-data:/data redis-slave: image: redis:7.2-alpine container_name: redis-slave command: redis-server --slaveof redis-master 6379 --masterauth masterpass --requirepass slavepass ports: - 6380:6379 volumes: - ./slave-data:/data depends_on: - redis-master在主库里写数据去从库能看到docker exec -it redis-master redis-cli -a masterpass set foo bar docker exec -it redis-slave redis-cli -a slavepass get foo返回bar说明主从同步生效了。这里有个细节容易踩坑Redis 5.0之前配置项叫slaveof从5.0开始陆续引入replicaof作为替代到7.x已经全部替换为replicaof。网上大量旧教程还在用slaveof老版本用着没问题换到新版Redis就报参数不识别了。我上面用的--slaveof其实是为了兼容说明新版本建议直接用--replicaof redis-master 6379。主从复制是Redis高可用的地基哨兵和Cluster都是在这个机制上扩展的。理解这一层的同步流程后面排查“主库切了之后从库数据不一致”这类问题会轻松很多。2.4 可视化客户端怎么选Redis Desktop Manager还是Another Redis Desktop Manager命令行再熟练日常开发调试我还是喜欢配一个可视化客户端看数据、看TTL、看key分布都直观得多。市面上一堆GUI工具我用过的几款里被问得最多的就是这两个Redis Desktop ManagerRDM和Another Redis Desktop ManagerAnother RDM。两者核心区别我做了一张对照表方便大家选型维度Redis Desktop ManagerRDMAnother Redis Desktop Manager开源情况早期开源后续商业化开源免费社区活跃界面语言英文为主支持中文重命名key、批量删除支持支持操作更顺手连接类型TCP/SSH等常规方式支持TCP/SSH/集群等多种方式适合人群老牌用户、习惯英文界面中文用户、希望长期免费用的团队我的个人建议是如果只是本地连一个Redis两者随便选顺手最重要。如果公司要求不能装商业软件那就直接Another RDM。有一点提醒一下可视化工具再方便生产环境排查问题的时候命令行依然是底线技能。很多工具看一眼“连接不上”“读取超时”就给你一堆红色报错但实际上有用的信息在redis-cli info输出里。工具能辅助效率不能替代基本功。3. 把Redis放到阿里云上RDS、云服务器与Docker的落地选择3.1 云上Redis的三种用法先搞清楚自己该选哪种你的项目上了阿里云之后Redis怎么部署是自动容易忽略但影响很大的问题。主要选项就三个用云数据库Redis版RDS、在ECS上自己装、在ECS上用Docker跑。三者的优缺点和适用场景差得很多看这张表维度云数据库Redis版RDSECS自建ECSDocker部署成本有实例费围绕规格梯次定价只用付ECS费用只用付ECS费用运维负担云厂商负责主从切换、备份、监控自己装、自己备份、自己处理故障介于两者之间容器化降低环境差异高可用能力自带高可用架构故障自动切换需要自己搭哨兵/Cluster可以用Docker编排但复杂定制能力受云厂商控制台限制完全可控可控性高维护成本中等弹性扩展可在控制台扩规格但变更需谨慎手动迁移或加集群节点相对灵活选型逻辑其实很朴素。没有专职DBA的团队、预算允许的场景直接用RDS最省心。我自己在业务项目里就常用RDS因为它的主从切换、自动备份、监控报警这些能力是成熟的不需要自己半夜爬起来处理故障。反过来说如果你们对Redis版本有强需求、要改内核参数、或者Redis数据量极大需要靠实例规格之外的定制那就ECS自建。Docker更适合中等规模、团队有容器化经验、希望快速在测试环境复刻一套Redis的场景。另外要注意RDS和自建Redis在参数上有些差别。RDS为了保障托管实例稳定部分参数是锁定的比如config set这类动态命令在很多版本里不开放。你在本地玩顺手了config set上了RDS会发现不好使这时候别慌去控制台的参数组里改改完一般要重启实例才生效。3.2 RDS实操经验白名单、参数组、连接数规划如果你最终选了RDS有三件套要配好白名单、参数组、连接池。缺一个后面都会变成线上事故。白名单是很多新手第一个坑。第一次创建实例默认白名单通常只放行内网地址本地电脑连不上。有人图省事直接把白名单设成0.0.0.0/0这等于把数据库裸露在公网上扫描工具一打一个准。正规做法是在RDS控制台的“白名单”里只添加你应用所在的ECS内网IP或者安全组ID。如果你本地要调试临时加一下自己当前公网IP调完立刻删掉。参数组里重点关注三个参数。第一个是maxmemory-policy默认是noeviction意思是内存满了新写入直接报错这会导致线上莫名出现OOM command not allowed when used memory maxmemory。如果你把它改成allkeys-lruRedis会在内存满时自动淘汰最少使用的key适合做纯缓存场景。第二个是timeout空闲连接多久断建议设一个非零值比如300秒避免一堆空闲连接占着不释放。第三个是appendfsync如果对数据安全要求高可以设always但会明显影响写入性能常规业务用everysec就够了。连接数规划是个很容易拍脑袋的事。RDS实例规格不同最大连接数也不同超出之后会直接拒绝新连接。预估时别只算平均QPS要看业务峰值的那十分钟。我之前有个项目活动一开始QPS翻了三倍连接数瞬间打满应用侧全部超时排查到最后就是连接池配置偏小加上RDS规格偏低。那两个数字要匹配应用层连接池上限加起来不要超过RDS最大连接数的80%留点余量给运维排查工具和临时任务。3.3 工程配套Maven配置阿里云仓库顺手接上云SDK搞定了Redis本身接着就要在工程里接它。Java后端几乎是标配地会遇到Maven依赖下载慢的问题尤其是新环境第一次构建拉几百个jar包能把人急死。解决办法是在Maven的settings.xml里配置阿里云仓库把中央仓库指向国内节点下载速度会快非常多。mirrors mirror idaliyunmaven/id mirrorOf*/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror /mirrors这个配置写在${MAVEN_HOME}/conf/settings.xml里对所有工程生效也可以写在项目内~/.m2/settings.xml。配完之后Maven下依赖会优先走这个镜像源。如果你还用到了阿里云的短信服务、OSS对象存储、百炼平台的API等等对应的SDK也是走Maven依赖引入这时候镜像仓库就更有用了因为这些SDK及其传递依赖往往有一大堆。接Redis的话Spring Boot项目里简单直接spring: data: redis: host: r-xxx.redis.aliyuncs.com # RDS实例的内网连接地址 port: 6379 password: ${REDIS_PASSWORD} timeout: 3s lettuce: pool: max-active: 200 max-idle: 50 min-idle: 10Lettuce是Spring Boot默认的Redis客户端基于Netty连接复用做得不错。但注意一个坑Lettuce在遇到网络异常时连接状态恢复有时不那么及时如果线上偶发“Redis command timed out”除了看网络还可以考虑换成Jedis。Jedis虽然线程不安全但够简单配合连接池用排查心智负担小很多。我自己线上项目两种都用过小规模应用Jedis反而更直白Lettuce的优点在连接数极高的场景才能体现出来。3.4 HTTPS证书续期、网关重启顺手把Redis连接池检查一遍热词里有个“阿里云SSL证书免费续期”这件事本身是云上应用配HTTPS时经常遇到的。我在实际维护中观察到证书自动续期或手动替换后Nginx或网关经常会重启重启的那一瞬间所有经过网关的请求会重新建立后端连接其中Redis连接池如果没调好马上会出现一波连接风暴。所以我养成了一个习惯每次做证书续期这类动静较大的变更时顺手检查三样东西。第一Redis的连接池最大连接数配置是不是过高超过了RDS规格上限第二连接池的最小空闲连接数是不是维持了太多空闲连接太多也没意义浪费资源第三代码里有没有每次请求都new一个连接、用完不close这种写法是泄漏源时间长了连接数悄悄涨满。JedisPoolConfig config new JedisPoolConfig(); config.setMaxTotal(200); config.setMaxIdle(50); config.setMinIdle(5); config.setTestOnBorrow(true); config.setTestOnReturn(true); JedisPool pool new JedisPool(config, host, port, 3000, password);setTestOnBorrow(true)会在每次借连接时做一次ping验证能淘汰坏连接代价是每次操作多一次网络往返不过对绝大多数业务可以忽略。这个参数是我调连接池时的底线配置默认值false虽然性能好一点但在云环境偶发网络抖动时容易借到坏连接很坑。4. 数据类型与序列化八种核心结构一次讲透4.1 五种基础类型到底什么场景用什么结构很多人背数据类型背得滚瓜烂熟到真写代码的时候还是全往String里塞。这是没把类型和业务场景建立对应关系。我这里直接摆一张多年使用沉淀下来的对照表类型典型业务场景常用命令String缓存、计数器、分布式ID、验证码、会话tokenSET、GET、INCR、EXPIREHash对象属性存取、购物车、用户资料HSET、HGET、HDEL、HGETALLList消息队列、最新评论、操作日志LPUSH、RPOP、LRANGESet去重、抽奖、好友关注、标签SADD、SISMEMBER、SINTERZSet排行榜、延时队列、限流滑动窗口ZADD、ZRANGEBYSCORE、ZREVRANK举例说登录验证码用String就够了SET code:13800138000 123456 EX 300五分钟后自动失效不用自己再起个定时任务清理。用户购物车用Hash最合适一个用户一个key商品ID是field数量是value加减商品就是在hash上做操作不用把整个购物车序列化成一个JSON再覆盖写回去。排行榜和延迟队列是ZSet的两大经典玩法。排行榜直接以score存分数ZREVRANGE取前几名延迟队列则以时间戳当score轮询脚本用ZRANGEBYSCORE task:later 0 now把到期任务取出来处理。用ZSet做延迟队列有一个好处同一个score重复插入不会丢而且取数据时可以原子地移除不会出现两个消费者取到同一条任务的问题。4.2 三种高级类型Bitmap、HyperLogLog、Geo用对了都是杀手锏String之外还有三种高级结构它们不是噱头是专门为了解决特定类型问题设计的。先讲Bitmap。它本质是String上的位操作适合存状态开关类的海量数据。我做过的典型场景是“用户签到统计”一年365天一个用户一个Bitmap key第几天签到就把那一位设成1。统计这个用户连续签到多少天用BITCOUNT配合BITFIELD的GET就能算出来不需要扫数据库几十万行记录。在线状态也类似几十万用户在线与否Bitmap只占几十KB。再讲HyperLogLog。它的特点是内存占用极小赢在固定适合做大规模去重统计最典型的场景是UV独立访客。一天的用户访问量如果做到千万级存Set会占几百MB换成HyperLogLog只占12KB左右。代价是统计结果有约0.81%的误差。如果你做的是“大概多少用户进来过”这种量级统计这个误差完全能接受。最后是Geo。它基于ZSet实现专门处理经纬度相关的“附近的人”问题。存入门店坐标GEOADD shop:geo 116.397128 39.916527 北京门店 GEODIST shop:geo 北京门店 上海门店 km GEORADIUS shop:geo 116.40 39.92 5 km WITHCOORD这样“查询附近5公里门店”的需求不用接地图SDK也能先做一版接口出来点数不多时性能非常好。需要注意的是Geo底层是ZSetscore是经纬度的编码值不要手动去改这个score否则坐标就乱了。4.3 序列化方案怎么选好看的代码背后藏着线上事故Java项目接入Redis时序列化是最容易埋雷的地方。Spring Data Redis默认用的是JdkSerializationRedisSerializer直接把对象二进制序列化后丢进Redis。好处是写代码省事坑也很深第一存进去的东西肉眼完全不可读在Redis客户端里看到一堆\xAC\xED\x00\x05t...没法排查第二一旦某个类字段改了旧缓存反序列化直接报错第三如果项目以后要对接非Java的服务Jdk序列化数据根本没法读。我推荐的做法是key统一用StringRedisSerializervalue用GenericJackson2JsonRedisSerializer或者自带类型信息的序列化器。手动控制格式存到Redis里是一眼能看懂的JSON排查问题的时候至少能知道这条数据是什么。RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(connectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); template.afterPropertiesSet();另一个实际经验是给不同的业务模块的key加统一前缀比如order:info:10001、user:profile:13800138000。这么做的好处是排查线上问题时可以按照前缀批量扫描归类的key而不是从几百万个杂乱key里大海捞针。还有用了JSON序列化后存储空间比Jdk序列化小很多对内存紧张的Redis实例来说是立竿见影的优化。5. 分布式锁与缓存治理生产环境最考验功底的两个方向5.1 分布式锁的正确打开方式手写SETNX和Redisson怎么选分布式锁是Redis使用频率极高的功能也是网上文章水分最大的话题之一。最原始的实现其实就是一条命令SET lock:order:10001 uuid_value NX EX 30NX保证只有key不存在时才能设置成功相当于加锁EX 30是锁的过期时间防止持有锁的进程挂了之后锁永远不释放。释放锁的时候不能直接DEL因为可能存在一种情况线程A的锁已经过期了线程B拿到了锁此时线程A的延时任务跑完一个DEL把B的锁删了。解决办法是删除前先比对value用Lua保证原子性if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end手写这套方案能应对简单业务但有个麻烦锁过期时间设长了万一持有者真挂了几分钟其他线程干等设短了正常业务还没跑完锁就过期了其他线程趁虚而入。业务复杂时我建议直接用Redisson。它内置了“看门狗”机制默认每10秒检查一次只要锁持有者还活着就自动续期彻底解决了“业务没跑完、锁先过期”的死结。Redisson还支持可重入同一线程可以在持有锁的状态下继续加锁不会死锁。RLock lock redissonClient.getLock(order: orderId); if (lock.tryLock(3, 30, TimeUnit.SECONDS)) { try { // 业务逻辑 } finally { lock.unlock(); } }一句话总结简单场景手写SETNXLua够用复杂的、长时间的业务锁直接上Redisson不必自己造轮子。无论如何都要记住锁的value一定要用唯一ID比如UUID绝不能写固定的常量字符串。5.2 缓存三大问题穿透、击穿、雪崩每一类都有对应的解法线上缓存出问题九成集中在三个词上缓存穿透、缓存击穿、缓存雪崩。这三个东西名字像但成因和解法完全不同。缓存穿透指的是“查一个神仙都不存在的key”缓存和数据库里都没有于是每次都打到数据库。高并发场景下攻击者可以伪造一批不存在的ID疯狂请求数据库直接被拖垮。解决方案有两个层次第一层是缓存空值查不到数据库时也把空结果缓存一分钟再给key额外加个“空标记”第二层是布隆过滤器把所有可能存在的ID先放进过滤器请求来时先用过滤器判断不存在直接返回。缓存击穿说的是“某个热点key正好过期了”大量请求同一时刻涌去数据库。和穿透的区别是这个key在数据库里是存在的只是缓存刚好失效。最简单有效的办法是互斥锁重建缓存时先拿锁拿到锁的线程去查库并重建缓存其他线程先返回旧数据或者短暂等待。也可以用逻辑过期的方法优点是性能好缺点是实现起来要处理“旧数据过期但正在重建”的状态逻辑更复杂。缓存雪崩是大量key在同一段时间内集体过期或者Redis直接宕机。如果是过期时间设置的问题好办在基础过期时间上加一个随机值比如EXPIRE key 3600 random(0, 600)把这些key的过期时间打散。但真正主因往往是Redis宕机或者网络分区这种时候缓存全废流量直接打满数据库。除了依赖云RDS的高可用和主从切换业务侧还要考虑降级方案比如本地缓存兜底或者限流。5.3 缓存一致性先更新数据库还是先删缓存别再凭感觉写缓存治理里最容易被低估的是缓存一致性问题。很多人知道“先更新数据库再删缓存”但不清楚为什么要这么做。直接说结论Cache Aside模式是推荐的即读的时候先查缓存没有则查库并回填写的时候先更新数据库再删除缓存。为什么不“先更新缓存再更新数据库”因为并发环境下会出现不可挽回的旧值。线程A先更新了缓存为“新值”线程B在数据库更新前读到了这个新值但线程B因业务失败回滚了数据库缓存里的“新值”就永远变成假数据了。反过来“先更新DB再删缓存”只有一种极端竞态线程A更新DB后删缓存之前线程B读到了旧的缓存值这个窗口期极短而且等缓存被删后就会回源数据最终一致。还要注意更新DB和删缓存这两个动作不是原子事务删缓存可能失败。所以生产级写法是补一个“延迟双删”删完缓存后过几百毫秒再删一次这样即便写库期间读线程回填了旧缓存也能被第二次删除清掉。再严谨一点用MQ异步通知一个消费者去删缓存删除失败还可以重试。我自己实际项目里用过延迟双删效果够用但延迟时间要根据业务耗时来定务业逻辑重的话几百毫秒不够需要调高。6. 日志、慢查询、监控与高频面试题快答6.1 Redis日志和慢查询到底要怎么看生产排障必备线上Redis出问题第一件事不是猜原因而是看日志和慢查询。Redis日志默认在logfile配置指定的路径我一般把日志级别设成notice这个级别信息量刚好。平时看日志主要找四类东西启动失败配置语法错误、端口占用、持久化出错RDB fork失败、AOF写盘失败、主从同步断连sync频繁中断、内存超限告警。慢查询是定位延迟问题最直接的入口。用命令查询# 查最近10条慢查询 slowlog get 10 # 设置阈值为10毫秒超过的记录 config set slowlog-log-slower-than 10000 config set slowlog-max-len 256注意slowlog-log-slower-than的单位是微秒10000等于10毫秒。业务正常的Redis单命令延迟通常不到1毫秒一旦出现超过10毫秒的操作就要重点排查Key是否过大、是否存在阻塞命令比如KEYS *、SMEMBERS全量返回、是否触发了AOF重写或RDB保存。线上千万别临时执行KEYS *大库上这一条命令能把Redis卡住几秒。要扫描key就用官方推荐的SCAN游标遍历。INFO命令是状态读取宝库。我常态化看三个指标keyspace_hits和keyspace_misses两个计数器的命中率低于90%说明缓存价值没发挥出来connected_clients是否接近maxclientsused_memory和maxmemory的差值。命中率不高的问题比较隐蔽它不报错但说明很多请求没走缓存对于热点系统来说是个持续放血的隐患。6.2 高频Redis面试题和可用的答案方向面试题这部分我本来不想写因为网上一搜一大堆但热词里“redis面试题”搜得确实多所以整理几个最核心的附上我认为能过关的回答角度。不用背答案理解背后的逻辑就够了。第一个问题Redis为什么快四个维度答到位纯内存操作IO多路复用单线程高效处理海量连接底层数据结构经过优化比如跳表、压缩列表对于特定场景性能极好单线程模型避免了多线程上下文切换和锁竞争。第二个问题Redis单线程为什么还能处理高并发关键在IO多路复用。Redis的网络读写和命令处理都在一个线程里但通过epoll等机制同时监听大量客户端连接只有数据就绪的连接才会被处理避免了阻塞等待。第三个问题RDB和AOF怎么选一句话RDB是某个时间点的全量快照恢复快但有丢数据风险AOF记录每次写操作数据更安全但文件大、恢复慢。生产环境通常是RDBAOF混用RDB做冷备AOF做精细恢复。第四个问题分布式锁怎么实现先说SET NX EXLua防误删再说Redisson看门狗续期和可重入再提一嘴主从切换导致锁丢失这种极端情况能区分出你是有生产经验的人。第五个问题Redis集群为什么是16384个槽位因为槽位数量经过设计CRC16算法对key计算后对16384取模。槽位太多消息头开销大太少数据倾斜调整难16384在可用性和开销之间平衡。实际回答不需要背数字细节但至少知道槽位是集群分配数据的基础。第六个问题内存淘汰策略有哪些基础八种按两类记noeviction是默认满了直接报错allkeys-lru全局按LRU淘汰allkeys-random随机淘汰volatile-lru只淘汰设置了过期时间的key。对纯缓存场景allkeys-lru是最常用的。6.3 线上问题排查速查表一张表对照着查省一半时间下面这些场景都是我在真实环境里遇到过的整理成表方便快速定位现象可能原因排查手段解决方向连接超时白名单未放行、网络不通、连接数打满检查安全组/白名单INFO clients看连接数补访问策略调大连接池缓存全是垃圾数据key过期时间没设置TTL抽查看配置文件是否设了默认过期业务代码统一加过期时间内存涨到60%以上持续不降大量带TTL的key堆积INFO memory、SCAN扫描大key开启淘汰策略重构缓存key结构偶发命令延迟突刺大key阻塞、AOF重写、RDB forkslowlog查看是否在BGSAVE拆分大key调整持久化策略重启后数据丢了一部分AOF策略配置不当查appendfsync、恢复文件大小改everysec或always定期备份锁偶尔失效主从切换、锁过期时间过短查看锁日志、过期时间设定上Redisson合理设置过期时间应用连接数持续增长代码连接泄漏排查是否有未close的Jedis连接使用连接池规范关闭这张表是“速查”定位不是万能药。更深的排查还是要配合慢查询日志和监控数据一起看。但有一个原则我反复讲线上出问题不要先改配置先看日志和数据定位清楚再动手。最后一章内容到这里正好打住。我整理这套2026版笔记的时候最深的感受是Redis这类基础组件看着简单真正吃透还是靠场景积累。两年前我处理过一个凌晨2点的故障告警白天排查了半天没头绪最后发现就是连接池泄漏加过期时间设置不合理两个问题叠加。所以大家看完笔记一定要自己动手把环境装起来跑一遍踩一遍坑记得比看十遍文章都牢。如果你照着这套笔记搭好了环境欢迎在评论区把你在安装、配置、排障中遇到的新问题丢出来共同补全这个速查表。