Redis缓存
Redis缓存由于Redis追求速度将数据存在缓存层中,就会有缓存异常的三个问题,分别是缓存雪崩、缓存击穿、缓存穿透。
此表格为下文的总结 :
缓存异常名称
引发原因
解决办法
缓存雪崩
针对大量数据(key)在同一时间失效
不同的失效时间/互斥锁/后台更新缓存
Redis宕机
Redis集群/限流
缓存击穿
热点数据失效
设置热点数据不过期或长过期时间/缓存预热/互斥锁
缓存穿透
大量Key不存在缓存与数据库中
参数校验/缓存无效Key/布隆工作器
缓存雪崩缓存雪崩指的是缓存在同一时间大面积的失效,导致大量的请求都直接落到了数据库上,对数据库造成了巨大的压力。
缓存在同一时间内大面积失效的情景 : 大量数据(key)在同一时间失效 或 Redis宕机。
解决办法针对大量数据(key)在同一时间失效:
设置不同的失效时间:可以给失效时间加上一个随机数。
互斥锁;当业务线程在处理用户请求时,如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一时间内只有一个请求来构建缓存(从数 ...
miniSpring开发(5)-解决Bean依赖
Bean之间的依赖在注入属性值的时候,如果这个属性本身是一个对象怎么办呢?这就是 Bean 之间的依赖问题了。
在spring中如何处理? 引入ref标签
参考以下代码:在bean baseservice中,有 ref="basebaseservice",代表其希望此处注入的是一个 Bean 而不是一个简单的值。所以在对应的 AServiceImpl 里,也得有类型为 BaseService 的域 ref1。
12345678910111213141516<?xml version="1.0" encoding="UTF-8" ?><beans> <bean id="basebaseservice" class="com.minis.test.BaseBaseService"> <property type="com.minis.test.AServiceImpl" name="as" ...
Redis高可用
Redis高可用Redis的高可用性是指在系统中使用Redis作为数据存储组件时,通过一系列的技术和架构设计,确保系统在面对硬件故障、网络问题或其他不可预测的情况下仍能够持续提供稳定的服务和数据可访问性。
在传统的单节点Redis部署中,如果该节点出现故障,整个系统的可用性会受到影响。为了提高Redis的可用性,通常采取以下一些方法:
主从复制(Master-Slave Replication): 在这种模式下,有一个主节点(Master)和多个从节点(Slaves)。主节点负责处理写操作,而从节点复制主节点的数据,处理读操作。如果主节点发生故障,可以将一个从节点升级为新的主节点,从而实现快速切换和恢复。
哨兵模式(Sentinel): 哨兵是一种监控和管理Redis集群的系统。它可以监测主节点和从节点的健康状况,当主节点不可用时,自动选择一个健康的从节点提升为新的主节点,以确保系统的持续可用性。
集群模式(Cluster): Redis集群模式将数据分散存储在多个节点上,每个节点负责管理部分数据。这种方式可以提供更高的可用性和横向扩展能力,但需要应用程序进行适当的分片和管理。
持久 ...
Redis内存管理
Redis内存管理Redis的内存管理中,有两个主要的策略:过期删除策略和内存淘汰策略。
过期删除策略过期删除策略指的是可以对 key 设置一个过期时间,并将已过期的键值对删除。
一般来说,Redis中的数据都会有一个过期时间。设置过期时间有这两个好处 :
因为内存是有限的,如果没有过期时间,很容易占满内存。
对于短信验证码之类有时效性的数据,如果放在数据库中就需要自己判断是否过期,这样不但麻烦而且性能较低。
设置过期时间的方法:
字符串类型:setex <key> <time> <valule> (setex == set + expire ,添加了键值对并且设置过期时间)
其他类型: expire <key> <time>
查看剩余过期时间的方法: ttl <key> 、 取消过期剩余时间的方法: persist <key>
Redis如何判断过期?Redis 通过一个叫做过期字典(可以看作是 hash 表)来保存数据过期的时间。
过期字典的键指向 Redis 数据 ...
Redis持久化
Redis持久化官方文档地址:https://redis.io/topics/persistence
Redis 的读写操作都是在内存中,所以 Redis 性能才会高。那么在内存中带来的问题就是重启后会数据丢失,Redis如何实现持久化功能的呢?
注意共有三种数据持久化的方式:
AOF 日志:(append-only file,只追加文件)每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里;
RDB 快照(snapshotting,快照):将某一时刻的内存数据,以二进制的方式写入磁盘;
AOF 和 RBD混合持久化方式
AOF日志AOF 日志文件其实就是普通的文本,将每一次的写操作命令都记录到该文本中,就是AOF日志。
值得注意的是,AOF日志是先执行完命令再记录日志。
这样的好处是:
避免额外的检查开销,AOF 记录日志不会对命令进行语法检查;
在命令执行完之后再记录,不会阻塞当前的命令执行。
这样也带来了风险:
如果刚执行完命令 Redis 就宕机会导致对应的修改丢失;
可能会阻塞后续其他命令的执行(AOF 记录日志是在 Redis 主线程中进行的)。
基本的 ...
(FEND)A Future Enhanced Distribution-Aware Contrastive Learning Framework for Long-tail Trajectory Prediction
[Title]FEND: A Future Enhanced Distribution-Aware Contrastive Learning Framework for Long-tail Trajectory Prediction(CVPR2023)摘要
困难 : trajectory prediction suffers from data imbalance in the prevalent datasets, and the tailed data is often more complicated and safety-critical.
本文目标 : we focus on dealing with the long-tail phenomenon in trajectory prediction.
前人不足 : Previous methods dealing with long-tail data did not take into account the variety of motion patterns in the tailed data.
本文特色 :
I ...
Java自定义注解
本篇文章的主要内容关于Java自定义注解。
什么是注解Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法。
Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的 Annotion对象,然后通过 Annotion对象来获取注解里面的元数据。
元注解Java元注解是用于定义和处理其他注解的特殊注解。元注解本身并不直接应用于代码的元素(类、方法、字段等),而是用于修改或解释其他注解。Java中有四个标准的元注解,它们可以用于自定义注解,并对注解的行为进行控制:
@Retention: 用于指定注解的保留策略,即注解在何时可见。它有以下三个策略:
RetentionPolicy.SOURCE: 注解仅保留在源代码中,编译后不会包含在class文件中。
RetentionPolicy.CLASS: 注解保留在class文件中,但在运行时不可访问。
RetentionPolicy.RUNTIME: 注解保留在class文件中,并在运行时可通过反射访问。
@Target: 用于指定注解可以应用的目标元素 ...
miniSpring(4)-实现DI
在前面主要是实现了Bean的拓展,如图。
接下来要做的事情是实现依赖注入。
回顾DI首先,我们要定义在 XML 配置文件中使用 setter 注入和构造器注入的配置方式。
Setter 注入是提供了一个 setter 方法,调用 setXXX() 来注入值。
constructor 就是在构造器 / 构造函数里传入参数来进行注入。
先看一下在Spring中如何实现的依赖注入 :
setter注入 :配置bean时为属性赋值,property标签
1234567<bean id="studentOne" class="com.atguigu.spring.bean.Student"> <!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 --> <!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关)--> <!-- value属性:指定属性值 --> <property n ...
线程与进程(待补充)
进程进程定义 :进程是一个正在执行的程序。进程是程序在一个数据集合上的运行过程,它是系统进行资源分配和调度的一个独立单位。 进程和程序相关联,但是是两个截然不同的概念。比如正在打开的高德地图就是一个进程,但高德地图不是进程。
进程与程序的区别?
程序是代码编译后的静态文件
进程是正在运行的动态实例
进程有五个基本特征:
动态性。有生命期。
并发性。多个进程实体同存于内存,能并发执行(注意和并行的区别)。
独立性。具备申请系统资源的独立单位。
异步性。进程以各自独立、不可预知的速度向前推进。
结构特性。为描述进程的运动变化过程,每个进程都由程序段、数据段和一个进程控制块(PCB)三部分组成
进程的状态进程活动状态 :
运行状态。该时刻进程占用 CPU;
就绪状态。进程已处于准备运行状态,由于其他进程处于运行状态而暂时停止运行,即进程获得了除了处理器之外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)即可运行
阻塞状态。又称为等待状态,进程正在等待某一事件而暂停运行如等待某资源为可用或等待 IO 操作完成,(如等待输入/输出操作的完成)而暂时停止运行,这时,即 ...
miniSpring(3)-拓展BeanDefinition
前面通过定义一个单例接口的实现类,并让classpathxmlApplication继承这个类,从而实现了单例bean,具体如图 :
下面要干两件事 :
增加事件监听。虽然这里没有用到,但是预留了事件监听的接口,方便后续进一步解耦代码逻辑。
扩展 BeanDefinition。扩展 BeanDefinition,添加一些属性,现在它只有 id 和 class 两个属性,我们要进一步地丰富它。
给BeanFactory 新增接口。这里新增的接口对应步骤2中新增的属性。
增加事件监听为了监控容器的启动状态,我们要增加事件监听。事件监听使用ApplicationEvent,事件发布使用ApplicationEventPublisher。这两个都写在context目录下。
ApplicationEvent:定义一个事件监听类,继承Java事件模型 EventObject,在 Java 的事件监听的基础上进行了简单的封装。虽然目前还没有任何实现,但这为我们后续使用观察者模式解耦代码提供了入口。
1234567public class ApplicationEvent extends E ...