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.mzph.cn/news/647221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab绘图杂谈-stem函数和plot函数

出发点 今天在论文中看到一副这样的图&#xff0c;它既有曲线&#xff0c;又有点&#xff0c;并且对两者都添加了图例。三条曲线应该是用plot函数绘制的&#xff0c;而target哪个绿色的圆圈&#xff0c;我的理解是用stem函数绘制的。它只是1个点&#xff0c;并且没有竖线&…

Linux文件管理技术实践

shell shell的种类(了解) shell是用于和Linux内核进行交互的一个程序&#xff0c;他的功能和window系统下的cmd是一样的。而且shell的种类也有很多常见的有c shell、bash shell、Korn shell等等。而本文就是使用Linux最常见的bash shell对Linux常见指令展开探讨。 内置shell…

ElasticSearch搜索引擎入门到精通

ES 是基于 Lucene 的全文检索引擎,它会对数据进行分词后保存索引,擅长管理大量的数据,相对于 MySQL 来说不擅长经常更新数据及关联查询。这篇文章就是为了进一步了解一下它,到底是如何做到这么高效的查询的。 在学习其他数据库的时候我们知道索引是一个数据库系统极其重要…

【基础配置】Python2/Python3并存安装配置教程

Nx01 产品简介 Python是一种高级的、解释型的、面向对象的通用编程语言&#xff0c;具有简单易学、代码可读性强、功能强大、可移植性好等特点。它可以应用于多种领域&#xff0c;如Web开发、数据科学、人工智能、机器学习、科学计算、自动化测试等。Python由Guido van Rossum于…

如何使用phpStudy软件测试本地PHP及环境搭建

各位同学朋友们大家好&#xff01;我是咕噜铁蛋&#xff01;我们经常需要在本地进行PHP代码的开发和测试。而phpStudy作为一个集成了Apache、MySQL和PHP的软件套装&#xff0c;提供了方便快捷的环境搭建和测试工具。今天铁蛋为大家详细介绍如何使用phpStudy来测试本地PHP及环境…

雨云服务器部署幻兽帕鲁PalWorld联机服务器详细教程

幻兽帕鲁是Pocketpair开发的一款开放世界生存制作游戏&#xff0c;游戏中&#xff0c;玩家可以在广阔的世界中收集神奇的生物“帕鲁”&#xff0c;派他们进行战斗、建造、做农活&#xff0c;工业生产等。 最近&#xff0c;这款游戏挺火&#xff0c;为了获得更好的游戏体验&…

Vue构建项目断点调试过程问题总结

Vue构建项目断点调试过程问题总结 问题背景 前端开发过程中&#xff0c;碰到问题时需要debug&#xff0c;快速分析和解决问题。一般除了console.log的方式打印日志外&#xff0c;更方便直观的方式就是打断点debug。本文对vue项目debug过程可能碰到的问题进行总结&#xff0c;…

“数据同步大揭秘:Canal工具如何让实时处理变得轻而易举?“

介绍&#xff1a;Canal是一个基于MySQL数据库增量日志解析的开源数据同步工具。 Canal的主要功能是提供增量数据订阅和消费&#xff0c;它通过解析MySQL数据库的增量日志来捕获数据变更事件&#xff0c;并将这些事件转换成数据变更流&#xff0c;供用户订阅和消费。这样&#x…

Deepin基本环境查看(四)【硬盘/分区、文件系统、硬连接/软连接】

Linux操作系统(Deepin、Ubuntu&#xff09;操作系统中&#xff0c;硬盘分区的管理与Windows操作系统不同&#xff1b; 在Linux系统中维护着一个统一的文件目录体系&#xff0c;而硬盘和分区是以资源的形式由操作系统挂接和调度&#xff1b;此外Linux系统中连接&#xff08;硬连…

NTFS 磁盘管理 :NTFS Disk by Omi NTFS

NTFS Disk by Omi NTFS是一款专为Mac系统设计的NTFS文件系统读写解决方案的工具。它可以帮助Mac用户方便地访问和管理NTFS格式的硬盘、U盘、移动硬盘以及其他存储设备&#xff0c;提供高效稳定的NTFS卷管理功能。 NTFS 磁盘管理 &#xff1a;NTFS Disk by Omi NTFS 该软件的主…

Mistral AI vs. Meta:顶级开源LLM比较

为了提高性能&#xff0c;大型语言模型(llm)通常会通过增加模型大小的方法来实现这个目标&#xff0c;但是模型大小的增加也增加了计算成本和推理延迟&#xff0c;增加了在实际场景中部署和使用llm的障碍。 Mistral AI是一家总部位于巴黎的欧洲公司&#xff0c;一直在研究如何…

QT入门篇---无门槛学习

1.1 什么是 Qt Qt 是⼀个 跨平台的 C 图形⽤⼾界⾯应⽤程序框架 。它为应⽤程序开发者提供了建⽴艺术级图形界⾯所需的所有功能。它是完全⾯向对象的&#xff0c;很容易扩展。Qt 为开发者提供了⼀种基于组件的开发模式&#xff0c;开发者可以通过简单的拖拽和组合来实现复杂的…

车险到期提醒,快速查询交强险投保日期!

随着社会的进步和人们生活水平的提高&#xff0c;车辆已经成为人们出行的重要工具。而为了保障行车安全&#xff0c;车辆保险成为了必备的选择。交强险作为一种强制性的保险&#xff0c;其投保期限对车主来说尤为重要。本文将通过介绍一个API接口&#xff0c;帮助车主们快速查询…

图中点的层次——树与图的广度优先遍历

问题描述 代码实现 #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N 1e5 10;int n, m; int h[N], ne[N * 2], e[N * 2], idx; int d[N]; // 从节点1到当前节点的距离 int q[N * 2]; // 数组模拟队列void ad…

01-echarts如何绘制三维折线图

echarts如何绘制三维折线图 一、相关依赖包1、下载依赖2、引入依赖 二、创建图表盒子1、创建盒子2、定义数据3、编写方法1、初始化盒子2、设置配置项3、修改数据格式4、设置颜色数组4、设置name数组5、设置线三维和点三维6、添加配置项7、设置图表自适应 4、调用方法 三、整体代…

Unity 面试篇|(三)设计模式篇 【全面总结 | 持续更新 | 建议收藏】

目录 1. 什么是设计模式&#xff1f;2. 设计模式的七大原则&#xff1f;3. 单例模式4. 三类设计模式5. 什么是单例模式&#xff0c;适用场景以及优缺点&#xff1f;6. 什么是原型模式&#xff0c;适用场景以及优缺点&#xff1f;7. 什么是生成器模式&#xff0c;适用场景以及优…

力扣经典题:链表合并

解决链表合并问题需要有特定的思路&#xff1a; 、链表合并 王赫辰/c语言 - Gitee.com 简述思路&#xff1a;首先先处理特殊情况&#xff0c;将空指针时的情况进行提前处理 然后再创建新的链表&#xff0c;此时使用尾插比较法&#xff1a; 循环条件&#xff1a;当两个链表中…

甲基四嗪-PEG5-炔烃,Methyltetrazine-PEG5-alkyne,可以提高生物分子的稳定性和保存期

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;甲基四嗪五聚乙二醇炔&#xff0c;甲基四嗪-PEG5-炔烃&#xff0c;Methyltetrazine-PEG5-alkyne 一、基本信息 产品简介&#xff1a;Methyltetrazine PEG5 alkyne contains methyltetrazole and PEG5 chains, as we…

pyecharts模块的下载方法以及介绍,折线图的创立

目录 1.pyecharts是什么 2.pyecharts下载方法 1.在屏幕左下角搜索这里输入cmd&#xff0c;找到命令提示符并且打开 2.输入pip install pyecharts 然后回车进行下载 3.检查是否下载完成 4.另一个方法 3.pyecharts入门 4.pyecharts的配置选项 set_global_opts全局配置选…

有关Quick BI中Case子句中多次使用lod函数返回空值问题分析

一、Quick BI中的lod_ include函数 lod_ include {维度1[,维度2]...:聚合表达式[:过滤条件]} 作用&#xff1a;将表达式中的维度一起作为分组依据进行订算。其中&#xff0c; 1) 维度1[,维度2]... &#xff1a;声明维度&#xff0c;指定聚合表达式要连接到的一个或多个维…