day29 Redis入门与Java客户端

day29 - Redis入门与Java客户端

一、Redis 简介

1.1 什么是 Redis

Redis(Remote Dictionary Server)是一个基于内存的键值型 NoSQL 数据库。数据以 key-value 形式存储,value 支持字符串、数值、JSON 等多种结构。

1.2 SQL 与 NoSQL 的对比

维度 SQL(关系型数据库) NoSQL(非关系型数据库)
数据结构 结构化(表、字段、约束严格) 非结构化,形式松散自由
关联关系 表之间存在关联(外键) 无关联关系,靠业务逻辑维护
查询方式 统一 SQL 语法 各数据库查询语法差异大
事务 满足 ACID 不保证严格 ACID,遵循 BASE
存储方式 基于磁盘,IO 较多 基于内存,读写速度快

ACID vs BASE:ACID 强调强一致性(原子性、一致性、隔离性、持久性);BASE 强调基本可用、软状态、最终一致性,用一致性换取高可用和高性能。


二、Redis 安装

Redis 官方不提供 Windows 安装包,企业一般基于 Linux 部署。以 CentOS 7 为例,安装包版本为 redis-6.2.6。

2.1 安装步骤

第 1 步:安装编译依赖

Redis 基于 C 语言编写,需要先安装 gcc 等编译工具:

1
yum install -y gcc tcl

第 2 步:上传并解压安装包

将 redis-6.2.6.tar.gz 上传到虚拟机(如 /usr/local/src),然后解压:

1
2
3
cd /usr/local/src
tar -xzf redis-6.2.6.tar.gz
cd redis-6.2.6

第 3 步:编译安装

1
make && make install

安装完成后,可执行文件默认在 /usr/local/bin 目录下(已配置到环境变量),主要命令:

命令 说明
redis-cli 命令行客户端
redis-server 服务端启动脚本
redis-sentinel 哨兵启动脚本

第 4 步:修改配置文件

先备份原配置文件,再修改 redis.conf:

1
2
cp redis.conf redis.conf.bck
vi redis.conf

redis.conf 中常用配置项:

配置项 说明
bind 0.0.0.0 允许任意 IP 访问(生产环境不要设为 0.0.0.0)
daemonize yes 后台运行
requirepass 123321 访问密码
port 6379 监听端口
databases 16 数据库数量,默认 16 个(编号 0~15)
maxmemory 512mb 最大内存限制
logfile "redis.log" 日志文件名

第 5 步:启动服务

指定配置文件启动(后台运行):

1
redis-server redis.conf

停止服务(需带密码):

1
redis-cli -u 123321 shutdown

第 6 步:设置开机自启

新建 systemd 服务文件:

1
vi /etc/systemd/system/redis.service

内容如下:

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
PrivateTmp=true

[Install]
WantedBy=multi-user.target

重载系统服务并设置开机自启:

1
2
3
4
5
6
systemctl daemon-reload      # 重载服务
systemctl start redis # 启动
systemctl stop redis # 停止
systemctl restart redis # 重启
systemctl status redis # 查看状态
systemctl enable redis # 开机自启

三、Redis 常见命令

Redis 是 key-value 数据库,key 一般为 String,value 支持多种数据结构。常见的 5 种数据结构:

类型 说明 典型命令
String 普通字符串,也可存整数/浮点 SET、GET、INCR、SETEX、SETNX
Hash 散列,类似 HashMap,可对单个字段操作 HSET、HGET、HGETALL
List 双向链表,有序可重复 LPUSH、RPUSH、LRANGE
Set 无序不可重复,支持交/并/差集 SADD、SMEMBERS、SINTER
SortedSet 可排序的 set,带 score ZADD、ZRANGE

通用命令适用于所有类型:KEYS、DEL、EXISTS、EXPIRE、TTL。

key 支持层级结构,用 : 分隔,如 heima:user:1,可视化工具会以目录形式展示。


四、Redis 的 Java 客户端

4.1 三种客户端对比

客户端 特点
Jedis 直连 Redis,API 与命令一一对应;线程不安全,多线程需为每个线程创建独立实例;推荐配合连接池使用
Lettuce 基于 Netty,线程安全,支持响应式编程
Spring Data Redis 对 Jedis 和 Lettuce 做了抽象封装,提供统一的 RedisTemplate API

4.2 Jedis 使用

基本步骤:引入依赖 → 创建 Jedis 对象建立连接 → 执行命令 → 释放资源。

1
2
3
4
5
6
7
8
9
10
11
// 建立连接
Jedis jedis = new Jedis("192.168.150.101", 6379);
jedis.auth("123321");
jedis.select(0);

// 使用
jedis.set("name", "虎哥");
String name = jedis.get("name");

// 释放资源
jedis.close();

Jedis 连接池:由于 Jedis 线程不安全,且频繁创建销毁连接有性能损耗,实际使用连接池:

1
2
3
4
5
6
7
8
9
10
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(8);
config.setMaxIdle(8);
config.setMinIdle(0);
config.setMaxWaitMillis(1000);

JedisPool pool = new JedisPool(config, "192.168.150.101", 6379, 1000, "123321");
Jedis jedis = pool.getResource();
// ... 使用后 close 会将连接归还连接池
jedis.close();

4.3 Spring Data Redis 使用

Spring Boot 提供了 spring-boot-starter-data-redis 自动装配,默认使用 Lettuce。

1. 引入依赖:

1
2
3
4
5
6
7
8
<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>

2. 配置文件(Spring Boot 3.x 新写法):

Spring Boot 3.x 把 Redis 配置从 spring.redis 迁移到了 spring.data.redis:

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
data:
redis:
host: 192.168.233.128
port: 6379
password: 123456
database: 0
lettuce:
pool:
max-idle: 8
min-idle: 0
max-wait: 1000
max-active: 8

3. 注入并使用 RedisTemplate:

1
2
3
4
5
@Autowired
private RedisTemplate<String, Object> redisTemplate;

redisTemplate.opsForValue().set("name", "虎哥");
Object name = redisTemplate.opsForValue().get("name");

五、RedisTemplate 的序列化器

5.1 为什么要配置序列化器

RedisTemplate 默认使用 JDK 序列化,写入 Redis 的数据可读性差且内存占用大。需要自定义序列化方式:key 用 String,value 用 JSON。

讲义中使用的 GenericJackson2JsonRedisSerializer 在新版 Spring Data Redis 中已废弃,应改用 RedisSerializer.json()。

5.2 新版序列化器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);

redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(RedisSerializer.json());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
redisTemplate.setHashValueSerializer(RedisSerializer.json());

redisTemplate.afterPropertiesSet();
return redisTemplate;
}

key 和 hashKey 用 RedisSerializer.string(),value 和 hashValue 用 RedisSerializer.json()。


六、手动序列化

6.1 为什么手动序列化

JSON 序列化器会在 value 中写入类的全限定名(用于反序列化时识别类型),带来额外内存开销。为了节省内存,可以使用 StringRedisTemplate + 手动 JSON 序列化,value 中只存纯 JSON 字符串。

6.2 StringRedisTemplate + ObjectMapper

StringRedisTemplate 是 RedisTemplate 的子类,key 和 value 默认都使用 String 序列化,省去了自定义序列化器的步骤。

1
2
3
4
5
6
7
8
9
10
11
12
@Autowired
private StringRedisTemplate stringRedisTemplate;

private static final ObjectMapper mapper = new ObjectMapper();

// 写入:手动序列化
String json = mapper.writeValueAsString(user);
stringRedisTemplate.opsForValue().set("user:200", json);

// 读取:手动反序列化
String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
User user = mapper.readValue(jsonUser, User.class);

今日总结

模块 核心要点
Redis 简介 基于内存的键值型 NoSQL 数据库;SQL 满足 ACID 存磁盘,NoSQL 遵循 BASE 存内存
安装 CentOS 7 下解压 → 编译安装 → 修改 redis.conf → 配置 systemd 自启
数据结构 String、Hash、List、Set、SortedSet 五种;key 用 : 做层级分隔
Java 客户端 Jedis 线程不安全需配合连接池;Lettuce 线程安全;Spring Data Redis 统一封装为 RedisTemplate
新版配置 Spring Boot 3.x 配置路径变为 spring.data.redis
序列化器 默认 JDK 序列化可读性差;自定义 key 用 string、value 用 json;新版用 RedisSerializer.json()
手动序列化 用 StringRedisTemplate + ObjectMapper 手动序列化,避免写入 class 信息,节省内存