
先聊点实在的。只要你做过后端开发或者正在自学后端技术栈“Redis”这个名字迟早会出现在你眼前。翻一下招聘要求Java、Go、Python 后端岗基本都写着“熟悉 Redis 优先”打开面试题库Redis 相关问题的出现频率高得离谱再看实际生产环境只要系统流量稍微起来一点Redis 几乎就是标配。它不是某个大厂内部才能用到的小众技术而是已经落入“常规基础设施”范畴的通用组件。这一篇是“Redis 学习笔记”系列的开头我准备用最通俗的方式把 Redis 讲明白它到底解决什么问题、凭什么这么快、怎么快速安装起来跑通第一个命令以及初学阶段你最应该盯住的核心主线。不管你是刚接触后端的学生、想补基础经验的初级开发还是准备深入优化系统的工程师这一篇都值得你花十分钟读一遍。我不打算一上来堆概念而是从一段真实场景聊起。1. 为什么我们需要认识 Redis先从一杯咖啡说起1.1 一个扛不住的“小网站”假设你写了个个人博客或者校园论坛初期存储在 MySQL 里的数据也就几千条读写都很快压根感觉不到性能瓶颈。但某天你发了一篇爆款文章用户同时涌进来不少人反复刷新查看文章列表和详情这时候数据库的查询压力就上来了。MySQL 本身并不是不能扛并发问题在于频繁的磁盘 I/O、行锁竞争还有重复查询都在浪费资源。说得直白点一百个人同时查同一条热门文章数据库就得把同一份数据从磁盘捞出来一百次。这个“重复劳动”既拖慢响应速度也加重服务端压力。这时候你非常需要一层“快得多的缓存”挡在数据库前面把那些高频访问的数据提前放在一个随手能拿到的地方。Redis 干的就是这个活儿。它把数据放在内存里读写速度快到让数据库“望尘莫及”一份热点数据只要被读一次后续相同的请求就可以直接命中内存压根碰不到数据库。这就是 Redis 最简单、最核心的定位一层高速缓存。1.2 Redis 到底是个什么东西严格说Redis 是一个基于内存的、支持多种数据结构的 NoSQL 键值存储系统。它名字里的“REmote Dictionary Server”翻译过来就是“远程字典服务器”你可以粗暴理解为它是一张超级大、超级快的 HashMap外面允许很多台机器通过 TCP 协议来读写这张表。为什么它快最直接的原因就是内存。内存的随机访问延迟一般都在几十纳秒到一百多纳秒的级别而磁盘的随机访问延迟往往要几毫秒甚至更高这中间差着好几个数量级。再加上 Redis 本身用 C 语言编写、命令设计精简、对事件循环和内存分配做了大量优化所以它在普通机器上都能轻松做到每秒十万甚至几十万次的 QPS每秒查询次数。很多人喜欢拿 Redis 和关系型数据库、Memcached 做对比简单梳理一下你就清楚了维度Redis传统关系型数据库如 MySQLMemcached主要存储介质内存可持久化到磁盘磁盘为主内存数据结构支持String、Hash、List、Set、ZSet 等表结构、SQL 查询、事务只支持简单 KV持久化RDB 快照 AOF 日志事务日志、Binlog 等不支持典型应用场景缓存、分布式锁、排行榜、消息队列等业务数据存储、复杂查询纯缓存场景单机吞吐量极高常达 10w QPS一般几千到几万 QPS极高这个表不是让你背下来的而是想说明一件事Redis 不是一个“什么都能存的数据库”它更像是一个能力很强的通用数据结构服务器。正因为数据结构丰富、底层又是内存操作所以它不仅能做缓存还能顺手做一堆别的有趣的事情后面我会详细展开。1.3 学习 Redis 能解决什么问题对后端开发来说Redis 几乎是躲不开的必修课。你写业务接口的时候要考虑怎么降低数据库压力你做登录认证要处理 Session 和 Token 的存储你要做并发控制需要一把跨服务的锁你要做排行榜、文章浏览量、在线状态Redis 都能给出比数据库更优雅的方案。对架构师和运维来说Redis 的持久化策略选型、高可用方案主从复制、哨兵模式、集群模式、缓存一致性保障都是生产环境必须反复权衡的问题。网上经常能看到“缓存穿透导致数据库被打爆”的案例这些事故本质上都是对 Redis 的底层机制理解不够造成的。对学生和初学者来说Redis 是一个非常理想的“第二个数据库”。它命令简单、安装容易、可视化工具也多你不需要理解太复杂的 SQL学完基础命令就能做出“分布式登录态共享”“排行榜”“消息队列”这样看起来挺厉害的小项目对建立自信和积累项目经验帮助特别大。2. 初识 Redis搞清楚那些让人上头的特性2.1 五种基础数据结构与两种“隐藏款”Redis 之所以特别很大程度是因为它不是一个只认字符串的 Key-Value 仓库。它内部提供了五种基础数据结构每种结构都有对应的使用场景。我先把最实用的部分列出来再逐个拆。数据结构底层含义典型使用场景常用命令举例String字符串、数字、二进制串缓存对象、计数器、分布式锁SET、GET、INCR、SETNXHash字段-值映射表存储对象属性如用户信息、商品信息HSET、HGET、HGETALLList双向链表消息队列、时间线、最新列表LPUSH、RPUSH、LPOP、LRANGESet无序字符串集合去重、共同关注、抽奖、标签系统SADD、SISMEMBER、SINTERZSet有序集合带权重的有序集合排行榜、延时队列、热搜榜ZADD、ZRANGE、ZSCORE实际开发里最常见的 String 可以存一个序列化后的 JSON 对象也可以直接存数字做自增操作。Hash 比 String 更适合存“需要频繁修改部分字段”的对象比如用户昵称和头像要独立更新时用 Hash 就特别顺手不用把整个缓存对象取出来再重写一遍。List 的双向特性让它既能当“队列”左进右出也能当“栈”左进左出。Set 最典型的就是交集、并集、差集运算比如“我关注的人里有哪些也关注了你”一条 SINTER 命令就能搞定。ZSet 则是给每个元素绑定了一个分数分数决定排序位置排行榜就是它的主场。除此之外Redis 还提供了一些进阶的数据结构比如 Bitmap位图、HyperLogLog基数统计、Geo地理位置、Stream更完善的消息队列模型以及通过模块支持的布隆过滤器。初学阶段不用急着全啃下来先把五种基础结构用熟后面遇到“UV 统计”“附近的人”“消息可靠投递”这些场景时再逐个击破。2.2 单线程模型为什么单线程还能这么快我见过不少刚接触 Redis 的人都会有个疑惑“Redis 是单线程的那它凭什么还能扛住这么高的并发”这个问题的答案其实是理解 Redis 性能的一把钥匙。首先要澄清一点Redis 的命令执行核心确实主要是单线程的也就是说同一时刻只有一个命令在真正处理数据。但 Redis 的底层用了 IO 多路复用机制能够同时监控成千上万个客户端连接一旦哪个连接有请求数据进来事件循环就会立刻处理它。因为内存操作本身极快每个命令又极短单线程处理它们根本不会成为瓶颈反而避免了很多多线程编程的麻烦。你可以把单线程模型类比成“一个人在多个窗口间快速接待客户”窗口再多接待员也只有一个但他处理得足够快而且不用考虑窗口之间的排队锁、资源抢占整体效率反而更高。更妙的是由于 Redis 单线程保证了命令执行的原子性所以像 INCR、SETNX 这些命令天然就没有并发竞争问题这为后面做分布式锁打下了非常好的基础。有个细节容易被面试官问到Redis 6.0 之后引入了多线程 IO网络数据的读写部分会交给额外线程处理但命令执行仍然是单线程的。也就是说“单线程执行命令”这个核心设计没有变多线程只是把网络收发的耗时分摊出去。理解了这一点你就能很自然地回答“Redis 6.0 多线程是怎么回事”。2.3 持久化内存数据库的数据安全感不少人会问内存里的数据万一机器重启了不就全没了吗Redis 当然考虑到了这个问题它提供了两种持久化方案这也是生产环境必须做的功课。RDBRedis DataBase是快照式持久化简单说就是定期把内存里的全量数据“拍一张照片”保存到磁盘的 dump.rdb 文件里。它的优点是文件紧凑、加载速度快非常适合做备份和灾难恢复缺点是如果两次快照之间发生了数据变更中间这部分数据就会丢失因为快照不是每时每刻都在拍的。AOFAppend Only File则是日志型持久化它会把每一条写命令按照追加的方式记录到文件里。你可以把它想象成记账本每一笔流水都记下来恢复数据时只要把命令从头到尾重新执行一遍。AOF 提供了多种刷盘策略比如每秒刷盘、每修改就刷盘数据安全性更高但文件体积通常比 RDB 大恢复速度也相对慢一些。我习惯打个比方RDB 像你定期给手机联系人备份到本地恢复方便但可能漏掉最近新增的号码AOF 像你随时用备忘录记录每个新号码更全但记录文件很长。生产环境里最常见的做法是两者同时开启RDB 做冷备份和快速启动AOF 保证尽量少丢数据。等后面单独写持久化专题时我再把 rewrite 机制、fsync 策略、混合持久化这些细节展开讲。3. 上手实践把你的第一个 Redis 跑起来3.1 分平台安装指南Linux、macOS、Windows、Docker初学 Redis 最大的门槛不是命令而是先把环境搞起来。我按不同平台给出最快可行的方案Linux 环境如果你有云服务器或者本地虚拟机用包管理器安装是最快的。Debian/Ubuntu 系执行sudo apt update sudo apt install redis-serverRedHat/CentOS 系可以这样sudo yum install redis安装完成后启动服务并验证sudo systemctl start redis-server redis-cli ping如果看到返回 PONG就说明服务已经正常工作了。想改监听端口、密码等配置通常编辑 /etc/redis/redis.conf 后重启服务即可。源码编译安装更灵活能选择指定版本但步骤多一点我一般建议新手直接用包管理器等需要定制版本时再上源码编译。macOS 环境macOS 上最舒服的方式是 Homebrewbrew install redis brew services start redisbrew services 能帮你把 Redis 注册成后台服务开机自启日常开发非常省心。Windows 环境这里必须说实话Redis 官方其实不原生支持 Windows。网上流传的 Windows 安装包多是一些第三方移植版本版本普遍滞后官方仓库不再维护 Windows 版本了。如果你只是本地想跑一下 Redis我最推荐用 WSL 2Windows 自带的 Linux 子系统里安装 Redis这样环境更接近生产也可以直接用 Docker 跑一个 Redis 容器下面马上讲到。也有人保留着旧版 Windows 安装包比如 5.0.14.1 之类能在本地跑起来但仅适合学习测试不建议作为业务依赖。看到这里你应该明白为什么简历上写 Linux 经验很重要因为大量中间件根本不原生支持 Windows早一点适应 Linux 环境对后续工作帮助很大。Docker 环境如果你机器上已经装了 Docker这一条是所有人的通用解docker run -d --name redis-server -p 6379:6379 redis这一条命令会拉取官方 Redis 镜像所谓 Redis 镜像就是现成的、包含 Redis 运行环境的 Docker 镜像文件并启动一个映射到宿主机 6379 端口的容器。需要加密码的话可以再加一个参数docker run -d --name redis-server -p 6379:6379 redis redis-server --requirepass 123456Docker 方案的好处太多了不用操心系统兼容性、换版本只需要换镜像标签、删除容器对宿主机零污染。我自己做实验和写测试代码时基本都用 Docker 来快速拉起整套 Redis 环境。3.2 启动配置与第一个命令Redis 启动后默认监听 6379 端口。用客户端连上去敲下第一组命令你就算正式入门了redis-cli 127.0.0.1:6379 SET name hello-redis 127.0.0.1:6379 GET name 127.0.0.1:6379 PINGSET、GET 的语义一看就懂PING 返回 PONG 表示服务存活。聊一下几个初学者容易踩坑的配置项bind默认可能只绑定了 127.0.0.1意味着只有本机能访问。如果你要让其他机器连接需要改成0.0.0.0或者指定内网 IP但改完一定要配合密码和防火墙策略否则等于把数据裸奔在网络上。protected-modeRedis 默认开启保护模式混用 bind 和密码时必须理解它的作用当你绑定了公网地址但又没设密码时Redis 会拒绝外部连接。这算是一种“默认安全”保护不建议轻易关掉。requirepass设置访问密码。连接后需要执行AUTH 密码才能执行命令或者在连接时直接写redis-cli -a 密码。daemonize决定 Redis 是否以后台守护进程方式运行。Windows、Docker 里的运行方式略有不同但本地学习中我把daemonize yes改成后台运行避免每次关掉终端服务就停了。dir和dbfilename这两个配置决定 RDB 快照文件存哪里、叫什么名字对后续做数据备份和迁移非常重要。我给新手的建议是初学阶段不要在 bind、protected-mode 上折腾太多默认本机访问就够了当你要部署到服务器上跑真实业务时再认真设计网络暴露、防火墙规则和密码策略。3.3 可视化客户端redis-cli 之外的“图形化”选择命令行虽然强大但很多人初期看图识字效率更高尤其想直观看看一个 Key 里存了多少条 List、Hash 里有哪些字段。这时候可视化客户端就能派上用场。目前常用的有三款工具特点适合谁RedisInsightRedis 官方出品的 GUI 工具功能全面界面现代想用官方工具、看官方最佳实践的开发者Redis Desktop ManagerRDM老牌经典功能稳定社区版免费习惯传统界面、看中生态成熟度的人Another Redis Desktop Manager开源、轻量、跨平台适配性不错追求免费轻量、平时只需要基础 CRUD 的开发者无论选哪一款连接逻辑都差不多填主机地址、端口、密码如果有有些工具还支持 SSH 隧道方式连接远程 Redis。不过我想提醒一句可视化工具只是锦上添花实际工作中排查问题、写脚本、看延时统计最终还是要回到 redis-cli 和命令上。你可以把工具当辅助但不要把“会用可视化工具”当成“会 Redis”。4. 你以为 Redis 只是缓存盘点几个高频应用场景4.1 缓存Redis 最广为人知的身份读多写少的数据比如商品详情、用户资料、配置项非常适合放在 Redis 缓存里。经典的缓存策略是 Cache Aside先查缓存命中就直接返回没命中再查数据库把结果写回缓存并设置过期时间。这个模式简单可靠实际项目里九成以上缓存都是这么用的。不过“缓存”这两个字背后全是细节。比如“缓存穿透”用户不断请求一个缓存和数据库里根本就不存在的数据比如恶意用一个不存在的用户 ID 刷接口导致每次请求都穿透缓存打到底层数据库再比如“缓存击穿”某个热点 Key 过期的一瞬间大量请求同时冲进数据库还有人喜欢说“缓存雪崩”大量 Key 同一时间集中过期数据库瞬间被打爆。这些词的高频出现说明它们在生产环境里有多常见。处理手段很多包括缓存空值、布隆过滤器、加互斥锁、过期时间加随机值等但这些我打算放到后面“缓存治理”专题里细讲你了解到有这些坑就已经值回票价了。4.2 分布式锁从单体到多实例的并发控制单体应用里做同步Java 有 synchronized、Lock但服务一旦部署了多个实例锁得让所有实例都能看到这时候“分布式锁”就登场了。Redis 靠 SETNX 命令实现分布式锁是最经典的做法核心原理就是只有一个客户端能成功把 Key 设置进去谁设置成功谁就拿到了锁。简单演示一下加锁逻辑# 加锁px 表示过期时间防止持锁实例挂掉导致死锁 SET lock:order 1 NX PX 30000 # 业务处理完成后释放锁 DEL lock:order这套方案看起来简单但细节非常多锁要设置过期时间防止死锁释放锁时要判断是不是自己的锁防止误删别人的锁过期时间到了但业务还没执行完怎么办这些都需要引入 Lua 脚本或 Redisson 这样的框架来兜底。我现在讲这个只是让你知道 Redis 还有这个用法等后面专门讲分布式锁时再展开各种坑。4.3 更多有趣姿势计数器、排行榜、消息队列Redis 能做的不止缓存和锁。计数器用INCR article:read:1001就能做文章浏览量自增INCR天然原子不会因为并发导致计数少了。面试题里常出现的“Redis INCR 不准”本质是没用对按 key 粒度各增各的要做到全局总量正确需要换思路。排行榜ZSet 是榜单神器用分数存热度值ZADD rank:hot 100 article1再通过ZREVRANGE rank:hot 0 9就能拿到 TOP 10。各大排行榜系统背后基本都有 ZSet 的影子。简易消息队列List 的左进右出 (LPUSHBRPOP) 就能实现简单的生产者-消费者模式配合阻塞命令可以在没有现成 MQ消息队列的场景下先顶一阵。当然更完整的可靠消息队列建议用 Redis Stream 或者专业的 MQ 产品。这些玩法加在一起你就能感受到 Redis 为什么被叫作“瑞士军刀”它不是一个功能单一的缓存而是一个灵活高效的内存数据结构服务。5. 从入门到进阶梳理一套靠谱的学习实操路线5.1 先把地基打牢命令、数据类型、持久化我对学习顺序的建议是先不要急着去看集群和高可用先把单机版用熟。第一步把五种基础数据结构的所有常用命令过一遍尤其理解 Same Key 在不同数据类型下的行为差异第二步把 Redis 配置文件和持久化机制弄清楚做一次“重启后数据能不能恢复”的实验第三步用一门你熟悉的语言比如 Java 的 Spring Data Redis、Python 的 redis-py写一个小项目把缓存读写用起来。我自己当初学的时候就是先写了个带登录 Session 共享的小网站把用户登录状态放进 Redis才真正理解了 Key 过期时间、序列化和连接池这些概念。如果你第一次接触 Redis我强烈建议你也用真实项目来带动学习而不是对着命令表干背。5.2 核心场景逐个深挖缓存治理、分布式锁、高可用基础打完后就可以进入这个系列后续准备覆盖的内容缓存穿透、缓存击穿、缓存雪崩怎么预防分布式锁怎么实现才能保证安全可靠主从复制、哨兵模式和集群模式到底解决什么问题它们之间有什么区别。这些内容网上到处都有人写但真正的价值在于你能不能讲清楚什么场景选什么方案以及踩坑后怎么排查。比如 Redis 连接偶尔报 “command timed out” 超时异常很多人第一反应是加超时时间但真正原因可能是连接池耗尽、慢命令阻塞了事件循环甚至网络层面抖动。这种经验不亲手排查一次光看文档体会不出来。5.3 高频面试题背后其实是同一套底层逻辑Redis 相关的面试题很多但核心基本都绕不开Redis 为什么快单线程模型有什么利弊RDB 和 AOF 怎么选缓存和数据库的一致性怎么解决大 Key 怎么发现怎么处理主从延迟怎么降低热点 Key 怎么应对这几个问题表面看是不同知识点的考察实际上都在考察你对“内存存储、单线程事件循环、网络模型、持久化策略”这几个底层概念的融会贯通程度。你只需要把原理真正吃透遇到问题自然就不会只停留在“网上说这样干”的表层而是能推导出当前场景下哪个方案更合理。5.4 一个我坚持了很久的学习小习惯最后分享一个我自己的经验也算给这个系列开个题我学 Redis 的时候并没有一上来就背命令而是每学一个特性都会问一句“没有 Redis 的时候这个问题是怎么解决的”。比如没有 Redis 缓存数据库就多扛一些压力没有分布式锁就用数据库乐观锁或应用层锁没有 ZSet排行榜就得通过 SQL 反复排序。带着“解决什么问题”的眼光去学 Redis你会发现每个设计背后都有合理的动机学起来轻松得多面试时说起话来也会更有底气。下一篇我打算紧接着聊 Redis 的 String 和 Hash 类型到底怎么用才能发挥最大价值包括对象缓存和序列化的坑。你如果刚起步不妨先把这篇文章里的命令手动跑一遍对于“初识 Redis”这个目标来说你已经比大多数只会背概念的人走得靠前了。