Redis入门教程 - 从零开始学习Redis缓存数据库
Redis入门教程 - 从零开始学习Redis缓存数据库
目录
- Redis简介
- Redis安装与配置
- Redis数据类型
- Redis常用命令
- Redis持久化
- Redis事务
- Redis发布订阅
- Redis主从复制
- Redis集群
- Java操作Redis
- Redis应用场景
- Redis性能优化
- Redis最佳实践
- 总结与进阶
1. Redis简介
Redis(Remote Dictionary Server)是一个开源的、基于内存的数据结构存储系统,可以用作数据库、缓存和消息中间件。Redis支持多种数据类型,包括字符串、哈希、列表、集合、有序集合等。
核心特点:
- ✅ 高性能:数据存储在内存中,读写速度极快
- ✅ 丰富的数据类型:支持字符串、列表、集合、有序集合、哈希等
- ✅ 持久化:支持RDB和AOF两种持久化方式
- ✅ 原子操作:所有操作都是原子性的
- ✅ 发布订阅:支持消息的发布订阅模式
- ✅ 事务支持:支持事务操作
- ✅ 主从复制:支持主从复制,提高可用性
- ✅ 集群支持:支持集群模式,横向扩展
| 特性 | Redis | MySQL | MongoDB |
|---|---|---|---|
| 存储位置 | 内存 | 磁盘 | 磁盘 |
| 数据类型 | 丰富 | 关系型 | 文档型 |
| 性能 | 极高 | 中等 | 较高 |
| 持久化 | 可选 | 必须 | 必须 |
| 适用场景 | 缓存、会话 | 事务处理 | 文档存储 |
- 缓存:热点数据缓存,提升访问速度
- 会话存储:用户会话信息存储
- 计数器:实时计数、点赞数等
- 排行榜:游戏排行榜、热门文章等
- 消息队列:简单的消息队列实现
- 分布式锁:实现分布式锁
- 限流:API限流、防刷等
2. Redis安装与配置
Ubuntu/Debian系统
# 更新包列表
sudo apt update
# 安装Redis
sudo apt install redis-server
# 启动Redis服务
sudo systemctl start redis-server
# 设置开机自启
sudo systemctl enable redis-server
# 检查Redis状态
sudo systemctl status redis-serverCentOS/RHEL系统
# 安装EPEL仓库
sudo yum install epel-release
# 安装Redis
sudo yum install redis
# 启动Redis服务
sudo systemctl start redis
# 设置开机自启
sudo systemctl enable redis
# 检查Redis状态
sudo systemctl status redis源码编译安装
# 下载Redis源码
wget http://download.redis.io/redis-stable.tar.gz
# 解压
tar xzf redis-stable.tar.gz
cd redis-stable
# 编译
make
# 安装
sudo make install
# 创建配置目录
sudo mkdir /etc/redis
sudo cp redis.conf /etc/redis/
# 启动Redis
redis-server /etc/redis/redis.conf2.2 macOS安装Redis
# 使用Homebrew安装
brew install redis
# 启动Redis服务
brew services start redis
# 或者手动启动
redis-server /usr/local/etc/redis.conf- 下载Windows版本的Redis(推荐使用WSL或Docker)
- 或使用Docker运行Redis:
docker run -d -p 6379:6379 --name redis redis:latestRedis配置文件通常位于/etc/redis/redis.conf或安装目录下。
常用配置项
# 网络配置
bind 127.0.0.1 # 绑定IP地址
port 6379 # 端口号
protected-mode yes # 保护模式
# 通用配置
daemonize yes # 后台运行
pidfile /var/run/redis_6379.pid # PID文件
loglevel notice # 日志级别
logfile "" # 日志文件路径
# 持久化配置
save 900 1 # 900秒内至少1个key变化则保存
save 300 10 # 300秒内至少10个key变化则保存
save 60 10000 # 60秒内至少10000个key变化则保存
# RDB配置
dbfilename dump.rdb # RDB文件名
dir /var/lib/redis # 工作目录
# AOF配置
appendonly yes # 开启AOF
appendfilename "appendonly.aof" # AOF文件名
appendfsync everysec # 同步策略
# 内存配置
maxmemory 256mb # 最大内存
maxmemory-policy allkeys-lru # 内存淘汰策略
# 安全配置
requirepass yourpassword # 设置密码2.5 Redis客户端连接
命令行客户端
# 连接本地Redis
redis-cli
# 连接远程Redis
redis-cli -h hostname -p port
# 使用密码连接
redis-cli -a password
# 执行命令
redis-cli ping测试连接
# 启动Redis客户端
redis-cli
# 测试连接
127.0.0.1:6379> PING
PONG
# 查看信息
127.0.0.1:6379> INFO3. Redis数据类型
字符串是Redis最基本的数据类型,可以存储字符串、整数或浮点数。
基本操作
# 设置值
SET key value
SET name "Redis"
SET age 25
# 获取值
GET key
GET name
# 返回: "Redis"
# 设置多个值
MSET key1 value1 key2 value2
MSET name "Redis" age 25
# 获取多个值
MGET key1 key2
MGET name age
# 返回: 1) "Redis" 2) "25"
# 获取字符串长度
STRLEN key
STRLEN name
# 返回: 5
# 追加字符串
APPEND key value
APPEND name " Tutorial"
GET name
# 返回: "Redis Tutorial"
# 自增
INCR key
SET counter 10
INCR counter
# 返回: 11
# 自减
DECR key
DECR counter
# 返回: 10
# 增加指定值
INCRBY key increment
INCRBY counter 5
# 返回: 15
# 减少指定值
DECRBY key decrement
DECRBY counter 3
# 返回: 12
# 设置过期时间
SETEX key seconds value
SETEX session:123 3600 "user_data"
# 设置值(仅当key不存在时)
SETNX key value
SETNX lock:resource true应用场景
- 缓存:存储热点数据
- 计数器:文章阅读数、点赞数
- 会话存储:用户会话信息
- 分布式锁:简单的锁实现
哈希类型适合存储对象,可以存储字段和值的映射。
基本操作
# 设置字段值
HSET key field value
HSET user:1 name "Alice"
HSET user:1 age 25
HSET user:1 email "alice@example.com"
# 获取字段值
HGET key field
HGET user:1 name
# 返回: "Alice"
# 设置多个字段
HMSET key field1 value1 field2 value2
HMSET user:1 name "Alice" age 25 email "alice@example.com"
# 获取多个字段
HMGET key field1 field2
HMGET user:1 name age
# 返回: 1) "Alice" 2) "25"
# 获取所有字段和值
HGETALL key
HGETALL user:1
# 返回: 1) "name" 2) "Alice" 3) "age" 4) "25" 5) "email" 6) "alice@example.com"
# 获取所有字段名
HKEYS key
HKEYS user:1
# 返回: 1) "name" 2) "age" 3) "email"
# 获取所有值
HVALS key
HVALS user:1
# 返回: 1) "Alice" 2) "25" 3) "alice@example.com"
# 判断字段是否存在
HEXISTS key field
HEXISTS user:1 name
# 返回: 1
# 删除字段
HDEL key field1 field2
HDEL user:1 email
# 获取字段数量
HLEN key
HLEN user:1
# 返回: 2
# 字段值自增
HINCRBY key field increment
HINCRBY user:1 age 1应用场景
- 用户信息存储:存储用户对象
- 购物车:存储购物车商品信息
- 配置信息:存储系统配置
列表是简单的字符串列表,按照插入顺序排序,可以从头部或尾部添加元素。
基本操作
# 从左边推入元素
LPUSH key value1 value2
LPUSH list "a" "b" "c"
# 列表: c b a
# 从右边推入元素
RPUSH key value1 value2
RPUSH list "d" "e"
# 列表: c b a d e
# 从左边弹出元素
LPOP key
LPOP list
# 返回: "c"
# 列表: b a d e
# 从右边弹出元素
RPOP key
RPOP list
# 返回: "e"
# 列表: b a d
# 获取列表长度
LLEN key
LLEN list
# 返回: 3
# 获取指定范围的元素
LRANGE key start stop
LRANGE list 0 -1
# 返回: 1) "b" 2) "a" 3) "d"
LRANGE list 0 1
# 返回: 1) "b" 2) "a"
# 获取指定索引的元素
LINDEX key index
LINDEX list 0
# 返回: "b"
# 设置指定索引的元素
LSET key index value
LSET list 0 "x"
# 列表: x a d
# 在指定元素前/后插入
LINSERT key BEFORE|AFTER pivot value
LINSERT list BEFORE "a" "y"
# 列表: x y a d
# 删除指定值的元素
LREM key count value
# count > 0: 从头部删除count个
# count < 0: 从尾部删除count个
# count = 0: 删除所有
LREM list 1 "a"应用场景
- 消息队列:简单的队列实现
- 最新消息:存储最新N条消息
- 文章列表:存储文章ID列表
集合是字符串的无序集合,不允许重复元素。
基本操作
# 添加元素
SADD key member1 member2
SADD tags "java" "redis" "python"
# 获取所有成员
SMEMBERS key
SMEMBERS tags
# 返回: 1) "java" 2) "python" 3) "redis"
# 判断成员是否存在
SISMEMBER key member
SISMEMBER tags "java"
# 返回: 1
# 获取成员数量
SCARD key
SCARD tags
# 返回: 3
# 删除成员
SREM key member1 member2
SREM tags "python"
# 随机获取成员
SRANDMEMBER key [count]
SRANDMEMBER tags
# 随机返回一个成员
# 随机弹出成员
SPOP key [count]
SPOP tags
# 随机删除并返回一个成员
# 集合运算
SADD set1 "a" "b" "c"
SADD set2 "b" "c" "d"
# 交集
SINTER set1 set2
# 返回: 1) "b" 2) "c"
# 并集
SUNION set1 set2
# 返回: 1) "a" 2) "b" 3) "c" 4) "d"
# 差集
SDIFF set1 set2
# 返回: 1) "a"应用场景
- 标签系统:文章标签、用户标签
- 共同关注:计算共同好友
- 去重:去除重复数据
- 随机抽奖:随机选择用户
有序集合是集合的升级版,每个成员都关联一个分数,按分数排序。
基本操作
# 添加成员
ZADD key score member
ZADD leaderboard 100 "Alice"
ZADD leaderboard 200 "Bob"
ZADD leaderboard 150 "Charlie"
# 获取成员分数
ZSCORE key member
ZSCORE leaderboard "Bob"
# 返回: "200"
# 获取成员排名(从低到高)
ZRANK key member
ZRANK leaderboard "Bob"
# 返回: 2
# 获取成员排名(从高到低)
ZREVRANK key member
ZREVRANK leaderboard "Bob"
# 返回: 0
# 获取指定范围的成员(按分数排序)
ZRANGE key start stop [WITHSCORES]
ZRANGE leaderboard 0 -1
# 返回: 1) "Alice" 2) "Charlie" 3) "Bob"
ZRANGE leaderboard 0 -1 WITHSCORES
# 返回: 1) "Alice" 2) "100" 3) "Charlie" 4) "150" 5) "Bob" 6) "200"
# 获取指定范围的成员(按分数倒序)
ZREVRANGE key start stop [WITHSCORES]
ZREVRANGE leaderboard 0 -1
# 返回: 1) "Bob" 2) "Charlie" 3) "Alice"
# 获取指定分数范围的成员
ZRANGEBYSCORE key min max [WITHSCORES]
ZRANGEBYSCORE leaderboard 100 150
# 返回: 1) "Alice" 2) "Charlie"
# 增加成员分数
ZINCRBY key increment member
ZINCRBY leaderboard 50 "Alice"
# 返回: "150"
# 获取成员数量
ZCARD key
ZCARD leaderboard
# 返回: 3
# 统计指定分数范围的成员数量
ZCOUNT key min max
ZCOUNT leaderboard 100 200
# 返回: 3
# 删除成员
ZREM key member1 member2
ZREM leaderboard "Alice"应用场景
- 排行榜:游戏排行榜、热门文章
- 延时队列:按时间排序的任务队列
- 范围查询:按分数范围查询
4. Redis常用命令
# 检查键是否存在
EXISTS key
EXISTS name
# 返回: 1(存在)或 0(不存在)
# 删除键
DEL key1 key2
DEL name age
# 设置过期时间(秒)
EXPIRE key seconds
EXPIRE session:123 3600
# 设置过期时间(时间戳)
EXPIREAT key timestamp
EXPIREAT key 1640995200
# 查看剩余过期时间
TTL key
TTL session:123
# 返回: 剩余秒数,-1表示永不过期,-2表示键不存在
# 移除过期时间
PERSIST key
PERSIST session:123
# 重命名键
RENAME key newkey
RENAME oldkey newkey
# 随机返回一个键
RANDOMKEY
# 获取键类型
TYPE key
TYPE name
# 返回: string, hash, list, set, zset等
# 查找匹配的键(生产环境慎用)
KEYS pattern
KEYS user:*
KEYS *session*
# 扫描键(推荐使用,不会阻塞)
SCAN cursor [MATCH pattern] [COUNT count]
SCAN 0 MATCH user:* COUNT 10# 选择数据库(0-15)
SELECT index
SELECT 1
# 清空当前数据库
FLUSHDB
# 清空所有数据库
FLUSHALL
# 查看数据库键数量
DBSIZE
# 查看服务器信息
INFO [section]
INFO server
INFO memory
INFO stats# 管道(Pipeline)批量执行
# 在客户端中,可以一次性发送多个命令
# 示例(使用redis-cli --pipe):
echo -e "SET key1 value1\nSET key2 value2\nGET key1" | redis-cli --pipe5. Redis持久化
RDB(Redis Database)是Redis的默认持久化方式,通过快照的方式保存数据。
RDB工作原理
- 在指定时间间隔内,将内存中的数据快照写入磁盘
- 生成一个压缩的二进制文件(dump.rdb)
- 恢复时直接加载RDB文件
配置RDB
# 保存条件
save 900 1 # 900秒内至少1个key变化
save 300 10 # 300秒内至少10个key变化
save 60 10000 # 60秒内至少10000个key变化
# RDB文件名
dbfilename dump.rdb
# 保存目录
dir /var/lib/redis
# 压缩
rdbcompression yes手动触发RDB
# 立即保存
SAVE
# 注意:会阻塞Redis,生产环境慎用
# 后台保存
BGSAVE
# 不阻塞Redis,在后台执行RDB优缺点
优点:
- 文件紧凑,恢复速度快
- 适合备份和灾难恢复
- 对性能影响小
缺点:
- 可能丢失最后一次快照后的数据
- 数据量大时,保存过程可能较长
5.2 AOF持久化
AOF(Append Only File)通过记录所有写操作来持久化数据。
配置AOF
# 开启AOF
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# 同步策略
# always: 每次写操作都同步(最安全,性能最低)
# everysec: 每秒同步一次(推荐)
# no: 由操作系统决定(最快,可能丢失数据)
appendfsync everysec
# AOF重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mbAOF重写
# 手动触发AOF重写
BGREWRITEAOFAOF优缺点
优点:
- 数据安全性高,最多丢失1秒数据
- 文件可读,便于分析
- 自动重写,文件不会过大
缺点:
- 文件体积较大
- 恢复速度比RDB慢
- 对性能有一定影响
同时开启RDB和AOF,结合两者优点:
# 开启AOF
appendonly yes
appendfsync everysec
# 开启混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes6. Redis事务
Redis事务通过MULTI、EXEC、DISCARD、WATCH命令实现。
# 开始事务
MULTI
# 执行命令(命令会进入队列)
SET key1 value1
SET key2 value2
GET key1
# 执行事务
EXEC
# 返回: 1) OK 2) OK 3) "value1"
# 取消事务
DISCARD- 原子性:事务中的所有命令要么全部执行,要么全部不执行
- 隔离性:事务执行过程中不会被其他客户端命令打断
- 一致性:事务执行前后数据保持一致
- 无回滚:Redis不支持回滚,执行失败的命令会被跳过
WATCH用于监控键,如果键被修改,事务将不会执行。
# 监控键
WATCH key1 key2
# 开始事务
MULTI
SET key1 newvalue
SET key2 newvalue2
# 如果在EXEC之前key1或key2被修改,事务将失败
EXEC
# 如果键被修改,返回: (nil)# 示例:转账操作
WATCH account:1 account:2
MULTI
DECRBY account:1 100
INCRBY account:2 100
EXEC7. Redis发布订阅
# 订阅频道
SUBSCRIBE channel1 channel2
SUBSCRIBE news
# 发布消息
PUBLISH channel message
PUBLISH news "Hello Redis"
# 取消订阅
UNSUBSCRIBE [channel]
# 订阅模式
PSUBSCRIBE pattern
PSUBSCRIBE news.*
# 取消模式订阅
PUNSUBSCRIBE [pattern]终端1(订阅者):
127.0.0.1:6379> SUBSCRIBE news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1终端2(发布者):
127.0.0.1:6379> PUBLISH news "Breaking news!"
(integer) 1终端1收到消息:
1) "message"
2) "news"
3) "Breaking news!"- 实时消息推送
- 系统通知
- 聊天室
- 事件通知
8. Redis主从复制
主从复制允许一个Redis服务器(主节点)的数据复制到一个或多个Redis服务器(从节点)。
主节点配置
主节点无需特殊配置,默认就是主节点。
从节点配置
方式1:配置文件
# 在从节点配置文件中添加
replicaof 192.168.1.100 6379
# 或使用旧版本命令
# slaveof 192.168.1.100 6379
# 如果主节点有密码
masterauth yourpassword方式2:命令行
# 在从节点执行
REPLICAOF 192.168.1.100 6379
# 或
SLAVEOF 192.168.1.100 6379
# 取消复制
REPLICAOF NO ONE# 查看主从信息
INFO replication
# 主节点输出示例:
# role:master
# connected_slaves:1
# slave0:ip=192.168.1.101,port=6379,state=online
# 从节点输出示例:
# role:slave
# master_host:192.168.1.100
# master_port:6379- 从节点连接主节点
- 主节点执行BGSAVE生成RDB文件
- 主节点将RDB文件发送给从节点
- 从节点加载RDB文件
- 主节点将后续写操作发送给从节点
9. Redis集群
Redis集群是Redis的分布式实现,通过分片(sharding)将数据分布到多个节点。
- 数据自动分片
- 高可用性
- 支持水平扩展
- 无中心化架构
创建集群节点
# 创建6个节点目录
mkdir -p /opt/redis-cluster/{7000,7001,7002,7003,7004,7005}
# 为每个节点创建配置文件
# 节点7000配置示例
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
appendonly yes启动所有节点
redis-server /opt/redis-cluster/7000/redis.conf
redis-server /opt/redis-cluster/7001/redis.conf
# ... 其他节点创建集群
# 使用redis-cli创建集群
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 19.4 集群操作
# 连接集群
redis-cli -c -p 7000
# 查看集群信息
CLUSTER INFO
# 查看集群节点
CLUSTER NODES
# 查看键所在的槽
CLUSTER KEYSLOT key
# 查看槽信息
CLUSTER SLOTS10. Java操作Redis
Maven项目
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>Gradle项目
implementation 'redis.clients:jedis:4.3.1'import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisExample {
public static void main(String[] args) {
// 创建连接池配置
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(100);
config.setMaxIdle(20);
config.setMinIdle(5);
// 创建连接池
JedisPool pool = new JedisPool(config, "localhost", 6379);
// 获取连接
try (Jedis jedis = pool.getResource()) {
// 字符串操作
jedis.set("name", "Redis");
String name = jedis.get("name");
System.out.println(name);
// 哈希操作
jedis.hset("user:1", "name", "Alice");
jedis.hset("user:1", "age", "25");
String userName = jedis.hget("user:1", "name");
System.out.println(userName);
// 列表操作
jedis.lpush("list", "a", "b", "c");
String item = jedis.rpop("list");
System.out.println(item);
// 集合操作
jedis.sadd("tags", "java", "redis");
boolean exists = jedis.sismember("tags", "java");
System.out.println(exists);
// 有序集合操作
jedis.zadd("leaderboard", 100, "Alice");
jedis.zadd("leaderboard", 200, "Bob");
Set<String> top = jedis.zrevrange("leaderboard", 0, 9);
System.out.println(top);
}
// 关闭连接池
pool.close();
}
}public class RedisPool {
private static JedisPool pool;
static {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(100);
config.setMaxIdle(20);
config.setMinIdle(5);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
pool = new JedisPool(config, "localhost", 6379, 2000, "password");
}
public static Jedis getJedis() {
return pool.getResource();
}
public static void close() {
pool.close();
}
}添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>配置文件
spring:
redis:
host: localhost
port: 6379
password:
database: 0
timeout: 2000
lettuce:
pool:
max-active: 100
max-idle: 20
min-idle: 5使用RedisTemplate
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void example() {
// 字符串操作
redisTemplate.opsForValue().set("name", "Redis");
String name = (String) redisTemplate.opsForValue().get("name");
// 哈希操作
redisTemplate.opsForHash().put("user:1", "name", "Alice");
Object userName = redisTemplate.opsForHash().get("user:1", "name");
// 列表操作
redisTemplate.opsForList().leftPush("list", "a");
Object item = redisTemplate.opsForList().rightPop("list");
// 集合操作
redisTemplate.opsForSet().add("tags", "java", "redis");
Boolean exists = redisTemplate.opsForSet().isMember("tags", "java");
// 有序集合操作
redisTemplate.opsForZSet().add("leaderboard", "Alice", 100);
Set<Object> top = redisTemplate.opsForZSet().reverseRange("leaderboard", 0, 9);
}11. Redis应用场景
// 缓存查询结果
public User getUserById(Long id) {
String key = "user:" + id;
String userJson = redisTemplate.opsForValue().get(key);
if (userJson != null) {
return JSON.parseObject(userJson, User.class);
}
User user = userMapper.selectById(id);
if (user != null) {
redisTemplate.opsForValue().set(key, JSON.toJSONString(user), 3600, TimeUnit.SECONDS);
}
return user;
}public boolean tryLock(String key, String value, long expireTime) {
Boolean result = redisTemplate.opsForValue()
.setIfAbsent(key, value, expireTime, TimeUnit.SECONDS);
return Boolean.TRUE.equals(result);
}
public void releaseLock(String key, String value) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) else return 0 end";
redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Collections.singletonList(key),
value
);
}// 文章阅读数
public void incrementViewCount(Long articleId) {
String key = "article:view:" + articleId;
redisTemplate.opsForValue().increment(key);
}
// 获取阅读数
public Long getViewCount(Long articleId) {
String key = "article:view:" + articleId;
String count = (String) redisTemplate.opsForValue().get(key);
return count != null ? Long.parseLong(count) : 0L;
}// 添加分数
public void addScore(String userId, double score) {
redisTemplate.opsForZSet().add("leaderboard", userId, score);
}
// 获取排行榜
public List<String> getTopUsers(int limit) {
Set<Object> users = redisTemplate.opsForZSet()
.reverseRange("leaderboard", 0, limit - 1);
return new ArrayList<>(users.stream()
.map(Object::toString)
.collect(Collectors.toList()));
}public boolean isAllowed(String key, int limit, int window) {
String script = "local current = redis.call('incr', KEYS[1]) " +
"if current == 1 then " +
"redis.call('expire', KEYS[1], ARGV[2]) end " +
"return current <= tonumber(ARGV[1])";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Collections.singletonList(key),
String.valueOf(limit),
String.valueOf(window)
);
return Boolean.TRUE.equals(result == 1);
}12. Redis性能优化
# 使用合适的数据类型
# 小数据用String,对象用Hash,列表用List等
# 设置过期时间
EXPIRE key seconds
# 使用压缩
# 对于大value,考虑压缩后再存储
# 内存淘汰策略
maxmemory-policy allkeys-lru# 使用批量操作
MGET key1 key2 key3
MSET key1 value1 key2 value2
# 使用Pipeline
# 在客户端中批量发送命令
# 避免使用KEYS命令
# 使用SCAN代替
SCAN 0 MATCH pattern COUNT 100// 使用连接池
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(100);
config.setMaxIdle(20);
config.setMinIdle(5);
config.setTestOnBorrow(true);- 合理选择数据类型
- 控制数据大小
- 使用压缩
- 避免大key
13. Redis最佳实践
# 使用冒号分隔层级
user:1:profile
article:123:views
session:abc123
# 使用有意义的名称
# 好的命名
user:1001:name
# 不好的命名
u1001n// 设置合理的过期时间
redisTemplate.opsForValue().set(key, value, 3600, TimeUnit.SECONDS);
// 热点数据可以设置较长过期时间
// 临时数据设置较短过期时间// 大key问题
// 1. 内存占用大
// 2. 操作耗时长
// 3. 网络传输慢
// 解决方案
// 1. 拆分大key
// 2. 使用压缩
// 3. 定期清理# 监控Redis
redis-cli INFO
redis-cli INFO memory
redis-cli INFO stats
# 慢查询日志
CONFIG SET slowlog-log-slower-than 10000
SLOWLOG GET 10# 设置密码
requirepass yourpassword
# 绑定IP
bind 127.0.0.1
# 禁用危险命令
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
# 使用非root用户运行14. 总结与进阶
通过本教程,你已经掌握了:
- ✅ Redis的基本概念和安装配置
- ✅ Redis的五种基本数据类型
- ✅ Redis的常用命令
- ✅ Redis持久化机制
- ✅ Redis事务和发布订阅
- ✅ Redis主从复制和集群
- ✅ Java操作Redis
- ✅ Redis应用场景和优化
Redis源码学习
- 数据结构实现
- 命令执行流程
- 持久化机制
高级特性
- Redis Stream(消息队列)
- Redis Modules(扩展模块)
- Redis Lua脚本
性能优化
- 内存优化
- 网络优化
- 集群优化
运维管理
- 监控告警
- 故障处理
- 容量规划
- 官方文档:https://redis.io/docs/
- 中文文档:http://redis.cn/
- GitHub:https://github.com/redis/redis
- Redis命令参考:https://redis.io/commands
- 实现一个缓存系统
- 实现分布式锁
- 实现排行榜功能
- 实现消息队列
- 搭建Redis集群
结语
Redis是一个功能强大、性能优异的缓存数据库。通过本教程的学习,相信你已经掌握了Redis的核心功能和使用方法。
记住:
- 多实践:理论结合实践,多写代码
- 理解原理:理解Redis的工作原理
- 关注性能:注意性能优化
- 持续学习:关注Redis新特性
祝你学习愉快,编程顺利! 🚀
本教程由Java突击队学习社区编写,如有问题欢迎反馈。