1. 为什么 Java 后端离不开 Redis
1.1 从一次接口超时说起
前阵子帮一个刚转 Java 的同事排查线上问题,场景特别典型:一个订单查询接口,数据库每秒扛到几千次查询,高峰期直接打满连接池,接口从几十毫秒一路涨到几秒。我上去一看代码,里面没有任何缓存,所有请求全部怼到 MySQL。当时我做的第一件事,就是给热点订单数据加了一层 Redis 缓存。加完之后接口耗时直接掉到个位数毫秒,数据库压力瞬间降了一大截。
这个场景你应该不陌生。只要你做的系统要撑住并发,迟早会碰到“数据库扛不住”的瓶颈。这时候 Redis 几乎就是 Java 后端技术栈里的默认答案。这些年我见过不少项目,小到单机服务,大到一二十个节点的集群,都在用 Redis 做缓存、做分布式锁、做计数器、做排行榜。它上手快、生态成熟,Java 里用 Spring Boot 接入也就几行配置的事。但越是容易上手的东西,越容易被用糙。很多人把 Redis 当成了“一个能存数据的 Map”,用完 GET/SET 就觉得自己会了,结果一上生产就各种翻车。
这篇文章不打算讲那些人人都能搜到的命令手册,而是从一个 Java 开发者的实际使用视角,拆一拆 Redis 作为分布式缓存的核心技术点:该掌握到什么程度、怎么用才稳、缓存三大坑怎么踩平、分布式锁怎么做才算合理,以及面试官真正想考你的是什么。
1.2 本地缓存与分布式缓存的区别
先理清楚一个概念:为什么说 Redis 是“分布式”缓存,它和你在代码里写的 HashMap、ConcurrentHashMap 到底差在哪。
本地缓存指的是 JVM 进程内的缓存。你用 Caffeine、Guava Cache,或者干脆用一个 ConcurrentHashMap 存数据,查询的时候先查本地内存,没命中再查库。优点是快,因为不经过网络,直接读内存;缺点是每个 JVM 实例各存一份,数据不一致。一旦服务部署了多个节点,A 节点更新了缓存,B 节点还是旧数据。如果缓存的是用户会话、商品库存这种强一致数据,本地缓存就应付不了。
分布式缓存是独立部署的缓存服务,所有应用节点通过网络共享同一份缓存数据。Redis 就是最典型的代表。节点 A 写入 key,节点 B 立刻能读到;数据一致性由缓存服务统一保证,应用只负责调用客户端。它的代价是每次读写都多一次网络 IO,性能比本地缓存慢几个量级,但换来的是多实例共享、集中管理、持久化、过期策略这些分布式场景必须的能力。
那两者能互相替代吗?不能。实际项目里更常见的做法是“多级缓存”:一级用 Caffeine 做本地缓存挡掉 90% 的热点流量,二级用 Redis 做分布式缓存扛住集群共享的那部分数据,最后才打到底层数据库。这种方案我后面还会细讲,先说结论:本地缓存解决性能上限,Redis 解决数据一致性和共享问题,两者不是替代关系,是协作关系。
1.3 Redis 到底赢在哪里
Redis 的核心优势归纳起来就八个字:快、简单、丰富、可靠。
快,是因为它是纯内存操作,单线程 IO 多路复用模型下,QPS 能轻松破十万,极限可以到十几万。简单,是因为数据模型就是 key-value,命令语义清晰,几乎没有学习曲线。丰富,是指它提供了 String、Hash、List、Set、ZSet、Stream 等多种数据结构,同一个缓存中间件还能兼职做分布式锁、延迟队列、排行榜、布隆过滤器。可靠,是指它支持 RDB 和 AOF 两种持久化方式,支持主从复制、哨兵、集群,能构建高可用架构。
但 Redis 也不是万能的。它没有原生事务(准确说是弱事务),不支持复杂的 SQL 查询和联合索引,内存成本远高于磁盘存储。所以你不能什么数据都往 Redis 里塞,得想清楚哪些数据值得进缓存、缓存多久、淘汰策略是什么。把 Redis 用明白的人,本质上是在做数据分层:什么数据放内存、什么数据放磁盘、什么数据可以丢、什么数据必须持久化。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Redis 安装与环境准备
2.1 Windows 快速安装(含可视化客户端)
很多用 Windows 开发机的朋友,一上来就卡在环境安装上。Redis 官方其实没有正式支持 Windows,微软过去维护过一个老版本分支,后面也不再更新了。现在的主流做法有两种。
第一种:直接用 Redis 官方提供的 Windows 移植版,去 Redis 官网或者 GitHub releases 页面找带 .zip 或 .msi 后缀的 Windows 包。下载后解压到你想要的目录,比如 D:\redis,打开命令行进入该目录,执行:
bash复制redis-server.exe
看到 Ready to accept connections 的日志就说明启动成功了。默认端口 6379,默认无密码,本地开发够用。想换端口或设置密码时,编辑同目录下的 redis.windows-service.conf,改完启动命令后带配置文件路径:
bash复制redis-server.exe redis.windows-service.conf
第二种:用 Docker 在 Windows 里跑 Linux 容器。这种方式更接近生产环境,后面我会单独讲。Windows 下用 Docker Desktop 装一个 Redis 镜像,比下载移植版更干净,升级也方便。
开发环境下我建议再装一个可视化客户端。热词里很多人搜 Redis Desktop Manager,这个工具现在改名叫 Another Redis Desktop Manager,界面更现代,功能也更全,支持连接多个 Redis 实例、查看 key、执行命令、分析大 key。连接的时候填服务器地址、端口,如果有密码就在对应位置填上,几乎不需要额外配置。
注意:Windows 下 redis-server.exe 启动后会占用当前命令行窗口,关掉窗口 Redis 就停了。想挂后台可以注册成 Windows 服务,用
redis-server --service-install redis.windows-service.conf来注册,之后用net start redis启动。
2.2 Linux 与 Docker 方式部署
生产环境里,Redis 几乎都跑在 Linux 上。如果用宿主机直接部署,流程是下载源码、编译、安装。
bash复制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
安装完成后,redis-server 命令就进系统 PATH 了,编辑一个自定义配置文件,比如 /etc/redis/redis.conf,然后启动:
bash复制redis-server /etc/redis/redis.conf
几处生产必改的配置项我要单独提一下:
daemonize yes:后台运行,否则 SSH 一断开 Redis 就停了。requirepass:设置访问密码,生产环境必须开。bind:默认只监听 127.0.0.1,外部访问要改成实际内网 IP,千万不要直接绑 0.0.0.0 并暴露到公网,否则会被恶意扫描攻击。protected-mode:没设密码时最好保持 yes,避免被局域网内其他机器随意连接。
如果用了 Docker,部署就更简洁。先把数据和配置目录挂载出来,方便升级和维护:
bash复制docker run -d --name redis \
-p 6379:6379 \
-v /data/redis/data:/data \
-v /data/redis/redis.conf:/etc/redis/redis.conf \
redis:7.2 redis-server /etc/redis/redis.conf
Docker 部署的另一个隐藏价值是方便搭主从和集群。比如主从复制,一条命令就能起一个从节点:
bash复制docker run -d --name redis-slave -p 6380:6379 \
-v /data/redis-slave/data:/data \
redis:7.2 redis-server --slaveof 192.168.1.10 6379
生产环境我见过很多团队用 Docker Compose 把 Redis 主从、Sentinel、集群一次性编排起来,比在裸机上一个个起进程省事太多。不过主从复制只解决数据备份和读扩展,不解决自动故障转移,想做到高可用,还得上哨兵或集群方案。这部分内容在面试里考得很多,后面统一讲。
2.3 开发环境的前置检查:JDK 与 Maven
这一步很多人容易忽略。Redis 本身是 C 语言写的,不依赖 Java,但你作为 Java 开发者要用它,本机肯定得有可用的 JDK 和 Maven 环境。我看到热词里大量的人在搜 java 环境变量配置和 java 安装,这里顺嘴提
