提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
[一、Redis 是什么?不止是缓存的 "全能选手"](#一、Redis 是什么?不止是缓存的 “全能选手”)
[Redis 核心特性:为什么它能成为后端标配?](#Redis 核心特性:为什么它能成为后端标配?)
[二、Redis 安装:从单节点到集群的部署之路](#二、Redis 安装:从单节点到集群的部署之路)
[方式 1:系统包管理器安装(以 Ubuntu 为例)](#方式 1:系统包管理器安装(以 Ubuntu 为例))
[方式 2:源码编译安装(适合生产环境定制)](#方式 2:源码编译安装(适合生产环境定制))
[步骤 1:下载并解压源码](#步骤 1:下载并解压源码)
[步骤 2:编译并安装](#步骤 2:编译并安装)
[步骤 3:配置并启动](#步骤 3:配置并启动)
[方式 3:Docker 安装(容器化部署)](#方式 3:Docker 安装(容器化部署))
[扩展:Redis 高可用集群部署](#扩展:Redis 高可用集群部署)
[三、Redis 实战:从 "Hello Redis" 到 "场景化应用"](#三、Redis 实战:从 “Hello Redis” 到 “场景化应用”)
[示例 1:基础数据结构操作(命令行 + 客户端)](#示例 1:基础数据结构操作(命令行 + 客户端))
[安装 redis-plus-plus(C++ Redis 客户端)](#安装 redis-plus-plus(C++ Redis 客户端))
[示例 2:缓存场景(减轻数据库压力)](#示例 2:缓存场景(减轻数据库压力))
[示例 3:分布式锁场景(保证操作原子性)](#示例 3:分布式锁场景(保证操作原子性))
[四、Redis 工程化实践:那些你该知道的细节](#四、Redis 工程化实践:那些你该知道的细节)
[1. 持久化策略选择](#1. 持久化策略选择)
[2. 内存管理与优化](#2. 内存管理与优化)
[3. 性能监控与调优](#3. 性能监控与调优)
一、Redis 是什么?不止是缓存的 "全能选手"
Redis(Remote Dictionary Server)是一个开源的高性能键值(key-value)数据库,但它的能力远不止 "键值存储" 这么简单。它更像是一个 "数据结构服务器",支持字符串、哈希、列表、集合、有序集合等多种复杂数据结构,还提供了发布 / 订阅、事务、Lua 脚本等高级功能。
Redis 核心特性:为什么它能成为后端标配?
- 内存级速度:所有数据存储在内存中,读写速度极快(官方 benchmark 显示,每秒可处理超 10 万次读写操作)。
- 持久化保障:支持 RDB(快照)和 AOF(日志)两种持久化方式,防止系统故障导致数据丢失。
- 丰富数据结构:除了基本键值对,还支持列表(Lists)、哈希(Hashes)、集合(Sets)、有序集合(Sorted Sets)等,能灵活应对各种业务场景。
- 原子性操作:所有操作都是原子性的,多客户端并发访问时无需担心数据一致性问题。
- 发布 / 订阅机制:支持消息推送,可用于实现简单的消息队列或实时通知功能。
- 高可用架构:通过 Redis 哨兵(Sentinel)和集群(Cluster),实现自动故障转移和数据分片,保证服务高可用。
- Lua 脚本支持:可以在服务端执行复杂的 Lua 脚本,减少网络往返开销。
- 多语言客户端:支持 Python、Java、C++、Go 等几乎所有主流编程语言,接入成本极低。
二、Redis 安装:从单节点到集群的部署之路
Redis 的安装非常灵活,我们先从单节点安装入手,再扩展到高可用集群部署。
方式 1:系统包管理器安装(以 Ubuntu 为例)
这种方式最适合快速体验 Redis:
# 安装 Redis
sudo apt-get update
sudo apt-get install redis -y
# 启动 Redis 服务
sudo service redis-server start
# 停止 Redis 服务
sudo service redis-server stop
# 重启 Redis 服务
sudo service redis-server restart
安装完成后,Redis 会默认在 localhost:6379 端口启动。我们可以用 redis-cli 命令行工具连接测试:
redis-cli
# 进入 Redis 命令行后,执行 PING,若返回 PONG 则说明服务正常
PING
方式 2:源码编译安装(适合生产环境定制)
如果需要指定版本或更灵活的配置,源码编译是更好的选择:
步骤 1:下载并解压源码
从 Redis 官方下载页 下载对应版本的源码包(以 7.2.0 为例):
wget https://download.redis.io/releases/redis-7.2.0.tar.gz
tar -zxvf redis-7.2.0.tar.gz
cd redis-7.2.0/
步骤 2:编译并安装
make
sudo make install
步骤 3:配置并启动
Redis 的配置文件是 redis.conf,我们可以复制一份并修改配置:
cp redis.conf redis.conf.bak
vim redis.conf
常用配置项说明:
daemonize yes:以守护进程(后台)方式运行。bind 0.0.0.0:允许所有 IP 访问(生产环境需谨慎,建议指定具体 IP)。port 6379:监听端口。requirepass your_password:设置访问密码(生产环境必开)。
启动 Redis:
redis-server redis.conf
方式 3:Docker 安装(容器化部署)
在容器化环境中,用 Docker 运行 Redis 也很方便:
docker run -d \
--name redis \
-p 6379:6379 \
-v /your/redis/data:/data \
-v /your/redis/conf/redis.conf:/etc/redis/redis.conf \
redis:7.2.0 redis-server /etc/redis/redis.conf
这样可以将数据和配置文件挂载到宿主机,避免容器销毁导致数据丢失。
扩展:Redis 高可用集群部署
生产环境中,为了保证 Redis 服务不宕机,通常会部署 Redis 集群。这里简单介绍三主三从集群的搭建流程:
-
准备 6 个 Redis 实例的配置文件,分别指定不同的端口(如 7001-7006)。
-
每个配置文件中开启集群模式:
cluster-enabled yes、cluster-config-file nodes.conf、cluster-node-timeout 5000。 -
启动所有 Redis 实例。
-
用
redis-cli --cluster create命令创建集群:redis-cli --cluster create 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 127.0.0.1:7006 --cluster-replicas 1
--cluster-replicas 1 表示每个主节点有 1 个从节点。
三、Redis 实战:从 "Hello Redis" 到 "场景化应用"
光装好了还不够,我们通过几个场景,看看 Redis 在实际开发中怎么用。
示例 1:基础数据结构操作(命令行 + 客户端)
Redis 的命令行工具 redis-cli 非常强大,我们可以直接在命令行操作各种数据结构:
# 字符串(Strings)
SET name "Redis 实战"
GET name
INCR counter # 自增(counter 不存在则初始为 0,然后自增为 1)
# 哈希(Hashes)
HSET user:1 id 1 name "张三" age 25
HGETALL user:1
HGET user:1 name
# 列表(Lists)
LPUSH fruits "苹果" "香蕉" "橙子"
LRANGE fruits 0 -1 # 获取所有元素
RPOP fruits # 弹出最后一个元素
# 集合(Sets)
SADD tags "Java" "Python" "Redis"
SMEMBERS tags
SISMEMBER tags "Redis" # 判断是否存在
# 有序集合(Sorted Sets)
ZADD rank 100 "张三" 90 "李四" 80 "王五"
ZRANGE rank 0 -1 WITHSCORES # 按分数排序获取
ZREVRANGE rank 0 1 WITHSCORES # 倒序获取前两名
如果是编程场景,我们可以用 Redis 的客户端 SDK(如 Python 的 redis-py、C++ 的 redis-plus-plus 等)操作。以 C++ 的 redis-plus-plus 为例:
安装 redis-plus-plus(C++ Redis 客户端)
redis-plus-plus 是一个功能强大、使用简单的 C++ Redis 客户端库,安装步骤如下:
# 下载源码
git clone https://github.com/sewenew/redis-plus-plus.git
cd redis-plus-plus/
# 编译安装
mkdir build && cd build
cmake ..
make
sudo make install
安装完成后,在 C++ 代码中即可使用:
#include <sw/redis++/redis++.h>
#include <iostream>
int main() {
try {
// 创建 Redis 客户端(连接本地 6379 端口)
sw::redis::Redis redis("tcp://127.0.0.1:6379");
// 字符串操作
redis.set("name", "Redis 实战");
auto name = redis.get("name");
if (name) {
std::cout << "Name: " << *name << std::endl;
}
// 哈希操作
redis.hset("user:1", "id", "1");
redis.hset("user:1", "name", "张三");
redis.hset("user:1", "age", "25");
auto user = redis.hgetall("user:1");
for (const auto& [k, v] : user) {
std::cout << k << ": " << v << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
编译时需要链接 redis-plus-plus 和 hiredis 库:
g++ redis_cpp_demo.cpp -o redis_cpp_demo -lredis++ -lhiredis
示例 2:缓存场景(减轻数据库压力)
Redis 最经典的场景就是缓存,我们可以用它缓存数据库查询结果,减少数据库访问压力:
import redis
import time
from flask import Flask
app = Flask(__name__)
r = redis.Redis(host='localhost', port=6379, db=0)
@app.route('/get_user/<int:user_id>')
def get_user(user_id):
# 先从 Redis 缓存中查询
cache_key = f"user:{user_id}"
user = r.get(cache_key)
if user:
return f"从缓存获取用户:{user.decode()}, 耗时极短"
# 缓存未命中,从数据库查询(这里模拟数据库查询耗时)
time.sleep(0.5)
user_data = f"用户{user_id},姓名:张三,年龄:25"
# 将数据存入 Redis,设置过期时间为 300 秒
r.setex(cache_key, 300, user_data)
return f"从数据库获取用户:{user_data}, 耗时较长"
if __name__ == '__main__':
app.run()
这个例子中,第一次访问 /get_user/1 会从 "数据库"(模拟)查询,耗时较长;之后 300 秒内访问,会直接从 Redis 缓存获取,速度极快。
示例 3:分布式锁场景(保证操作原子性)
在分布式系统中,"分布式锁" 是保证资源互斥访问的关键。Redis 的 SETNX(Set if Not Exists)命令可以轻松实现分布式锁:
import redis
import time
import threading
r = redis.Redis(host='localhost', port=6379, db=0)
def acquire_lock(lock_key, lock_value, expire_time):
"""获取分布式锁"""
return r.set(lock_key, lock_value, ex=expire_time, nx=True)
def release_lock(lock_key, lock_value):
"""释放分布式锁(简单实现,生产环境建议用 Lua 脚本保证原子性)"""
current_value = r.get(lock_key)
if current_value == lock_value:
r.delete(lock_key)
return True
return False
def task(thread_id):
lock_key = "dist_lock"
lock_value = f"thread:{thread_id}"
# 获取锁,过期时间 10 秒
if acquire_lock(lock_key, lock_value, 10):
print(f"线程 {thread_id} 获取到锁,开始执行临界区逻辑...")
time.sleep(3) # 模拟临界区操作
release_lock(lock_key, lock_value)
print(f"线程 {thread_id} 释放锁")
else:
print(f"线程 {thread_id} 未获取到锁,等待重试...")
# 启动多个线程模拟并发
for i in range(5):
t = threading.Thread(target=task, args=(i,))
t.start()
这个例子中,多个线程并发竞争 "分布式锁",只有获取到锁的线程能执行临界区逻辑,保证了操作的原子性。
四、Redis 工程化实践:那些你该知道的细节
1. 持久化策略选择
- RDB 持久化:定期将内存中的数据快照写入磁盘,优点是恢复速度快,缺点是可能丢失最近一次快照后的所有数据。适合数据一致性要求不高的场景。
- AOF 持久化:将所有写操作以日志形式写入磁盘,优点是数据丢失少(最多丢失 1 秒数据),缺点是日志文件大、恢复速度慢。适合数据一致性要求高的场景。
- 生产建议 :开启 AOF 持久化,并设置
appendfsync everysec(每秒同步一次日志到磁盘),平衡性能和数据安全性。
2. 内存管理与优化
Redis 是内存数据库,内存不足会导致服务不可用。可以通过以下方式优化:
- 设置内存上限 :在
redis.conf中配置maxmemory,当内存达到上限时,按照maxmemory-policy(如volatile-lru、allkeys-lru等)淘汰数据。 - 数据压缩 :对于字符串类型数据,可以开启
set-max-intset-entries(集合压缩)、hash-max-ziplist-entries(哈希压缩)等配置,减少内存占用。 - 定期清理无效数据:通过定时任务清理过期键、无用缓存等。
3. 性能监控与调优
Redis 提供了 INFO 命令和 redis-cli --stat 工具监控性能:
# 查看 Redis 整体信息
redis-cli INFO
# 实时监控 Redis 性能指标
redis-cli --stat
常见性能瓶颈及解决:
- 网络瓶颈 :如果
used_cpu_sys高,可能是网络 IO 瓶颈,可考虑增加网卡带宽或优化客户端连接数。 - 内存瓶颈 :如果
used_memory接近maxmemory,需优化内存使用(如数据压缩、淘汰策略)。 - 命令瓶颈 :如果某些命令(如
KEYS *)执行时间长,需优化命令逻辑(如用SCAN代替KEYS)。