一、Redis的安装
1、解压压缩包
java
tar -zxvf redis-4.0.14.tar.gz
2、进入解压目录
bash
cd redis-5.0.4
make
3、安装到指定目录
bash
make PREFIX=/usr/local/src/zic/redis/server install
4、设置redis可远程访问(3.0默认允许,4.0需要手动设置) ,修改绑定地址为0.0.0.0
bash
cd /usr/local/src/zic/redis/software/redis-5.0.4
vim redis.conf

二、Redis启动
1、前台启动
直接运行bin/redis-server将以前端模式启动,前端模式启动的缺点是ssh命令窗口关闭则redis-server程序结束,不推荐使用此方法。

2、后台启动
修改redis.conf配置文件, daemonize yes 以后端模式启动。
执行以下命令启动redis

3、启动多个Redis实例
启动多个redis进程意义:
一个redis代表一个redis服务
方法1:
启动时指定端口可在一台服务器启动多个redis进程。
bash
./src/redis-server ./redis.conf --port 6380
方法2
创建多个redis目录,以端口号命名,比如:创建6379、6380两个目录
将redis-5.0.4目录中的文件拷贝到新的两个目录中
修改6379目录下的redis.conf设置端口号为6379
修改6380目录下的redis.conf设置端口号为6380

启动6379和6380目录下的redis-server程序:
在对应目录执行:
bash
./src/redis-server ./redis.conf

4、redis停止
强行终止Redis进程可能会导致redis持久化数据丢失。正确停止Redis的方式应该是向Redis服务发送SHUTDOWN命令,方法为:
save:在停止redis服务之前将所有的数据持久化保存
bash
./src/redis-cli shutdown save

三、redis客户端
学习意义:redis是服务端,要操作服务端(存取数据)是通过客户端。
在redis的安装目录中有redis的客户端,即redis-cli(Redis Command Line Interface),它是Redis自带的基于命令行的Redis客户端。
四、连接redis服务端
执行src/redis-cli连接redis服务端:
bash
./src/redis-cli

redis-cli连上redis服务后,可以在命令行发送命令。
发送ping
Redis提供了PING命令来测试客户端与Redis的连接是否正常,如果连接正常会收到回复PONG

set/get
使用set和get可以向redis设置数据、获取数据。

五、Redis多数据库
1、redis实例
一个redis进程就是一个redis实例,一台服务器可以同时有多个redis实例,不同的redis实例提供不同的服务端口对外提供服务,每个redis实例之间互相影响。每个redis实例都包括自己的数据库,数据库中可以存储自己的数据。
2、多数据库测试
一个Redis实例可以包括多个数据库,客户端可以指定连接某个redis实例的哪个数据库,就好比一个mysql中创建多个数据库,客户端连接时指定连接哪个数据库。
一个redis实例最多可提供16个数据库,下标从0到15,客户端默认连接第0号数据库,也可以通过select选择连接哪个数据库,如下连接1号库:

在1号库中查询上节设置的数据,结果查询不到:

重新选择第0号数据库,查询数据:

如果选择一个不存在数据库则会报错:

注意:redis不支持修改数据库的名称,只能通过select 0、select 1...选择数据库。
3、注意问题
在0号数据库存储数据,在1号数据库执行清空数据命令却把0号数据库的数据给清空了:

建议: 不同的应用系统要使用不同的redis实例而不是使用同一个redis实例下的不同数据库。
六、Redis数据类型
1、数据类型-String
1.1 介绍
redis中没有使用C语言的字符串表示,而是自定义一个数据结构叫SDS (simple dynamic string)即简单动态字符串。
打开下载的redis源码包,找到src下的sds.h文件查看sds源码

c语言对字符串的存储是使用字符数组,遇到'\0'字符则认为字符串结束,redis的字符串可以存储任何类型的数据,因为任何类型数据都可以表示成二进制,sds结构中的char buf[]就是存储了二进制数据。
redis的字符串是二进制安全的,什么是二进制安全?简单理解就是存入什么数据取出的还是什么数据。redis中的sds不像c语言处理字符串那样遇到'\0'字符则认证字符串结束,它不会对存储进去的二进制数据进行处理,存入什么数据取出还是什么数据。
1.2命令
1.2.1赋值与取值

1.2.2向尾部追加值

1.2.3获取字符串长度

1.2.4同时设置/获取多个键值
1.3应用
2、数据类型-hash
2.1需求
使用 redis存储用户信息,考虑使用string或其它方案。
{"birthday":1557743055507,"ename":"zhangsan","districtId":2,"sex":1,"id":1,"edate":1557743055507,"age":18,"sal":8000.0}
2.2使用string的问题
假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下:
保存、更新:
User对象 à json(string) à redis
如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题。
2.3redis hash介绍
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。如下:

2.4命令
2.4.1赋值与取值


2.4.2判断字段是否存在

当字段不存在时赋值,类似HSET,区别在于如果字段已经存在,该命令不执行任何操作。
2.4.3其它命令
删除字段,可以删除一个或多个字段,返回值是被删除的字段个数

只获取字段名或字段值

获取字段数量

2.5应用
3、数据类型-list
3.1redis list介绍
列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
3.2命令
3.2.1向列表两端增加元素
向列表左边增加元素
向列表右边增加元素

3.2.2从列表两端弹出元素
LPOP命令从列表左边弹出一个元素,会分两步完成,第一步是将列表左边的元素从列表中移除 ,第二步是返回被移除的元素值。

3.2.3获取列表中元素的个数

3.2.4获取列表片段
LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。
索引可以是负数,如:"-1"代表最后边的一个元素。

3.2.5其它命令
1、删除列表中指定的值
LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。
根据count值的不同,该命令的执行方式会有所不同:
当count>0时, LREM会从列表左边开始删除
当count<0时, LREM会从列表后边开始删除
当count=0时, LREM删除所有值为value的元素
2、获得/设置指定索引的元素值

3、只保留列表指定片段,指定范围和LRANGE一致

4、向列表中插入元素
LINSERT key BEFORE|AFTER pivot value
该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面

5、将元素从一个列表转移到另一个列表中

4、应用
4、数据类型-set
4.1redis set介绍
在集合中的每个元素都是不同的,且没有顺序。
集合类型和列表类型的对比:

集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型的Redis内部是使用值为空的散列表实现,所有这些操作的时间复杂度都为0(1)。
Redis还提供了多个集合之间的交集、并集、差集的运算。
4.2命令
4.2.1增加/删除元素

4.2.2获得集合中的所有元素


5、数据类型-sorted set
5.1redis sorted set介绍
在集合 类型的基础上有序集合 类型为集合中的每个元素都关联一个分数 ,这使得我们不仅可以完成插入 、删除 和判断元素是否存在在集合 中,还能够获得分数最高或最低的前N个元素 、获取指定分数范围内的元素等与分数有关的操作
在某些方面有序集合和列表类型有些相似。
1、二者都是有序的
2、二者都可以获得某一范围的元素
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。
5.2命令
5.2.1增加元素

5.2.2获得排名在某个范围的元素列表
获得排名在某个范围的元素列表
照元素分数从小到大的顺序返回索引从start到stop之间的所有元素

照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素)

如果需要获得元素的分数的可以在命令尾部加上WITHSCORES 参数

5.2.3获得指定分数范围的元素

命令:ZRANGEBYSCORE score 0 100 limit 1 3

5.2.4增加某个元素的分数,返回值是更改后的分数
给xx加xx分

获得集合中元素的数量

获得指定分数范围内的元素个数

5.3其他命令
5.3.1按照排名范围删除元素

按照分数范围删除元素

5.3.2获取元素的排名


5.4keys命令
5.4.1设置key的生存时间
Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。
EXPIRE key seconds 设置key的生存时间(单位:秒)key在多少秒后会自动删除
TTL key 查看key生于的生存时间
PERSIST key 清除生存时间
PEXPIRE key milliseconds 生存时间设置单位为:毫秒

5.5其它命令
1、keys
返回满足给定pattern 的所有key

2、exists
确认一个key 是否存在

3、del
删除一个key

4、rename
重命名key

5、type
返回值的类型

七、服务器命令
1、ping
测试连接是否存活
2、echo
在命令行打印一些内容
3、select
选择数据库。Redis 数据库编号从0~15,我们可以选择任意一个数据库来进行数据的存取。
4、quit
退出连接
5、dbsize
返回当前数据库中key 的数目

6、info
获取服务器的信息和统计

7、flushdb
删除当前选择数据库中的所有key。
8、flushall
删除所有数据库中的所有key
八、SpringBoot整合Redis
1、引入依赖
bash
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.42</version>
</dependency>
</dependencies>
之后进行配置文件的redis相关配置。
2、编写配置类进行redis序列化配置
java
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 1. 设置 Key 的序列化器 (使用 String,方便阅读)
template.setKeySerializer(new StringRedisSerializer());
// Hash 的 Key 也用 String
template.setHashKeySerializer(new StringRedisSerializer());
// 2. 设置 Value 的序列化器 (使用 JSON,方便存储对象)
GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
template.setValueSerializer(jsonSerializer);
template.setHashValueSerializer(jsonSerializer);
template.afterPropertiesSet();
return template;
}
}
3、编写实体类、controller
java
@NoArgsConstructor
@AllArgsConstructor
@Data
public class User implements Serializable {
private Long id;
private String name;
}
java
@RestController
@RequestMapping("/redis")
public class RedisController {
@Autowired
// 注意这里注入的是我们配置好的 <String, Object> 泛型
private RedisTemplate<String, Object> redisTemplate;
// 案例1:存入简单的字符串
@GetMapping("/String")
public String testString() {
// 存入数据,并设置 60秒 过期
redisTemplate.opsForValue().set("myKey", "Hello Redis", 60, TimeUnit.SECONDS);
return "String stored success";
}
// 案例2:存入对象 (验证 JSON 序列化)
@GetMapping("/Object")
public Object testObject() {
User user = new User(1L, "张三");
// Redis 中会存储为: {"@class":"...User", "id":1, "name":"张三"}
redisTemplate.opsForValue().set("user:1", user);
// 立刻取出来
return redisTemplate.opsForValue().get("user:1");
}
}
4、进行接口测试
启动项目,访问: localhost:8080/redis/Object

九、RedisTemplate相关API
1、通用操作

2、字符串操作

3、哈希操作

4、列表操作

5、集合操作

6、有序操作

十、Redis在SpringBoot中连接池的创建
在 Spring Boot 2.x 和 3.x 中,默认使用的 Redis 客户端是 Lettuce
Lettuce 的特点:基于 Netty(NIO)框架,它是线程安全的
依赖的关键:虽然 Lettuce 自己很强,但 Spring Boot 依然依赖一个通用对象池库来管理连接。这就是为什么我在上一个回答中让你必须引入 commons-pool2 的原因。
注意:如果你不引入 commons-pool2,Spring Boot 可能只会创建单连接或者无法正确配置连接池参数,导致高并发下性能崩盘。
Spring Boot 的启动流程如下:
-
读取配置 :启动时,读取 application.yml 中的 spring.data.redis 属性。
-
工厂类介入 :Spring Boot 内部有一个 LettuceConnectionConfiguration 类。
-
构建池配置 :它会把你的 YAML 参数封装成 GenericObjectPoolConfig 对象(这是 commons-pool2 提供的配置类)。
-
初始化工厂 :使用这个配置创建一个 LettuceConnectionFactory(连接工厂)。
-
注入 Template :最后,这个工厂被注入到 RedisTemplate 中。
-
使用时:当你调用 redisTemplate.opsForValue().get() 时,RedisTemplate 会向 LettuceConnectionFactory 要一个连接,工厂从池子里拿出一个给你。


