当前位置: 首页 > news >正文

redis整合

一.redis的发布订阅

        什么 是发布和订阅

                Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。

                Redis 客户端可以订阅任意数量的频道。

       1、Redis的发布和订阅

                客户端订阅频道发布的消息

                频道发布消息 订阅者就可以收到消息

        2、发布订阅的代码实现

                     打开一个客户端订阅channel1

                        SUBSCRIBE channel1

                        

                打开另一个客户端,给channel1发布消息hello

                        publish channel1 hello

                

                        返回的1是订阅者数量

                打开第一个客户端可以看到发送的消息

                

                

二.Redis事务

        1.事务简介:

                可以一次执行多个命令,本质是一组命令的集合。一个事务中的 所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

        单独的隔离的操作

                官网说明

https://redis.io/docs/interact/transactions/                https://redis.io/docs/interact/transactions/

        MULTI、EXEC、DISCARD、WATCH。这四个指令构成了 redis 事务处理的基础。

                1.MULTI 用来组装一个事务;将命令存放到一个队列里面

                2.EXEC 用来执行一个事务;//commit

                3.DISCARD 用来取消一个事务;//rollback

                4.WATCH 用来监视一些 key,一旦这些 key 在事务执行之前被改变,则取消事务的执行。

        例子:

                

redis> MULTI //标记事务开始
OK
redis> INCR user_id //多条命令按顺序入队
QUEUED queued
redis> INCR user_id
QUEUED
redis> INCR user_id
QUEUED
redis> PING
QUEUED
redis> EXEC //执行
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG

        有关事务,经常会遇到的是两类错误:

                1.调用 EXEC 之前的错误

                “调用 EXEC 之前的错误”,有可能是由于语法有误导致的,也可能时由于内存不足导致的。只要出现某个命令无法成功写入缓冲队列的情况,redis 都会进行记录,在客户端调用 EXEC 时,redis 会拒绝执行这一事务

        

        

> multi
OK
> haha
QUEUED
> ping
QUEUED
> exec
ReplyError: EXECABORT Transaction discarded because of previous errors.

2.调用 EXEC 之后的错误

                                

        

> multi
OK
> set age 23
QUEUED
//age 不是集合,所以如下是一条明显错误的指令
> sadd age 23
QUEUED
> set age 29
QUEUED
> exec //执行事务时,redis 不会理睬第 2 条指令执行错误
OK
OK
> get age
29 //可以看出第 3 条指令被成功执行了

        

        2.redis事务冲突

                双十一去购物的时候使用同一张银行卡去付款

                10000

                一个请求想给金额减8000

                一个请求想给金额减5000

                一个请求想给金额减1000

        解决方案

                悲观锁

                select * from biao where 1=1 for update;

                悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,

                每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,

                这样别人想拿这个数据就会block直到它拿到锁。

                传统的关系型数据库里边就用到了很多这种锁机制,

                比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

                12306抢票

                        乐观锁

                        version 1

                        查余额 10000 version:1

                10000>8000 -8000 update uuuu set moner-=8000 where version=1 1.1

                10000 -5000 UPDATE uuuuu SET MONTY-=5000 WHERE VERSION=1

                2000 2000>1000 UPDATE uuuu SET MONTY-=1000 WHERE VERSION=1.1 1.2

                version

                select * from ttt where uid =1

                version money

                        1 10000

                乐观锁

                乐观锁(Optimistic Lock), 顾名思义,就是很乐观,

                每次去拿数据的时候都认为别人不会修改,所以不会上锁,

                但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,

                可以使用版本号等机制。乐观锁适用于多读的应用类型,

                这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

        

三.Redis的使用

        java操作redis

        创建java项目

        添加redis的依赖

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version>
</dependency>

        相关API

        key的api
 @Testpublic  void testRedis() {//设置连接的服务器 端口号默认是6379// 服务器的默认值是localhostJedis jedis=new Jedis("8.140.27.154"); // redis的服务器的密码jedis.auth("xxx"); //设置密码// 设置选中的数据库的下标jedis.select(15);// 设置键值对jedis.set("k1", "v1");jedis.set("k2", "v2");jedis.set("k3", "v3");//获取所有的key值Set<String> keys = jedis.keys("*");System.out.println(keys.size());for (String key : keys) {System.out.println(key);}// 判断key是否存在System.out.println(jedis.exists("k1"));//获取key的过期时间System.out.println(jedis.ttl("k1"));// 获取key对应的值System.out.println(jedis.get("k1"));}}
        string-api
// 批量设置
jedis.mset("str1","v1","str2","v2","str3","v3");
//批量获取key
System.out.println(jedis.mget("str1","str2","str3"));
        hash-api
//设置 一个key叫做hash1 对应的field是username,value是lisi
jedis.hset("hash1","userName","lisi");
//获取key为hash1的对应的fileld为username的值
System.out.println(jedis.hget("hash1","userName"));
Map<String,String> map = new HashMap<String,String>();
map.put("telphone","13838389438");
map.put("address","郑州");
map.put("email","abc@163.com");
//批量设置
jedis.hmset("hash2",map);
//批量获取
List<String> result = jedis.hmget("hash2", "telphone","email");
for (String element : result) {System.out.println(element);
}
        set-api
jedis.sadd("orders", "order01");
jedis.sadd("orders", "order02");
jedis.sadd("orders", "order03");
jedis.sadd("orders", "order04");
Set<String> smembers = jedis.smembers("orders");
for (String order : smembers) {System.out.println(order);
}
//删除集合中的元素
jedis.srem("orders", "order02");
        zset-api
jedis.zadd("zset01", 100d, "z3");
jedis.zadd("zset01", 90d, "l4");
jedis.zadd("zset01", 80d, "w5");
jedis.zadd("zset01", 70d, "z6");Set<String> zrange = jedis.zrange("zset01", 0, -1);
for (String e : zrange) {System.out.println(e);
}
        list-api
//添加
jedis.lpush("mylist","test1","test2","test3");
//获取list里面的值
List<String> mylist = jedis.lrange("mylist", 0, -1);
for (String s : mylist) {System.out.println(s);
}

redis整合springboot

        创建springboot项目

        过程略

        加入redis的依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.6.0</version>
</dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>
</dependency>

        编写配置文件

#设置reis的索引
spring.redis.database=15
#设置连接redis的密码
spring.redis.password=xxx
#设置的redis的服务器
spring.redis.host=192.168.xx.33
#端口号
spring.redis.port=6379
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0

        设置配置类

package com.example.demo;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {/*** 连接池的设置** @return*/@Beanpublic JedisPoolConfig getJedisPoolConfig() {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();return jedisPoolConfig;}/*** RedisTemplate* @param factory* @return*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和publicom.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setConnectionFactory(factory);//key序列化方式template.setKeySerializer(redisSerializer);//value序列化template.setValueSerializer(jackson2JsonRedisSerializer);//value hashmap序列化template.setHashValueSerializer(jackson2JsonRedisSerializer);return template;}/*** 缓存处理* @param factory* @return*/@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}
}

http://www.lryc.cn/news/288208.html

相关文章:

  • 开循环低温样品架节约液氦操作技巧
  • 年薪30W+,待遇翻倍,我的经历值得每个测试人借鉴
  • DEB方式安装elastic search7以及使用
  • [Tomcat] [最全] 目录和文件详解
  • 微信小程序元素/文字在横向和纵向实现居中对齐、两端对齐、左右对齐、上下对齐
  • 兼容树莓派扩展模块,专注工业产品开发的瑞米派强势来袭
  • 云原生 - 微信小程序 COS 对象存储图片缓存强制更新解决方案
  • 设计公司设计ppt的优势—南京梵构广告
  • gitlab设置/修改克隆clone地址端口
  • Jellyfin影音服务本地部署并结合内网穿透实现公网访问本地资源
  • 笨蛋学设计模式行为型模式-责任链模式【18】
  • 【.NET Core】深入理解任务并行库 (TPL)
  • win10安装redis并配置加自启动(采用官方推荐unix子系统)
  • 【大数据面试题】HBase面试题附答案
  • SpringBoot中从HikariCP迁移到Oracle UCP指南
  • 第3章 接口和API设计
  • HBase入门:实现原理
  • Redis入门到实战-基础篇+实战篇+高级篇+原理篇
  • redis 工具类
  • 焕新升级,不同以“网” | AnyCase客户端全新上线
  • 导出 MySQL 数据库表结构、数据字典word设计文档
  • conda管理python安装包与虚拟环境的相关命令汇总
  • Vue3引用echart5 报错解决
  • 浅析HTTP协议
  • etcd未授权到控制k8s集群
  • 制作一个简单的HTML个人网站
  • 头歌C语言字符数组
  • 【mongoDB】文档 CRUD
  • 每日一题——LeetCode1337.矩阵中战斗力最弱的K行
  • docker指令存档