资讯动态

Linux上Redis实战指南:从安装配置到缓存与分布式锁

发布时间:2026/9/8 8:12:57 来源:尧图企业网站定制
1. 先弄明白Linux 上装 Redis你到底在装什么我第一次接触 Redis 的时候是在一台老旧的 CentOS 7 服务器上当时公司业务量不大缓存里存的就是用户登录 Session几万人在线撑死也就几 GB 内存。真正让我吃了一次教训的是后来业务量上来我把几乎所有“看着像热点”的数据都丢进 Redis结果线上出现过几次缓存雪崩顶层的 nginx 直接被打满。后来复盘时才发现问题不在 Redis 本身而是我对它的定位、数据结构选择、持久化策略没有系统性地想过出现问题全靠猜。这篇文章会沿着我日常最常用的操作路径往下走怎么在 Linux 上安装 Redis、怎么用命令行客户端把五大数据类型玩明白、怎么改配置让实例更稳、以及分布式锁、主从复制和缓存治理这几个高频场景怎么落地。适合刚接触 Linux 和 Redis 的运维、后端开发也适合那些已经能跑起 Redis 但一直靠“复制粘贴配置”的人。Redis 本质上是一个基于内存的 NoSQL 存储它最出名的能力是“缓存”但它的数据结构比普通 KV 缓存丰富得多。字符串、哈希、列表、集合、有序集合每种结构在设计时都对应了一类真实业务问题。Linux 之所以是 Redis 的主场一是因为官方对 Linux 的调度、网络、存储优化最积极二是因为生产环境绝大多数服务器都是 Linux遇到问题社区排查案例最多。所以这篇文章我只围绕 Linux 环境展开Windows 上的玩法不在讨论范围。1.1 一句 SET 背后发生了什么很多人第一次执行redis-cli set username zhangsan时只知道“数据存进去了”。其实这条命令经历了这么几步客户端发起 TCP 连接按 RESP 协议把命令编码成数组格式发给 RedisRedis 在内存中为这个 key 分配一个字符串对象更新字典索引然后返回OK。如果开启了 AOF 持久化后面还牵扯到写缓冲和落盘。把这一串拆开之后你就能理解很多基层原则为什么/redis-cli不建议频繁大批量执行单个命令因为每一次命令都有协议解析和网络往返的开销为什么 Redis 不建议存特别大的 value因为大对象会带来内存分配、序列化、网络传输的多重压力为什么同样一条数据有时用 Hash 比用 String 更省内存。别小看这些细节排查线上问题时它们往往就是关键线索。1.2 什么场景真的需要 Redis适合用 Redis 的场景其实很清晰热点数据缓存、计数器、排行榜、分布式锁、 Session 共享、消息队列的轻量替代、以及一些需要快速去重的集合运算。比如电商首页的商品信息缓存读多写少用 String 或 Hash 缓存非常合适再比如秒杀系统的库存扣减用DECR这类原子操作可以避免并发超卖。不适合的场景也很明显把 Redis 当成唯一数据源去存储核心交易数据在 Redis 里做复杂关联查询和多表 Join把所有冷数据也都塞进内存。简单说Redis 负责“快”关系型数据库负责“全”两者配合而不是互相替代。2. Redis 安装与启停包管理器、源码编译、容器三条路Redis 在 Linux 上的安装方式非常多我推荐根据环境来选择。个人学习或测试环境直接用系统包管理器最省事生产环境更建议源码编译或容器镜像因为可以精确控制版本和编译参数。2.1 包管理器安装适合快速上手Ubuntu / Debian 系列apt update apt install -y redis-server systemctl enable --now redis-server redis-cli pingCentOS / Rocky / AlmaLinux 系列yum install -y redis systemctl enable --now redis redis-cli ping这种方式胜在快依赖都是系统维护的补丁更新也方便。但有一个问题系统源里的 Redis 版本往往偏旧。比如某些 CentOS 源只提供 3.2 或 5.0 的老版本很多新特性用不了。所以我个人的习惯是本地开发可以用包管理器正式环境还是指定版本部署更可控。2.2 源码编译安装适合生产环境精确控制官方源码可以从https://download.redis.io/releases/下载选择稳定版本即可。以 Redis 7.2 为例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 -j$(nproc) make install PREFIX/usr/local/redis编译之前先确认系统有 gcc 和 make。如果缺少Ubuntu 用apt install -y build-essentialCentOS 用yum install -y gcc make。安装完成后把可执行文件路径配置到PATHecho export PATH/usr/local/redis/bin:$PATH /etc/profile.d/redis.sh source /etc/profile.d/redis.sh源码编译最大的好处是版本由自己掌控还可以在编译时针对 CPU 指令集做优化。代价是要自己处理 systemd 服务文件、日志轮转、目录规划这些运维细节。我在生产上一般会把数据目录单独放例如/data/redis避免和系统盘混在一起。2.3 用 Docker 安装环境隔离最省心如果你已经在用容器Docker 方式是启动 Redis 最快的路径docker run -d --name redis \ -p 6379:6379 \ -v /data/redis:/data \ redis:7.2不过生产环境用 Docker 跑 Redis务必注意数据卷挂载、内存限制、端口映射这几个关键点。容器删除前记得确认数据是否已持久化不挂/data目录的话容器一删数据就全没了。特别强调一下本地跑着玩可以不加密码只要暴露到局域网或云服务器公网端口扫描和恶意写入马上就会找上门。2.4 启停服务和日志定位启动方式根据安装方式不同而不同。用 systemd 安装包方式的systemctl start redis-server systemctl status redis-server systemctl stop redis-server用源码编译的redis-server /path/to/redis.conf redis-cli shutdownredis-cli shutdown会先执行持久化再退出比直接 kill 进程安全得多。如果实例没起来优先看日志。CentOS 包安装的日志多在/var/log/redis/redis.log源码方式看配置里的logfile字段。我在排查“连不上 Redis”时第一件事就是看日志里有没有Address already in use或权限报错往往比猜配置快得多。3. 先把五大数据类型玩熟再用 redis-cli 验证一切命令行客户端redis-cli是排查 Redis 问题最趁手的工具也是学习数据结构最好的交互台。只要 Linux 上装了 Redis就能直接用。连接远端可以加-h和-p生产环境如果开启了认证再带一个-a指定密码但注意命令会被 shell 历史记录保留更安全的方式是用REDISCLI_AUTH环境变量。需要图形界面的同学可以用 Another Redis Desktop Manager 或 RedisInsight。前者轻量连接管理方便后者是官方出品的数据可视化能力更完整。排查性能问题我还是首推命令行因为图形界面再直观也隔了一层命令行的返回信息最原始、最准确。3.1 String所有缓存的基础字符串是 Redis 最基础的结构value 可以是字符串、数字、二进制流最大 512MB。日常操作set user:10018 zhangsan get user:10018 incr visit_count decr visit_countincr这类自增操作是原子的非常适合计数器场景。比如文章阅读数、点赞数、限流窗口计数都可以直接用。不用先 get 回来再 set因为那个过程不是原子的并发下会丢数据。3.2 Hash描述一个对象Hash 适合存“一堆字段”的对象比如用户资料、商品详情、配置信息。hset user:10019 name lisi age 24 city hangzhou hget user:10019 name hgetall user:10019 hincrby user:10019 age 1比起把整个对象序列化成 JSON 塞进 StringHash 的好处是能单独修改某个字段不用整存整取。比如用户头像地址变了只需要hset user:10019 avatar /new/path一次省内存也省带宽。3.3 List实现一个轻量队列List 底层是链表适合做消息队列、时间线、通知流。最常用的是从左侧写入从右侧读取lpush notify:queue hello rpop notify:queue llen notify:queue如果多个消费者同时rpop天然实现了任务分发。当然这是很原始的队列模型如果需要可靠消费、延迟消息、死信队列还是上专业的消息队列更合适。但小流量场景下用 Redis List 撑住基本读写完全够用。3.4 Set去重和集合运算Set 是无序、不重复的字符串集合底层用哈希表实现。经常用于去重、标签系统、共同好友sadd article:1001 java redis linux scard article:1001 sismember article:1001 redis sinter article:1001 article:1002scard可以统计集合内元素数量做 UV 去重很顺手。sinter可以做交集比如找出同时浏览过两篇文章的用户。3.5 ZSet带权重的有序集合ZSet 每个成员关联一个 score按 score 排序最常见的场景就是排行榜zadd leaderboard 100 playerA zadd leaderboard 200 playerB zrevrange leaderboard 0 -1 withscores zincrby leaderboard 10 playerAzincrby能直接给某个成员的分数加分适合实时更新的榜单。底层是跳表加哈希表范围查询效率很高。除了排行榜还能做延迟队列比如把任务的执行时间戳当成 score用一个线程不断取最小 score 的数据来判断是否到期。3.6 Key 的通用操作除了数据类型的操作还有一批 key 级别的常用命令exists user:10018 expire user:10018 3600 ttl user:10018 persist user:10018 del user:10018我提醒一句生产环境千万不要用keys *去匹配所有 key。这个命令会对全量 key 做遍历数据量大时直接卡死整个 Redis 实例。需要枚举 key 就用scan 0 match user:* count 100它是游标式遍历不会阻塞太久。4. 配置文件精读十个关键参数改完再上生产默认配置文件里有很多可选项但真正会直接影响稳定性和安全的其实就集中在几块。我把 Redis 7.x 的 redis.conf 里最值得关注的参数整理成一张表参数默认值我的建议bind127.0.0.1内网环境改成实际网卡 IP公网禁止 0.0.0.0port6379如果有安全要求可以改成非标准端口protected-modeyes保持开启requirepass空生产环境必须设置daemonizeno用 systemd 管理时保持 no手动启动可设 yeslogfile空生产设置独立日志路径便于排查dir./改成独立数据目录如 /data/redismaxmemory0不限制按机器内存合理设置防止 OOM 拖垮系统maxmemory-policynoeviction缓存实例用 allkeys-lruappendonlyno根据数据可靠性要求开启4.1 安全和网络参数bind决定哪些网卡可以访问 Redis。默认只监听 127.0.0.1只适合本机访问。如果服务部署在应用服务器同机保持默认反而最安全。若需要被其他服务器访问建议明确绑定内网 IP 而不是 0.0.0.0。protected-mode这个机制也很重要在没有requirepass且 bind 了外部接口时它会拒绝非本机连接等于最后一道防线。requirepass设置后所有客户端都需要通过AUTH认证。千万不能用“比如用公司名端口”这种规则。建议使用至少 24 位随机串并放到配置管理或环境变量中而不是提交到代码仓库。4.2 持久化RDB 还是 AOFRedis 持久化有两种主流方式。RDB 是定时把内存快照写入磁盘恢复快但两次快照之间宕机会丢数据AOF 是追加写命令日志可靠性高但文件体积大恢复速度相对慢。Redis 4.0 之后支持混合持久化用 RDB 做全量快照再叠加增量命令日志兼顾恢复速度和数据完整性。我的经验分层来看纯缓存场景数据丢了可以从数据库回源甚至可以关掉持久化换取性能有订单、资金等更严格的数据必须开启 AOF并且设置appendfsync everysec或always同时做好备份。生产环境建议配置如下save 900 1 save 300 10 save 60 10000 appendonly yes appendfsync everysec4.3 内存上限和淘汰策略Redis 没有 maxmemory 时会无限使用内存这是生产环境最容易被忽视的坑。机器内存 64GBRedis 没有限制结果数据一直涨最后内存耗尽触发 Linux OOM KillerRedis 进程直接被杀。设置 maxmemory 时还要预留系统和其他进程的内存空间比如 64GB 机器给 Redis 50GB。淘汰策略决定了内存满了之后的行为noeviction写命令直接报错保证数据不丢适合存储重要数据。allkeys-lru从所有 key 里淘汰最近最少使用适合纯缓存。volatile-lru从设置了过期时间的 key 里淘汰适合有些 key 需要持久保留的场景。allkeys-lfu/volatile-lfu按访问频率淘汰适合流量分布非常不均匀的业务。4.4 慢查询和连接超时运维诊断时慢查询日志很重要。默认慢查询阈值是 10000 微秒也就是 10 毫秒才记录。很多操作 5 毫秒已经很慢了建议调试阶段调低slowlog-log-slower-than 10000 slowlog-max-len 128timeout默认是 0客户端可以一直占用空闲连接。对连接数敏感的服务可以设置timeout 300空闲 300 秒自动断开避免连接被打满。但要注意长连接应用需要开启tcp-keepalive否则服务端断开后对端不一定能及时发现。5. 日常运维命令与问题排查这些命令比你想的更有用Redis 命令行不只是操作数据它更像一个内置的“体检工具”。掌握一批高频命令线上排查问题时能省一大半时间。5.1 看状态INFO 命令的分层解读redis-cli info能一次性输出大量指标我通常配合分段使用redis-cli info server redis-cli info clients redis-cli info memory redis-cli info stats redis-cli info replication重点关注几类指标connected_clients是否接近上限used_memory是否逼近 maxmemorymem_fragmentation_ratio如果长期大于 1.5说明内存碎片偏高考虑重启或调优keyspace_hits与keyspace_misses的比值能反映缓存命中率instantaneous_ops_per_sec能看出当前 QPS。5.2 抓不到异常时用 Monitor 和 Slowlog如果线上出现操作超时但应用日志又看不到具体命令可以用monitor实时打印所有请求redis-cli monitormonitor会把所有命令实时刷在控制台适合短期抓取但线上大流量环境慎用因为它本身会拖累性能。慢查询是另一种方式低频问题建议用slowlog get 100查看最近 100 条慢命令然后针对性优化。1) 1) (integer) 41 2) (integer) 1713421200 3) (integer) 23054 4) 1) KEYS 2) user:*看到KEYS这种命令基本可以确定慢查询的来源赶紧去改应用代码。5.3 连接出问题时的排查顺序现状应用报错Cannot connect to Redis。我的排查顺序是固定的先确认进程监听状态ss -lntp | grep 6379确认网络可达redis-cli -h ip -p 6379 ping看日志有没有认证失败、内存不足的记录检查系统防火墙和云安全组是否放通端口看info clients是不是连接数满了。很多时候问题不在 Redis 进程本身而是云服务器安全组没放行。所以先把网络链路验证完再深入 Redis 内部效率会高很多。5.4 常用命令速查表命令示例作用redis-cli ping验证连通性redis-cli info memory查看内存使用redis-cli dbsize查看当前库 key 数量redis-cli slowlog get 10查看最近慢查询redis-cli client list查看所有客户端连接redis-cli config get maxmemory查看运行期配置redis-cli config set maxmemory 4gb动态调整配置redis-cli --bigkeys扫描大 keyredis-cli --scan --pattern user:*head -206. 进阶组合拳分布式锁、主从复制和缓存治理当你把基础命令和配置吃透之后难点通常会集中在分布式场景。这里挑三个高频点展开每一块都有很多网上的理论文章我尽量讲成实操可复现的方案。6.1 一个“合格”的 Redis 分布式锁长什么样分布式锁的经典实现是SET key value NX EX。比如SET lock:order:10001 uuid_value NX EX 10这条命令只有在 key 不存在时才会写入并且同时设置过期时间避免死锁。但只有 NX 和 EX 还不够释放锁的时候必须校验 value 是自己设置的防止把别人的锁给解了。用 Lua 脚本保证原子性if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end我在项目中一直用这个模式没有再遇到过“误删别人锁”“死锁卡住业务”的问题。特别提醒锁的过期时间要根据业务执行耗时来定如果业务可能超过过期时间可以考虑 Redisson 的看门狗续期机制而不是把过期时间盲目拉长。6.2 主从复制和 Docker 部署Redis 主从复制的主要目的是读写分离和高可用。主节点负责写从节点同步数据并负责读即使主节点故障也可以将从节点提升为主。最简单的配置在从节点的 redis.conf 里加一行replicaof 192.168.1.10 6379如果不想改文件也可以在启动后动态执行redis-cli -p 6380 replicaof 192.168.1.10 6379Docker Compose 方式启动一主两从的例子version: 3 services: redis-master: image: redis:7.2 container_name: redis-master command: [redis-server, --appendonly, yes] ports: - 6379:6379 redis-slave1: image: redis:7.2 container_name: redis-slave1 command: [redis-server, --slaveof, redis-master, 6379] depends_on: - redis-master ports: - 6380:6379 redis-slave2: image: redis:7.2 container_name: redis-slave2 command: [redis-server, --slaveof, redis-master, 6379] depends_on: - redis-master ports: - 6381:6379启动后可以用redis-cli -p 6380 info replication查看从节点状态看到master_link_status:up就说明同步正常。需要提醒的是上面这种方案只是主从复制故障发生时不会自动切换。生产环境要想自动故障转移得再引入 Redis Sentinel 或者使用 Redis Cluster。6.3 缓存三大痛点穿透、击穿、雪崩这三个概念面试常问实际工作中也确实是治理重点。缓存穿透是指查询一个必然不存在的数据缓存没有数据库也没有每次请求都打到数据库。方案是对空结果也缓存一个短过期时间或者用布隆过滤器先拦截明显不存在的 key。缓存击穿是指某个热点 key 过期瞬间大量并发请求全部打到数据库。方案是热点 key 过期时间设置为永不过期配合后台任务更新或者用分布式锁控制回源只允许一个请求去数据库加载。缓存雪崩是指大批 key 在同一时间过期或者 Redis 实例整体宕机导致请求洪水涌向数据库。方案是过期时间加随机因子分散做多级缓存比如应用本地缓存扛一层保持 Redis 高可用用主从加 Sentinel 保障不单点。我这里实际项目里最常用的治理组合是热点数据永不过期 异步线程刷新 过期时间抖动。这样命中率能稳定在 95% 以上数据库的压力小很多。6.4 备份与恢复别等到故障才想起来Redis 的备份其实很简单。RDB 模式下直接复制 dump.rdb 文件即可AOF 模式下把 aof 文件拷贝走也可以。如果是实例还在运行最好用redis-cli --rdb /data/backup/dump.rdb或者执行BGSAVE先产生一次最新快照再复制文件。恢复时只要把备份文件放到配置的dir目录下重启实例即可。我在生产上会同时保留每日 RDB 备份和 AOF 持续写入。备份不会占用太多精力写个 cron 脚本凌晨把文件打包传到异地存储就够了。真正出故障时一份能用的备份比任何技巧都值钱。7. 最后分享一点我自己的习惯写了这么多最后说点偏“个人体感”的东西。我在 Linux 上折腾 Redis 这些年最深的一个感受是不要嫌弃命令行太原始。环境变量、配置文件、replication 状态、slowlog这些信息最终都是命令行给你最准的结果。图形化工具可以当辅助但排障时请用 redis-cli。还有一个习惯我每次部署完 Redis 都会顺手执行一次redis-cli info server看看版本号和配置是否如预期。不要把“能跑”当作“配置对了”生产环境还差得很远。希望这篇文章能帮你少踩几个我曾经踩过的坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价