Redis介绍与使用
Redis简介
1.1 什么是 Redis?
Redis 是一个开源的、高性能的内存数据存储系统,可以作为数据库、缓存以及消息中间件使用。它支持丰富的数据结构,如字符串、哈希、列表、集合和有序集合等,因此被广泛用于需要高性能、高并发的应用场景。Redis 采用单线程模型和基于内存的存储方式,保证了非常高的读写速度。
简而言之,Redis 是一个键值数据库,它通过将数据存储在内存中,以实现快速的数据访问。Redis 支持丰富的功能,如持久化(将数据保存在硬盘上以防丢失)、事务处理、发布/订阅模式、Lua 脚本执行等。
Redis 的最大特点是它的速度极快,而这一点正是它在 Web 应用、高并发系统以及分布式环境中大受欢迎的原因之一。
1.2 Redis 的应用场景
Redis 因为其高速的读写能力和多种数据结构支持,应用场景非常广泛,常见的场景包括:
1.2.1 缓存系统
Redis 最常见的应用场景就是作为缓存层。在应用中,我们常常会缓存一些查询频繁且不经常变动的数据。Redis 作为缓存系统,可以极大提升数据读取速度,减轻数据库的负担。例如,网站首页的广告推荐信息、商品详情页的缓存等。
1.2.2 实时数据处理
Redis 支持的数据结构非常适合实时数据处理,例如排行榜、计数器、实时消息推送等。通过 Redis 的有序集合(ZSet),我们可以轻松实现排行榜等功能,并能实时更新排名数据。
1.2.3 消息队列
Redis 提供的列表(List)和发布/订阅(Pub/Sub)功能,非常适合用作消息队列。在一个分布式系统中,生产者将消息推送到队列中,消费者异步处理这些消息。Redis 提供的高效操作能确保消息队列处理的低延迟和高吞吐量。
1.2.4 会话管理
Redis 的高效性和内存存储使它非常适合用作 会话管理(Session Store)。比如,在 Web 应用中,用户登录时,常将用户会话信息存储在 Redis 中,这样可以快速访问与更新会话信息。
1.2.5 分布式锁
Redis 还可以用于实现分布式锁,通过它的 SETNX
命令,可以实现保证分布式环境下任务的互斥访问。
1.3 Redis 与传统数据库的区别
Redis 作为 NoSQL (对非关系型数据库的统称)数据库,与传统的关系型数据库(如 MySQL 和 SQLite3)相比,有许多显著的区别。我们从几个关键维度来对比 Redis 和传统数据库:
1.3.1 数据存储方式
-
Redis:将数据存储在内存中,访问速度极快。Redis 是一个内存数据库,支持内存持久化(RDB 快照和 AOF 日志)以实现数据持久化。
-
MySQL/SQLite3:是磁盘数据库,所有数据都存储在磁盘中,虽然也有内存缓存机制,但相较于 Redis,访问速度较慢。SQLite3 通常用于嵌入式应用和轻量级数据库,而 MySQL 更适用于中大型应用和多用户环境。
1.3.2 数据结构支持
-
Redis:支持丰富的内存数据结构,除了基础的键值对,还支持哈希表、列表、集合、有序集合等数据结构,适合多种应用场景(如计数器、队列、集合去重等)。
-
MySQL/SQLite3:主要支持表格结构,通过表格的行和列来组织数据。它们基于关系模型进行数据存储,所有操作都是基于 SQL 查询的。
1.3.3 性能与可扩展性
-
Redis:通过内存存储数据,Redis 的读写速度非常快,适合高并发访问的场景。它采用单线程模型,避免了多线程的上下文切换和锁的竞争,能够在高并发场景中提供更高的性能。
-
MySQL/SQLite3:虽然 MySQL 在大规模数据操作时表现出色,但在性能上受限于磁盘 I/O。SQLite3 通常用于单机环境,适合小型应用,不适合大规模的并发读写。
1.3.4 查询能力
-
Redis:没有复杂的查询语言,如 SQL。所有操作都通过 Redis 的命令完成,功能较为简单,适合简单的键值对存储以及对某些数据结构的操作。
-
MySQL/SQLite3:支持 SQL 查询,能够进行复杂的多表联合查询、聚合、过滤等操作。适用于关系型数据,能够进行更复杂的数据分析和报表生成。
1.3.5 数据一致性
-
Redis:Redis 对 ACID 特性的支持是有限的。它支持命令级别的原子性,但不提供传统意义上的事务隔离与强一致性保障。在分布式环境中,Redis 更加注重高性能和高可用性,允许在一定程度上牺牲数据一致性。。
-
MySQL/SQLite3:MySQL 提供了完善的事务支持,遵循 ACID 原则,可以确保数据的一致性、可靠性和持久性,适合要求高一致性的场景。
补充:ACID特性
缩写 | 全称 | 中文名 | 作用 |
---|---|---|---|
A | Atomicity | 原子性 | 确保事务中的所有操作要么全部执行成功,要么全部不执行 |
C | Consistency | 一致性 | 确保事务前后,数据库始终处于一致的状态 |
I | Isolation | 隔离性 | 确保并发事务之间互不干扰 |
D | Durability | 持久性 | 一旦事务提交,其修改的数据应永久保存在数据库中 |
原子性(Atomicity):
一个事务中的所有操作要么全部成功,要么全部失败,不可能只执行部分操作。
举例说明:
银行转账中,从账户 A 扣钱、给账户 B 加钱,这两个操作必须绑定执行。如果只扣了 A 的钱,但没给 B 加上,那事务就是不完整的 —— 原子性就被破坏了。
一致性(Consistency):
事务执行前后,数据库必须处于一致的状态,即遵守所有的约束条件(如唯一性、外键、业务规则等)。
举例说明:
继续银行转账的例子,假设两个账户总额是 10000 元,无论转多少次,只要每次事务正确执行,总额都不能改变 —— 这就体现了一致性。
隔离性(Isolation):
多个事务并发执行时,彼此之间互不干扰,各自的中间状态对其他事务不可见。
举例说明:
如果两个事务同时修改同一个库存,系统必须采取机制避免数据“被多次扣减”或出现“脏读”等问题。传统数据库通过锁机制或 MVCC(多版本并发控制)实现事务隔离,支持不同的隔离级别(如 Read Committed、Repeatable Read、Serializable 等)。
持久性(Durability):
一旦事务提交,其对数据库的更改必须永久保存,即使系统崩溃也不会丢失数据。
举例说明:
你转账后收到“转账成功”的提示,这笔交易即使服务器此时崩溃,系统重启后也必须能恢复该记录。数据库通常通过写 WAL(Write-Ahead Log)日志、刷盘等机制来保证持久性。
1.4 Redis 的优势与局限性
1.4.1 优势
-
高性能:Redis 的内存数据库模型使其读取和写入速度非常快,适用于高并发、高访问量的场景。
-
丰富的数据结构支持:除了基本的键值对,Redis 还支持哈希、列表、集合、有序集合等多种数据结构,使得 Redis 在解决特定问题时比传统数据库更具优势。
-
简单易用:Redis 提供的命令简洁且直观,容易上手,适合快速开发。
-
高可用性与分布式支持:Redis 提供了主从复制、Redis Sentinel 和 Redis Cluster 等功能,可以构建高可用、可扩展的分布式系统。
-
支持持久化:Redis 可以将内存数据持久化到磁盘,通过 RDB 快照或 AOF 日志来保证数据持久性,适应了大多数高性能应用场景。
1.4.2 局限性
-
内存限制:作为内存数据库,Redis 的存储受限于服务器的内存大小。如果存储大量数据,可能会遇到内存不足的情况。
-
不支持复杂查询:Redis 主要提供简单的 CRUD 操作,对于复杂的 SQL 查询(如多表关联、聚合查询等)不支持,需要结合其他工具进行实现。
-
数据一致性问题:Redis 牺牲了部分数据一致性和事务性,适用于非事务性和高可用性场景,但对于一些要求强一致性的应用,可能不合适。
Redis 基础概念
2.1 Redis 数据模型
2.1.1 键(Key)
在 Redis 中,每条数据都是一个键值对(Key-Value)。
Key 就是数据的唯一标识符,相当于传统数据库中的主键(Primary Key)。它的特性如下:
-
类型:字符串(string),但内容可以是任何字节数组。
-
最大长度:512 MB。
-
通常作为查询的入口,不支持模糊检索(除了
KEYS
命令)。 -
最佳实践:采用命名空间方式命名,如:
user:1001:name
2.1.2 值(Value)
值的类型可以是多种结构,不仅仅是字符串。这是 Redis 最有特色的设计。
2.1.3 数据类型
Redis 支持五大基础数据结构(以及一些高级结构,如 HyperLogLog、Bitmap、Geo):
类型 | 简介 | 使用场景 | 示例命令 |
---|---|---|---|
字符串(String) | 最基本的数据类型,可存储文本或二进制 | 缓存、计数器、token 存储 | SET key value , INCR key |
哈希(Hash) | 键值对集合,适用于对象表示 | 存储用户信息、配置项 | HSET user:1001 name zhang |
列表(List) | 有序链表,支持左右两端插入弹出 | 消息队列、时间线 | LPUSH , RPOP |
集合(Set) | 无序不重复元素集合 | 标签、好友推荐、去重 | SADD , SINTER |
有序集合(ZSet) | 每个元素有一个分数,用于排序 | 排行榜、带权集合 | ZADD , ZRANGE |
Redis 的强大正是因为值(Value)不仅是数据,也可以是结构化的数据集合。
2.2 Redis 内存存储机制
Redis 是内存数据库,数据读写全部在内存中完成,这也是其高性能的核心原因。
2.2.1 内存持久化(RDB 和 AOF)
【RDB】(快照)
-
以时间间隔为单位,周期性生成数据快照并写入磁盘(
.rdb
文件)。 -
优点:恢复速度快,占用空间小。
-
缺点:一旦崩溃,可能丢失上次快照之后的数据。
【AOF】(Append Only File)
-
每次写操作都会以命令形式写入日志文件(
.aof
)。 -
优点:数据几乎不丢失,恢复最完整。
-
缺点:文件大,恢复慢。
Redis 支持 RDB 和 AOF 混合持久化,也可以配置成只使用其中一种。
2.2.2 数据备份与恢复
-
备份方式:
-
复制 RDB 或 AOF 文件。
-
使用
SAVE
或BGSAVE
手动触发。
-
-
恢复方式:
-
直接将 RDB/AOF 文件放置到数据目录,重启 Redis。
-
[Redis 内存数据]||(定期快照)vRDB 文件 (或 AOF 日志)||v磁盘持久化文件
2.3 Redis 的高性能特点
Redis 在高性能方面的设计非常值得称道,以下三点是核心:
2.3.1 单线程模型
Redis 的命令处理采用单线程模型,不加锁、不阻塞,避免了线程切换开销。
-
所有命令串行执行,天然避免并发竞争问题。
-
主要瓶颈是 CPU,而不是锁。
客户端请求|v
+-----------+
| Redis 主线程 |
+-----------+|v
处理命令(串行执行)
2.3.2 异步 IO(非阻塞网络模型)
-
Redis 使用 epoll(Linux)/kqueue(BSD) 等多路复用技术进行 异步 IO 处理。
-
虽然命令执行是单线程,但网络收发是非阻塞的,连接处理效率极高。
-
底层采用
ae_event_loop
实现事件驱动模型。
+-------------+
| 客户端连接池 |
+-------------+|v
[ epoll 监听 socket 事件 ]|v
[ 有请求来了 ]|v
[ 主线程按序处理请求 ]
2.3.3 内存数据库
Redis 完全基于内存工作,数据访问无需磁盘 I/O:
-
所有数据保存在内存中,读写速度为纳秒级(ns)。
-
后台定期将内存数据异步持久化到磁盘(非阻塞)。
这就是 Redis 快如闪电的根本原因。
redis核心模型简化示意图
+----------------+ +----------------------+
| 客户端请求 | -----> | 网络层(非阻塞 IO) |
+----------------+ +----------------------+|v+------------------+| 单线程命令处理 | <- Redis 主线程(串行)+------------------+|+----------------+----------------+| |+----------------+ +--------------------+| 内存数据结构区 | | 持久化(RDB / AOF) |+----------------+ +--------------------+
redis安装与配置
3.1 linux安装 Redis
3.1.1 使用包管理器安装
sudo apt update
sudo apt install redis-server
安装完成后,可以使用以下命令启动和查看 Redis 服务:
sudo systemctl start redis
sudo systemctl enable redis # 开机启动
sudo systemctl status redis
默认配置文件路径为 /etc/redis/redis.conf
,默认端口是 6379
。
3.1.2 源码编译安装
# 1. 下载源码
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# 2. 编译
make -j4# 3. 可选:执行测试(需要 tcl)
make test# 4. 安装
sudo make install
安装后,会将 redis-server
、redis-cli
等可执行文件放到 /usr/local/bin/
。
你可以直接运行:
redis-server # 启动服务
redis-cli # 客户端命令行
配置文件可在源码目录中找到:redis.conf
,你可以复制到合适位置如 /etc/redis/
。
3.2 配置 Redis
Redis 的核心配置文件是:redis.conf
,默认位置因安装方式而异。
你可以使用:
redis-server /redis.conf的path
来自定义启动 Redis。
3.2.1 常见配置项(redis.conf)
配置项 | 作用 | 示例 |
---|---|---|
port | 监听端口 | port 6379 |
bind | 限制绑定的 IP | bind 127.0.0.1 |
requirepass | 设置访问密码 | requirepass yourpassword |
dir | 持久化文件保存目录 | dir /var/lib/redis/ |
dbfilename | RDB 文件名 | dbfilename dump.rdb |
appendonly | 是否开启 AOF | appendonly yes |
appendfilename | AOF 文件名 | appendfilename "appendonly.aof" |
maxmemory | 限制最大内存 | maxmemory 256mb |
maxmemory-policy | 内存淘汰策略 | allkeys-lru 、volatile-ttl |
3.2.2 安全配置(密码、IP 限制)
绑定指定 IP:
bind 127.0.0.1 # 限制本地访问
设置访问密码:要求所有客户端在执行任何命令前必须提供这个密码
requirepass mystrongpassword客户端连接时输入上述步骤设置的密码:
redis-cli -a mystrongpassword
关闭危险命令(如 FLUSHALL):
rename-command FLUSHALL ""
rename-command FLUSHDB ""
3.2.3 性能优化配置(内存、持久化等)
内存限制(适用于缓存场景):
# 设置 Redis 使用的最大内存为 512MB,超出后会触发内存淘汰策略
maxmemory 512mb# 设置内存淘汰策略为 allkeys-lru(从所有键中挑选最近最少使用的键淘汰)
maxmemory-policy allkeys-lru
持久化控制(视业务需求选择):
关闭持久化(仅做缓存):
save ""
appendonly no
开启 AOF 且设置为每秒同步:
appendonly yes
appendfsync everysec
Redis 常用命令
4.1 字符串(String)
Redis 中最基本的数据类型,类似于传统数据库中的单个字段值。
Redis 的字符串结构是:
Key -> "value"
常用命令:
-
SET key value
:设置键值。 -
GET key
:获取键值。 -
DEL key
:删除键。 -
INCR key
/DECR key
:对数值型字符串进行自增/自减操作。 -
INCRBY key amount
/DECRBY key amount
:按指定步长增减。 -
APPEND key value
:向原字符串追加内容。 -
STRLEN key
:返回字符串长度。 -
MSET key1 val1 key2 val2 ...
:批量设置多个键值对。 -
MGET key1 key2 ...
:批量获取多个键值。 -
SETNX key value
:仅当 key 不存在时设置。 -
SETEX key seconds value
:设置值并指定过期时间。
示例:
## 设置与获取
SET name "Alice"
# 返回: OK
# 当前键值对为:
# name -> "Alice"GET name
# 返回: "Alice"
# 说明: "name" 键的值为 "Alice"## 批量操作
MSET age 25 city "Shanghai"
# 返回: OK
# 当前键值对为:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"MGET name age city
# 返回:
# 1) "Alice"
# 2) "25"
# 3) "Shanghai"
# 说明: 返回 "name", "age", "city" 键的值## 自增自减
SET counter 10
# 返回: OK
# 当前键值对为:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "10"INCR counter
# 返回: 11
# 当前键值对为:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "11"INCRBY counter 5
# 返回: 16
# 当前键值对为:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "16"DECR counter
# 返回: 15
# 当前键值对为:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "15"DECRBY counter 2
# 返回: 13
# 当前键值对为:
# name -> "Alice"
# age -> "25"
# city -> "Shanghai"
# counter -> "13"## 字符串追加与长度
APPEND name " Smith"
# 返回: 11 # 新字符串长度
# 当前键值对为:
# name -> "Alice Smith"
# age -> "25"
# city -> "Shanghai"
# counter -> "13"GET name
# 返回: "Alice Smith"
# 说明: "name" 键的值已更新为 "Alice Smith"STRLEN name
# 返回: 11
# 说明: "name" 字段的长度为 11("Alice Smith")## 设置过期键值对
SETEX token 60 "abc123"
# 返回: OK
# 当前键值对为:
# name -> "Alice Smith"
# age -> "25"
# city -> "Shanghai"
# counter -> "13"
# token -> "abc123"(将在60秒后自动过期)GET token
# 返回: "abc123"
# 说明: "token" 键的值为 "abc123",且将在60秒后过期## 条件设置(键不存在时才设置)
SETNX city "Beijing"
# 返回: 0 # 因为 city 已存在,未设置成功
# 当前键值对为:
# name -> "Alice Smith"
# age -> "25"
# city -> "Shanghai"
# counter -> "13"
# token -> "abc123"(将在60秒后过期)GET city
# 返回: "Shanghai"
# 说明: "city" 键的值仍为 "Shanghai"## 最终键值状态(执行完上述命令后)name -> "Alice Smith"
age -> "25"
city -> "Shanghai"
counter -> "13"
token -> "abc123" (将于60秒后自动失效)
4.2 哈希(Hash)
哈希表用于存储对象,常用于表示用户信息、商品信息等。
Redis 的哈希结构是:
Key -> {field1: value1,field2: value2,...
}
常用命令:
-
HSET key field value
:设置字段。 -
HGET key field
:获取字段值。 -
HGETALL key
:获取所有字段和值。 -
HMSET key field1 val1 field2 val2 ...
:一次设置多个字段(Redis 4.0 后不推荐)。 -
HMGET key field1 field2 ...
:一次获取多个字段。 -
HDEL key field [field ...]
:删除字段。 -
HEXISTS key field
:判断字段是否存在。 -
HLEN key
:返回字段数量。 -
HINCRBY key field increment
:字段数值加减。 -
HSTRLEN key field
:字段值长度。
示例:
## 设置与获取
HSET user:1001 name "Bob" age "30" gender "male"
# 返回: 3 # 表示新增了3个字段
# 当前哈希表 user:1001 内容为:
# user:1001 -> {
# "name": "Bob",
# "age": "30",
# "gender": "male"
# }HGET user:1001 name
# 返回: "Bob"
# 说明: "name" 字段值为 "Bob"## 批量设置与获取
HMSET user:1001 email "bob@example.com" phone "123456789"
# 返回: OK
# 当前哈希表 user:1001 内容为:
# user:1001 -> {
# "name": "Bob",
# "age": "30",
# "gender": "male",
# "email": "bob@example.com",
# "phone": "123456789"
# }HMGET user:1001 name email phone
# 返回:
# 1) "Bob"
# 2) "bob@example.com"
# 3) "123456789"
# 说明: 分别返回 "name", "email", "phone" 字段的值## 删除字段与判断字段是否存在
HDEL user:1001 gender
# 返回: 1 # 成功删除1个字段
# 当前哈希表 user:1001 内容为:
# user:1001 -> {
# "name": "Bob",
# "age": "30",
# "email": "bob@example.com",
# "phone": "123456789"
# }HEXISTS user:1001 age
# 返回: 1 # 字段 age 存在
# 说明: "age" 字段仍然存在## 哈希结构长度信息
HLEN user:1001
# 返回: 4 # 当前哈希表中还有 4 个字段
# 当前哈希表 user:1001 内容为:
# user:1001 -> {
# "name": "Bob",
# "age": "30",
# "email": "bob@example.com",
# "phone": "123456789"
# }HSTRLEN user:1001 name
# 返回: 3 # name 字段的字符串长度为 3("Bob")
# 说明: "name" 字段的值长度为 3## 自增字段(用于数值字段)
HINCRBY user:1001 age 2
# 返回: 32 # 将 age 从 30 增加到 32
# 当前哈希表 user:1001 内容为:
# user:1001 -> {
# "name": "Bob",
# "age": "32",
# "email": "bob@example.com",
# "phone": "123456789"
# }## 获取全部字段和值
HGETALL user:1001
# 返回:
# 1) "name"
# 2) "Bob"
# 3) "age"
# 4) "32"
# 5) "email"
# 6) "bob@example.com"
# 7) "phone"
# 8) "123456789"
# 说明: 返回所有字段和值## 最终哈希表 user:1001 的结构如下:{"name": "Bob","age": "32","email": "bob@example.com","phone": "123456789"
}
4.3 列表(List)
列表是一种双向链表结构,支持从两端插入和弹出元素。
Redis 的列表结构是:
Key -> [ value1, value2, value3, ... ]
常用命令:
-
LPUSH key value [value ...]
/RPUSH key value [value ...]
:从左/右插入。 -
LPOP key
/RPOP key
:从左/右弹出。 -
LRANGE key start stop
:获取指定范围元素。 -
LLEN key
:获取列表长度。 -
LREM key count value
:移除指定值。 -
LSET key index value
:设置指定索引的值。 -
LINDEX key index
:获取指定索引值。 -
LTRIM key start stop
:保留指定区间,删除其余元素。 -
BLPOP key [key ...] timeout
/BRPOP key [key ...] timeout
:阻塞式弹出。
示例:
# 插入元素
LPUSH tasks "task3" "task2"
RPUSH tasks "task4"
head <--> "task2" <--> "task3" <--> "task4" <--> tail# 查询
LLEN tasks #LLEN tasks 返回列表的长度,结果是 3。LRANGE tasks 0 -1
#LRANGE tasks 0 -1 返回从索引 0 到 -1(即整个列表),结果是 ["task2", "task3", "task4"]。LINDEX tasks 1
LINDEX tasks 1 返回索引 1 的元素,结果是 "task3"。# 设置与移除
LSET tasks 1 "task2_updated"
head <--> "task2" <--> "task2_updated" <--> "task4" <--> tailLREM tasks 0 "task3"
head <--> "task2" <--> "task2_updated" <--> "task4" <--> tail# 截取与弹出
LTRIM tasks 0 1
head <--> "task2" <--> "task2_updated" <--> tailLPOP tasks
head <--> "task2_updated" <--> tailRPOP tasks
head <--> tail
4.4 集合(Set)
集合用于存储不重复元素,支持集合运算。
Redis 的集合结构是:
Key -> {value1,value2,value3,...}
常用命令:
-
SADD key member [member ...]
:添加元素。 -
SMEMBERS key
:获取所有元素。 -
SREM key member [member ...]
:删除元素。 -
SISMEMBER key member
:判断是否存在。 -
SCARD key
:集合元素数量。 -
SRANDMEMBER key [count]
:随机返回一个或多个元素。 -
SPOP key [count]
:随机弹出元素。 -
SUNION key1 key2 ...
:求并集。 -
SINTER key1 key2 ...
:求交集。 -
SDIFF key1 key2 ...
:求差集。
示例:
## 添加元素
SADD tags "redis" "database" "nosql"
# 返回: 3 # 成功添加了3个新元素
# 当前集合内容(顺序可能不同):
# tags -> {
# "redis",
# "database",
# "nosql"
# }## 再次添加重复元素
SADD tags "redis" "backend"
# 返回: 1 # 只有 "backend" 是新元素
# 当前集合内容(顺序可能不同):
# tags -> {
# "redis",
# "database",
# "nosql",
# "backend"
# }## 查看所有成员
SMEMBERS tags
# 返回:
# 1) "redis"
# 2) "nosql"
# 3) "database"
# 4) "backend"
# (集合是无序的,顺序可能不同)## 判断元素是否存在
SISMEMBER tags "redis"
# 返回: 1 # 表示存在SISMEMBER tags "mysql"
# 返回: 0 # 表示不存在## 移除元素
SREM tags "nosql"
# 返回: 1 # 成功移除1个元素
# 当前集合内容(顺序可能不同):
# tags -> {
# "redis",
# "database",
# "backend"
# }## 集合大小
SCARD tags
# 返回: 3## 随机弹出一个元素
SPOP tags
# 返回: (例如)"backend" # 每次随机,结果可能不同
# 当前集合内容(顺序可能不同):
# tags -> {
# "redis",
# "database"
# }## 最终集合内容
SMEMBERS tags
# 返回:
# 1) "redis"
# 2) "database"
# (假设弹出了 "backend")
4.5 有序集合(Sorted Set)
每个元素有一个 score,成员按照 score
自动从小到大排序。与集合(Set)相比,多了一个“分数”维度,且结果是有序的。。
Redis 的有序集合结构是:
Key -> {member1: score1,member2: score2,...
}
常用命令:
-
ZADD key score member [score member ...]
:添加元素。 -
ZRANGE key start stop [WITHSCORES]
/ZREVRANGE
:按分数排序查询。 -
ZREM key member [member ...]
:删除成员。 -
ZSCORE key member
:获取某成员的分数。 -
ZRANK key member
/ZREVRANK
:获取排名。 -
ZINCRBY key increment member
:对成员分数自增。 -
ZCOUNT key min max
:统计分数在范围内的元素数量。 -
ZRANGEBYSCORE key min max
:按分数范围查询。
示例:
# Redis 有序集合操作演示(scoreboard)# 1. 添加与查询
ZADD scoreboard 100 "Alice" 150 "Bob" 130 "Carol"
# 返回结果:
# (integer) 3 # 成功添加 3 个成员# Redis 中有序集合 scoreboard 内容为(按 score 排序):
# scoreboard -> {
# "Alice": 100,
# "Carol": 130,
# "Bob": 150
# }ZRANGE scoreboard 0 -1 WITHSCORES
# 返回结果(按 score 从小到大):
# 1) "Alice"
# 2) "100"
# 3) "Carol"
# 4) "130"
# 5) "Bob"
# 6) "150"ZREVRANGE scoreboard 0 1
# 返回结果(按 score 从大到小,前两个成员):
# 1) "Bob"
# 2) "Carol"# 2. 分数与排名查询
ZSCORE scoreboard Alice
# 返回结果:
# "100"
# 说明: "Alice" 的分数为 100ZRANK scoreboard Carol
# 返回结果:
# 1
# 说明: "Carol" 排名第 2(从 0 开始)ZREVRANK scoreboard Bob
# 返回结果:
# 0
# 说明: "Bob" 在倒序中排名第 1(最高分)# 3. 分数修改与范围查询
ZINCRBY scoreboard 10 Alice
# 返回结果:
# "110"
# 说明: "Alice" 的分数已增加 10,变为 110ZRANGE scoreboard 0 -1 WITHSCORES
# 返回结果(按 score 从小到大):
# 1) "Alice"
# 2) "110"
# 3) "Carol"
# 4) "130"
# 5) "Bob"
# 6) "150"ZCOUNT scoreboard 120 160
# 返回结果:
# (integer) 2
# 说明: "scoreboard" 中分数在 120 到 160 之间的成员有 2 个("Carol" 和 "Bob")ZRANGEBYSCORE scoreboard 120 200
# 返回结果:
# 1) "Carol"
# 2) "Bob"
4.6 键操作(Key Operations)
用于管理所有键的通用命令。
常用命令:
-
EXPIRE key seconds
:设置键过期时间。 -
TTL key
:查看剩余时间。 -
PERSIST key
:取消过期时间。 -
DEL key [key ...]
:删除键。 -
RENAME key newkey
:重命名键。 -
TYPE key
:查看键类型。 -
KEYS pattern
:通配符查询。 -
EXISTS key
:判断键是否存在。 -
MOVE key db:将指定的键迁移到指定的数据库
-
DOUBLE OBJECT key:查看给定键的内部信息(包括内存占用等)
# 1. EXPIRE key seconds:设置键的过期时间
SET mykey "Hello"
# 返回: OK
EXPIRE mykey 60
# 返回: 1 # 设置成功,键 mykey 将在60秒后过期
TTL mykey
# 返回: 60 # 返回剩余过期时间为 60 秒# 2. TTL key:查看剩余时间
TTL mykey
# 返回: 60 # mykey 剩余过期时间 60 秒# 3. PERSIST key:取消过期时间
PERSIST mykey
# 返回: 1 # 表示取消了过期时间
TTL mykey
# 返回: -1 # 不再有过期时间# 4. DEL key [key ...]:删除一个或多个键
DEL mykey
# 返回: 1 # 删除成功
TTL mykey
# 返回: (error) No such key # 键已删除,不存在# 5. RENAME key newkey:重命名键
SET mykey "Hello"
# 返回: OK
RENAME mykey newkey
# 返回: OK # 重命名成功
GET newkey
# 返回: "Hello" # 可以通过新键名获取相同的值# 6. TYPE key:查看键的类型
SET mykey "Hello"
# 返回: OK
TYPE mykey
# 返回: string # 表示 mykey 的类型是 string# 7. KEYS pattern:通配符查询
SET user1 "Alice"
SET user2 "Bob"
SET admin "Charlie"
# 返回: OK
KEYS user*
# 返回:
# 1) "user1"
# 2) "user2"# 8. EXISTS key:判断键是否存在
EXISTS mykey
# 返回: 0 # 表示 mykey 不存在
EXISTS newkey
# 返回: 1 # 表示 newkey 存在# 9. MOVE key db:将键迁移到指定的数据库
SET mykey "Hello"
# 返回: OK
MOVE mykey 1
# 返回: 1 # 表示成功将 mykey 从当前数据库迁移到数据库 1
SELECT 1
# 返回: OK
GET mykey
# 返回: "Hello" # 在数据库 1 中可以找到 `mykey`# 10. OBJECT key:查看给定键的内部信息
SET mykey "Hello"
# 返回: OK
OBJECT ENCODING mykey
# 返回: "raw" # 返回键的编码方式
OBJECT IDLETIME mykey
# 返回: 0 # 返回 mykey 的空闲时间(单位:秒)
4.7 redis常用数据库管理命令
SELECT index
切换 Redis 数据库。Redis 默认有 16 个数据库,使用索引来切换。
SELECT 2
# 返回: OK # 选择数据库 2
FLUSHDB
删除当前数据库中的所有键。清空当前数据库,但不会影响其他数据库中的数据。
PFLUSHDB
异步删除当前数据库中的所有键,Redis 5.0+ 引入,减少阻塞。
FLUSHALL
删除所有数据库中的所有键。执行后会清空 Redis 实例中的所有数据。此命令操作不可逆。
PFLUSHALL
异步删除所有数据库中的所有键,类似于 FLUSHALL
,但执行时不会阻塞其他客户端请求。
DBSIZE
返回当前数据库中键的数量。用于获取当前数据库中的键数量。
INFO [section]
获取 Redis 实例的各种信息,可以指定某一部分的详细信息(如服务器、内存、客户端、持久化等)。
INFO
# 返回:
# # Server
# redis_version:6.2.1
# # Clients
# connected_clients:10
# # Memory
# used_memory:100000
LATENCY LATEST
查看 Redis 实例的最新延迟信息。
CLIENT LIST
返回当前所有客户端的连接信息。包括客户端的 ID、连接地址、空闲时间等。
CLIENT LIST
# 返回:
# 1) id=1 addr=127.0.0.1:6379 fd=8 name= age=10 idle=5 flags=N db=0
# 2) id=2 addr=127.0.0.1:6380 fd=9 name= age=20 idle=15 flags=N db=1
CLIENT KILL id
关闭指定的客户端连接。
CONFIG GET parameter
获取 Redis 配置参数的当前值。
CONFIG GET maxmemory
# 返回:
# 1) "maxmemory"
# 2) "0"
CONFIG SET parameter value
设置 Redis 配置参数的值。注意某些配置只能在启动时设置。
CONFIG SET maxmemory 1024mb
# 返回: OK # 将最大内存限制设置为 1024MB
CONFIG REWRITE
重写 Redis 配置文件,将当前的配置更新到 Redis 配置文件中。适用于持久化配置更改。
CONFIG REWRITE
# 返回: OK # 配置文件重写成功
SHUTDOWN
关闭 Redis 实例。
LASTSAVE
返回 Redis 上次成功保存数据的时间戳
Redis 持久化与备份
Redis 提供了两种主要的持久化机制:RDB(快照)持久化和AOF(追加文件)持久化。此外,Redis 还支持 混合持久化,即同时启用 RDB 和 AOF 持久化。
6.1 RDB 快照持久化
RDB 是 Redis 的一种持久化方式,能够在指定时间间隔内创建 Redis 数据库的快照,保存在磁盘上。RDB 文件存储了 Redis 数据的完整快照,能够在 Redis 重启时用于数据恢复。
6.1.1 配置与触发机制
Redis 的 RDB 快照持久化通过配置文件中的 save
指令来控制触发条件。每当 Redis 发生某些变化时,它会在满足特定条件后自动保存数据。
save
配置参数示例:
save 900 1 # 在 900 秒(15分钟)内,如果有至少 1 个键被修改,则触发 RDB 快照保存
save 300 10 # 在 300 秒(5分钟)内,如果至少有 10 个键被修改,则触发 RDB 快照保存
save 60 10000 # 在 60 秒内,如果至少有 10000 个键被修改,则触发 RDB 快照保存
配置说明:
-
每条
save
规则由两个数字组成,<seconds>
和<changes>
,即在<seconds>
秒内,如果发生了至少<changes>
次写操作,Redis 会触发 RDB 快照持久化。 -
例如,
save 900 1
表示在 900 秒(15分钟)内,如果有至少 1 个键被修改,则触发快照保存。
手动触发 RDB 快照:
你也可以手动触发 RDB 快照:
BGSAVE
该命令会在后台创建 RDB 快照,并保存到磁盘中,允许 Redis 继续响应客户端请求。
RDB 快照触发的场景:
-
定期自动保存:按照
save
配置的规则触发。 -
手动保存:通过
BGSAVE
或SAVE
命令手动触发。 -
主从同步:当 Redis 实例作为主服务器时,RDB 快照也会用于从服务器同步数据。
6.1.2 恢复与恢复时的注意事项
RDB 恢复过程非常简单,Redis 启动时会自动加载最新的 RDB 快照文件。恢复时需要注意以下几点:
-
文件路径:RDB 快照文件默认保存为
dump.rdb
,位于 Redis 配置文件中指定的dir
目录。 -
启动时恢复:当 Redis 启动时,它会自动检查当前目录中的
dump.rdb
文件并加载它。如果找到了该文件,Redis 会根据快照中的数据来恢复数据库。 -
数据丢失问题:RDB 快照的恢复时间受保存的时间间隔影响。如果发生 Redis 重启,且上次保存快照时已有变化,恢复时会丢失在快照保存和重启期间的数据。
6.2 AOF 日志持久化
AOF(Append Only File)是 Redis 的另一种持久化方式,它通过记录每个写命令到一个日志文件中,以此来实现持久化。
6.2.1 配置与触发机制
Redis 默认情况下不启用 AOF 持久化,若启用 AOF,Redis 会将所有写命令追加到 AOF 文件中。你可以在 Redis 配置文件中通过设置 appendonly
参数来启用 AOF。
AOF 配置参数示例:
appendonly yes # 启用 AOF 持久化
appendfsync everysec # 每秒同步一次 AOF 文件
AOF 文件的三种同步策略:
-
always:每次执行写命令后立即同步 AOF 文件(会导致性能下降)。
-
everysec:每秒同步一次 AOF 文件(这是默认设置,性能与安全平衡)。
-
no:不自动同步(只有通过后台线程在某个间隔内同步)。
6.2.2 数据恢复
AOF 恢复过程如下:
-
Redis 启动时会读取 AOF 文件,并按照文件中记录的写操作依次执行,从而恢复数据。
-
AOF 文件通常比 RDB 文件要大,因为它记录了每个写操作,因此恢复过程可能会比 RDB 恢复慢。
AOF 恢复时的注意事项:
-
AOF 文件的位置与 RDB 文件类似,默认保存在 Redis 的工作目录中,文件名为
appendonly.aof
。 -
如果 AOF 文件损坏,Redis 会尝试修复(启用
aof-load-truncated
配置项)。 -
为了避免 AOF 文件膨胀过大,Redis 提供了
AOF 重写
(AOF Rewrite)功能,它会根据当前数据库状态生成一个新的 AOF 文件,去除重复操作。
6.3 混合持久化(RDB + AOF)
Redis 5.0 引入了混合持久化模式,它结合了 RDB 和 AOF 的优势,既能提供数据的持久化,又能保证数据恢复时的快速性和完整性。
混合持久化工作原理
混合持久化在 RDB 快照的基础上,将 AOF 文件和 RDB 文件结合。在持久化时,Redis 会将数据库的快照存储在 RDB 文件中,同时将增量的写操作记录到 AOF 文件中。这样做的好处是:
-
RDB 提供了快速的恢复:通过 RDB 快照快速恢复数据。
-
AOF 提供了精确的恢复:AOF 文件记录所有的写操作,可以精确地恢复数据。
混合持久化启用方式:
在配置文件中,可以通过设置 appendonly
和 appendfsync
参数来启用混合持久化。Redis 默认启用了这种模式:
appendonly yes # 启用 AOF 持久化
appendfsync everysec # 每秒同步一次 AOF 文件
混合持久化的优势
-
恢复速度快:使用 RDB 文件作为基础快照,并通过 AOF 增量更新数据,可以提高数据恢复速度。
-
数据完整性:AOF 文件记录了所有写命令,确保数据不会丢失。
-
高效的空间使用:混合持久化减少了 AOF 文件的写入操作,减少了 AOF 文件的大小。
混合持久化恢复
恢复时,Redis 首先加载 RDB 快照文件,然后应用 AOF 文件中记录的增量操作,以恢复数据。此过程的恢复速度相较于单纯使用 AOF 快照要快得多。
Redis 高级特性
7.1 发布/订阅(Pub/Sub)
Redis 提供了内建的发布/订阅消息系统(Pub/Sub),允许消息从发送者(发布者)广播给一个或多个接收者(订阅者),而无需两者之间直接通信。
它是一种典型的消息广播模型,适用于聊天室、实时通知、系统广播等场景。
核心命令:
命令 | 说明 |
---|---|
SUBSCRIBE channel [channel ...] | 订阅一个或多个频道 |
PUBLISH channel message | 向指定频道发布消息 |
UNSUBSCRIBE [channel ...] | 取消订阅 |
PSUBSCRIBE pattern [pattern ...] | 使用通配符订阅多个频道 |
PUNSUBSCRIBE [pattern ...] | 取消模式订阅 |
示例:
开启终端 A(作为订阅者):
SUBSCRIBE news
此时 Redis 会将该客户端状态切换为“订阅模式”,并阻塞式监听名为 news
的频道。Redis 会自动推送任何发布到该频道的消息到这个客户端。
注意:客户端一旦 SUBSCRIBE
或 PSUBSCRIBE
,进入阻塞状态,就不能再发送普通命令(比如 SET
、GET
),只能接收消息,直到:UNSUBSCRIBE或连接断开。
开启终端 B(作为发布者):
PUBLISH news "Redis 7.0 Released!"
注意: Redis 不会缓存消息,消息是实时广播的,若发布时没有任何订阅者,消息直接被丢弃,消息传递是同步推送到所有订阅者,大量订阅者可能拖慢发布速度。
终端 A 将自动接收到消息:
1) "message" 表示这条数据是一个消息类型的推送。
2) "news" 这是消息来自的频道名称。
3) "Redis 7.0 Released!" 这是发布者发送的具体消息内容。
Redis 协议会把推送过来的内容打包成一个“数组”,所以你看到的是 1)
、2)
、3)
,这其实就是 Redis 的 RESP 协议(Redis Serialization Protocol)中的数组结构形式。
+-------------------+ +-------------------+
| Publisher | | Subscriber A |
|-------------------| |-------------------|
| PUBLISH news "..."|-----> | SUBSCRIBE news |
+-------------------+ +-------------------++-------------------+| Subscriber B ||-------------------|| SUBSCRIBE news |+-------------------+-- 任何 PUBLISH news 的消息将同时被 A 和 B 接收到 --
7.2 事务(MULTI / EXEC / WATCH)
Redis 支持简单形式的事务机制,允许将多个命令打包为一个事务块执行,从而实现操作的原子性。
Redis 事务主要由以下指令组成:
-
MULTI
:标记事务开始。 -
EXEC
:执行所有事务命令。 -
DISCARD
:放弃事务。 -
WATCH
:对一个或多个键设置监视,当其中任意键在事务执行前被修改,事务将被中断。
Redis 事务的执行流程
-
WATCH
(可选)对关键 key 进行乐观锁监控。 -
MULTI
开启事务队列。 -
后续所有命令将被入队缓存。
-
EXEC
触发事务,Redis 依次执行队列中的命令。 -
如果期间被监视的 key 被外部修改,事务失败,
EXEC
返回 nil。
示例操作 1:普通事务
MULTI
SET user:score 100
INCRBY user:score 50
GET user:score
EXEC
返回:
1) OK
2) (integer) 150
3) "150"
示例操作 2:使用 WATCH 实现乐观锁(模拟余额扣款)
客户端 A:
SET balance 100
WATCH balance
GET balance # → "100"
MULTI
DECRBY balance 20
EXEC
如果此时客户端 B 修改了 balance:
客户端 B:
SET balance 50
那么客户端 A 的 EXEC
将返回 nil
,表示事务失败:
(nil)
这是因为监视的键 balance
在事务期间被其他客户端改动,Redis 终止执行,以保证数据一致性。
注意:
特性 | 说明 |
---|---|
✅ 原子性 | EXEC 中的命令会顺序执行,不会被打断 |
❌ 回滚能力 | Redis 事务不支持回滚(没有 ROLLBACK) |
❌ 隔离级别 | 没有真正的隔离性,其他客户端仍可读写 |
✅ 并发控制 | 可使用 WATCH 模拟乐观锁 |
7.3 脚本与 Lua 支持
为什么需要脚本支持?
Redis 本身只支持原子执行的命令,但不支持复杂逻辑控制(如条件、循环)。Lua 脚本支持带来了以下优势:
-
原子性执行:脚本中的所有命令作为一个整体执行,中间不会被其他命令打断。
-
减少网络开销:多个操作通过一次请求提交,节省 RT。
-
支持复杂逻辑:如 if/else、for 循环、函数等。
基本命令
EVAL script numkeys key [key ...] arg [arg ...]
-
script:Lua 脚本代码字符串
-
numkeys:表示接下来有几个 key 参数
-
key1...keyN:传递给脚本的 Redis 键名
-
arg1...argN:额外的参数,不作为键
示例 :只有在键不存在时才设置
EVAL "if redis.call('exists', KEYS[1]) == 0 then redis.call('set', KEYS[1], ARGV[1]) return 'OK' else return 'EXISTS' end" 1 mykey myvalue
解释:
-
KEYS[1]
为"mykey"
,ARGV[1]
为"myvalue"
-
如果
mykey
不存在,则设置为"myvalue"
并返回"OK"
-
否则返回
"EXISTS"
示例 :批量删除匹配前缀的 key
EVAL "local keys = redis.call('keys', ARGV[1])for i,k in ipairs(keys) do redis.call('del', k) end return #keys" 0 "temp:*"
说明:
-
删除所有匹配
"temp:*"
的 key -
#keys
返回删除的数量
Lua脚本常用命令:
函数 | 参数 | 说明 | 使用示例 |
---|---|---|---|
redis.call(command, ...) | command : Redis 命令字符串;...args : 参数列表 | 用于执行 Redis 命令,并返回结果 | lua<br>local result = redis.call('get', KEYS[1])<br>return result |
redis.pcall(command, ...) | command : Redis 命令字符串;...args : 参数列表 | 类似 redis.call ,但在错误时返回 nil | lua<br>local result = redis.pcall('get', KEYS[1])<br>if result then<br>return result<br>else<br>return "Key not found"<br>end |
redis.sha1hex(string) | string : 需要计算 SHA1 校验和的字符串 | 计算字符串的 SHA1 校验和 | lua<br>local sha1 = redis.sha1hex('this is a test string')<br>return sha1 |
redis.evalsha(sha1, numkeys, ...) | sha1 : 脚本的 SHA1 校验和;numkeys : 键的数量;... : 键和参数列表 | 执行已加载的 Lua 脚本(使用 SHA1) | lua<br>local sha1 = redis.sha1hex('return redis.call("get", KEYS[1])')<br>redis.evalsha(sha1, 1, 'my_key') |
redis.log(level, message) | level : 日志级别("debug", "verbose", "notice", "warning" 等);message : 日志内容 | 记录日志消息 | lua<br>redis.log("notice", "This is a log message") |
redis.sleep(seconds) | seconds : 暂停的秒数(可以是小数) | 暂停脚本执行指定的时间 | lua<br>redis.sleep(2)<br>return "Finished Sleeping" |
redis.setex(key, seconds, value) | key : 键名;seconds : 过期时间(秒);value : 设置的值 | 设置一个带有过期时间的键 | lua<br>redis.setex("my_key", 300, "value")<br>return "Key set with expiration" |
redis.bitcount(key) | key : 键名 | 计算指定键的位计数 | lua<br>redis.bitcount("my_bit_key") |
redis.getrange(key, start, end) | key : 键名;start : 起始位置;end : 结束位置 | 获取指定键的子字符串 | lua<br>redis.getrange("my_key", 0, 5) |
7.4 Redis 集群与分片
为了突破单机 Redis 在容量与并发性能上的限制,Redis 官方提供了原生的 Redis Cluster 机制,它通过数据的分片(sharding)与节点间的协作,实现了高可用、可扩展的分布式部署方式。
7.4.1 分片(Sharding)与哈希槽机制
分片(Sharding) 是将数据水平切分为多个部分,每个部分存储在不同 Redis 节点上,从而分担负载、提升容量。Redis Cluster 采用的是哈希槽分片策略。
注意:Redis Cluster 使用多个主节点(master nodes)来实现分片,每个主节点负责一部分哈希槽(0 ~ 16383 之间的一段)。
哈希槽(Hash Slot) 是 Redis Cluster 的核心分片单位。Redis 将整个 key 空间划分为 16384 个槽(编号 0 到 16383),每个键通过哈希函数映射到某个槽位,再由特定节点负责这个槽。
哈希槽计算方法:
HASH_SLOT = CRC16(key) mod 16384
也就是说,Redis 使用 CRC16
哈希算法对 key 计算哈希值,并将其对 16384 取模,结果即为槽编号。
示例:计算某个键属于哪个哈希槽
> CLUSTER KEYSLOT mykey
(integer) 10285
7.4.2 Redis Cluster 架构与节点角色
节点类型
Redis Cluster 中的节点分为两类:
-
主节点(Master):负责持有实际的数据和哈希槽。
-
从节点(Slave):用于主节点的备份,当主节点故障时进行故障转移。
高可用机制
当某个主节点宕机且多数节点(>半数)发现异常后,会自动触发 故障转移(failover),其从节点会被提升为主节点。
假设有 6 个主节点(M1 ~ M6),如果 M1 宕机,要至少有一半以上的其他主节点(也就是至少 ceil(6/2) = 4
个)同时认为 M1 不可达(PFAIL 或 FAIL),才会触发 failover 流程。这些判断是在 Redis Cluster 的 Gossip 协议中完成的,主节点之间会周期性地互相 PING/ACK 探测是否“可达”。
典型拓扑结构
-
至少 3 个主节点 + 3 个从节点
-
每个主节点管理若干个哈希槽
-
从节点分别跟随某个主节点做备份
Node A (Master) --> Node A1 (Slave)
Node B (Master) --> Node B1 (Slave)
Node C (Master) --> Node C1 (Slave)
7.4.3 Redis 集群搭建流程(以 6 个节点为例)
Step 1:准备配置文件
创建 6 个 Redis 实例配置文件,以下为示例配置重点:
redis.confport 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
其他端口(7001 - 7005)依次修改端口号。
Step 2:启动所有 Redis 实例
redis-server ./7000/redis.conf
redis-server ./7001/redis.conf
...
redis-server ./7005/redis.conf
Step 3:创建集群
使用 redis-cli
的 --cluster create
命令:
redis-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1--cluster-replicas 1,意味着:每个主节点都配一个从节点
16384 个哈希槽均匀分配给3个主节点
这些节点的主从角色是 redis-cli 在执行时自动决定的,而不是你手动指定谁是主谁是从。
如果你想手动决定哪些是主哪些是从,**就不能使用这个命令,而是得用更底层的命令逐个 CLUSTER MEET、CLUSTER ADDSLOTS 等来构建集群。
此命令会自动分配槽位,并为每个主节点分配一个从节点。
Step 4:验证集群状态
redis-cli -c -p 7000 cluster info
redis-cli -c -p 7000 cluster nodes
7.4.4 集群管理相关命令
命令 | 说明 |
---|---|
CLUSTER INFO | 查看当前节点的集群信息 |
CLUSTER NODES | 查看整个集群的所有节点 |
CLUSTER SLOTS | 查看槽分布情况 |
CLUSTER KEYSLOT <key> | 查询 key 属于哪个哈希槽 |
CLUSTER FORGET <node-id> | 移除某个节点(强制) |
CLUSTER MEET <ip> <port> | 添加新节点到集群 |
CLUSTER REPLICATE <node-id> | 将当前节点设置为某主节点的从节点 |
CLUSTER RESET | 重置节点并清除其集群配置 |
示例:
查看集群信息
127.0.0.1:7000> CLUSTER INFO
输出:
cluster_state:ok 表示集群正常。
cluster_slots_assigned:16384 表示总共分配了 16384 个槽位。
cluster_size:3 表示集群有 3 个主节点。
....查看集群节点信息
127.0.0.1:7000> CLUSTER NODES
07c37dfeb2352e56c38e8c801c0bb4a6b5fd64a6 127.0.0.1:7000 master - 0 1624567890 1 connected 0-5460
3c3f3f5c6b44c1a1beec77c57d56b983f56cb0a1 127.0.0.1:7003 slave 07c37dfeb2352e56c38e8c801c0bb4a6b5fd64a6 0 1624567891 2 connected
......
列出了集群中的所有节点。
每行展示一个节点的状态,包括节点 ID、IP 地址、角色(master/slave)以及其负责的槽位范围。查看哈希槽分配情况
127.0.0.1:7000> CLUSTER SLOTS
1) 1) (integer) 02) (integer) 54603) 1) "127.0.0.1"2) (integer) 70003) "my-cluster-1"
2) 1) (integer) 54612) (integer) 109223) 1) "127.0.0.1"2) (integer) 70013) "my-cluster-2"
3) 1) (integer) 109232) (integer) 163833) 1) "127.0.0.1"2) (integer) 70023) "my-cluster-3"
显示了哈希槽(0-16383)的分配情况,列出了每个主节点及其负责的槽区间。
每个主节点对应的从节点会在后续的操作中自动关联。查看某个键属于哪个哈希槽
127.0.0.1:7000> CLUSTER KEYSLOT mykey
(integer) 10285
mykey被分配到哈希槽10285中。......