一、Redis 是什么
Redis 是一种基于键值对(key-value)的 NoSQL 数据库,与很多键值对数据库不同的是,Redis 中的值可以由 string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成,因此 Redis 可以满足很多的应用场景,而且因为 Redis 会将所有数据都存放在内存中,所以它的读写性能非常惊人。不仅如此,Redis 还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会"丢失"。除了上述功能以外,Redis 还提供了键过期、发布订阅、事务、流水线、Lua 脚本等附加功能。
二、Redis 的特点
1、速度快
正常情况下,Redis 执行命令的速度非常快,官方给出的数字是读写性能可以达到 10 万 / 秒,当然这也取决于机器的性能,但这里先不讨论机器性能上的差异,只分析一下是什么造就了 Redis 如此之快,可以大概归纳为以下四点:
- Redis 的所有数据都是存放在内存中的
- Redis 基本使用单线程(6.0 版本后,Redis 引入了多线程 I/O(用于网络数据的读写和解析),但命令执行仍然是单线程的),Redis 的性能瓶颈主要在于内存读写和网络 I/O,而非 CPU 计算。单线程足以跑满内存带宽和网卡吞吐量。且单线程天然不需要锁,不存在线程切换、上下文切换、缓存一致性维护等开销,代码更简单、运行更稳定
- Redis 是使用C语言实现的,一般来说C 语言程序直接编译成机器码,不经过虚拟机/解释器,执行速度相对会更快。
2、基于键值对的数据结构服务器
-
键值对存储方式:类似编程语言中的字典(如 C++ map、Java Map、Python dict),但 Redis 的值不限于字符串,而是支持多种数据结构。
-
Redis 全称:REmote Dictionary Server(远程字典服务器)。
-
5 种基本数据结构:
-
字符串(string)
-
哈希(hash)
-
列表(list)
-
集合(set)
-
有序集合(sorted set / zset)
-
-
两种衍生"数据结构"(基于字符串):位图(Bitmaps)和 HyperLogLog。
-
地理信息功能:自 3.2 版本起支持 GEO(基于位置服务 LBS)。
-
核心优势:多数据结构支持,便于快速开发各种应用场景。
3、丰富的功能
Redis除了支持存储多种数据结构的功能之外,还有以下额外的功能
-
键过期:可设置键的存活时间,适用于缓存场景(如会话管理、热点数据过期)。
-
发布订阅(Pub/Sub):支持消息的发布与订阅,可用于实现轻量级消息系统。
-
Lua 脚本:支持编写 Lua 脚本,可创建自定义的 Redis 命令,实现原子性操作。
-
简单事务:提供事务功能(MULTI/EXEC),能在一定程度上保证命令的原子执行。
-
流水线(Pipeline):客户端可将一批命令一次性发送给 Redis,减少网络往返开销,提升吞吐量。
4、持久化
通常,将数据放在内存中是不安全的,一旦发生断电或机器故障,重要数据可能丢失。因此,Redis 提供了两种持久化方式:RDB 和 AOF,可将内存数据保存到硬盘中。当 Redis 服务重启后,它会自动检测硬盘上的持久化文件(优先 AOF,其次 RDB)并完成加载,从而保证数据的持久性。
5、主从复制
-
核心概念 :从节点完整拷贝主节点数据,作为其"镜像",实现主写从读的单向数据同步。
-
主要作用:
-
数据冗余:多机热备份,主节点故障时数据不丢失。
-
读写分离:主节点处理写,从节点处理读,提升吞吐量。
-
高可用基础:为哨兵(Sentinel)和集群(Cluster)模式提供支撑。
-
6、高可用和分布式
Redis 提供了高可用实现的 Redis 哨兵(Redis Sentinel),能够保证 Redis 节点的故障发现和故障自动转移。同时也提供了 Redis 集群(Redis Cluster),它是真正的分布式实现,提供了高可用、读写和容量的扩展性。
三、Redis的使用场景
1、数据库: 对与一些性能要求高的场景,需要使用 Redis 来保证速度
2、缓存:根据 "二八原则",把热点数据存储在 Redis 上
3、用来存储 session: 一般情况下,session 是存储在服务器上的,浏览器只存储一个用户的身份标识(叫做cookie 或 sessionId)。
而在下图情况下,同一个客户端不同时刻发送的请求经过负载均衡器的分配,可能会分配到不同的应用服务器上,而这个应用服务器上可能没有相关的 session 信息,将会导致用户需要进行多次登录的场景,影响用户体验。

如何解决这种问题呢:
- 通过负载均衡器将同一用户的请求始终路由到同一台应用服务器(如
userId % 机器数)。 - 把会话数据单拎出来,放到一组独立的机器上存储(Redis),后续每一个应用服务器在读取或写入会话时都去访问 Redis
显然第二种方式会更好,方式一有以下缺点:
-
机器扩容/缩容时,取模结果变化,大量用户需要重新路由;
-
某台机器宕机时,该机器上的所有用户会话全部丢失,需要重新登录;
-
服务器自身仍存储 session,内存占用不均。
而使用 Redis 集中存储 Session 就没有上述问题
四、Redis 不适合的场景
大规模数据不适合使用 Redis 进行存储。