安装Redis依赖
(1)Redis是基于C语言编写的,因此首先需要安装Redis所需要的gcc依赖
yum install -y gcc tcl
上传Redis安装包并解压、安装
(1)将redis-6.2.6.tar.gz包,上传到/usr/local/src目录下
(2)解压redis-6.2.6.tar.gz,进入解压后目录,运行编译命令,如果没有报错则安装成功
tar -zxvf redis-6.2.6.tar.gz
cd redis-6.2.6
make && make install
(3)默认的安装路径:/usr/local/bin目录下
(4)该目录已经默认配置到环境变量中,可以在任意目录下运行这些命令
1)redis-cli:Redis提供的命令行客户端
2)redis-server:Redis的服务端启动脚本
3)redis-sentinel:Redis的哨兵启动脚本
启动Redis
(1)默认启动
1)安装完成后,在任意目录输入redis-server命令即可启动Redis
2)这种启动属于前台启动,会阻塞整个会话窗口,窗口关闭或者按下CTRL + C,则Redis停止【不推荐使用】
redis-server
(2)指定配置启动
1)修改Redis配置文件redis.conf(路径:/usr/local/src/redis-6.2.6)
2)备份redis.conf
cp redis.conf redis.conf.bak
3)修改redis.conf文件中的一些配置
# 监听的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes
# 密码,设置后访问Redis必须输入密码
requirepass 123321
4)Redis的其它常见配置
# 监听的端口
port 6379
# 工作目录,默认是当前目录(哪里启动,哪里就是工作目录),也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"
5)启动Redis
# 进入redis安装目录
cd /usr/local/src/redis-6.2.6
# 启动
redis-server redis.conf
6)停止服务
# 利用redis-cli来执行shutdown命令,即可停止Redis服务,因为之前配置了密码,因此需要通过-a来指定密码
redis-cli -a 123321 shutdown
(3)开机自启
1)新建一个系统服务文件
vim /etc/systemd/system/redis.service
2)输入以下内容
[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
3)重载系统服务
systemctl daemon-reload
4)可以用下面这组命令来操作redis
# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis
5)让redis开机自启
systemctl enable redis
Jedis官网:https://github.com/redis/jedis
maven依赖
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
<version>3.7.0version>
dependency>
Jedis基础操作
package com.swaggyhang;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.Map;
/**
* Jedis基础操作
*/
public class JedisTest {
private Jedis jedis;
@Before
public void setUp() {
// 1.建立连接
jedis = new Jedis("192.168.6.128", 6379);
// 2.设置密码
jedis.auth("123321");
// 3.选择库
jedis.select(0);
}
@Test
public void testString() {
// 存入数据
String result = jedis.set("name", "虎哥");
System.out.println("result = " + result);
// 获取数据
String name = jedis.get("name");
System.out.println("name = " + name);
}
@Test
public void testHash() {
// 存入数据
jedis.hset("user:1", "name", "jack");
jedis.hset("user:1", "age", "21");
// 获取数据
Map<String, String> map = jedis.hgetAll("user:1");
System.out.println(map);
}
@After
public void tearDown() {
if (jedis != null) {
// 关闭连接
jedis.close();
}
}
}
Jedis连接池
(1)Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,推荐使用Jedis连接池代替Jedis的直连方式
package com.swaggyhang.jedis.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* Jedis连接池工具类
*
* @author swaggyhang
* @create 2023-07-12 20:52
*/
public class JedisConnectionFactory {
private static final JedisPool JEDIS_POOL;
static {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(8);
poolConfig.setMaxIdle(8);
poolConfig.setMaxWaitMillis(1000);
// 创建连接池对象
JEDIS_POOL = new JedisPool(poolConfig, "192.168.6.128", 6379, 1000, "123321");
}
public static Jedis getJedis() {
return JEDIS_POOL.getResource();
}
}
SpringData:是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就是SpringDataRedis
SpringDataRedis官网:https://spring.io/projects/spring-data-redis
特征
(1)提供了对不同Redis客户端的整合(Lettuce和Jedis)
(2)提供了RedisTemplate统一API来操作Redis
(3)支持Redis的发布/订阅模型
(4)支持Redis哨兵和Redis集群
(5)支持基于Lettuce的响应式编程
(6)支持基于JDK(默认)、JSON、字符串、Spring对象的数据序列化和反序列化
(7)支持基于Redis的JDKCollection实现
常见API
(1)SpringDataRedis中通过提供了RedisTemplate工具类,其中封装了各种对Redis的操作,并且将不同数据类型的操作API封装到不同的类型中
maven依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
application.yaml配置
spring:
redis:
host: 192.168.6.128
port: 6379
password: 123321
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 1000ms
基础操作:SpringBoot已经提供了对SpringDataRedis的支持,使用非常简单
package com.swaggyhang;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
@SpringBootTest
class RedisDemoApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testString() {
// 写入数据
redisTemplate.opsForValue().set("name", "虎哥");
// 读取数据
Object value = redisTemplate.opsForValue().get("name");
System.out.println("value = " + value);
}
}
RedisTemplate可以接收任意Object作为值写入Redis,在写入Redis之前会把Object序列化为字节形式,默认采用JDK序列化
采用JDK序列化的缺点
(1)可读性差
(2)内存占用较大
创建Redis配置类,指定RedisTemplate的key和value的序列化方式
package com.swaggyhang.redis.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
/**
* @author swaggyhang
* @create 2023-07-12 21:32
*/
@Configuration
public class RedisConfig {
/**
* RedisConnectionFactory无需手动创建,由SpringBoot自动创建
*
* @param connectionFactory redis连接工厂类
* @return RedisTemplate
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
// 创建RedisTemplate对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置连接工厂
template.setConnectionFactory(connectionFactory);
// 设置key的序列化:StringRedisSerializer
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// 设置value的序列化:GenericJackson2JsonRedisSerializer
template.setValueSerializer(RedisSerializer.json());
template.setHashValueSerializer(RedisSerializer.json());
return template;
}
}
测试类
package com.swaggyhang;
import com.swaggyhang.redis.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
@SpringBootTest
class RedisDemoApplicationTests {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testString() {
// 写入数据
redisTemplate.opsForValue().set("name", "虎哥");
// 读取数据
Object value = redisTemplate.opsForValue().get("name");
System.out.println("value = " + value);
}
@Test
public void testSaveUser(){
redisTemplate.opsForValue().set("user:100", new User("虎哥", "21"));
User user = (User) redisTemplate.opsForValue().get("user:100");
System.out.println("user = " + user);
}
}
尽管JSON的序列化方式可以满足需求,但依然存在一些问题,为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入Redis的value中,带来额外的内存开销
为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化
Spring默认提供了一个StringRedisTemplate类,其key和value的序列化方式默认就是String方式,因此,我们无需自定义StringRedisTemplate
package com.swaggyhang;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.swaggyhang.redis.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
@SpringBootTest
class RedisDemoApplicationTests {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test
public void testString() {
// 写入数据
stringRedisTemplate.opsForValue().set("name", "虎哥");
// 读取数据
Object value = stringRedisTemplate.opsForValue().get("name");
System.out.println("value = " + value);
}
@Test
public void testSaveUser() throws JsonProcessingException {
User user = new User("虎哥", "21");
String json = OBJECT_MAPPER.writeValueAsString(user);
stringRedisTemplate.opsForValue().set("user:100", json);
String jsonUSer = stringRedisTemplate.opsForValue().get("user:100");
User user1 = OBJECT_MAPPER.readValue(jsonUSer, User.class);
System.out.println("user1 = " + user1);
}
}
操作Hash类型
@Test
public void testHash() {
stringRedisTemplate.opsForHash().put("user:200", "name", "虎哥");
stringRedisTemplate.opsForHash().put("user:200", "age", "21");
// 获取所有
Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:200");
System.out.println("entries = " + entries);
}