Redis

Redis 缓存一致性

巧了我就是萌 提交于 2020-12-14 22:13:37
引入缓存后,随之带来的问题就是DB数据更新时,缓存中的数据会与db数据不一致,这时需要对缓存的数据进行更新或者淘汰缓存 先更新DB还是先操作缓存? 更新DB和操作缓存明显缺乏原子性,有可能更新DB完成,但是缓存操作失败,反之亦然。这里推荐先更新DB 再更新或者淘汰缓存 原因如下: 1 如果先更新缓存的话,然后数据库中数据更新失败了,下一个读请求过来,读到的数据是是未更新的数据库中的数据,这样的数据明显是错误的 2 如果先淘汰缓存,然后更新DB,如果在DB更新完成之前,来了一个新的请求,那么就会查询出数据库中的旧数据,缓存到redis,导致DB更新完成之后,两者数据不一致。 3 如果先更新DB 然后缓存操作失败,客户端读到的是旧数据,此时也存在DB缓存不一致,但是实际业务上,我们还是以DB数据为准,这种读取到旧数据的业务影响可能比读取到未更新到DB的数据影响更小。 如何保持更新DB和操作缓存之间的连续性? 两个动作原则上是非原子性的,一个是更新DB,一个是更新Redis.可以使用消息队列来实现最终一致性的消息保证。 先更新数据库,然后通过发送缓存的消息到消息队列中,进行更新缓存操作,还需要利用消息队列的重试机制,保证缓存能够更新成功,如果多次失败可能是由于网络原因或者是redis服务挂了。 更新缓存还是淘汰缓存? 严格来说 不论是更新缓存还是淘汰缓存都可能出现缓存不一致

Spring Boot 的2020最后一击:2.4.1、2.3.7、2.2.12 发布

夙愿已清 提交于 2020-12-14 12:27:23
近日,Spring Boot官方发布了本年度最后一次版本更新,主要针对目前维护的三个版本: 2.4.x:第一个bug修复版本 2.4.1 2.3.x:常规维护版本 2.3.7 2.2.x:常规维护版本 2.2.12 由于2.2.x和2.3.x已经非常稳定,所以我们主要关注本次2.4.1的更新。 2.4.1版本内容 由于在Spring Boot 2.4.0版本中,对原有的配置加载机制做了较大改动,不少开发者反映在升级的时候也出现了各种不同的问题。而这次2.4.1的发布,主要着手解决了不少关于配置相关的Bug。下面我们一起看看这次都解决了哪些重要问题: 通过通配符匹配的配置文件互相覆盖的问题 配置属性与JavaBean之间绑定的顺序问题 允许递归配置文件组的引用 外部应用程序属性加载顺序的问题 @Name在Kotlin中绑定失败的问题 Redis健康检查器对性能消耗过大的问题 Actuator端点在MVC和WebFlux下运行时,无法正确响应自定义HTTP状态码 Actuator的env端点没有正确显示包装类型的数据 通过配置树绑定非字符串属性时,找不到转换器的问题 使用Log4J调用LoggingSystem时会抛出NullPointerException的问题 加载属性文件的时候,“#”标注之后的内容会丢失 在启用 WebTestClientContextCustomizer 之前

高并发下的接口幂等性解决方案!

陌路散爱 提交于 2020-12-14 08:32:05
一、背景 我们实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果。 例如: 前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果。 我们发起一笔付款请求,应该只扣用户账户一次钱,当遇到网络重发或系统bug重发,也应该只扣一次钱; 发送消息,也应该只发一次,同样的短信发给用户,用户会哭的; 创建业务订单,一次业务请求只能创建一个,创建多个就会出大问题。 等等很多重要的情况,这些逻辑都需要幂等的特性来支持。 二、幂等性概念 幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。 这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数. 更复杂的操作幂等保证是利用唯一交易号(流水号)实现. 我的理解:幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的 三、技术方案 1. 查询操作 查询一次和查询多次,在数据不变的情况下,查询结果是一样的。select是天然的幂等操作 2. 删除操作 删除操作也是幂等的,删除一次和多次删除都是把数据删除。

高并发下接口幂等性解决方案

心不动则不痛 提交于 2020-12-14 08:28:45
阅读文本大概需要3分钟。 0x01、幂等性概念 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数. 更复杂的操作幂等保证是利用唯一交易号(流水号)实现. 一句话: 幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的。 0x02、幂等性场景 1、查询操作 查询一次和查询多次,在数据不变的情况下,查询结果是一样的。select是天然的幂等操作; 2、删除操作 删除操作也是幂等的,删除一次和多次删除都是把数据删除。(注意可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条,返回结果多个) ; 3、唯一索引 防止新增脏数据。比如:支付宝的资金账户,支付宝也有用户账户,每个用户只能有一个资金账户,怎么防止给用户创建资金账户多个,那么给资金账户表中的用户ID加唯一索引,所以一个用户新增成功一个资金账户记录。要点:唯一索引或唯一组合索引来防止新增数据存在脏数据(当表存在唯一索引,并发时新增报错时,再查询一次就可以了,数据应该已经存在了,返回结果即可); 4、token机制:防止页面重复提交 原理上通过session

高并发下接口幂等性解决方案

廉价感情. 提交于 2020-12-14 08:26:55
点击关注上方“ JAVA开发大本营 ”,设为“ 置顶或星标 ”,第一时间送达技术干货。 来源: rrd.me/fffMq 作者:抽离的心 一、背景 我们实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果。 例如: 前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果。 我们发起一笔付款请求,应该只扣用户账户一次钱,当遇到网络重发或系统bug重发,也应该只扣一次钱; 发送消息,也应该只发一次,同样的短信发给用户,用户会哭的; 创建业务订单,一次业务请求只能创建一个,创建多个就会出大问题。 等等很多重要的情况,这些逻辑都需要幂等的特性来支持。 二、幂等性概念 幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。 幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。 这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。 例如,“getUsername()和setTrue()”函数就是一个幂等函数. 更复杂的操作幂等保证是利用唯一交易号(流水号)实现. 我的理解: 幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的 三、技术方案 1. 查询操作 查询一次和查询多次

Redis缓存穿透和缓存雪崩以及解决方案

时光总嘲笑我的痴心妄想 提交于 2020-12-14 04:43:11
原文: Redis缓存穿透和缓存雪崩以及解决方案 Redis缓存穿透和缓存雪崩以及解决方案 Redis缓存穿透和缓存雪崩以及解决方案 缓存穿透 解决方案 布隆过滤 缓存空对象 比较 缓存雪崩 解决方案 保证缓存层服务高可用性 依赖隔离组件为后端限流并降级 数据预热 缓存并发 分布式锁 缓存穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存不命中,接着查询数据库也无法查询出结果,因此也不会写入到缓存中,这将会导致每个查询都会去请求数据库,造成缓存穿透; 解决方案 布隆过滤 对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力; 缓存空对象 当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源; 但是这种方法会存在两个问题: 如果空值能够被缓存起来,这就意味着缓存需要更多的空间存储更多的键,因为这当中可能会有很多的空值的键; 即使对空值设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响。 比较 缓存雪崩 缓存雪崩是指,由于缓存层承载着大量请求,有效的保护了存储层,但是如果缓存层由于某些原因整体不能提供服务,于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会挂掉的情况。 解决方案

Redis进阶实践之四Redis的基本数据类型

大城市里の小女人 提交于 2020-12-14 01:53:19
一、引言 今天正式开始了Redis的学习,如果要想学好Redis,必须先学好Redis的数据类型。Redis为什么会比以前的Memchaed等内存缓存软件使用的更频繁,适用范围更广呢?就是因为Redis使用起来更方便,之所以方便,是因为Redis支持的数据类型比以前的Memchaed缓存支持数据类型的更多了。Redis有五种基本数据类型,String(字符串),Hash(哈希),List(链表),Set(集合),ZSet(有序集合),在这五种基本的数据类型中,String类型是最基础的。为什么说String类型是最基础的,就拿List为例来说,它是以列表的形式组织字符串数据,Set类型是以集合类型来组织字符串数据的。今天就让我们比较全面的来认识一下redis的基本数据类型吧。 二、NoSQL的介绍 NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,意为反Sql运动,提倡运用非关系型的数据存储,随着Web2.0网站的兴起,传统的关系型数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经力不从心,暴露了很多难以克服的问题,而非关系型数据库则由于其本身的特点得到了迅速发展。 NoSQL是以key-value形式存储,和传统的关系型数据库不一样,不一定遵循传统数据库的一些基本要求,比如:遵循Sql标准,ACID属性

Java动态创建与修改定时任务

爱⌒轻易说出口 提交于 2020-12-14 01:20:37
  最近遇到一个需求,需要能够按照特定的配置执行定时任务,而且定时任务需要在应用不重启的情况下动态增删改,Spring提供的 @Scheduled 注解是硬编码形式,只能实现固定的定时任务,随后经过一番探究,依托注明的quartz框架终于实现了该功能,下面来分享一下我的方案。 首先引入quartz maven依赖: <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <!-- 由于我的项目继承了spring-boot-starter-parent,因此这里可以不用写版本号,会直接使用父pom文档中dependencyManagement的quartz版本号 --> <!-- <version>2.3.2</version> --> </dependency> 我的定时任务配置是存储在MySQL数据库当中的,当程序启动时,初始化过程会的 init() 方法会读取一遍所有有效的定时任务配置,然后将其实例化为一个个对象,一个对象便代表了一个定时任务,我定义的类为 public class ScheduledClauseTriggerEngine implements ClauseTriggerEngine<Void>, Job, AutoCloseable ,其中

什么是接口的幂等性,如何实现接口幂等性?一文搞定

為{幸葍}努か 提交于 2020-12-14 01:13:57
听说微信搜索《Java鱼仔》会变更强哦! 本文收录于 JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看哦 每天一个知识点 什么是接口的幂等性,如何实现接口幂等性? (一)幂等性概念 幂等性原本是数学上的概念,用在接口上就可以理解为:同一个接口,多次发出同一个请求,必须保证操作只执行一次。 调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生。 比如下面这些情况,如果没有实现接口幂等性会有很严重的后果: 支付接口,重复支付会导致多次扣钱 订单接口,同一个订单可能会多次创建。 (二)幂等性的解决方案 唯一索引 使用唯一索引可以避免脏数据的添加,当插入重复数据时数据库会抛异常,保证了数据的唯一性。 乐观锁 这里的乐观锁指的是用乐观锁的原理去实现,为数据字段增加一个version字段,当数据需要更新时,先去数据库里获取此时的version版本号 select version from tablename where xxx 更新数据时首先和版本号作对比,如果不相等说明已经有其他的请求去更新数据了,提示更新失败。 update tablename set count=count+1,version=version+1 where version=#{version} 悲观锁 乐观锁可以实现的往往用悲观锁也能实现

最简单的 K8S 部署文件编写姿势,没有之一!

折月煮酒 提交于 2020-12-14 01:13:24
1. 头疼编写K8S部署文件? K8S yaml 参数很多,需要边写边查? 保留回滚版本数怎么设? 如何探测启动成功,如何探活? 如何分配和限制资源? 如何设置时区?否则打印日志是GMT标准时间 如何暴露服务供其它服务调用? 如何根据CPU和内存使用率来配置水平伸缩? 首先,你需要知道有这些知识点,其次要把这些知识点都搞明白也不容易,再次,每次编写依然容易出错! 2. 创建服务镜像 前一篇文章 讲解了如何快速创建自己的服务镜像,不过为了演示,这篇文章我们以 redis:6-alpine 镜像为例。 3. 完整K8S部署文件编写过程 首先安装 goctl 工具 GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/tal-tech/go-zero/tools/goctl 一键生成K8S部署文件 goctl kube deploy -name redis -namespace adhoc -image redis:6-alpine -o redis.yaml -port 6379 生成的 yaml 文件如下: apiVersion: apps/v1 kind: Deployment metadata: name: redis namespace: adhoc labels: app: redis