# 初识 Redis
# 认识 Redis
Redis 诞生于 2009 年全称是 Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型 NoSQL 数据库
特征:
- 键值(key-value)型,value 支持多种不同数据结构,功能丰富
- 单线程,每个命令具备原子性
- 低延迟,速度快(基于内存、IO 多路复用、良好的编码)
- 支持数据持久化
- 支持主从集群、分片集群
- 支持多语言客户端
# 安装 Redis
# 单机安装 Redis
# 安装 Redis 依赖
Redis 是基于 C 语言编写的,因此首先需要安装 Redis 所需要的 gcc 依赖
# 上传安装包并解压
| tar -zxvf redis-6.2.6.tar.gz |
| cd redis-6.2.6 |
| make && make install |
默认安装在 /usr/local/bin
目录下:
- redis-cli:是 redis 提供的命令行客户端
- redis-server:是 redis 的服务端启动脚本
- redis-sentinel:是 redis 的哨兵启动脚本
# 开机自动启动
# 默认启动
安装完成后,在任意目录输入 redis-server 命令即可启动 Redis,这种启动属于 前台启动
,会阻塞整个会话窗口,窗口关闭或者按下 CTRL + C
则 Redis 停止
# 指定配置启动
以后台方式启动,需要修改 Redis 配置文件,目录 /usr/local/src/redis-6.2.6
,名字叫 redis.conf
| cp redis.conf redis.conf.bck |
| |
| bind 0.0.0.0 |
| |
| daemonize yes |
| |
| requirepass root |
| |
| port 6379 |
| |
| dir . |
| |
| databases 1 |
| |
| maxmemory 512mb |
| |
| logfile "redis.log" |
启动与停止 Redis
| |
| cd /usr/local/src/redis-6.2.6 |
| |
| redis-server redis.conf |
| |
| |
| redis-cli -u root shutdown |
# 开机自启
建立一个系统服务文件
| vi /etc/systemd/system/redis.service |
| |
| [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 |
操作 redis
| |
| systemctl start redis |
| |
| systemctl stop redis |
| |
| systemctl restart redis |
| |
| systemctl status redis |
执行命令可以让 redis 开机自动启动
# Redis 客户端
# Redis 命令行客户端
| redis-cli [options] [commonds] |
常见 options
-h 127.0.0.1
:指定要链接 redis 节点的 IP
-p 6379
:指定要连接的 redis 节点端口,默认 6379
-a root
:指定 redis 的访问密码
commonds 是 Redis 操作命令
ping
:与 redis 服务端做心跳测试,服务端正常会返回 pong
# 图形化桌面客户端 Redis Desktop Manager
# Redis 命令
# Redis 数据结构介绍
Redis 是一个 key-value 的数据库,key 一般是 String 类型,不过 value 的类型多种多样
类型 |
范例 |
String |
hello world |
Hash |
|
List |
[A -> B -> C -> D] |
Set |
|
SorttedSet |
|
GEO |
|
BitMap |
0110110101110101011 |
HtperLog |
0110110101010100101 |
# Redis 通用命令
命令名 |
命令作用 |
KEYS |
查看符合模板结构的所有 key,不建议在生产环境设备上使用 |
DEL |
删除一个指定的 key |
EXISIT |
判断 key 是否存在 |
EXPIRE |
给一个 key 设置有效期,有效期到期时 key 会被自动删除 |
TTL |
查看一个 key 的剩余有效期 |
# String 类型
# 介绍
String 类型,也就是字符串类型,是 Redis 中最简单的存储类型
- string:普通字符串
- int:整数类型,可以做自增、自减操作
- float:浮点类型,可以做自增、自减操作
# 用法
方法名 |
说明 |
示例 |
SET |
添加或者修改一个已经存在的 String 类型键值对 |
set name baozi |
GET |
根据 key 获取 String 类型的 value |
get name |
MSET |
批量添加多个 String 类型键值对 |
mset name baozi age 18 |
MGET |
根据多个 key 获取多个 String 类型 value |
mget name age |
INCR |
让一个整型的 key 自增 1 |
incr age |
INCRBY |
让一个整型的 key 自增并指定步长 |
incrby age 2 |
INCRBYFLOAT |
让一个浮点类型数自增并指定步长 |
incrbyfloat num 3.14 |
SETNX |
添加一个 String 类型键值对,前提是这个 key 不存在,否则不执行 |
setnx name baozi |
SETEX |
添加一个 String 类型键值对,并且指定有效期 |
setex name 10 baozi |
# key 的结构
Redis 的 key 允许有多个单词形成层级结构,多个单词之间用 ':' 隔开
- user 相关的 key:
baozi:user:1
baozi:user:2
# Hash 类型
# 介绍
Hash 类型,也叫散列,其 value 是一个无序字典,类似于 Java 中的 HashMap 结构
# 用法
命令名 |
说明 |
示例 |
HSET |
添加或者修改 hash 类型 key 的 field 值 |
hset user01 name baozi |
HGET |
获取一个 hash 类型的 key 的 field 的值 |
hget user01 name |
HMSET |
批量添加多个 hash 类型 key 的 field |
hmset user01 name baozi age 18 sex men |
HMGET |
批量获取多个 hash 类型 key 中的所有 field 的值 |
hmget user01 name age sex |
HGETALL |
获取一个 hash 类型的 key 中所有的 field 和 value |
hgetall user01 |
HKEYS |
获取一个 hash 类型的 key 中所有的 field |
hkeys user01 |
HVALS |
获取一个 hash 类型的 key 中所有的 value |
hvals user01 |
HINCRBY |
让一个 hash 类型 key 字段值自增并指定步长 |
hincrby user01 age 2 |
HSETNX |
添加一个 hash 类型 key 的 field 值,前提是这个 field 不存在 |
hsetnx user01 name baozi |
# List 类型
# 介绍
Redis 中的 List 类型与 Java 中的 LinkedList 类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
# 用法
命令名 |
说明 |
示例 |
LPUSH |
向列表左侧插入一个或多个元素 |
lpush list01 1 2 3 |
LPOP |
移除并返回列表左侧的第一个元素 |
lpop list01 |
RPUSH |
向列表右边插入一个或多个元素 |
rpush list01 4 5 |
RPOP |
移除并返回列表右侧的第一个元素 |
rpop list01 |
LRANGE |
返回一段角标范围内的所有元素 |
lrange list01 1 3 |
BLPOP 和 BRPOP |
与 LPOP 和 RPOP 类似,只不过在没有元素时等待指定时间 |
blpop list01 100 |
# Set 类型
# 介绍
Redis 的 Set 结构与 Java 中的 HashSet 类似,可以看做是一个 value 为 null 的 HashMap
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
# 用法
命令名 |
说明 |
示例 |
SADD |
向 set 中添加一个或多个元素 |
sadd set01 a b c |
SREM |
移除 set 中指定元素 |
srem set01 a |
SCARD |
返回 set 中元素个数 |
scard set01 |
SISMEMBER |
判断一个元素是否存在于 set 中 |
sismember set01 a |
SMEMBERS |
获取 set 中的所有元素 |
smembers set01 |
SINTER |
求 key1 和 key2 的交集 |
sinter set01 set02 |
SDIFF |
求 key1 和 key2 的差集 |
sdiff set01 set02 |
SUNION |
求 key1 和 key2 的并集 |
sunion set01 set02 |
# SortedSet 类型
# 介绍
Redis 的 SortedSet 是一个可排序的 set 集合,与 Java 中的 TreeSet 有些类似,但底层数据结构却差别很大。SortedSet 中的每一个元素都带有一个 score 属性,可以基于 score 属性对元素排序,底层的实现是一个跳表(SkipList)加 hash 表
- 可排序
- 元素不重复
- 查询速度快
# 用法
命令名 |
说明 |
示例 |
ZADD |
添加一个或多个元素到 sorted set,如果已经存在则更新其 score 值 |
zadd sortset01 99 tom 98 jery |
ZREM |
删除 sorted set 中一个指定元素 |
zrem sortset01 tom |
ZSCORE |
获取 sorted set 中指定元素的 score |
zscore sortset01 99 |
ZRANK |
获取 sorted set 中指定元素的排名 |
zrank sortset01 tom |
ZCARD |
获取 sorted set 中元素个数 |
zcard sortset01 |
ZCOUNT |
统计 score 值在指定范围内所有元素数量 |
zcount sortset01 90 100 |
ZINCRBY |
让 sorted set 中的指定元素自增 |
aincrby sortset01 10 tom |
ZRANGE |
按照 score 排序后,获取指定排名范围内的元素(参数索引) |
zrange sortset01 0 3 |
ZRANGEBYSCORE |
按照 score 排序后,获取指定 score 范围内的元素 |
zrangebyscore sortset01 80 100 |
ZDIFF ZINTER ZUNION |
求差集、交集、并集 |
zdiff sortset01 sortedset02 |
# Redis 的 Java 客户端
# Jedis
# 引入依赖
| <dependency> |
| <groupId>redis.clients</groupId> |
| <artifactId>jedis</artifactId> |
| <version>3.8.0</version> |
| </dependency> |
# 建立连接
| @BeforeEach |
| void setUp() { |
| jedis = new Jedis("192.168.116.129",6379); |
| jedis.auth("root"); |
| jedis.select(0); |
| } |
# 测试 string
| @Test |
| void TestString() { |
| String result = jedis.set("name","baozi"); |
| System.out.println(result); |
| String name = jedis.get("name"); |
| System.out.println(name); |
| } |
# 释放连接
| @AfterEach |
| void tearDown() { |
| if(jedis != null) { |
| jedis.close(); |
| } |
| } |
# Jedis 连接池
| public class JedisConnectionFactory { |
| private static final JedisPool jedispool; |
| static { |
| JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); |
| jedisPoolConfig.setMaxTotal(8); |
| jedisPoolConfig.setMaxIdle(8); |
| jedisPoolConfig.setMinIdle(0); |
| jedisPoolConfig.setMaxWait(Duration.ofMillis(1000)); |
| jedispool = new JedisPool(jedisPoolConfig,"192.168.116.129",6379,1000,"root"); |
| } |
| public static Jedis getJedis() { |
| return jedispool.getResource(); |
| } |
| } |
# SpringDataRedis
# 介绍
SpringData 是 Spring 中数据操作的模块,包含对各种数据库的集成,其中对 Redis 的集成模块就叫做 SpringDataRedis
# 快速入门
SpringDataRedis 中提供了 RedisTemplate 工具类,其中封装了各种对 Redis 的操作。并且将不同数据类型的操作 API 封装到了不同的类型中
API |
返回值类型 |
说明 |
redisTemplate.opsForValue() |
ValueOperations |
操作 String 类型数据 |
redisTemplate.opsForHash() |
HashOperations |
操作 Hash 类型数据 |
redisTemplate.opsForList() |
ListOperations |
操作 List 类型数据 |
redisTemplate.opsForSet() |
SetOperations |
操作 Set 类型数据 |
redisTemplate.opsForZSet() |
ZSetOperation |
操作 SortedSet 类型数据 |
redisTemplate |
|
通用命令 |
# SpringBoot 整合 SpringDataRedis
# 引入依赖
| |
| <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> |
# yml 配置文件
| spring: |
| redis: |
| host: 192.168.116.129 |
| port: 6379 |
| password: root |
| lettuce: |
| pool: |
| max-active: 8 |
| max-idle: 8 |
| min-idle: 0 |
| max-wait: 100 |
# 编写测试用例
| @SpringBootTest |
| public class RedisTest { |
| @Autowired |
| private RedisTemplate redisTemplate; |
| @Test |
| void testString() { |
| redisTemplate.opsForValue().set("name","baozi"); |
| String name = (String) redisTemplate.opsForValue().get("name"); |
| System.out.println("name = " + name); |
| } |
| } |
# SpringDataRedis 的序列化方式
RedisTemplate 可以接收任意 Object 作为值写入 Redis,只不过写入前会把 Object 序列化为字节形式,默认是采用 JDK 序列化
- 可读性差
- 内存占用较大
# StringRedisTemplate 解决序列化问题
| @SpringBootTest |
| public class SpringDataRedisApplicationTests { |
| @Autowired |
| private StringRedisTemplate stringRedisTemplate; |
| private static final ObjectMapper mapper = new ObjectMapper(); |
| @Test |
| void testUser() throws JsonProcessingException { |
| User user = new User(); |
| user.setName("baozi"); |
| user.setage(18); |
| String json = mapper.writeValueAsString(user); |
| stringRedisTemplate.opsForValue().set("user",json); |
| String jsonUser = stringRedisTemplate.opsForValue().get("user"); |
| User user1 = mapper.readValue(jsonUser, User.class); |
| System.out.println(user1); |
| } |
| } |