Redis是一个在内存中存储数据的中间件,用于作为数据库和数据缓存,在分布式系统中能够大展拳脚。
在redis官方首页中,举例出下面六个特性,我一 一解释~
一.redis特性
1.1内存数据结构存储(In-memory data structures)
Redis 最为人所熟知的特性之一,就是它支持丰富的内存数据结构存储。作为一个 “数据结构服务器”,Redis 支持字符串(strings)、哈希表(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)、流(streams)等多种数据结构。
MySQL 主要是通过“表”的方式来存储组织数据的->“关系型数据库”
Redis 主要是通过“键值对”的方式来存储组织数据的->“非关系型数据库”
假设你正在开发一个社交应用,需要存储用户的个人信息。你可以使用 Redis 的哈希表(hashes)来存储每个用户的信息。例如:
HSET user:1000 name "John Doe"
HSET user:1000 email "john@example.com"
HSET user:1000 age 30
key 都是 string
value 则可以是上述的这些数据结构
这样,你可以方便地获取和更新用户的信息,而不需要像关系型数据库那样进行复杂的表连接操作。
1.2可编程性(Programmability)
Redis 支持通过 Lua 脚本和 Redis 函数进行服务器端脚本编程。这意味着你可以在 Redis 服务器端执行复杂的逻辑操作,而不需要将数据传输到客户端进行处理。
针对Redis的操作,可以直接通过简单的交互式命令进行操作.
也可以通过一些脚本的方式,批量执行一些操作(可以带有一些逻辑)
举一个栗子~:
假设你需要实现一个秒杀功能,确保在高并发情况下只有有限的用户能够成功购买商品。你可以使用 Lua 脚本在 Redis 服务器端实现这一逻辑:
local stock = redis.call('GET', KEYS[1])
if stock and tonumber(stock) > 0 then
redis.call('DECR', KEYS[1])
return 1
end
return 0
这个脚本首先检查商品的库存,如果库存大于 0,则减少库存并返回 1(表示秒杀成功),否则返回 0(表示秒杀失败)。通过在服务器端执行这个脚本,可以避免网络延迟和并发问题,提高秒杀功能的性能和可靠性。
1.3可扩展性(Extensibility)
Redis 提供了一个模块 API,允许你使用 C、C++ 和 Rust 等语言为 Redis 构建自定义扩展。这意味着你可以根据自己的需求扩展 Redis 的功能,例如添加新的数据结构或命令。
通过这几个语言编写 Redis 扩展(本质上就是一个动态链接库)
自己去扩展 Redis 的功能.
比如, Redis 自身已经提供了很多的数据结构和命令. 通过扩展, 让 Redis 支持更多的数据结构以及支持更多的命令~~
windows 上的 dll就可以理解为redis的扩展,可以让 exe 去调用,里面包含很多代码~
Linux 上的动态库是 .so,虽然和 dll 格式不同,本质是一样的~~
举个栗子~:
假设你需要在 Redis 中支持一种新的数据结构,比如布隆过滤器(Bloom Filter)。你可以使用 C 语言编写一个 Redis 模块,实现布隆过滤器的功能。然后,你可以将这个模块加载到 Redis 中,从而在 Redis 中使用布隆过滤器来进行高效的去重操作
1.4持久性(Persistence)
Redis 将数据集保存在内存中以实现快速访问,但也可以将所有写入操作持久化到永久存储中,以应对重启和系统故障。
对于持久化,Redis把数据存储在内存上的~~
内存的数据是“易失”的,比如进程退出/系统重启
Redis会把数据存储在硬盘上,主要是内存为主, 硬盘为辅.
(硬盘相当于对内存的数据备份了一下)
如果Redis重启了, 就会在重启时加载硬盘中的备份数据
使Redis的内存恢复到重启前的状态.
举一个例子~
假设你正在运行一个 Redis 实例,用于缓存用户的会话信息。如果 Redis 服务器意外重启,内存中的会话信息将会丢失。为了避免这种情况,你可以配置 Redis 的持久化选项,将会话信息定期保存到磁盘上。这样,当 Redis 服务器重启时,可以从磁盘上恢复会话信息,确保用户的会话状态不会丢失。
1.5集群(Clustering)
Redis 支持基于哈希分片的水平扩展,可以扩展到数百万个节点,并在集群扩展时自动重新分区。
Redis作为一个分布式系统中的中间件,能够支持集群是非常关键的特性。
这种水平扩展的方式,类似于数据库中的“分库分表”概念。
由于单个Redis能存储的数据受限于其内存空间,是有限的。因此可以通过引入多个主机,部署多个Redis节点,每个Redis节点仅存储数据的一部分,以此来提升整体的存储和处理能力。
举一个栗子~:
假设你的应用程序需要存储大量的用户数据,单个 Redis 实例已经无法满足存储需求。这时,你可以使用 Redis 集群来扩展存储容量。你可以将数据分散存储在多个 Redis 节点上,每个节点存储一部分数据。当数据量增加时,你可以添加更多的节点到集群中,Redis 会自动将数据重新分片,以平衡各个节点的负载。
1.6高可用性(High availability)
redis 支持基于哈希分片的水平扩展,可以扩展到数百万个节点,并在集群扩展时自动重新分区。
高可用,意味着具备冗余和备份机制。
Redis自身支持“主从”结构,从节点就相当于主节点的备份。在独立部署和集群部署模式下,都能实现带有自动故障转移的复制功能,从而保障系统的高可用性。
举一个栗子~:
假设你的应用程序需要存储大量的用户数据,单个 Redis 实例已经无法满足存储需求。这时,你可以使用 Redis 集群来扩展存储容量。你可以将数据分散存储在多个 Redis 节点上,每个节点存储一部分数据。当数据量增加时,你可以添加更多的节点到集群中,Redis 会自动将数据重新分片,以平衡各个节点的负载。
1.7高性能(High performance)
- 内存存储:Redis 的数据存储在内存中,相比访问硬盘的数据库,速度要快得多。
- 简单逻辑:Redis 的核心功能都是比较简单的逻辑,主要是操作内存中的数据结构。
- IO 多路复用:Redis 使用了 IO 多路复用的方式(如 epoll),可以使用一个线程管理很多个 socket,提高了并发处理能力。
- 单线程模型:Redis 使用单线程模型(虽然更高版本的 Redis 引入了多线程),减少了不必要的线程之间的竞争开销。
举一个栗子~:
假设你需要处理一个高并发的请求,比如每秒处理数千个用户的登录请求。使用 Redis 作为缓存,可以将用户的登录信息存储在内存中,从而快速响应客户端的请求。相比之下,如果使用传统的关系型数据库,每次查询都需要访问硬盘,性能会大打折扣。
二.redis经典使用场景
在当今的互联网架构中,Redis 凭借其出色的性能和丰富的功能,成为了众多企业级应用的首选中间件。今天,我们就来深入探讨 Redis 的三大经典应用场景
2.1实时数据存储(Real-time data store)
Redis 凭借其灵活的内存数据结构,能够为那些对低延迟和高吞吐量有严格要求的实时应用构建数据基础设施。
把Redis当作数据库。在大多数数据存储场景下,优先考虑的是“大”(数据量),但仍有部分场景考虑的是“快”(低延迟和高吞吐量)。例如,对于一些对实时性要求极高的应用,利用Redis多样的内存数据结构来构建数据基础设施。
举一个栗子~:
在广告搜索业务中,比如搜索引擎的广告推广服务,性能要求极高。这类搜索系统不会采用像 MySQL 这样的传统数据库,而是将所有需要检索的广告数据存储在内存中,使用类似 Redis 这样的内存数据库来完成快速检索。当然,使用这种内存数据库存储大量数据需要不少硬件资源投入。而且在这种场景下,Redis 存储的是全量数据,这些数据至关重要,不能轻易丢失。
2.2缓存与会话存储(Caching & session storage)
Redis 的速度优势使其成为缓存数据库查询、复杂计算、API 调用和会话状态的理想选择。
举一个栗子~:
使用 MySQL 存储数据时,在面对高并发访问时,速度会比较慢。根据二八原则,我们可以把热点数据(比如用户频繁访问的商品信息)单独提取出来,存储在 Redis 中。Redis 存储的只是部分数据,全量数据还是以 MySQL 为主。即使 Redis 中的数据丢失了,还可以从 MySQL 中重新加载回来。在会话存储方面,之前会话是存储在应用服务器上的。当有多台应用服务器和负载均衡器时,可能会出现用户请求分配到不同服务器导致会话不一致的问题。解决方法之一是把会话数据单独拎出来,放到 Redis 这样一组独立的机器上存储,这样即使应用程序重启了,会话也不会丢失。
2.3流处理与消息传递(Streaming & messaging)
Redis 的流数据类型支持高吞吐量的数据摄入、消息传递、事件溯源和通知。
举一个栗子~:
这里所说的消息队列不是 Linux 进程间通信的那种消息队列。基于 Redis 的流数据类型可以实现一个网络版本的生产者 - 消费者模型。在分布式系统中,服务器和服务器之间有时候也需要用到生产者 - 消费者模型。其优势在于解耦合和削峰填谷。虽然业界有很多知名的消息队列如 RabbitMQ、Kafka、RocketMQ 等,但如果当前场景对消息队列功能依赖不多,又不想引入额外依赖,Redis 可以作为一个选择。