前言
此文是写给完全没有redis基础知识和nacos基础知识看的,简单的入门测试代码。了解redis和nacos的可以闪了!!!
基础知识
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,数据存储在内存中,也可持久化到磁盘中,多数用来做数据缓存和分布式锁。
结构
redis的key一般都是字符串,value值Redis有5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合),入门先掌握key是String和value也是String
用法
安装略过,一般运维会给我安装好redis,会给我们用户和密码,在项目中我们一般在配置文件中这样写。 配置文件我们一般写在nacos上,nacos后续介绍。一般在配置文件这样配置就好。
##redis配置
#redis地址
spring.redis.host=172.1.1.12
#redis的database分区一共有0到16个默认是0
spring.redis.database=0
#redis的密码 没有密码=号后面不写
spring.redis.password=5huFdsoSiq3
#redis的端口
spring.redis.port=6379
#连接池中的最小空闲连接 默认为 0
spring.redis.lettuce.pool.min-idle=5
#连接池中的最大空闲连接 默认为8
spring.redis.lettuce.pool.max-idle=10
#连接池最大连接数(使用负值表示没有限制) 默认为8
spring.redis.lettuce.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制) 默认为-1
spring.redis.lettuce.pool.max-wait=1ms
#关闭超时时间
spring.redis.lettuce.shutdown-timeout=100ms
在项目中引入redis引入如下jar
import org.springframework.data.redis.core.RedisTemplate;
注入使用
@Autowired
private RedisTemplate redisTemplate;
代码中使用
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
String操作
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("test")
public void Test() {
//存key 为lei, value为leixiaohong的键值对
redisTemplate.opsForValue().set("lei", "leixiaohong");
//存储的时候过期时间2分钟 意思是两分钟之后redis就删除了key是li,value为leixiaohong123的键值对
redisTemplate.opsForValue().set("li", "leixiaohong123", 2, TimeUnit.MINUTES);
String a = redisTemplate.opsForValue().get("lei").toString();
System.out.println("rerdis key为lei的值是:" + a);
String b = redisTemplate.opsForValue().get("li").toString();
System.out.println("rerdis key为li的值是:" + b);
}
输出如下:
List操作
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("test1")
public void Test1() {
//list数组对象和添加数组值 将数据添加到key对应的现有数据的左边,也就是头部
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
redisTemplate.opsForList().leftPush("leixiaohong", list);
//list数组对象和添加数组值 将数据添加到key对应的现有数据的右边,也就是尾部
List list1 = new ArrayList();
list1.add("4");
list1.add("5");
list1.add("6");
redisTemplate.opsForList().rightPush("leixiaohong", list1);
//用redisTemplate模板类从Redis中根据key获取list集合 从左取
List list2 = (List) redisTemplate.opsForList().leftPop("leixiaohong");
//循环输出
for (Object o : list2) {
System.out.println("left的list的值:"+o);
}
//用redisTemplate模板类从Redis中根据key获取list集合 从右取
List list3 = (List) redisTemplate.opsForList().rightPop("leixiaohong");
//循环输出
for (Object o : list3) {
System.out.println("right的list的值:"+o);
}
//一般从哪一遍(left/right)存就从哪边取(Pop)
//刷新时间 用expire方法对key设置过期时间,适合所有的类型。比如刷新key为leixiaohong的时间为60分钟。
redisTemplate.expire("leixiaohong", 60, TimeUnit.SECONDS);
}
结果如下:key左边的list和key右边的list分别不同。
set的操作
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("test2")
public void Test2() {
//定义Map集合和类型
Map<String,String> map = new HashMap<>();
map.put("key1","leixiaohong1");
map.put("key2","leixiaohong2");
map.put("key3","leixiaohong3");
//用redis模板类把map设置到redis中
redisTemplate.opsForHash().putAll("map",map);
Map<String,String> resultMap = redisTemplate.opsForHash().entries("map");
for (String s : resultMap.keySet()) {
System.out.println("循环map结果,key是:"+s+",value是:"+resultMap.get(s));
}
List<String> reslutMapList = redisTemplate.opsForHash().values("map");
for (String s : reslutMapList) {
System.out.println("循环List结果:"+s);
}
Set<String> resultMapSet = redisTemplate.opsForHash().keys("map");
for (String s : resultMapSet) {
System.out.println("循环Set结果:"+s);
}
String value = (String)redisTemplate.opsForHash().get("map","key1");
System.out.println("直接取map的key1的值:"+value);
//同样可以熟悉刷新时间
redisTemplate.expire("map", 60, TimeUnit.SECONDS);
}
结果:
set操作
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("test3")
public void Test3() {
//定义一个set集合并设置集合值
SetOperations<String, String> set = redisTemplate.opsForSet();
set.add("set1", "123");
set.add("set2", "1234");
set.add("set3", "123");
//通过key获取set集合中的对象值
Set<String> resultSet = redisTemplate.opsForSet().members("set1");
//差值
redisTemplate.opsForSet().difference("set1", "set2");
//比较第一个和第三个集合的差值,并把差值添加到set4
redisTemplate.opsForSet().differenceAndStore("set1", "set2", "set4");
Set<String> resultSet1 = redisTemplate.opsForSet().members("set4");
//交集
Set set1 = redisTemplate.opsForSet().intersect("set1", "set3");
//集合1和集3的交集,并把交集添加至集合set5
redisTemplate.opsForSet().intersectAndStore("set1", "set3", "set5");
Set<String> resultSet2 = redisTemplate.opsForSet().members("set5");
//并集
Set union = redisTemplate.opsForSet().union("set1", "set2");
//集合1和集合2的并集,并添加至集合3
redisTemplate.opsForSet().unionAndStore("set1", "set2", "set6");
Set<String> resultSet3 = redisTemplate.opsForSet().members("set6");
}
redis总结
差不多redis的常用就这些,一般使用场景就是比如缓存用户信息,将用户信息封在token信息中,把token当做key,用户信息封装成json字符串,保存在redis中记得设置过期时间,过期了让重新登录就好,下次登录鉴权的时候,不用直接去数据库取数据,可以直接在redis中用token取用户信息。
二缓存数据,比如我们把热点数据缓存在redis中,之前不用redis的时候我们直接去mysql数据库查询,这样io次数多,效率低,有了redis之后我们可以这样做,第一次先去mysql数据库查询,把查询回来的数据保存在redis中,并把结果同时返回给前端,那么下次(以后)再来查询相同的数据的时候,我们直接在redis中拿出来,直接返回给前端,就不用从数据库查询了。如果这个值需要更新操作,先去更新数据库,然后把redis的数据设置过期,或者删掉,下次再来查询的时候再从数据库查询再存redis,下次再直接从redis取数据。这个涉及到数据一致性,先不讨论。
nacos简介
nacos的官网推荐去看nacos.io/zh-cn/docs/…
主要的作用就是用于服务的注册和发现,和服务的配置,配置很好理解吧,我们一般会在bootstrap.yml配置文件,但是这个配置一旦改的需要去代码中改配置文件,比较麻烦影响系统的稳定性,那么有没有个配置中心统一配置配置文件,我们项目只要连上配置中心那么就能读取配置中心的配置文件,nacos的配置中心就是做这个的。还要注册中心我们一般微服务有很多个节点,我们想把所有节点启动起来都注册到一个统一的地方注册中心,然后使用网关统一连接注册中心就能找到我们注册的服务,一般是结合springcloud的网关使用。
和springboot项目的结合
引入nacos的配置和注册jar,默认nacos运维已经安装好并提供端口和地址使用。
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-alibaba-nacos-config', version: '0.9.0.RELEASE'
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-alibaba-nacos-discovery', version: '0.9.0.RELEASE'
bootstrap.yml配置引入nacos
spring:
application:
name: test
profiles:
active: dev
include: env
cloud:
nacos:
discovery:
config:
ext-config[0]:
data-id: database.yml
ext-config[1]:
data-id: redis.yml
ext-config[2]:
data-id: log_level.yml
ext-config[3]:
data-id: proxy.yml
## 环境相关配置
---
spring:
profiles: dev
cloud:
nacos:
discovery:
server-addr: 172.1.1.1:8848
namespace: da6c169f-b02a-4beb-86ec-dcaf7642697c
config:
server-addr: 172.1.1.1:8848
namespace: da6c169f-b02a-4beb-86ec-dcaf7642697c
---
spring:
profiles: prod
cloud:
nacos:
discovery:
server-addr: 172.1.1.2:8848
namespace: da6c169f-b02a-4beb-86ec-dcaf76jhjhjh
config:
namespace: da6c169f-b02a-4beb-86ec-dcaf76jhjhjh
server-addr: 172.1.1.2:8848
说明:主要是配置注册中心信息,和注册中心信息对应config和discovery。server-addr为nacos的地址和端口。namespace为命名空间。dev和prod一般是两个环境对应测试环境和正式环境,当然你可以配更多的环境比如预发布环境,切换的时候只需要修改active:xx切换xx就行。对应上面的配置active:dev说明现在是测试环境。如果需要连接正式环境的nacos修改为active:prod。
使用nacos管理端
命名空间
地址:一般是http://ip:8848/nacos/#/login 打开界面是这样,默认用户名和密码都是nacos/nacos
先建你自己项目的命名空间,public是默认的,下面四个是我项目中实际建的,命名空间ID
对应上面配置的namespace
配置中心
在配置列表去找我们的配置文件。上文我们配置了四个配置文件 database.yml,redis.yml,log_level.yml,proxy.yml分别是数据库配置,redis配置,日志配置和其他开发中需要的配置。对应下图的四个配置文件,我打码了,正确会显示database.yml,redis.yml,log_level.yml,proxy.yml这四个文件。任意点开一个可以看见配置。比如我们点开redis的配置。可以对配置修改删除回退等。
redis配置示例:
到这一步你在nacos配置的比如redis配置,你的项目中在用redis的时候就用的你配置中心连接的redis
注册中心
打开服务列表会看见你启动的服务注册到nacos上,点开详情有详细的信息,比如哪个ip注册上来的,比如你有多个服务你可以让其中一个服务下线等。
服务列表详情
nacos总结
nacos其他的我用的少,只是结合springboot用于服务的配置,服务的发现与注册。