Redis 装到 Windows 上这件事,说简单也简单,解压一个压缩包、双击一个 exe 就能跑起来;说麻烦也麻烦,因为官方从很多年前就不发布 Windows 原生版本了,微软当年自己维护的那个分支也停在了 3.2.100,导致很多人第一次去官网翻下载页,翻半天找不到.msi或者.zip,最后随便下了一个来源不明的包,装完发现服务起不来、客户端连不上、重启电脑数据全丢。我把 Redis 装到 Windows 上的流程走了不止一遍,从最早的 msi 一路到现在的免安装 zip,中间踩的坑包括但不限于:配置文件里bind没改导致局域网连不上、dir用了相对路径导致服务方式启动时找不到数据目录、把安装目录放在Program Files下面结果日志写不进去。这篇就是把这一整套流程从头到尾捋清楚,包含版本选择、下载渠道辨别、配置文件逐条解释、注册成服务开机自启、可视化客户端选型、以及连不上时怎么一步步排查。不管你是刚学 Redis 想在本机练手,还是需要在测试环境里快速搭一个单机实例,照着走都能落地。
1. 为什么在 Windows 上装 Redis,先把预期定清楚
1.1 官方版本与 Windows 分支的现状
先把一个容易让人困惑的事说清楚:Redis 官网的下载页面,给的是 Linux 源码包,没有 Windows 可执行文件。这不是官网藏起来了,而是 Redis 服务端本身深度依赖 Unix 的 fork、epoll 这类机制,官方长期没有把 Windows 作为一等公民来维护。早年间微软开放技术团队做过一个 Windows 移植版本,版本号停在 3.2.100,这个项目后来归档不再更新。现在 Windows 上能用的较新版本,主要来自社区维护的移植分支,比较主流的是 tporadowski 维护的那个仓库,提供 5.0.x 系列;另外还有商业化的 Memurai,兼容 Redis 协议,走的是另外一条路线。
这意味着你在 Windows 上用到的新特性会比 Linux 版落后一些,比如部分 6.x、7.x 引入的 ACL、多线程 IO、新的 RESP3 协议,在老移植版上是没有的。但对于学习数据结构、练习命令、做本地开发环境的缓存层,5.0 已经完全够用,常见的 String、Hash、List、Set、ZSet 一个不少,发布订阅、事务、Lua 脚本、RDB 和 AOF 持久化也都在。
我的建议很直接:本地学习和小型测试用社区维护的 5.0.x Windows 版;如果项目要上生产、要用新版本特性,老老实实上 Linux 或者用容器。不要在 Windows 原生版上纠结版本号够不够新,它的定位就是让你顺手练手,不是让你扛线上流量。
1.2 三种安装路径的取舍
Windows 上跑 Redis 常见有三条路,各自适用场景差别挺大,选错了后面会一直别扭。
| 方式 | 上手难度 | 版本新旧 | 资源占用 | 适合谁 |
|---|---|---|---|---|
| MSI 安装包 | 最低,双击到底 | 一般 3.2 或 5.0 | 中等 | 完全新手,只想跑起来 |
| ZIP 免安装 | 中等,要改配置 | 5.0.x 为主 | 低 | 想搞懂每个参数的人 |
| 容器/WSL | 偏高,要装环境 | 跟官方同步 | 较高 | 要接近生产环境的人 |
MSI 的好处是省事,装完自动注册成 Windows 服务,开机自启,你什么都不用管。坏处是它默认的配置你可能不想要,而且卸载重装时残留的服务项和注册表项偶尔会闹脾气。ZIP 免安装的好处是全透明,解压出来就那么几个文件,改哪个参数、数据落哪个目录,全在你眼皮底下,出问题好排查,这也是我最推荐的方式。容器和 WSL 的版本最新,但对 Windows 家庭版用户来说,前置步骤不少,装完一圈可能半小时过去了,练手场景下性价比不高。
1.3 装之前先确认的三件事
第一,确认你的系统架构。现在基本都是 64 位,但老机器上还有 32 位系统。社区版的压缩包里通常同时有redis-server.exe和redis-server-32bit.exe之类,下错了直接报“不是有效的 Win32 应用程序”。在“设置 → 系统 → 关于”里看一眼系统类型,或者命令行敲echo %PROCESSOR_ARCHITECTURE%,返回AMD64就是 64 位。
第二,确认 6379 端口没被占用。Redis 默认端口是 6379,如果你机器上已经有别的实例在跑,新起的会直接启动失败。用netstat -ano | findstr 6379查一下,有输出说明被占了,要么停掉旧的,要么改端口。
第三,想清楚数据放哪。练手阶段数据丢了无所谓,但如果你打算拿它当本地开发环境的缓存,写进去的东西中途没了会很难受。这就需要提前决定持久化策略,以及数据目录是不是要固定到一个不会被清理的位置。临时目录、下载目录都不是好选择,系统清理工具可能顺手给你删了。
2. 安装前的环境准备与下载渠道辨别
2.1 下载渠道怎么选,别乱下
网上搜“redis windows 下载”,出来的结果五花八门,有的站点把压缩包重新打包过,里面塞了别的东西。我的做法是只认两个来源:一是 GitHub 上社区维护仓库的 Release 页面,二是靠谱的镜像站点。判断标准很简单——看 Release 页有没有源码、有没有版本更新记录、Issue 区有没有人维护。一个仓库如果最后提交是好几年以前,Issue 里全是没人回的问题,那就要掂量一下。
顺便提醒一句,别去那种需要你输入手机号、关注公众号才能拿到下载链接的页面。Redis 本体是开源软件,获取它不该有任何附加条件。
下载下来一般是个.zip,命名类似Redis-x64-5.0.14.1.zip,体积几 MB 到十几 MB。下载完先看一眼文件大小,如果只有几百 KB,多半是个下载器或者广告壳,直接删掉。正规的压缩包里应该能解出一个完整的Redis-x64-5.0.14.1文件夹,里面有服务端、客户端、配置文件、几个 DLL。
提示:下载完成后,把压缩包右键属性里如果有“解除锁定”,勾一下再解压。从网络下载的压缩包有时会被系统标记,解压出来的 exe 运行时会弹安全警告。
2.2 目录规划的讲究
我见过太多人把 Redis 解压到桌面,或者塞进C:\Program Files\下面,然后启动服务时报错说不清原因。这里面的门道在于Windows 服务的运行身份和文件夹权限。
服务方式启动时,进程通常以LocalSystem或者你指定的账户运行。C:\Program Files\这个目录在 Windows 上有特殊保护,普通进程往里写文件会被 UAC 拦下来。而 Redis 启动时要写日志、写 RDB 快照、写 AOF 文件,一旦写不进去,表现就是服务装上了但启动秒退,事件查看器里一堆看不懂的错误。
我的做法是固定用一个结构清晰的目录,比如:
D:\dev\redis\ ├── bin\ # 可执行文件和配置 │ ├── redis-server.exe │ ├── redis-cli.exe │ ├── redis.windows.conf │ └── ... ├── data\ # RDB / AOF 落盘位置 └── logs\ # 日志文件把数据和日志单独拆出来,好处是升级的时候直接替换bin目录里的文件,数据一点不动。清理的时候也方便,想重置环境就把data里的东西删掉。
2.3 解压后的文件清单与作用
解压出来大概是这样一堆东西,第一次见容易懵,其实常用的就那么几个:
redis-server.exe:服务端主程序,真正跑起来的就是它redis-cli.exe:命令行客户端,连接和操作数据全靠它redis.windows.conf:默认配置文件,Windows 版的配置文件名带 windows 后缀redis.windows-service.conf:专门给服务模式用的配置,参数略有差异redis-benchmark.exe:压测工具,想看看本机 QPS 可以玩玩redis-check-rdb.exe/redis-check-aof.exe:RDB 和 AOF 文件的修复检查工具dump.rdb:如果之前跑过,会有这个持久化文件- 若干
.dll:运行时依赖库,别删
这里有个容易踩的坑:redis.windows.conf和redis.windows-service.conf是两个不同的文件。很多人手动改配置改的是前者,注册服务时却让服务读了后者,结果配置死活不生效,折腾半天以为改错了地方。注册服务时明确指定你要用哪个配置文件,这一点后面会细说。
3. ZIP 免安装版完整实操过程
3.1 先跑起来看一眼再改配置
我习惯先不改任何配置,直接用默认参数启动一次,确认程序本身是好的,再动配置。这一步能帮你快速区分“程序有问题”和“配置改错了”这两类情况。
打开cmd或 PowerShell,cd到bin目录,执行:
redis-server.exe redis.windows.conf正常的话会刷出一屏日志,最后停在类似这样的输出上:
[xxxx] 01 Jan 00:00:00.000 * Ready to accept connections看到 “Ready to accept connections”,说明服务起来了。这时候这个窗口不要关,它是前台运行状态。另开一个命令行窗口,cd到同一目录,执行:
redis-cli.exe进入交互界面后敲:
127.0.0.1:6379> ping PONG返回 PONG 就说明链路通了。再试个写入:
127.0.0.1:6379> set name redis-test OK 127.0.0.1:6379> get name "redis-test"这几步走完,证明程序没问题,可以放心进入配置环节。
3.2 redis.windows.conf 关键参数逐条改
配置项几十个,但真正需要你动的没几个。下面这几条是我每次都会调整的,逐条说清楚为什么。
bind 参数。默认通常写的是bind 127.0.0.1,意思是只监听本机回环地址,外部机器连不上。这个默认值是安全的,本机开发别改。如果你确实需要局域网内的其他机器连过来(比如手机调试、同事联调),改成bind 0.0.0.0。但改之前想清楚:一旦暴露在网络里,必须同时设置密码,否则就是把自己的数据敞开放着。
port。默认port 6379。端口冲突的时候改这里,比如改成6380。
requirepass。默认是注释掉的,也就是无密码。设置方式:
requirepass your_strong_password_here密码别用123456、redis这种,本来就是为了防未授权访问,用弱密码等于没设。设了密码之后,客户端连接进来需要先auth your_strong_password_here,或者连接时加-a参数。
dir。这个参数决定 RDB 和 AOF 文件写在哪里。默认值往往是./,也就是当前工作目录。问题在于,用服务方式启动时,“当前工作目录”是系统目录而不是你的 Redis 目录,数据就飞到C:\Windows\System32下面去了。这就是前面说的“重启后数据全丢”的常见原因之一。强烈建议改成绝对路径:
dir D:/dev/redis/data注意这里路径用正斜杠/而不是反斜杠\,Redis 配置文件里反斜杠是转义字符,写成D:\dev\redis\data会被解析成奇怪的东西。这一点特别容易被忽略。
logfile。默认是空字符串,表示日志输出到标准输出。服务方式运行没有控制台,日志就没地方去了。改成具体文件:
logfile D:/dev/redis/logs/redis.logmaxmemory 和 maxmemory-policy。这两个是内存上限和淘汰策略。不设maxmemory的话,Redis 会一直吃内存直到把机器撑爆。做本地缓存用的时候,我一般设个几百 MB:
maxmemory 512mb maxmemory-policy allkeys-lruallkeys-lru的意思是内存满了以后,在所有键里按最近最少使用的规则淘汰。如果你只希望淘汰设了过期时间的键,用volatile-lru。
appendonly。AOF 持久化开关,默认no。RDB 是定时快照,宕机可能丢最近一段时间的写入;AOF 是追加写日志,丢的数据更少但文件更大、写入稍慢。本地练手开不开都行,如果要存不能丢的数据,改成appendonly yes。
save。RDB 快照的触发条件,默认大概是:
save 900 1 save 300 10 save 60 10000意思是 900 秒内至少 1 个键变化、300 秒内至少 10 个、60 秒内至少 10000 个,满足任一条件就落盘。如果你只要 AOF 不要 RDB,可以把这几行前面加#注释掉,或者写save ""。
3.3 用改好的配置再启动验证
配置改完,保存,重新启动:
redis-server.exe redis.windows.conf启动日志里会显示加载了哪个配置文件、监听哪个端口、数据目录在哪。重点看两行:一行是The server is now ready to accept connections,一行是Configuration loaded。如果数据目录路径写错了,启动会直接失败并提示Can't chdir to ...,这时候回去检查dir参数。
启动后去data目录看看有没有生成dump.rdb,用redis-cli写几个键,然后执行:
127.0.0.1:6379> save OK再看data目录,文件时间戳应该更新了。这一步是验证持久化路径真的生效,别等到重启才发现写错地方。
3.4 注册成 Windows 服务实现开机自启
前台跑着虽然直观,但每次开机都要手动启动太麻烦,而且关掉那个命令行窗口服务就没了。注册成 Windows 服务是最省心的方案。
第一步,先停掉前台运行的实例。在跑着的窗口按Ctrl+C,或者直接关掉窗口。
第二步,执行注册命令。注意要以管理员身份打开命令行,否则会报权限不足:
redis-server.exe --service-install redis.windows.conf --loglevel verbose这里指定了用redis.windows.conf作为服务配置。如果你想让服务用一个单独的配置文件,比如redis.windows-service.conf,把文件名换掉即可。关键点是:注册时指定的配置文件名,必须和你实际改过参数的那个文件一致,这就是前面说的坑。
第三步,启动服务:
redis-server.exe --service-start或者用 Windows 自带的服务管理:
net start Redis服务名默认是Redis。启动后可以去“服务”管理器里看到它,启动类型设置成“自动”,开机就自己起来了。
第四步,验证服务状态。redis-cli连上去ping一下,返回 PONG 就行。如果连接被拒绝,先看服务列表里 Redis 是不是“正在运行”,如果是停止状态,右键启动看报什么错。
其他几个常用命令也记一下:
redis-server.exe --service-stop # 停止服务 redis-server.exe --service-uninstall # 卸载服务卸载的时候如果提示服务正在运行,先 stop 再 uninstall。
3.5 MSI 安装版的流程与差异
如果你选择 MSI 安装包,流程确实短很多:双击 → 一路 Next → 勾选“Add to PATH” → 设置端口和内存上限 → Install。装完服务自动就注册好了,配置界面里能直接设端口、maxmemory,还有个复选框问你要不要加防火墙例外。
MSI 版和 ZIP 版的差异主要在三点。一是配置文件位置不透明,通常在安装目录下,你得自己去找;二是它默认可能绑定0.0.0.0并开放防火墙,方便是方便,安全性要自己补密码;三是卸载重装时,旧的服务项和dump.rdb可能残留在安装目录,导致新装的实例一启动就加载了旧数据,出现“明明清空了怎么还有数据”的幻觉。
注意:MSI 安装时如果勾了防火墙例外,等于把 6379 端口对局域网开放了。装完第一件事就是设
requirepass,别拖。
我的习惯是:新手期用 MSI 快速跑通,一旦开始正式用,就换成 ZIP 版自己管配置。因为出问题时你能看到的每一层都是自己配的,排查成本低很多。
4. 客户端连接与可视化管理工具选型
4.1 redis-cli 的日常用法
命令行客户端是最可靠的,图形工具挂了它也不会挂。除了ping、set、get,几个常用的:
redis-cli.exe -h 127.0.0.1 -p 6379 -a yourpassword-h指定主机,-p指定端口,-a指定密码。注意-a后面直接跟密码会有一条警告,提示这样可能被历史记录看到,可以改用--askpass交互输入。
想不开交互界面直接执行一条命令:
redis-cli.exe -h 127.0.0.1 -p 6379 -a yourpassword get name在 Redis 里切换数据库用select,默认有 16 个库(0 到 15):
127.0.0.1:6379> select 1 OK 127.0.0.1:6380[1]>看当前库里所有键用keys *,但这命令在键多的时候会阻塞服务,生产环境别用,用scan替代:
127.0.0.1:6379> scan 0 count 100查看某个键的类型和剩余过期时间:
127.0.0.1:6379> type name string 127.0.0.1:6379> ttl name -1ttl返回-1表示没有设置过期时间,返回-2表示键不存在。
4.2 图形客户端怎么挑
命令行敲久了确实累,图形工具能直观看到键的分布、类型、大小,调试时省事。市面上常见的有几个:
| 工具 | 特点 | 是否免费 | 适用场景 |
|---|---|---|---|
| RedisInsight | 官方出品,功能全,带监控面板 | 免费 | 想深入看慢查询、内存分析 |
| Another Redis Desktop Manager | 轻量,启动快,支持多平台 | 免费开源 | 日常查看和改键 |
| Redis Desktop Manager | 老牌工具,版本较久 | 老版本免费 | 习惯旧界面的人 |
| 各语言生态的调试插件 | 集成在 IDE 里 | 随 IDE | 边写代码边看数据 |
我自己的组合是:日常快速看一眼用 Another Redis Desktop Manager,它启动真的是秒开,连接配置也简单;要做内存分析、看命令统计的时候开 RedisInsight,它的可视化做得好,能直接看到哪些键占内存最多。
连接配置无非几项:主机填127.0.0.1,端口6379,有密码填密码,没密码留空。填完点测试连接,通了就能用。
4.3 连不上时的排查顺序
图形工具报“连接失败”是最常见的问题,按下面这个顺序走,基本都能定位:
第一,服务到底起没起。任务管理器里找redis-server.exe进程,或者服务列表看状态。进程不在,前面全白搭。
第二,端口通不通。命令行执行:
telnet 127.0.0.1 6379如果提示 telnet 不是内部命令,先去“启用或关闭 Windows 功能”里把 Telnet 客户端勾上。连不上说明端口层面就不通,要么服务没监听这个端口,要么被防火墙拦了。
第三,密码对不对。报NOAUTH Authentication required就是没带密码,报WRONGPASS invalid username-password pair就是密码错了。带密码的工具里填一下,注意别多半角空格。
第四,bind 绑对没。本机连接应该没问题,如果是从别的机器连,确认bind是不是还是127.0.0.1,以及防火墙有没有放行 6379。
第五,protected-mode。Redis 有个保护模式,当没设密码且绑定了非回环地址时会拒绝外部连接,报错信息里会明确提到 protected mode。解决办法是要么设密码,要么改bind,要么把protected-mode no(但这么干等于裸奔,不推荐)。
5. 常见问题与排查技巧实录
5.1 启动闪退和端口占用
闪退这事儿,双击redis-server.exe一闪而过,几乎百分百是因为它没找到配置文件或者配置有语法错误。双击只会用内置默认配置启动,而且日志打到标准输出后窗口就关了,你什么都看不到。正确做法是在命令行里启动,让日志留在窗口上:
redis-server.exe redis.windows.conf看到具体报错再对症下药。常见的有配置项拼错、路径不存在、端口被占。
端口占用的报错很直白:
Could not create server TCP listening socket 127.0.0.1:6379: bind: No error遇到这个,先查是谁占着:
netstat -ano | findstr :6379最后一列是进程 PID,用tasklist | findstr <PID>看是什么程序。如果判断是残留的 redis 进程,去任务管理器结束掉,或者:
taskkill /F /PID <PID>5.2 配置文件那些反直觉的坑
配置文件里的坑,我列几个印象最深的。
路径分隔符。前面提过,反斜杠会被当转义符。logfile D:\dev\logs\redis.log这种写法,\d、\l、\r都会被解释掉,结果路径变成一堆乱码。统一用正斜杠。
单位不写等于零。maxmemory 512是指 512 字节,不是 512 MB。必须带上单位,512mb或者512MB都行。这个如果写错,Redis 会疯狂淘汰键,你会觉得数据莫名其妙没了。
注释符号。只支持#,不支持//或者;。用错符号那一行不会被注释掉,直接导致解析失败启动不起来。
配置项前不能有空格。如果某一行前面多了个空格,Redis 会认为这是上一行的续行,参数就串了。检查配置时留意行首对齐。
中文注释和 BOM 头。用记事本编辑过配置文件的,可能会在文件开头插入 BOM 字节,导致第一行解析异常。建议用 VSCode 或 Notepad++ 编辑,保存时选 UTF-8 无 BOM。
5.3 常见问题速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 双击 exe 闪退 | 无配置或配置语法错 | 命令行启动看日志 |
| 服务启动后立即停止 | 数据目录不存在或没权限 | 检查 dir 路径、手动建目录 |
| 重启后数据丢失 | dir 指向了临时目录 | 改成绝对路径并验证 |
| 客户端连不上 | 服务未启动 / 端口占用 / 防火墙 | 按 4.3 顺序排查 |
| NOAUTH 报错 | 服务设了密码客户端没带 | 客户端补密码 |
| 内存报警或键被清 | maxmemory 写成了字节数 | 补上 mb 单位 |
| 配置改了不生效 | 服务读的是另一个配置文件 | 核对注册服务时指定的文件名 |
| 日志文件不生成 | logfile 路径目录不存在 | 先手动创建目录 |
5.4 几个我踩过的实操心得
给服务指定单独的配置文件。注册服务时我用redis.windows-service.conf,平时手动调试用redis.windows.conf,两个文件内容保持一致但分开维护。这样调试时改参数不会影响到线上服务,改完确认没问题再同步过去。
改完配置一定要重启服务,Redis 不热加载配置文件,改了文件不重启等于没改。重启命令:
redis-server.exe --service-stop redis-server.exe --service-start升级版本时先备份 dump.rdb 和 appendonly.aof。低版本写的 RDB 文件高版本一般能读,反过来的兼容性说不准。备份一下,出问题能回滚。
别忘了给 Redis 目录做排除。如果你用了某些杀毒软件或者文件夹清理工具,把 Redis 的目录加到白名单里,否则哪天它把你正在写的 AOF 文件锁住或者删掉,排查起来会很费劲。
装完先跑一遍基本命令。ping、set、get、del,四个命令一遍过,能覆盖连接、鉴权、读写权限这几个主要环节。每次装完新实例我都这么过一遍,几十秒的事,能省很多后面扯皮的时间。
6. 装完之后:从数据类型到实际用法
6.1 五种基础类型对应的真实场景
装好只是开始,真正用起来得知道每种类型适合干什么。缓存和计数是 Redis 最常被用到的两个方向。
String是最通用的,存对象序列化后的 JSON、存计数器、存分布式锁的标识,都用它。计数器场景:
127.0.0.1:6379> set article:1001:views 0 OK 127.0.0.1:6379> incr article:1001:views (integer) 1 127.0.0.1:6379> incrby article:1001:views 10 (integer) 11incr这类操作是原子性的,多个客户端同时加也不会算错,这是它比“读出来加一再写回去”靠谱的地方。
Hash适合存对象的多个字段。比如一个用户信息:
127.0.0.1:6379> hset user:1 name alice age 28 city beijing (integer) 3 127.0.0.1:6379> hget user:1 name "alice" 127.0.0.1:6379> hgetall user:1 1) "name" 2) "alice" 3) "age" 4) "28" 5) "city" 6) "beijing"相比把整个对象序列化成 String 存,Hash 的好处是改单个字段不用读出整个对象再写回。
List天然适合做队列和最新列表。lpush从左边进,rpop从右边出,就是个先进先出的队列。做“最新 N 条”这种功能,配合ltrim只保留固定长度:
127.0.0.1:6379> lpush news:latest "标题A" (integer) 1 127.0.0.1:6379> ltrim news:latest 0 99 OK这样列表永远最多 100 条,老的自动丢掉,不会越积越大。
Set是无序不重复集合,做去重、求交集并集很顺手。比如统计两个用户共同关注的人:
127.0.0.1:6379> sadd follow:1 100 101 102 (integer) 3 127.0.0.1:6379> sadd follow:2 101 102 103 (integer) 3 127.0.0.1:6379> sinter follow:1 follow:2 1) "101" 2) "102"ZSet有序集合,带分数排序,排行榜的标准解法:
127.0.0.1:6379> zadd rank 95 alice 88 bob 99 carol (integer) 3 127.0.0.1:6379> zrevrange rank 0 2 withscores 1) "carol" 2) "99" 3) "alice" 4) "95" 5) "bob" 6) "88"zrevrange按分数从高到低取,天然就是排行榜的前三名。
6.2 序列化方式怎么选
在 Java、Python 这类语言里用 Redis,绕不开序列化。存进去的时候把一个对象转成字节,读出来再还原。
String 类型存对象,本质上就是序列化问题。常见几种做法:
- JSON 字符串:可读性最好,用
redis-cli直接看能看明白,缺点是体积比二进制大,解析有点开销。调试期我首选这个。 - JDK 序列化:Java 里默认的那套,写出来的东西带一堆类名信息,体积大而且有安全顾虑,新项目不建议。
- Protobuf / MessagePack 这类二进制格式:体积小、速度快,缺点是没法直接肉眼读,调试时得写工具解码。
我的建议是:开发调试阶段用 JSON,等确定接口稳定、性能成为瓶颈了再考虑换二进制格式。别一上来就为了那点性能上二进制,后面排查问题的时候你会怀念能直接get出来看内容的日子。
还有一点要特别注意,序列化方式一旦定了就别随便换。老数据是用 JSON 写进去的,你换了 Protobuf 去读,读出来就是乱码或者直接反序列化异常。真需要换,得做数据迁移。
6.3 用 Redis 做分布式锁的基本思路
本机练手经常会碰到“多个请求同时改一个数据”的场景,Redis 可以做个简单的锁。
核心命令是set带nx和过期时间参数:
127.0.0.1:6379> set lock:order:1001 unique-token nx px 10000 OKnx表示键不存在才设置成功,px 10000表示 10 秒后自动过期。设置成功说明抢到锁了,返回nil说明被别人拿着。执行完业务逻辑后释放锁:
127.0.0.1:6379> del lock:order:1001这里有个关键细节:值不要随便写个 1,要写一个能区分客户端身份的唯一值(比如 UUID)。为什么?因为如果 A 拿锁后业务卡住超过 10 秒,锁自动过期,B 拿到了锁;这时候 A 缓过来执行del,就把 B 的锁给删了。正确做法是释放前先比对值是不是自己的,比对和删除要原子执行,用 Lua 脚本:
if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end把这几个坑绕开,单机场景下这套锁基本够用。但要注意,单实例的 Redis 锁在实例挂掉时是有风险的,要求更高的话得上多实例的方案,那属于另一个话题了,本地练手先把这个跑通理解原理就行。
我自己在这套流程上折腾的次数不少,最早因为dir用了相对路径,服务启动起来看着正常,重启后数据全没了,排查了小半天才反应过来数据写到系统目录去了。后来把目录结构固定下来,配置文件里所有路径一律写绝对路径加正斜杠,就再没出过这类问题。还有一次是注册服务时用了redis.windows-service.conf,但改的是redis.windows.conf,怎么改都不生效,最后对着两个文件一行行比对才发现改错了对象。所以最后再强调一句:改配置前先确认服务到底读的是哪个文件,改完一定要重启服务,然后去data和logs目录看文件是不是真的按预期生成了——眼见为实,别靠猜。