在 Windows 上启动 Redis,这件事看起来小,但真的能拦住一批人。我自己从 Redis 3.x 时代就在 Windows 上折腾过,当时微软还维护着官方移植版,双击 redis-server.exe 就能跑;后来官方明确不维护 Windows 版,网上教程也跟着乱了起来,有人喊你用 Docker,有人让你装 WSL,有人直接甩给你一个旧编译包,导致文档对不上、版本对不上,越搞越晕。这篇文章就把“Windows 系统启动 Redis”这件事完整捋一遍,从选版本、下载安装、改配置、启动服务,到验证连接、排错,再到本地缓存和分布式锁的实战接入,适合刚接触 Redis 的初学者,也适合被连接超时、闪退、端口占用折磨的日常开发。
1. 版本选型:为什么 Windows 启动 Redis 这么绕
1.1 官方不维护 Windows 版,不等于没得选
先讲清楚背景。Redis 官方 server 的目标平台是 Linux 和 macOS,Windows 从来没被列入官方支持范围。早年微软在 GitHub 上维护过一个 Redis 的 Windows 移植分支,版本停留在 2.x/3.x,用来本地学习足够,但新特性、性能优化统统跟不上。这种现象让很多人误以为“Windows 跑不了 Redis”,其实不是跑不了,而是需要绕个路。
目前在 Windows 上把 Redis 跑起来,主流就四条路:
| 方案 | 典型代表 | 版本范围 | 适合场景 |
|---|---|---|---|
| Windows 原生移植版 | tporadowski/redis | Redis 5.x | 本地学习、快速起服务、测试脚本 |
| 兼容 Redis API 的商业软件 | Memurai | 兼容 Redis 7.x | 不想碰 Linux 的 Windows 团队、生产环境对齐 |
| WSL2 内运行 | 官方 Redis | Redis 7.x | 开发环境贴近生产、体验纯正 Linux 下的 Redis |
| Docker Desktop 容器 | 官方 redis 镜像 | Redis 7.x | 多版本切换、隔离环境、团队协作 |
我的建议很直接:临时在本机起一个服务做学习、测试,优先用 tporadowski 的 Windows 安装包,原生体验最好,双击就能装成 Windows 服务。如果公司线上是 Redis 6 或 Redis 7,需要本地对齐版本,就走 WSL2 或 Docker。Memurai 更多是给“公司政策不允许装虚拟机/WSL”的环境准备的,它安装方便,API 兼容性也做得不错。
1.2 选 5.x 还是 7.x,影响到底有多大
不少新手会纠结“Windows 上只能找到 Redis 5,我是不是落后了”。说实话,对大部分日常开发来说,5.x 和 7.x 在基本命令层面高度一致,String、List、Hash、Set、ZSet 这些数据结构哪一代都能用,SET/GET、EXPIRE、LPUSH、HSET 这些命令也是通用的。真正拉开差距的是 Redis 7 引入的 sharded pub/sub、ACL 精细权限、更好的过期清除机制,以及 Streams 的增强能力。
所以判断标准就一条:你要新特性,还是只需要稳定好用?做本地缓存、分布式锁、session 共享,5.x 完全撑得住。要跟线上版本严格一致,或者要用 ACL、Redis 7 的流式能力,那就别在原生 Windows 版上硬凑,直接切到 WSL2 或 Docker 的官方镜像。你甚至可以同时在 Windows 上跑一个 6379 端口的 5.x,再在 WSL2 里跑一个 6380 端口的 7.x,两边对比着学,压根不用非此即彼。
2. 下载安装与初始化:最省事的原生路径
2.1 下载安装包时认准这两个细节
如果你决定走 Windows 原生移植版,去 GitHub 搜索tporadowski/redis,看 releases 页面里最新的 Windows 安装包,通常是Redis-x64-5.0.14.1.msi这种格式。下载安装时有两个细节容易踩坑:
第一,安装路径里不要带中文和空格。很多工具在解析配置文件时会因为路径里的空格把参数截断,Redis 在 Windows 上本来就是个移植版,对路径容忍度更低。我通常装在C:\Redis,干净好记,后面对路径或查日志都方便。
第二,MSI 安装过程中会询问是否注册为 Windows 服务,建议勾选。注册成服务的好处是开机自启、后台常驻,不用每次都开窗口敲命令。如果不勾选,后面也可以手动注册,这个我放到下一章讲。
装完之后,你会在安装目录里看到redis-server.exe、redis-cli.exe、redis.windows.conf这几个关键文件。redis-server.exe是服务端,redis-cli.exe是命令行客户端,配置文件是redis.windows.conf,注意不是 Linux 版的redis.conf,文件名差一点,但内容格式一样。
2.2 安装后先做一次体检
装完别急着点服务,先做两件事。第一,打开命令行窗口,进入安装目录,手动执行redis-server.exe redis.windows.conf看前台能不能起来。正常情况下会看到一行带版本号的 Logo,以及Running in stand alone mode之类的输出,最后停在Server initialized。
为什么先手动跑一遍?因为这样你能直接看到启动日志,任何配置问题都会在窗口里立刻报出来。我见过太多人直接启动 Windows 服务,失败后只能去翻系统事件日志,信息又少又难找;而前置执行能在一分钟内暴露出绝大多数问题,比如配置路径错误、端口被占用。
第二件事是确认端口。默认情况下 Redis 监听 6379,这个端口特别容易被其他软件占用,尤其是本地装了一堆开发工具时。手动启动后如果看到bind: No error或报错退出,大概率就是端口冲突,排查方法我放在后面的常见问题章节,这里先记住:启动日志是最直接的诊断入口。
3. 启动服务的核心实操:前台、服务化、配置一次讲透
3.1 三种启动方式分别什么时候用
第一种是前台启动。命令行进入C:\Redis,执行redis-server.exe redis.windows.conf。这种方式适合调试,窗口不关,Redis 就一直在跑,Ctrl+C 就能停。缺点是关掉窗口服务就断了,而且只能占住一个命令行窗口。
第二种是服务启动。如果你是 MSI 安装时勾选了注册服务,那么打开“服务”(Win+R 输入 services.msc),能看到一个名为Redis的服务,点启动即可。命令行也可以操作:
redis-server --service-start --service-name Redis这种方式最贴近日常使用,开机自启、后台运行、不占窗口。我自己的习惯是:开发机上把 Redis 装成服务,用的时候不用关心它启动没启动。
第三种是临时指定配置启动。有时候你只想开一个临时实例,比如测一下不同端口、不同密码,可以这样:
redis-server --port 6380 --requirepass 123456服务化实例和临时实例可以共存,只要端口不同就行。这在实际开发里特别有用,比如你想在 6380 端口开一个只做缓存、里面数据清空了也不心疼的实例,就跟 6379 的正式实例完全隔离。
3.2 配置文件里必须改的几个参数
用记事本打开redis.windows.conf,不要急着全改,先盯住这几个关键项:
bind 0.0.0.0 protected-mode no requirepass yourpassword maxmemory 256mb maxmemory-policy allkeys-lru appendonly yes logfile "redis_log_6379.txt"我来逐个解释为什么。bind 0.0.0.0是允许所有网卡上的连接访问,默认配置可能只允许本机回环地址,如果你要从另一台电脑连这台 Windows 上的 Redis,不改这个就连接不上。但这里有个安全前提:只建议在内网或本机开发环境这么干,别把没设密码的 Redis 直接暴露到公网,否则会被恶意脚本扫描、写脏数据甚至勒索。
requirepass设置访问密码,生产环境必须设置,开发环境我也建议设置,哪怕密码简单点。因为在 Windows 上,Redis 很可能是开发机上的一个常驻服务,你不设密码,同一个局域网里的同事或测试脚本随时能把你的缓存内容清空。
maxmemory和maxmemory-policy是给 Redis 加个内存上限。新手最容易忽略的就是这个,跑着跑着内存飙满,系统开始卡顿。默认的noeviction策略到了上限就直接返回错误,写不进数据;改成allkeys-lru后,内存不够时会优先淘汰最久没用的 key,对缓存场景特别合适。256mb 是我给本地开发环境常用的值,具体按你机器内存调整。
appendonly yes开启 AOF 持久化,追加方式记录写操作。这个配置保证机器重启后数据还在,而且是按操作日志重放,丢数据的窗口很小。如果只是临时测试、不在乎重启丢数据,可以不开。
最后是logfile,重要程度被很多人低估。Windows 服务模式启动时,窗口不可见,日志写到哪里决定了你能不能定位问题。设置一个相对路径,比如redis_log_6379.txt,启动失败或运行异常时,直接打开安装目录下的这个文件看报错,比抓系统事件日志高效太多。
改完配置后,如果是服务模式,记得先重启服务让配置生效:命令行执行redis-server --service-stop --service-name Redis,再执行redis-server --service-start --service-name Redis。
4. 连接验证与工具链:从命令行到可视化界面
4.1 redis-cli 是最快的验证手段
服务启动后,第一件事就是验证它真的能响应请求。打开命令行,执行:
redis-cli -h 127.0.0.1 -p 6379 -a yourpassword ping返回PONG就代表 Redis 正常响应。这里有个小坑:加了-a密码后,命令行会提示你密码明文暴露在进程列表里,Windows 本地使用无所谓,但如果是在服务器环境的命令行里,建议改用交互方式:先不传 -a,进入 redis-cli 后执行auth yourpassword。
验证完 ping,顺手把五个常用数据结构过一遍:
SET user:1 "zhangsan" GET user:1 HSET user:1 name "lisi" age 18 HGETALL user:1 LPUSH news:list "headline-1" LRANGE news:list 0 -1 SADD tags "java" "redis" SMEMBERS tags ZADD scores 90 "player1" ZRANGE scores 0 -1 WITHSCORES这些命令分别对应 String、Hash、List、Set、ZSet,都返回正常就说明 Redis 实例完全可用了。我建议新手在正式写代码之前,先用 redis-cli 把所有常用命令试一遍,因为很多代码里遇到的“奇怪问题”,其实只是对数据结构理解不透。
4.2 可视化工具怎么选、怎么连
命令行用熟练了,日常管理还是有个可视化界面更舒服。我用过不少,结论是分两类:
第一类是Another Redis Desktop Manager,GitHub 上开源,界面简洁,连接树、key 浏览、命令行面板都有,个人开发完全够用。它的优势在于免费、跨平台、更新活跃,我目前的主力工具就是它。
第二类是Redis Insight,Redis 官方出的可视化客户端。它比第三方工具有个明显优势,能直接展示内存分析报告,哪些 key 占了多少内存、哪些过期时间设置不合理,一眼就能看出来。适合排查线上 Redis 内存爆炸的问题,本地开发用起来也顺手。
连接配置很固定:主机填127.0.0.1,端口填6379,密码填你设置的requirepass。如果连不上,优先检查三件事:Redis 服务有没有跑、密码对不对、bind和protected-mode有没有把你挡在外面。
5. 高频故障排查实录:我在 Windows 上踩过的坑
5.1 端口被占用:最经典的启动失败原因
现象是启动redis-server.exe后立刻报错退出,或者 Windows 服务启动了但又自动停掉。这类问题我遇到的最多,原因九成是 6379 被别的进程占了。
排查命令很简单:
netstat -ano | findstr 6379看到协议、本地地址和 PID,然后去任务管理器里找这个 PID 的进程,或者用命令强制结束:
taskkill /F /PID 进程号但这里有个被我反复踩过的坑:有些软件占端口是暂时的,你杀掉之后它还会重新占用。更稳妥的做法是直接把 Redis 换到其他端口,比如 6380,改配置文件里的port参数,然后重启服务。端口只是一个数字,没有玄学意义,能跑通才是目的。
5.2 闪退与服务启动失败:日志是最好的侦探
Windows 上启动 Redis 闪退,很多人第一反应是重装,其实没必要。服务模式启动失败时,去“事件查看器”里翻系统日志,信息又少又难懂;更直接的是打开你配置的logfile文件,看最后几行。
我遇到过的几类日志错误如下:
| 日志特征 | 原因 | 处理方式 |
|---|---|---|
Can't open the log file | 日志路径目录不存在或无权限 | 改用绝对路径,确认目录存在 |
Can't chdir to './' | 当前工作目录不对 | 从安装目录启动,或用绝对路径指定配置文件 |
Could not create server TCP listening socket *:6379: bind: No error | 端口被占用 | 执行 `netstat -ano |
# Warning: no config file specified | 服务没有读到你期望的配置文件 | 启动时显式加redis.windows.conf参数 |
其实大部分启动问题都是路径、端口、权限这三个老演员,别慌,按日志逐行看,基本十分钟内能定位。
5.3 连接超时、拒绝连接:别急着怀疑代码
这个场景太常见了:Java 项目里 Spring Boot 报Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException,或者redis-cli直接提示连接失败。
我现在的排查顺序是固定的:先ping 127.0.0.1看网络通不通,再telnet 127.0.0.1 6379看端口通不通,然后确认 Redis 进程是否在跑,接着检查配置里的bind、protected-mode、requirepass三项。如果是远程连接,还要看 Windows 防火墙有没有放行 6379。
防火墙放行命令如下:
netsh advfirewall firewall add rule name="Redis 6379" dir=in action=allow protocol=TCP localport=6379这条命令在 Windows 10/11 上通用。值得注意的是,即使 Redis 配了密码,也不建议把 6379 无条件暴露给所有来源,更稳妥的做法是在防火墙规则里限定只允许公司内网网段访问,比如把remoteip设成192.168.1.0/24。
5.4 配置改了没生效:常见认知误区
很多人改完redis.windows.conf,重启了服务,但设置还是老样子。问题多半出在服务启动时根本没有加载你改的文件。MSI 安装的服务默认有固定的启动参数,你手动改文件之前,先确认服务对应的是哪个配置文件,方法是:
sc qc Redis这个命令会显示 Redis 服务的二进制路径和启动参数,如果指向的是redis-server.exe --service-run,说明它默认加载安装目录下的redis.windows.conf。如果你手动修改的文件放到了别的目录,服务根本读不到。所以我的经验是:配置文件只放在安装目录下,且文件名保持默认,这样最省心。
6. 启动 Redis 之后:缓存与分布式锁的实战接入
6.1 用 Redis 做本地缓存:Spring Boot 最小接入
Redis 跑起来不接入代码就白跑了。最典型的是做缓存,Spring Boot 项目里引入依赖后,配置几个连接参数,就能把热点数据查库改成先查 Redis。
连接参数是:
spring: redis: host: 127.0.0.1 port: 6379 password: yourpassword代码上用StringRedisTemplate或者RedisTemplate,写入读取示例:
@Autowired private StringRedisTemplate redisTemplate; public void setUserCache(String userId, String userJson) { redisTemplate.opsForValue().set("user:" + userId, userJson, 30, TimeUnit.MINUTES); } public String getUserCache(String userId) { return redisTemplate.opsForValue().get("user:" + userId); }设置 30 分钟过期时间,是为了避免缓存数据一直堆在 Redis 里。这个模式里最容易犯的错是忘记设置过期时间,导致 Redis 内存越来越大。如果你用的是注解式缓存,还需要统一配置缓存过期策略,否则每个注解的失效时间都不一样,排查起来会很麻烦。
缓存治理这块,稍微往深一点说,生产环境经常要面对缓存穿透、缓存击穿、缓存雪崩。穿透是指查询一个根本不存在的 key,每次都打到数据库;击穿是指一个热点 key 失效,大量请求同时打到数据库;雪崩是大量 key 同时过期,数据库瞬间被压垮。常见应对思路是:穿透用空值缓存或布隆过滤器,击穿用互斥锁或逻辑过期,雪崩用随机过期时间加多级缓存。本地搭一套 Redis,就可以把这些场景都模拟出来练手。
6.2 用 Redis 做分布式锁:SET NX PX 这个组合
另一个绕不开的场景是分布式锁。Windows 本机启动 Redis 之后,你就可以完整跑一遍分布式锁的流程。最推荐的入门写法是 SET 命令的原子操作,而不是先 GET 再 SET,因为两个步骤之间可能被打断。
命令核心是:
SET lock:order:1001 "client-1" NX PX 30000NX 表示只有当 key 不存在时才设置成功,PX 30000 表示这个锁 30 秒后自动释放。这样多个客户端并发执行,只有一个能成功设置,拿到锁的做业务,没拿到的就等待或重试。释放锁的时候也有讲究,要用 Lua 脚本校验 value 是不是自己设置的,防止误删别人的锁:
String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";这段脚本的意思很简单:先看 key 的 value 是否等于当前客户端的标识,等于才删除,不相等说明锁已经过期被别的客户端拿到了,不能删。
自己写锁实现是学习路径,实际项目中我更推荐直接用现成框架,比如 Redisson 的RLock,它内部处理了锁续期、等待、重试这些细节。在 Windows 上启动 Redis,再配一个 Spring Boot 项目,你完全可以把这套流程完整走通,理解了底层原理之后再上框架,踩的坑会少很多。
6.3 Redis 还能当中间件用:消息队列的轻量姿势
最后再拓展一个视角。Redis 不只是缓存和锁,它还能做轻量级中间件。比如用 List 的LPUSH和BRPOP组合,就能实现一个简单的可靠消息队列。生产端LPUSH task:queue task-1,消费端BRPOP task:queue 0会阻塞等待新消息,天然支持先进先出。
再进阶一点,Redis 5.x 引入 Streams 数据结构,Redis 7 又做了增强,支持消费者组、消息确认、消息回溯,功能上已经能打薄薄的一层 MQ。很多企业内部服务内部的异步任务,就是用 Redis Streams 实现的,省掉了再部署一套重型消息队列的成本。
当你把 Windows 上的 Redis 真正用进这些场景里,它就不再是一个“本地测试工具”,而是一个可以承载业务逻辑的中间件。我个人的体会是,先在 Windows 上把一个 Redis 实例跑得滚瓜烂熟,再去看 Linux 生产环境、主从复制、哨兵集群这些东西时,所有概念都能落在实处,因为你已经在本地亲手敲过每一个命令了。如果你现在还卡在启动那一步,别着急,按这篇文章的顺序走一遍,该装的装好,该改的配置改掉,启动其实就这么点事。