Redis学习
系列文章目录
基础知识、数据类型学习 | 万年历项目 | 代码逻辑训练习题 |
代码逻辑训练习题 | 方法、数组学习 | 图书管理系统项目 |
面向对象编程:封装、继承、多态学习 | 封装继承多态习题 | 常用类、包装类、异常处理机制学习 |
集合学习 | IO流、多线程学习 | 仓库管理系统JavaSE项目 |
员工管理系统、多表查询、反射实现DBHelper学习 | DML、DDL、数据库对象学习 | |
网络编程、各种标签、CSS学习 | ECMAScript、BOM学习 | DOM、jQuery学习 |
Servlet、JSP、Cookie、Ajax学习 | 融资管理系统JavaWeb项目 | |
MyBatis框架学习 | 逆向工程、Spring框架IOC、AOP学习 | SpringMVC框架学习 |
SpringBoot框架学习 | 招聘网站框架项目 | |
Vue介绍、窗体内操作、窗体间操作学习 | Vue路由配置、网络请求访问框架项目、element组件介绍学习 | 标准管理系统Vue项目 |
Linux安装、Nginx反向代理、负载均衡学习 | Docker学习 | Jenkins学习 |
Nexus学习 | Spring Security学习 | RabbitMQ学习 |
Redis学习 | ||
文章目录
- 系列文章目录
- 前言
- 一、Redis介绍
- 1. Redis介绍
- 2. Redis八种基本数据类型
- 2.1 String(字符串)
- 2.2 Hash(哈希)
- 2.3 List(列表)
- 2.4 Set(集合)
- 2.5 Zset(有序集合)
- 2.6 Geospatial(地理空间)
- 2.7 Bitmap(位图)
- 2.8 HyperLogLog(基数估计)
- 二、Redis安装
- 1. 拉取镜像文件
- 2. 启动Redis并设置密码
- 三、Radis整合SpringBoot
- 1. 创建maven项目
- 2. 导入依赖
- 3. 在application.yml文件配置redis
- 4. 添加RedisConfig类
- 5. 设置SpringBoot启动类
- 6. 常用方法介绍
- 6.1 redisTemplate
- 6.2 HashOperations
- 6.3 ListOperations
- 6.4 SetOperations
- 6.5 ZSetOperations
- 四、相关知识点
- 1. 缓存穿透
- 2. 缓存击穿
- 3. 缓存雪崩
- 总结
前言
本文我们要讲述:
Redis
在下攸攸太上,突如其来的有点想吃鸭货。
一、Redis介绍
1. Redis介绍
Redis是一个开源的高性能键值存储系统,其全称为远程字典服务(Remote Dictionary Server)。它被广泛用作内存缓存、数据库、消息中间件和分布式锁等场景。
Redis以键值对的形式存储数据,其中键和值都可以是字符串、数字或者二进制数据。它的设计目标是提供高性能和可扩展性,能够在高并发的场景下快速地读写大量数据。
简单来说,Redis是一个高性能的键值存储系统,用于存储和访问数据。
2. Redis八种基本数据类型
2.1 String(字符串)
是最基本的数据类型,它可以存储任何类型的数据,例如整数、浮点数、JSON字符串等。String类型支持一些常见的操作,如获取和设置值、增加或减少值、获取子字符串等。
2.2 Hash(哈希)
类似于对象或者Map,它是一个键值对的集合。Hash类型适合存储对象,可以方便地进行增加、删除、获取字段和值等操作。
2.3 List(列表)
是一个有序的字符串列表。可以将List看作是一个按照插入顺序排列的可重复的元素集合,可以在List的两端进行元素的插入和删除操作。
2.4 Set(集合)
是一个无序的、不重复的字符串集合。Set类型中的元素是无序的,且每个元素都是唯一的。可以进行添加、删除、判断元素是否存在以及计算交集、并集等操作。
2.5 Zset(有序集合)
是一个有序的、不重复的字符串集合。Zset类型将每个元素与一个浮点数值(称为分数)进行关联,根据分数的大小对元素进行排序。可以进行添加、删除、获取元素以及按照分数范围获取元素等操作。
除了以上五种常用的数据类型,Redis还提供了其他三种不太常用的数据类型:
2.6 Geospatial(地理空间)
用于存储和操作地理位置信息。
2.7 Bitmap(位图)
用于进行位操作,例如记录用户的在线状态、统计用户的签到情况等。
2.8 HyperLogLog(基数估计)
用于统计集合中不重复元素的个数,占用的内存空间很小。
二、Redis安装
1. 拉取镜像文件
docker pull redis:6.2.6
2. 启动Redis并设置密码
docker run -d --name redis-6379 -p 6379:6379 redis:6.2.6 --requirepass 123456
三、Radis整合SpringBoot
1. 创建maven项目
2. 导入依赖
导入spring-boot-starter-data-redis时需要稍等一会儿
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.jjy</groupId><artifactId>240925_Redis</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.13</version></parent><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.6.13</spring-boot.version><jwt.version>0.7.0</jwt.version><fastjson.version>1.2.60</fastjson.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>compile</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--json--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version><scope>compile</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><classifier>exec</classifier></configuration></plugin></plugins></build>
</project>
3. 在application.yml文件配置redis
spring:redis:host: 192.168.32.186port: 6379password: 123456
4. 添加RedisConfig类
package com.jjy.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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {/*** 配置 RedisTemplate<String, Object>* 设置了键和值的序列化方式,键用字符串序列化,值用JSON序列化** @return RedisTemplate*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {GenericJackson2JsonRedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer();StringRedisSerializer keySerialize = new StringRedisSerializer();RedisTemplate<String, Object> result = new RedisTemplate<>();result.setConnectionFactory(redisConnectionFactory);result.setKeySerializer(keySerialize);result.setValueSerializer(valueSerializer);result.setHashKeySerializer(keySerialize);result.setHashValueSerializer(valueSerializer);return result;}
}
5. 设置SpringBoot启动类
package com;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootMain {public static void main(String[] args) {SpringApplication.run(SpringBootMain.class, args);}
}
6. 常用方法介绍
6.1 redisTemplate
方法:
redisTemplate.hasKey(key); //判断是否有key所对应的值,有则返回true,没有则返回false
redisTemplate.opsForValue().get(key); //有则取出key值所对应的值
redisTemplate.delete(key); //删除单个key值
redisTemplate.delete(keys); //其中keys:Collection<K> keys
redisTemplate.dump(key); //将当前传入的key值序列化为byte[]类型
redisTemplate.expire(key, timeout, unit); //设置过期时间
redisTemplate.expireAt(key, date); //设置过期时间
redisTemplate.keys(pattern); //查找匹配的key值,返回一个Set集合类型
redisTemplate.rename(oldKey, newKey); //返回传入key所存储的值的类型
redisTemplate.renameIfAbsent(oldKey, newKey); //如果旧值存在时,将旧值改为新值
redisTemplate.randomKey(); //从redis中随机取出一个key
redisTemplate.getExpire(key); //返回当前key所对应的剩余过期时间
redisTemplate.getExpire(key, unit); //返回剩余过期时间并且指定时间单位
redisTemplate.persist(key); //将key持久化保存
redisTemplate.move(key, dbIndex); //将当前数据库的key移动到指定redis中数据库当中
6.2 HashOperations
方法:
HashOperations opsForHash = redisTemplate.opsForHash();opsForHash.get(key, field); //获取变量中的指定map键是否有值,如果存在该map键则获取值,没有则返回null
opsForHash.entries(key); //获取变量中的键值对
opsForHash.put(key, hashKey, value); //新增hashMap值
opsForHash.putAll(key, maps); //以map集合的形式添加键值对
opsForHash.putIfAbsent(key, hashKey, value); //仅当hashKey不存在时才设置
opsForHash.delete(key, fields); //删除一个或者多个hash表字段
opsForHash.hasKey(key, field); //查看hash表中指定字段是否存在
opsForHash.increment(key, field, long increment); //给哈希表key中的指定字段的整数值加上增量increment
opsForHash.increment(key, field, double increment); //给哈希表key中的指定字段的整数值加上增量increment
opsForHash.keys(key); //获取所有hash表中字段
opsForHash.values(key); //获取hash表中存在的所有的值
opsForHash.scan(key, options); //匹配获取键值对,ScanOptions.NONE为获取全部键对
6.3 ListOperations
方法:
ListOperations opsForList = redisTemplate.opsForList();opsForList.index(key, index); //通过索引获取列表中的元素
opsForList.range(key, start, end); //获取列表指定范围内的元素(start开始位置, 0是开始位置,end 结束位置, -1返回所有)
opsForList.leftPush(key, value); //存储在list的头部,即添加一个就把它放在最前面的索引处
opsForList.leftPush(key, pivot, value); //如果pivot处值存在则在pivot前面添加
opsForList.leftPushAll(key, value); //把多个值存入List中(value可以是多个值,也可以是一个Collection value)
opsForList.leftPushIfPresent(key, value); //List存在的时候再加入
opsForList.rightPush(key, value); //按照先进先出的顺序来添加(value可以是多个值,或者是Collection var2)
opsForList.rightPushAll(key, value); //在pivot元素的右边添加值
opsForList.set(key, index, value); //设置指定索引处元素的值
opsForList.trim(key, start, end); //将List列表进行剪裁
opsForList.size(key); //获取当前key的List列表长度//移除并获取列表中第一个元素(如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止)
opsForList.leftPop(key);
opsForList.leftPop(key, timeout, unit); //移除并获取列表最后一个元素
opsForList.rightPop(key);
opsForList.rightPop(key, timeout, unit); //从一个队列的右边弹出一个元素并将这个元素放入另一个指定队列的最左边
opsForList.rightPopAndLeftPush(sourceKey, destinationKey);
opsForList.rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit);//删除集合中值等于value的元素(index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素; index<0, 从尾部开始删除第一个值等于value的元素)
opsForList.remove(key, index, value);
6.4 SetOperations
方法:
SetOperations opsForSet = redisTemplate.opsForSet();opsForSet.add(key, values); //添加元素
opsForSet.remove(key, values); //移除元素(单个值、多个值)
opsForSet.pop(key); //删除并且返回一个随机的元素
opsForSet.size(key); //获取集合的大小
opsForSet.isMember(key, value); //判断集合是否包含value
opsForSet.intersect(key, otherKey); //获取两个集合的交集(key对应的无序集合与otherKey对应的无序集合求交集)
opsForSet.intersect(key, otherKeys);//获取多个集合的交集(Collection var2)
opsForSet.intersectAndStore(key, otherKey, destKey); //key集合与otherKey集合的交集存储到destKey集合中(其中otherKey可以为单个值或者集合)
opsForSet.intersectAndStore(key, otherKeys, destKey); //key集合与多个集合的交集存储到destKey无序集合中
opsForSet.union(key, otherKeys); //获取两个或者多个集合的并集(otherKeys可以为单个值或者是集合)
opsForSet.unionAndStore(key, otherKey, destKey); //key集合与otherKey集合的并集存储到destKey中(otherKeys可以为单个值或者是集合)
opsForSet.difference(key, otherKeys); //获取两个或者多个集合的差集(otherKeys可以为单个值或者是集合)
opsForSet.differenceAndStore(key, otherKey, destKey); //差集存储到destKey中(otherKeys可以为单个值或者集合)
opsForSet.randomMember(key); //随机获取集合中的一个元素
opsForSet.members(key); //获取集合中的所有元素
opsForSet.randomMembers(key, count); //随机获取集合中count个元素
opsForSet.distinctRandomMembers(key, count); //获取多个key无序集合中的元素(去重),count表示个数
opsForSet.scan(key, options); //遍历set类似于Interator(ScanOptions.NONE为显示所有的)
6.5 ZSetOperations
方法:
ZSetOperations提供了一系列方法对有序集合进行操作
ZSetOperations opsForZSet = redisTemplate.opsForZSet();opsForZSet.add(key, value, score); //添加元素(有序集合是按照元素的score值由小到大进行排列)
opsForZSet.remove(key, values); //删除对应的value,value可以为多个值
opsForZSet.incrementScore(key, value, delta); //增加元素的score值,并返回增加后的值
opsForZSet.rank(key, value); //返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
opsForZSet.reverseRank(key, value); //返回元素在集合的排名,按元素的score值由大到小排列
opsForZSet.reverseRangeWithScores(key, start,end); //获取集合中给定区间的元素(start 开始位置,end 结束位置, -1查询所有)
opsForZSet.reverseRangeByScore(key, min, max); //按照Score值查询集合中的元素,结果从小到大排序
opsForZSet.reverseRangeByScoreWithScores(key, min, max); //返回值为:Set<ZSetOperations.TypedTuple<V>>
opsForZSet.count(key, min, max); //根据score值获取集合元素数量
opsForZSet.size(key); //获取集合的大小
opsForZSet.zCard(key); //获取集合的大小
opsForZSet.score(key, value); //获取集合中key、value元素对应的score值
opsForZSet.removeRange(key, start, end); //移除指定索引位置处的成员
opsForZSet.removeRangeByScore(key, min, max); //移除指定score范围的集合成员
opsForZSet.unionAndStore(key, otherKey, destKey);//获取key和otherKey的并集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合)
opsForZSet.intersectAndStore(key, otherKey, destKey); //获取key和otherKey的交集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合)
四、相关知识点
1. 缓存穿透
概念:指的是缓存和数据库中都没有的数据,但是用户不断发起请求,导致每次请求都会到数据库,给数据库造成压力。
解决办法:可以通过业务层校验、不存在数据设置短过期时间以及使用布隆过滤器来解决缓存穿透的问题。
2. 缓存击穿
概念:指的是Redis中某个热点key在失效的同时,大量的请求过来,全部到达数据库,给数据库造成压力。
解决办法:可以通过设置热点数据永不过期、定时更新或使用互斥锁来解决缓存击穿的问题。
3. 缓存雪崩
概念:指的是Redis中缓存的数据大面积同时失效或Redis宕机,导致大量请求直接到数据库,给数据库造成压力。
解决办法:可以通过设置有效期均匀分布、数据预热和保证Redis服务高可用来解决缓存雪崩的问题。
总结
本文讲述了:
Redis:用于降低数据库压力的缓存技术
在下攸攸太上,我收到的月饼还没吃完,呜呜……