目录
[1. NoSQL与关系型数据库对比](#1. NoSQL与关系型数据库对比)
[2. Redis核心特性](#2. Redis核心特性)
[3. 为什么使用Redis?](#3. 为什么使用Redis?)
[1. 问题描述](#1. 问题描述)
[2. 问题分析](#2. 问题分析)
[3. 解决方案](#3. 解决方案)
[1. Redis五种数据结构实战](#1. Redis五种数据结构实战)
[1.1 String(字符串类型)](#1.1 String(字符串类型))
[1.2 Hash(哈希类型)](#1.2 Hash(哈希类型))
[1.3 List(列表类型)](#1.3 List(列表类型))
[1.4 Set(集合类型)](#1.4 Set(集合类型))
[1.5 SortedSet(有序集合)](#1.5 SortedSet(有序集合))
[2. Redis通用命令](#2. Redis通用命令)
[3. Redis桌面客户端使用](#3. Redis桌面客户端使用)
[4. StringRedisTemplate实战](#4. StringRedisTemplate实战)
[4.1 SpringBoot项目集成](#4.1 SpringBoot项目集成)
[4.2 基本使用示例](#4.2 基本使用示例)
[4.3 对象存储的最佳实践](#4.3 对象存储的最佳实践)
[4.4 事务操作](#4.4 事务操作)
[1. Redis键的命名规范](#1. Redis键的命名规范)
[2. 数据库选择](#2. 数据库选择)
[3. 数据类型选择策略](#3. 数据类型选择策略)
[4. 命令使用技巧](#4. 命令使用技巧)
[5. StringRedisTemplate优势](#5. StringRedisTemplate优势)
[6. 常用操作接口](#6. 常用操作接口)
前言
时隔一周,今天我开始学习企业级项目中必不可少的缓存中间件------Redis。在前几天完成了苍穹外卖项目后,我深刻体会到数据访问性能的重要性,而Redis作为高性能的内存数据库,正是解决高并发访问、数据缓存等问题的利器。
今天主要学习Redis的基础概念、安装部署以及基本数据结构操作,为后续在实际项目中应用Redis打下坚实基础。

一、今日完结任务
-
✅ 学习NoSQL数据库概念及其与关系型数据库的区别
-
✅ 了解Redis的特点和应用场景
-
✅ 掌握Windows环境下Redis的安装与配置
-
✅ 学习Redis的5种基本数据结构及其常用命令
-
✅ 使用Redis可视化客户端进行基本操作
二、今日核心知识点总结
1. NoSQL与关系型数据库对比
NoSQL特点:
-
非结构化:数据格式灵活,没有严格的表结构约束
-
无关联性:数据间没有外键关联,关系维护依赖业务逻辑
-
高性能 :基于内存操作,读写速度快,适合高并发场景
-
可扩展性强:支持水平扩展,适合海量数据存储

核心对比:
| 对比维度 | 关系型数据库 | NoSQL数据库 |
|---|---|---|
| 数据结构 | 结构化,表格式 | 非结构化,灵活 |
| 数据关联 | 表间关联(外键) | 无关联或业务维护 |
| 查询语言 | SQL(标准统一) | 各数据库不同 |
| 事务支持 | ACID原则 | 基本一致或不支持 |
| 存储方式 | 磁盘存储,有IO | 内存为主,速度快 |
| 扩展方式 | 垂直扩展(主从) | 水平扩展(分片) |
2. Redis核心特性

-
内存存储:数据主要存储在内存中,读写性能极高
-
单线程模型:命令执行具备原子性,避免线程安全问题
-
丰富的数据结构:支持String、Hash、List、Set、SortedSet等

-
持久化支持:可将内存数据保存到磁盘,防止数据丢失
-
高可用性:支持主从复制、哨兵模式、集群部署
-
多语言客户端:Java、Python、Go等主流语言都支持
3. 为什么使用Redis?
主要是因为 Redis 具备**「高性能」和「高并发」**两种特性。
1. Redis 具备高性能
假如用户第一次访问 MySQL 中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据缓存在 Redis 中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了,操作 Redis 缓存就是直接操作内存,所以速度相当快。
2. Redis 具备高并发
单台设备的 Redis 的 QPS(Query Per Second,每秒钟处理完请求的次数) 是 MySQL 的 10 倍,Redis 单机的QPS 能轻松破 10w,而 MySQL 单机的 QPS 很难破 1w。
所以,直接访问 Redis 能够承受的请求是远远大于直接访问 MySQL 的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。
三、遇到的问题:连接Redis服务失败
1. 问题描述
在Windows中安装Redis后,使用Redis客户端连接时出现以下错误:
Could not connect to Redis at 127.0.0.1:6379: Connection refused
2. 问题分析
-
Redis服务未启动
-
防火墙阻止了6379端口
-
Redis配置绑定了特定IP地址(默认只允许本地访问)
3. 解决方案
步骤1:保证Redis在后台运行
步骤2:修改Redis配置文件
编辑redis.conf文件,关键配置修改:
bash
# 允许所有IP访问(生产环境需谨慎)
bind 0.0.0.0
# 以守护进程方式运行
daemonize yes
# 设置密码(可选)
requirepass 123456
步骤3:重启Redis服务
在Redis安装目录下启动cmd输入
# 指定配置文件启动
redis-server.exe redis.windows.conf
步骤4:测试连接
# 使用密码连接
redis-cli -h 127.0.0.1 -p 6379 -a 123456
# 测试连接
ping # 应返回PONG
四、今日实战收获
1. Redis五种数据结构实战
1.1 String(字符串类型)
String类型,也就是字符串类型,是Redis中最简单的存储类型。
适用场景:缓存、计数器、分布式锁
bash
# 设置值
SET name "张三"
# 获取值
GET name
# 设置过期时间(10秒)
SETEX token 10 "abc123"
# 数值递增
INCR views # 自增1
INCRBY views 5 # 自增5
1.2 Hash(哈希类型)
Hash类型,也叫散列,其value是一个无序字典,类似于Java中的HashMap结构。
适用场景:存储对象信息,如用户信息、商品详情
bash
# 设置单个字段
HSET user:1001 name "李四"
HSET user:1001 age 25
# 批量设置字段
HMSET user:1002 name "王五" age 30 city "北京"
# 获取所有字段
HGETALL user:1001
# 获取指定字段
HGET user:1001 name
# 字段递增
HINCRBY user:1001 age 1
1.3 List(列表类型)
Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。
适用场景:消息队列、最新列表、历史记录
bash
# 左侧插入
LPUSH messages "msg1" "msg2"
# 右侧插入
RPUSH messages "msg3"
# 左侧弹出
LPOP messages
# 右侧弹出
RPOP messages
# 获取范围元素
LRANGE messages 0 2
1.4 Set(集合类型)
Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的**HashMap。**因为也是一个hash表,因此具备与HashSet类似的特征:

适用场景:标签、共同好友、随机推荐
bash
# 添加元素
SADD tags "Java" "Redis" "MySQL"
# 查看所有元素
SMEMBERS tags
# 删除元素
SREM tags "MySQL"
# 集合运算
SADD set1 "A" "B" "C"
SADD set2 "B" "C" "D"
# 交集
SINTER set1 set2 # 返回: B C
# 并集
SUNION set1 set2 # 返回: A B C D
# 差集
SDIFF set1 set2 # 返回: A
1.5 SortedSet(有序集合)
Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。
适用场景:排行榜、带权重的队列
bash
# 添加带分值的元素
ZADD leaderboard 100 "张三" 95 "李四" 85 "王五"
# 按分值升序获取(0到2名)
ZRANGE leaderboard 0 2
# 按分值降序获取(0到2名)
ZREVRANGE leaderboard 0 2
# 获取元素排名(从0开始)
ZRANK leaderboard "李四"
# 获取元素分值
ZSCORE leaderboard "张三"
2. Redis通用命令
bash
# 查看所有key(生产环境慎用)
KEYS *
# 查看以user开头的key
KEYS user:*
# 判断key是否存在
EXISTS user:1001
# 设置key过期时间(秒)
EXPIRE token 3600
# 查看key剩余生存时间
TTL token
# 删除key
DEL user:1001
# 选择数据库(0-15)
SELECT 1
3. Redis桌面客户端使用
安装了Another Redis Desktop Manager,通过图形界面:
-
直观查看所有key和value
-
支持多种数据结构可视化展示
-
可直接编辑、删除数据
-
支持批量操作和导入导出
4. StringRedisTemplate实战
4.1 SpringBoot项目集成
Maven依赖:
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
配置文件application.yml:
XML
spring:
redis:
host: localhost
port: 6379
password: 123456
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 100ms
4.2 基本使用示例
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class RedisService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
// 1. String类型操作
public void stringOperations() {
// 设置值
stringRedisTemplate.opsForValue().set("username", "张三");
// 获取值
String username = stringRedisTemplate.opsForValue().get("username");
// 设置过期时间
stringRedisTemplate.opsForValue().set("token", "abc123", 3600, TimeUnit.SECONDS);
// 递增操作
stringRedisTemplate.opsForValue().increment("pageView");
stringRedisTemplate.opsForValue().increment("pageView", 5);
}
// 2. Hash类型操作
public void hashOperations() {
// 设置hash字段
stringRedisTemplate.opsForHash().put("user:1001", "name", "李四");
stringRedisTemplate.opsForHash().put("user:1001", "age", "25");
// 获取hash字段
String name = (String) stringRedisTemplate.opsForHash().get("user:1001", "name");
// 获取所有字段
Map<Object, Object> user = stringRedisTemplate.opsForHash().entries("user:1001");
}
// 3. List类型操作
public void listOperations() {
// 左侧插入
stringRedisTemplate.opsForList().leftPush("messages", "Hello");
stringRedisTemplate.opsForList().leftPush("messages", "World");
// 获取范围元素
List<String> messages = stringRedisTemplate.opsForList().range("messages", 0, -1);
}
// 4. Set类型操作
public void setOperations() {
// 添加元素
stringRedisTemplate.opsForSet().add("tags", "Java", "Redis", "MySQL");
// 获取所有元素
Set<String> tags = stringRedisTemplate.opsForSet().members("tags");
}
}
4.3 对象存储的最佳实践
使用JSON序列化存储对象:
java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@Service
public class UserService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final ObjectMapper objectMapper = new ObjectMapper();
// 存储对象(手动序列化为JSON)
public void saveUser(User user) throws JsonProcessingException {
String userJson = objectMapper.writeValueAsString(user);
String key = "user:" + user.getId();
stringRedisTemplate.opsForValue().set(key, userJson);
// 可以设置过期时间
stringRedisTemplate.expire(key, 1, TimeUnit.HOURS);
}
// 获取对象(手动反序列化)
public User getUser(Long userId) throws JsonProcessingException {
String key = "user:" + userId;
String userJson = stringRedisTemplate.opsForValue().get(key);
if (userJson != null) {
return objectMapper.readValue(userJson, User.class);
}
return null;
}
// 存储对象到Hash
public void saveUserToHash(User user) {
String key = "user:hash:" + user.getId();
Map<String, String> userMap = new HashMap<>();
userMap.put("id", user.getId().toString());
userMap.put("name", user.getName());
userMap.put("age", user.getAge().toString());
userMap.put("email", user.getEmail());
stringRedisTemplate.opsForHash().putAll(key, userMap);
}
}
4.4 事务操作
java
public void transactionalOperations() {
// 使用SessionCallback执行事务
stringRedisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.multi(); // 开启事务
operations.opsForValue().set("key1", "value1");
operations.opsForValue().set("key2", "value2");
operations.opsForValue().increment("counter");
return operations.exec(); // 执行事务
}
});
}
五、小知识点总结
1. Redis键的命名规范
bash
# 使用冒号分隔形成层级结构
# 项目名:数据类型:ID
user:1001:info
product:2001:detail
order:3001:items
2. 数据库选择
-
Redis默认有16个数据库(0-15)
-
不同数据库完全隔离,key可以重复
-
生产环境建议使用默认的0号库
3. 数据类型选择策略
-
String:简单KV,如缓存、计数器
-
Hash :对象类型,如用户信息
-
List :有序可重复,如消息队列
-
Set :无序不重复,如标签系统
-
SortedSet :有序不重复,如排行榜
4. 命令使用技巧
-
批量操作:使用MSET、HMSET、SADD等批量命令,减少网络开销
-
管道技术:一次性发送多个命令,提升执行效率
-
原子操作 :INCR、DECR等命令是原子性的,适合计数器场景
5. StringRedisTemplate优势
-
避免序列化问题:不存储类信息,不会因类路径变化导致反序列化失败
-
跨语言兼容:存储的是JSON字符串,其他语言也可以读取
-
便于调试:Redis中可以直接查看存储的内容
-
节省内存:不存储额外的类信息,内存占用更小
6. 常用操作接口

总结
今天系统地学习了Redis的基础知识,从NoSQL概念到Redis具体安装配置,再到5种核心数据结构的操作命令。通过实践操作,我深刻体会到Redis作为内存数据库(缓存)的独特优势:
-
性能卓越:内存操作带来的毫秒级响应,完全满足高并发场景需求
-
数据结构丰富:不仅仅是简单的KV存储,多种数据结构能灵活应对不同业务场景
-
操作原子性:单线程模型保证了命令执行的原子性,简化了并发控制
-
部署灵活:支持多种集群模式,能满足不同规模的业务需求


