ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Redis安装配置实战:从环境搭建到避坑指南

Redis安装配置实战:从环境搭建到避坑指南 做后端这几年Redis基本成了标配。缓存、分布式锁、排行榜、会话共享、消息队列哪个场景背后都能看到它的影子。很多人都用过现成的Redis环境但真到自己从头装一次、把配置捋一遍的时候才发现坑比想象中多。这篇是“Redis从入门到精通”系列的第一篇我就把简介、安装和配置这件事一次讲透。文章会覆盖Linux、Windows、Docker三种常见环境的安装方式再把redis.conf里那些绕不开的配置项逐条拆开讲最后附上我实际踩过的一些坑和排查经验。不管你是第一次接触Redis还是以前只会在项目里跟着教程敲两行代码这篇都适合静下心来看完。1. Redis到底是什么又厉害在哪1.1 从“缓存需求”说起先想一个问题你的系统访问量上来了数据库压力大怎么办最常见的办法就是把热点数据放到内存里读的时候先查内存查不到再去数据库。这就是缓存。而Redis本质上就是一个基于内存的键值存储系统它把数据存在内存里读写速度极快。但Redis又不只是“缓存”这么简单。它支持的数据结构非常丰富字符串、哈希、列表、集合、有序集合还有Bitmap、HyperLogLog、GEO、Stream这些高级类型。这意味着排行榜可以用有序集合做去重可以用集合做简单的消息队列可以用列表或Stream做。再加上它原生支持持久化、主从复制、哨兵、集群所以很多场景下Redis并不只是一个缓存而是系统里一个独立的基础设施。我用过很多版本的Redis从2.8一路用到7.x。坦白说早期版本之间的差异还不算大但从6.0开始引入了多线程IO、RESP3协议、ACL权限控制到7.0引入的Function和Redis Search模块化能力Redis的能力边界一直在扩大。如果现在要从零学习和选型直接上7.x是没问题的。1.2 和其他方案对比为什么选Redis一说内存缓存有人会想到Memcached觉得它更简单。Memcached确实把缓存这件事做到了极致简单纯KV、内存分配效率高、多线程模型天然不存在IO瓶颈。但它有个致命的短板只有字符串类型无法做复杂数据结构不支持持久化重启全丢主从复制虽然是有的但高可用的生态远不如Redis成熟。Redis相对Memcached来说不是一个“更高级的缓存”而是一个“功能更全的数据存储”。你可以在Redis上跑一个完整的抽奖活动用集合存储用户ID用有序集合存分数排行用发布订阅给客户端推送实时消息。这些东西如果扔给Memcached你得上很多额外的代码。还有一部分人会把Redis和本地缓存比如Caffeine、Guava Cache比较。我的看法是本地缓存和Redis不是二选一的关系经常是搭配使用。本地缓存放在应用进程内速度最快但多个实例之间数据不一致Redis放在应用外面所有实例共享同一份数据虽然多一次网络IO但一致性有保障。实践中常见的是“两级缓存”先查本地缓存查不到再查Redis再查不到才落库。2. 安装前先想清楚的三件事2.1 版本选型7.x还是6.x选定版本这件事比很多人想象的重要。直接说结论新项目直接用Redis 7.2及以上版本旧项目如果跑得稳没必要为了升级而升级。Redis 7.0开始引入了Redis Function把Lua脚本的能力往前推进了一大步7.2又强化了ACL、提升了内存效率7.4之后Redis移除了对集群模式下脚本的处理限制还引入了调度的新特性。另外还有一个背景大家应该知道Redis从7.4开始修改了开源许可证。如果你的公司对license比较敏感又希望保持纯开源那可以关注一下Valkey这个从Redis 7.2 fork出来的分支API完全兼容Redis由Linux基金会托管。我个人的建议是学习阶段直接用最新的稳定版体验新特性生产环境则选择一个你已经踩过足够多坑的版本比如7.2.x然后把版本号锁死后续升级走正式的变更流程。2.2 平台选型Linux、Windows还是Docker这是很多新手纠结最多的问题。生产环境基本不用纠结99%是Linux。Windows上安装Redis的方式大多是社区维护的移植版或者旧版本只适合本地开发调试不适合上线。如果你用的是Windows而且又希望环境尽量和Linux一致我推荐两条路一是装WSL2在WSL里安装Linux版的Redis二是用Docker桌面版直接跑Redis官方镜像。这两条路都能绕开Windows移植版的种种奇怪问题。如果在Linux服务器上那又分为两种一种是直接用系统的包管理器安装比如apt install redis或者yum install redis另一种是下载源码自己编译安装。包管理器装出来的版本通常比较旧比如Ubuntu 22.04官方源里还是Redis 6.0.x但胜在方便、有systemd服务脚本。源码编译则能拿到最新版目录结构也完全可控。2.3 三种安装方式怎么选我画个简单的表格大家一看就明白各场景的取舍安装方式适用场景优点缺点Linux包管理器对版本要求不高的生产环境安装快、自动注册服务版本较旧Linux源码编译需要指定版本、自定义编译参数版本可控、路径可控需要手动配置服务Docker容器本地开发、测试环境、快速搭建一条命令搞定、环境隔离数据持久化需额外配置Windows移植版纯Windows本地冒烟测试下载解压即用版本老、坑多WSL2Windows开发环境和Linux一致需要开启WSL3. Linux环境安装Redis源码编译全流程3.1 下载源码、编译、安装我以目前主流的7.2.5为例完整走一遍源码编译安装。首先需要系统里有gcc和make一般最小化安装的服务器这两个工具可能没有。# 先装编译工具 sudo apt update sudo apt install -y wget build-essential # 下载Redis源码 wget https://download.redis.io/releases/redis-7.2.5.tar.gz # 解压并进入目录 tar xzf redis-7.2.5.tar.gz cd redis-7.2.5 # 编译 make # 安装到指定目录比如 /usr/local/redis sudo make install PREFIX/usr/local/redis这里有一个很多初次接触的人会忽略的点make之后其实已经可以在源码目录的src子目录下找到redis-server和redis-cli直接用这两个文件就能跑起来。但我不建议这么干因为源码目录一旦被清理或者移动服务就废了。用make install PREFIX...把可执行文件安装到独立目录是更规范的做法。安装完成后把配置文件也拷贝过去sudo mkdir /etc/redis sudo cp redis.conf /etc/redis/redis.conf sudo mkdir -p /data/redis配置文件我习惯放在/etc/redis下数据目录单独放到/data/redis不要和安装目录混在一起这样升级时不用迁移数据。3.2 配置systemd服务编译安装不会自动注册系统服务需要手动写一个systemd单元文件。这一步很多人会漏掉导致服务器重启后Redis没起来。正确做法如下创建/etc/systemd/system/redis.service[Unit] DescriptionRedis Server Afternetwork.target [Service] Typeforking ExecStart/usr/local/redis/bin/redis-server /etc/redis/redis.conf ExecReload/bin/kill -s HUP $MAINPID ExecStop/usr/local/redis/bin/redis-cli -a 你的密码 shutdown Restartalways Userredis Groupredis RuntimeDirectoryredis PIDFile/var/run/redis/redis-server.pid [Install] WantedBymulti-user.target其中Typeforking意味着redis-server启动后自身会转入后台运行。Redis默认的daemonize no在systemd环境下不需要改成yes因为systemd本身就能管理前台进程。如果你在redis.conf里设置了daemonize yes那systemd这边就要用Typeforking两者别搞混。还需要创建一个专用的系统用户sudo useradd --system --no-create-home --groups redis redis sudo chown -R redis:redis /data/redis /etc/redis/redis.conf然后启动并设置开机自启sudo systemctl daemon-reload sudo systemctl start redis sudo systemctl enable redis sudo systemctl status redis这里我给一个我实际踩过的坑如果用root用户启动Redis部分版本会直接拒绝运行提示“Redis needs to be run under a dedicated user”。所以最好一开始就单独建用户别图省事。3.3 验证启动结果服务起来之后用redis-cli验证一下/usr/local/redis/bin/redis-cli ping正常情况下会返回PONG。如果配置了密码需要加上-a参数/usr/local/redis/bin/redis-cli -a 你的密码 ping再看一下INFO里的几个关键指标/usr/local/redis/bin/redis-cli -a 你的密码 INFO | grep -E redis_version|used_memory_human|connected_clientsredis_version能确认版本号对不对used_memory_human能看到内存占用connected_clients是当前连接数。我习惯把这三项作为每次部署Redis之后的“开机自检项”不用看太多指标先确认服务健康再说。4. Windows环境安装Redis三种靠谱姿势4.1 官方不提供Windows版那Windows用户怎么办很多人到官网一看下载页面根本没有Windows的安装包立刻懵了。Redis官方确实不提供Windows版本GitHub上确实有tporadowski维护的Windows移植版当前停留在5.0.14.1这不是官方出品但也有不少人在用。如果是纯本地学习Redis命令、测试客户端连接用这个版本完全够用。下载release里的zip包解压后直接运行redis-server.exe即可默认端口6379。再开一个终端运行redis-cli.exe就能敲命令了。但要提醒一下不要因为这个zip包解压即用就把Redis的数据或者主从复制跑在上面。Windows移植版有几个历史遗留问题比如某些命令的Fork行为异常、RDB持久化在特定场景下会卡顿、对于Lua脚本的支持不完整。本地玩一玩可以别太当真。4.2 WSL2才是Windows开发的正道如果你在Windows上做开发又希望Redis行为和生产Linux完全一致WSL2是目前的最优解。步骤如下# 在Windows PowerShell里查看WSL状态 wsl --status # 如果没有启用先装WSL2注意看系统提示 wsl --install # 进入Ubuntu发行版后直接安装Redis sudo apt update sudo apt install -y redis-server # 启动服务 sudo service redis-server start用WSL2的最大好处是环境零差异你学的、配置的、跑的命令和Linux服务器一模一样。而且WSL2对文件系统的IO性能在过去几个版本优化了不少本地开发跑Redis问题不大。唯一的麻烦是WSL2默认不会自动启动服务每次进入终端都要手动执行service redis-server start。解决办法是在~/.bashrc里加上一行启动命令或者直接在Windows的任务计划程序里配置启动时执行的脚本。4.3 Docker跑Redis一条命令搞定Docker的方式其实适合所有平台Windows、Mac、Linux都一样。只要你装了Docker接下来就很简单# 拉取并启动一个最基本的Redis容器 docker run -d --name redis-demo -p 6379:6379 redis:7.2 # 带数据持久化 docker run -d --name redis-demo -p 6379:6379 -v redis-data:/data redis:7.2 --appendonly yes # 挂载自定义配置文件推荐这种方式 docker run -d --name redis-demo -p 6379:6379 \ -v /data/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \ -v redis-data:/data \ redis:7.2 redis-server /usr/local/etc/redis/redis.conf第二种方式要注意一点--appendonly yes是传给容器的启动参数也就是覆盖默认的redis-server启动命令。而如果你要挂载自定义配置文件就得像第三种方式那样显式指定redis-server /usr/local/etc/redis/redis.conf否则挂载的配置文件会被忽略。Docker方式最大的好处是干净想删掉重来就一条命令。很多人在本机装了一堆环境Redis、MySQL、Nginx全在系统里时间长了版本冲突就能让人崩溃。我用Docker装了Redis、PostgreSQL、RabbitMQ这些基础设施之后本机系统清爽了很多。5. redis.conf配置详解每一个值得改的项5.1 网络、访问控制与安全先说网络。配置文件里默认的bind 127.0.0.1意思只允许本机访问。如果你要远程连接必须改成bind 0.0.0.0或者指定你服务器的内网IP。这里有个安全细节bind 0.0.0.0意味着所有网卡都开放6379端口如果Redis没有设置密码等于把数据裸奔在网络上公网环境下几分钟就会被扫描器打穿。所以远程访问必须配合protected-mode和requirepass一起用。protected-mode在Redis 3.2之后默认打开。这个模式有个特点如果Redis没有配置密码也没有显式配置bind它只允许本机的回环地址连接。一旦你设置了requirepassprotected-mode就自动退场。我建议的安全基线是bind 0.0.0.0 port 6379 protected-mode yes requirepass 这里填一个足够复杂的密码还有一项容易被忽略的配置rename-command。如果你们公司有安全审计要求可以把一些危险命令重命名或禁用掉比如rename-command FLUSHALL rename-command DEBUG 这会直接让FLUSHALL和DEBUG命令失效防止误操作和恶意攻击。5.2 持久化RDB和AOF怎么选Redis的数据存在内存里但如果不做持久化重启之后内存数据全部清空。持久化有RDB和AOF两种机制。RDB是快照方式按固定间隔把内存数据写进一个二进制文件默认文件名是dump.rdb。它的优点是文件紧凑、恢复速度快缺点是间隔期内如果宕机这段时间的数据会丢。AOF是追加日志方式把每次写命令追加到一个日志文件里。它的优点是数据安全性高最多丢1秒或者1次写操作的数据缺点是文件体积大恢复速度相对慢。Redis 7.0之后引入了AOF文件混合持久化功能重写后的AOF文件里既包含RDB的二进制快照又包含增量写命令兼顾了体积和安全性。我给出一个比较典型的配置组合appendonly yes appendfilename appendonly.aof appendfsync everysec auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb这里我建议把appendfsync设置为everysec也就是每秒刷盘一次。阿里云等云厂商的默认配置也基本都这样。always模式虽然更安全但每写一次都刷盘性能损失很大不适合高并发写场景。如果你既想恢复快又不想丢太多数据可以把RDB和AOF都打开Redis会优先用AOF文件恢复数据。不过说实话以现在SSD的性能除非你对数据丢失零容忍否则只开AOF也够用了。5.3 内存上限与淘汰策略Redis不能无限占内存得给它设一个上限。maxmemory 256mb maxmemory-policy allkeys-lrumaxmemory就是Redis允许使用的最大内存量。注意这里指的是数据内存不包含内存碎片、子进程写RDB时的内存等。所以实际进程的RSS内存会大于这个值。maxmemory-policy是内存满了之后的淘汰策略常见的几种策略含义适用场景noeviction不淘汰直接报错不能丢任何数据的场景allkeys-lru从所有key中按LRU淘汰纯缓存场景volatile-lru只从设置了过期时间的key中按LRU淘汰混合场景allkeys-random随机淘汰所有key不太建议淘汰的随机性太强volatile-ttl淘汰即将过期的key依赖过期时间的场景我见过不少人在生产环境用noeviction结果缓存一满大量写请求直接返回错误业务方一脸懵。实际上如果是纯缓存场景用allkeys-lru最省心如果Redis里既存了缓存数据又存了不能丢的业务数据那就用volatile-lru并且给缓存key都设置合理的过期时间。还有一个容易被忽略的参数maxmemory-samples默认值是5。它决定了LRU策略的采样数量值越大淘汰结果越精确但CPU消耗也越高。一般保持默认就行不用动。5.4 其他常见配置项databases 16Redis默认有16个逻辑数据库编号0到15。现在业界普遍不建议在一个Redis实例里开多个库原因和MySQL的多库一样职责不清、运维复杂。如果真有隔离需求更推荐开多个实例或者使用Redis Clusters。timeout 300客户端空闲300秒自动断开连接。默认是0表示不超时。如果是公网连接这个超时能帮你清理一些半开连接如果是内网设不设都行我一般保留默认0。tcp-keepalive 300建议设置让操作系统层定期探测连接是否还活着对清理僵尸连接很有帮助。6. 客户端连接与可视化工具配置6.1 redis-cli命令行常用操作安装了Redis之后redis-cli是你最基本、最可靠的调试工具。# 普通连接 redis-cli -h 127.0.0.1 -p 6379 -a 密码 # 进入交互模式 redis-cli 127.0.0.1:6379 ping PONG 127.0.0.1:6379 set name hello OK 127.0.0.1:6379 get name hello # 非交互模式直接执行命令 redis-cli -a 密码 INFO我建议认真记一遍Redis常用命令而不只是会set/get几个。比如# 查看所有key生产环境慎用会阻塞 keys * # 用scan遍历key不会卡服务 scan 0 match user:* count 100 # 查看key的类型和过期时间 type user:1001 ttl user:1001 # 查看当前连接数和命令统计 info clients info commandstats实际生产环境我几乎不用keys *因为它在key很多时会导致Redis阻塞线上事故的常见根源之一。排查问题时请用scan。6.2 图形化客户端RDM和Another Redis Desktop Manager命令行再强有时候也想要个图形界面看看数据结构。这里提两款我用过的工具。Redis Desktop ManagerRDM是很经典的选择。老版本免费新版本已经转为商业软件。如果你只用基础功能找个旧的免费版也行但界面偏重、启动偏慢。我个人觉得现在更好用的是Another Redis Desktop Manager又被称为A Redis Desktop Manager这是一款开源跨平台工具底层用Go和Vue写的启动速度快界面清爽支持Windows/Mac/Linux而且直接支持SSH隧道连接对云服务器的排查提供了很大便利。另外还有几个选择RedisInsight是Redis官方出的GUI工具功能最全可视化数据浏览、内存分析、慢日志查看都做得很好RedisPlus是另一款桌面客户端但更新较慢如果你是后端开发并且已经在用JetBrains系列IDE那IDEA里的Redis插件也能满足一些简单的查看需求。配置连接时要注意填写密码和数据库编号。默认连的是db0如果你实际用的是db1在RDM或者Another Redis Desktop Manager里都得手动切换。7. 实操中常见的坑和排查套路7.1 明明启动了为什么连接被拒绝这类问题在初学者里出现的频率最高90%出在bind和protected-mode上。你本机执行redis-cli ping没问题换成另一台服务器连接就报Connection refused或者超时。首先确认Redis进程是不是确实在监听外网IPss -tlnp | grep 6379如果显示的是127.0.0.1:6379说明配置文件里的bind还是默认值。改成bind 0.0.0.0并重启Redis。第二道坎就是protected-mode yes。它的逻辑是当Redis没有配置requirepass时只允许本机访问远程一律拒绝。如果你的Redis确实需要远程访问第一种解法是设置密码第二种是显式把protected-mode设为no。但这里我强烈建议只走“设置密码”这条路不要关闭protected模式。还有云服务器安全组的问题。很多人本地怎么测都通不了最后发现是云服务器的安全组没放行6379端口。阿里云、腾讯云的服务器默认安全组都不放行非标端口需要去控制台加一条入方向规则。7.2 密码配置之后客户端连不上修改requirepass之后常见的一个问题是客户端工具里没写对密码。这个其实好办但很多人忽略了一件事config rewrite这个命令。假设你现在把密码写到了配置文件里重启后生效。但如果你直接运行了CONFIG SET requirepass newpass这是运行时改的不会写回配置文件。等下次重启密码又变回旧的了。所以改配置时要么改文件重启要么运行时修改后用CONFIG REWRITE把配置写回文件。redis-cli -a 旧密码 config set requirepass 新密码 redis-cli -a 新密码 config rewrite注意两条命令之间密码已经变了要用新密码来执行config rewrite否则会提示认证失败。7.3 systemd重启后Redis没起来服务能跑但服务器一重启Redis就不见了。先检查两件事systemctl is-enabled redis systemctl status redis如果执行结果显示disabled说明服务没有设置开机自启。执行systemctl enable redis即可。另一个更隐蔽的问题是systemd服务文件里写的是ExecStart路径不对。比如你源码编译安装到了/usr/local/redis但服务文件还是写/usr/bin/redis-server系统就找不到可执行文件启动失败。解决办法是重新确认which redis-server的路径并更新服务文件。还有一个坑如果你的配置里有daemonize yes而systemd的Typeforksing没配对systemd会认为服务启动失败直接杀掉进程。我建议systemd环境下配置里写daemonize no服务类型用Typesimple。7.4 连接数打满、内存碎片、慢日志生产环境还有几个常见问题值得提前了解。maxclients限制的是最大连接数默认10000如果你的应用连接池配得过大或者有连接泄露会触达上限。排查时看INFO clients里的connected_clients和blocked_clients连接数异常高且不下降大概率是应用层没有正确归还连接。内存碎片率可以用INFO memory里的mem_fragmentation_ratio看。如果这个值长期大于1.5说明内存碎片很严重。解决办法是执行CONFIG SET activedefrag yes或者通过memory purge手动清理。不过activedefrag本身也消耗CPU建议在低峰期开启。最后是慢日志。Redis的SLOWLOG GET命令能拿到执行时间超过阈值的命令。我一般把阈值设为10毫秒slowlog-log-slower-than 10000 slowlog-max-len 128当某个命令频繁出现在慢日志里就要认真分析是不是keys *、hgetall大哈希、或者范围查询太大导致的。这是线上性能排查的第一步。写到这里第一阶段的安装、基础配置和问题排查就基本覆盖了。我个人在实际操作中的体会是Redis安装本身不难难的是理解每个配置对运行行为的影响。很多人在本地装完能跑就以为大功告成结果一上服务器就抓瞎。其实只要把bind、protected-mode、requirepass、maxmemory这几个配置理解透了Redis的基础使用就已经拿下一大半。下一篇我会写Redis的数据类型和应用场景欢迎继续看下去。
返回列表