中间件复习之-消息队列

news2024/11/25 23:34:56

消息队列在分布式架构的作用

消息队列:在消息的传输过程中保存消息的容器,生产者和消费者不直接通讯,依靠队列保证消息的可靠性,避免了系统间的相互影响。
主要作用:

  • 业务解耦
  • 异步调用
  • 流量削峰

业务解耦

将模块间的 RPC调用改为通过消息队列中转,解除系统间的耦合。

  • 提升系统稳定性(自身模块不受其他模块影响)
  • 通过广播消息避免多次调用(调用下游多次改为下游自己订阅,自己只发一次消息通知)
  • 提高编码效率(不用关注下游代码更改)
    在这里插入图片描述

异步调用

对于无需关注调用结果的场景,可以通过消息队列异步处理。
下单链路的通知卖家以及数据记录都可以改为异步流程,不影响主流程。
下单处理原逻辑:风控拦截->扣减库存->通知卖家->记录数据
下单优化后流程:风控拦截->扣减库存->消息异步通知卖家->消息异步记录数据
在这里插入图片描述
在这里插入图片描述

流量削峰

系统的吞吐量往往取决于底层存储服务的处理能力,数据访问层可以调整消费速度缓解存储服务压力,避免短暂的高峰将系统压垮。
在这里插入图片描述

主流消息队列选型对比

  • Kafka:系统间的数据流通道
  • RocketMQ:高性能可靠消息传输
  • RabbitMQ:可靠消息传输
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

RocketMQ深入剖析

RocketMQ功能特性

  • 支持事务型消息
  • 支持延时消息
  • 支持消息重发
  • 支持consumer端tag过滤
  • 支持消息回放

RocketMQ拓扑图

  • NameServer: 类似注册中心的定位。他们之间完全独立,互相没有交互。所有的broker把自己的信息注册到所有的NameServer上(IP、key-cluser-value-[brokers]、key-broker-value-主从节点、key-topic-value-[brokers],可以后面把这个结构debug一下放到这里todo)。
  • Broker:用于消息存储
  • Producer:生产者,投递消息到broker上。从NameServer做服务发现。
  • Consumer:消费者,从broker上消费消息。从NameServer做服务发现。
    在这里插入图片描述

RocketMQ架构

  • Broker主从部署,自身注册信息在NameServer中
  • Client(Producer、Consumer)从NameServer中获取Broker信息
  • NameServer节点相对独立,无数据交互
    在这里插入图片描述

RocketMQ消息存储

在这里插入图片描述

  • CommitLog:存储消息主体
    • 所有topic的消息都写在CommitLog文件中
    • 顺序写、随机读,当某几个topic的消费速度比较快的时候数据就相对比较离散,怎么去优化?
  • ConsumeQueue:消息消费队列
    • dispatch线程将CommitLog里的消息按主题-topic分发到ConsumeQueue队列里(ConsumeQueue也是物理文件,一个topic可能对应多个ConsumeQueue队列,注1:这里的负载均衡是Producer做的,每个消息都会带上要存储的队列序号。注2:这里只存储commitLog的偏移量-commitLogOffset和大小msgSize,实际消费时还是去CommitLog里拿
    • maxOffset:下次消息往这里写。
    • cusomerOffset:消费者当前消费到的位置。
    • minOffset:rocketMQ使用这个字段保证消息不丢。consumer消费每次会拉一批数据,拉完之后就会更新cusomerOffset,但是minOffset到cusomerOffset之间还存在没消费完的。当consumer成功把所有拉去的数据消费完之后,会给broker发一个ack,此时minOffset才会移动到上次拉走数据的位置。这样能保证拉走的数据都能成功消费完。比如consumer拉了10条数据,但是只消费了9条,然后cosumer端服务挂了重启之后就会从minOffset再去拉数据。
  • IndexFile:消息索引文件

优化手段

RocketMQ应对CommitLog随机读顺序写的性能优化

  • CommitLog切分,默认1G
  • MMap提升文件访问性能
  • 磁盘升级SSD

消息存储流程

broker消息接收入口
  • 获取主题信息
  • 获取队列信息
  • 延时消息,事务消息处理
    在这里插入图片描述
CommitLog写入
  • 获取CommitLog文件
    • 判断CommitLog是不是满了,满了就获取一个新的CommitLog(对应代码mapedFile)
  • 追加写入
    • 写入不成功则创建新文件
  • 刷盘
  • 复制
    在这里插入图片描述
Dispatch消息分发
  • 获取消息类型,如延时消息、事务消息
  • 普通消息则获取消息信息
    • topic、队列id、大小等
  • 通过主题和队列id找到队列
  • 往队列里写值
    在这里插入图片描述

特性分析

  • 可靠性分析
  • 可用性分析
  • 生产、消费方式
  • 负载均衡

可靠性分析

可靠性的问题主要是存的数据会不会丢? 按需配置

单机情况下的优化
  • 同步刷盘
    • 性能低,可靠性高
  • 异步刷盘
    • 性能高,可靠性低
      在这里插入图片描述
集群下的优化

这里主要是主从之间的数据同步

  • 异步复制
    • 生产者发送消息至master后,master就会反馈给生产者消息发送成功。master会单独开启一个线程,将数据copy到slave中。这样造成的风险就是如果master挂了,而数据还没有copy到slave节点,就会造成数据的丢失。
  • 同步双写
    • 生产者发送消息至master节点后,master节点copy数据到slave节点。当copy成功时,master节点才会告诉生产者,消息发送成功。这样保证了数据的备份,但是会影响性能。为了高可用,还是要选择这种模式,因为选用异步模式,根本没解决多master模式所造成的问题。

最可靠的方式就是 同步刷盘+同步双写。一般情况下用异步刷盘、异步复制就够了。

可用性分析

这里需要引入RocketMQ集群架构
公司目前使用rocketMQ,raft协议Dledger搭建集群。
RocketMQ Dledger高可用集群的Leader消息写入是同步刷盘的方式。在Dledger中,当Leader节点收到消息后,会首先将消息写入本地磁盘并进行同步刷盘,以保证数据的可靠性和一致性。只有当消息被成功写入本地磁盘后,Leader节点才会将消息发送给Follower节点进行复制。
而在Dledger中,Leader和Follower之间的同步是异步复制的方式。当Leader节点将消息写入本地磁盘并进行同步刷盘后,会异步地将消息发送给Follower节点进行复制。这样可以提高消息发送的性能和吞吐量。

普通集群:

  • Master
    • 主节点,可以进行读和写操作。
  • Slave
    • 从节点,只可以读,不进行写操作。

也就是 Producer 只能和 Master 角色的 Broker 连接写入消息;Consumer 可以连接 Master 角色的 Broker,也可以连接 Slave 角色的 Broker 来读取消息。

Master 和 Slave 的区别:在 Broker 的配置文件中,参数 brokerId 的值为 0 表明这个 Broker 是 Master,大于 0 表明这个 Broker 是 Slave,同时 brokerRole 参数也会说明这个 Broker 是 Master 还是 Slave。

  • 主从模式Master宕机
    • Broker可读不可写
  • 集群搭建方式
    • 单Master模式(线上一般不考虑)
    • 多Master模式
      • 优点:多master集群,一个topic在每个master中都有,相当于对topic进行了横向扩展。当有很多生产者往topic中发送消息时,可以负载到多个master节点上,提高写入数据的效率。
      • 缺点:如果某个master宕机,则这个master上的数据将不可用。根本原因还是没有对master上的数据进行主从备份的原因。多个master节点各自存着自己的数据,不会相互备份。如当主1挂了、主2还在时,主2还可以投递,但是主1没消费完的消息就丢失了,直到主1恢复以后才能继续消费。
  • 多Master模式多Slave模式-异步复制
  • 多Master模式多Slave模式-同步双写
RcoketMQ普通集群与Dledger高可用集群

普通集群:
这种集群模式下会给每个节点分配一个固定的角色,master负责响应客户端的请求,并存储消息。slave则只负责对master的消息进行同步保存,并响应部分客户端的读请求。消息同步方式分为同步同步和异步同步。这种集群模式下各个节点的角色无法进行切换,也就是说,master节点挂了,这一组Broker就不可用了。

Dledger高可用集群:
Dledger是RocketMQ自4.5版本引入的实现高可用集群的一项技术。这个模式下的集群会随机选出一个节点作为master,而当master节点挂了后,会从slave中自动选出一个节点升级成为master。Dledger技术做的事情:

  1. 接管Broker的CommitLog消息存储,普通集群是由broker自己去写CommitLog消息存储,现在是由Dledger去写CommitLog消息存盘
  2. 从集群中选举出master节点,Dledger最主要的功能
  3. 完成master节点往slave节点的消息同步

Dledger是怎样进行leader选举的呢?
在探究这个问题之前,我们先要明确一件事情,Dledger使RocketMQ集群的每个节点都有三个状态:

  1. **Leader 主节点:**主要用于接收客户端请求
  2. **Follower 从节点 :**主要用于Leader节点的数据备份,当有客户端请求到Follower时,Follower节点会把请求转到Leader节点
  3. **Candidate 候选者节点:**只有Candidate状态的节点才会参与主节点的选举。

原文链接:https://blog.csdn.net/qq_45076180/article/details/113775278

生产方式

  • 同步(sync)
    • 投递完后等待MQ回ACK 生产者一般都用同步的方式去发消息
  • 异步(async)
    • 投递过去后不关注结果
  • 单向(oneway)
    • 投递过去MQ不用回包

消息消费

消息消费一般分Pull和Push的两种消费方式,两种方式都有各自的特点,同时也会带来不同的影响。

  • PUSH
    • 消息队列主动地将消息推送给消费者。
    • 优点:消息实时性高。
    • 缺点:没有考虑到客户端的消费能力,导致客户端消息堆积。
  • PULL
    • 由消费者客户端主动向消息队列拉取消息。
    • 优点:客户端按消费能力拉取消息。
    • 缺点:消息实时性低,可能造成大量无效请求。
RocketMQ消费模式

RocketMQ的消费方式基于拉模式,但是使用了一种长轮询机制,来平衡上面Push/Pull模型的各自缺点。

  • LongPoll
    • Consumer发送拉取消息
    • Broker hold住请求,直到有新消息再返回(类似一个push的动作)
    • 请求超时,Consumer再次发起请求
    • 请求超时时间默认30s
消息消费方式
  • 集群消费
    • 集群内竞争消费,单条消息只消费一次
  • 广播消费
    • 各集群消费全量消息,单条消息在每个集群都会被消费一次
    • 集群内广播消费
      • 集群内每个消费者消费一次消息
    • 大部分场景下都是集群内竞争,集群间广播

负载均衡

  • Producer端负载均衡
  • Consumer端负载均衡
Producer端负载均衡
  • 定时获取Queue信息
    • 从NameServer定时获取队列信息
  • 负载均衡算法:随机递增取模(轮询)
    • 按照队列数量轮询分发
  • 容错机制:故障延迟
    • eg.500ms发送超时,下次发送到这个队列的延迟改为1s。
Consumer端负载均衡
  • 客户端定时上报数据
    • 服务端知道有多少的客户端
  • 定时Rebalance 20S
    • 获取队列信息
    • 获取消费者信息
    • 排序平均分配(按照获得的信息平均分配)在这里插入图片描述
    • 与上次结果对比(左边是本次计算出的队列,entity1、entity2是上次负载均衡计算的结果,需要去除。entity3、entity4是上次就在的,entity5、entity6是本次新分配的)在这里插入图片描述

消息消费失败

消费失败策略

  • 默认重试16次
    • 失败后消息重新投递到重试队列
  • 重试时间间隔递增
  • 失败进入死信队列
    实现原理
  • 自动创建失败消息主题
  • 客户端默认订阅
  • 结合延时消息实现重试间隔 支持18种延时,先进入延时队列,再进入重试队列。默认的一个topic重试队列只有一个,导致只有一个consumer能消费。

RocketMQ高级功能

  • 事务消息
  • 延时消息

事务消息

业务场景分析:

  • 用户下单
    • 创建订单 + 减库存
  • 发布或更新商品信息
    • 写商品库 + 更新外置索引
分布式事务
  • 强一致
  • 柔性事务
  • 事务消息
强一致性协议
  • 一致性协议
    • 两阶段提交 2PC在这里插入图片描述

      • 事务协调者:程序
      • 事务参与者A:数据库A
      • 事务参与者B:数据库B
      • 缺陷:第一阶段没问题,第二阶段假如只commit了事务参与者A,发完后事务协调者挂了,则B未提交。
    • 三阶段提交 3PC在这里插入图片描述

      • 将第二阶段拆成两段,第二阶段对齐事务状态,所有事务参与者在此刻都知道事务可以提交了。
      • 第三阶段参与者等待事务协调者触发,若事务协调者挂了未执行触发。则指定一个超时时间,超过超时时间未触发则事务参与者自动提交。
  • 落地规范
    • XA规范(很少使用,性能衰减严重
      • 资源管理器 - 事务参与者
        • 写入加锁
      • 事务管理器 - 事务协调者
        • 本地记录事务执行状态
柔性事务(最终一致性方案)
  • TCC (Try-Confirm-Cancel)

    • 尝试执行业务,预留资源
    • 确认执行业务,使用Try阶段资源
    • 取消执行业务,释放Try阶段预留的资源
    • TCC成功处理流程在这里插入图片描述
    • TCC失败处理流程在这里插入图片描述
    • 缺点:逻辑全部由开发处理。非常复杂
  • SAGA 模型

    • 一个分布式事务拆分为多个本地事务;
    • 本地事务都有相应的执行模块(commit事务)和补偿模块(对补偿模块做逆操作);
    • 事务管理器负责在事务失败时调度执行补偿逻辑;
事务消息
  • 简化了分布式事务模型
    • 两次RPC调用 -> 一次RPC + 一次事务消息。只保证落DB + 消息发送的事务。
  • 对业务友好
RocketMQ事务消息机制

两阶段提交:

  • 发送半消息
    • 投递到MQ里不会被消费,发送完后MQ返回半消息发送成功通知。
  • 执行本地事务
    • 写db等操作
  • 发送Commit/Rollback
  • 提供回查接口(业务侧提供,缺点就是侵入业务)
    • 如果MQ-server很久都没有接收到业务系统发送commit或者rollback的消息的话,MQ-Server就会做半消息的回查,查业务系统来获取这个Message是该提交还是该Rollback。
      在这里插入图片描述
RocketMQ事务消息原理

半消息主题(Topic)

  • HALF消息:RMQ_SYS_TRANS_HALF_TOPIC(临时存放消息信息)
    • MQ会有一个HALF消息的topic:RMQ_SYS_TRANS_HALF_TOPIC(临时存放消息信息)
    • 在发送消息的时候用半消息的主题替换原主题去做投递,保存原主题和队列信息(数据投递到半消息队列中)
    • 半消息对Consumer不可见,不会被投递
  • OP消息:RMQ_SYS_TRANS_OP_HALF_TOPIC(记录二阶段操作)
    • Rollback:只做记录
    • Commit:根据备份信息重新构造消息并投递
  • 回查
  • 对比HALF消息和OP消息进行回查
    在这里插入图片描述

延时消息

延迟需求:由业务场景或现实情况决定,需要在当前时候之后某一时间触发指定的业务逻辑或操作。
业务场景分析

  • 即时通讯消息重发
    • IM系统为了确保消息触达接收方,消息发出几秒后没有收到ack,需要重发 消息。
  • 订单状态流转
    • 取消规定时间内未付款的订单。商家发货后,长时间未确认的订单自动确认收货。
RocketMQ延时消息

RocketMQ支持18个级别的延时等级,默认值为“1s5s10s30s1m2m3m4m5m6m7m8m9m10m20m30m1h2h”,生产者发消息时通过设置delayLevel选择

客户端调用
  • 消息体里设置延时属性,值为延时的级别
public void setDelayTimeLevel(intlevel{
	this.putProperty(MessageConst.PROPERTY_DELAY_TIME_LEVEL,String.valueOf(level));
}
实现原理
  • 缓存缓存消息
    • 替换主题SCHEDULE_TOPIC_XXX,根据延时级别放入对应的队列
  • 18个Queue对应18个延时级别
  • 每个队列创建定时任务进行调度
  • 恢复到期消息重新投递到真实的Topic(Delay queue投递到CommitLog)
    在这里插入图片描述
代码分析
  • 替换主题代码
    • 替换主题
    • 根据延时级别放到对应的延时队列中去
      在这里插入图片描述
特点
  • 不支持任意时间延时
  • Broker配置中指定,只支持18个level
  • 不灵活、配置调整需要重启

消息队列拓展功能实现

RocketMQ可扩展功能:

  • 事务消息
    • 业务侵入大
  • 延时消息
    • 支持场景有限

事务消息

  • 通过客户端实现
  • 事务消息表记录发消息事件
    • 数据库每个实例里面都创建一个事务消息表
  • 本地事务保证业务数据与写消息表原子性
  • 事务管理器维护事务消息表
    • 扫库发送、清理
      在这里插入图片描述
      5 - 消息投递成功了,删除消息记录
客户使用示例
  • 本地数据库写入
  • 事务消息客户端发送消息(把落db和发送消息都封装起来)
  • con.getAutoCommit代表本次有没有开启事务。
    在这里插入图片描述
MybatisransactionMsgClient类设计
  • 获取数据库连接
  • 调用sendMsg
    在这里插入图片描述
事务消息客户端实现
  • 消息内容落库

    • con.getAutoCommit代表本次有没有开启事务
  • 发送消息(消息放到队列)
    在这里插入图片描述

  • 后台发送队列设计

    • 发送失败将消息放到优先级队列里
      在这里插入图片描述
  • 发送消息后台任务

    • 因为事务还没处理完队列里就已经有消息了
      在这里插入图片描述
  • 若事务还没提交,则可以将消息放到重试队列。

  • 若消息发送成功,修改数据库状态
    在这里插入图片描述

  • 后台优先队列维护

    • 从队列中取出数据,判断是否到期,到期则重新放入待发送队列
      在这里插入图片描述
  • 事务消息表设计

    • status 是否已投递出去
      在这里插入图片描述

延时消息

时间轮算法

时间轮算法:可以用于高效的执行大量的定时任务,实现简单并且有非常高的精度。

  • 基本概念
    • 事件:可以认为是一个个定时任务,比如下单未支付事件。
    • 桶:每个数组元素可以认为是一个桶,桶内的链表为一个个事件(桶里的事件的特点是同一时刻到期、触发)
    • 游标:指到哪个桶,那这个桶里的事件就要触发了
    • 时间精度:游标移动的速度,1s移动一次,表示支持秒级别的触发。1分钟移动一次,表示支持分钟级别的触发。
    • 循环数组
  • 数据结构
    • 数组+链表
      在这里插入图片描述
长时间跨度问题

如果要支持高精度调度,15天的长度,那数组空间的占用就会非常大!

  • 使用文件+内存的方式处理
    磁盘文件的内容按时间倒序,每个文件存储半小时。若过来一个请求,在当前半小时内的,直接将半小时内的这条数据落在redis,如果在半小时之外的,则落到磁盘文件中。然后每经过半小时时间(提前个5分钟),将文件中的内容读取到redis内存中。
    在这里插入图片描述
延时消息服务端设计
  • Dispatch改造
  • 延时消息存储
    • 使用内存+文件替代RocketMQ原来的18个队列
  • 内存索引(时间轮)
  • 延时消息投递
    在这里插入图片描述
Dispatch改造
  • 拓展消息类型
  • 根据类型标记判断延时消息
  • 根据时间分发到ScheduleLog或内存时间轮
    在这里插入图片描述
延时消息存储设计(ScheduleLog)

存放延时消息的一组文件,将延时消息按到期时间划分,以半小时为一个区间,存放到指定的ScheduleLog文件中。

  • 文件命名:时间 + 偏移量(将文件切分,因为每个时间周期内的ScheduleLog文件大小太不固定了,因此按128M将文件做多个切分,该时段内的时间都一样,偏移量按文件顺序排序)
    • 202002171430(时间)+ 000000000
  • 文件大小:默认128M
  • 存储内容
    • 消息体 OR 消息索引(offset + length)

存储内容是按消息体存还是消息索引存??

  • 消息索引
    • 优点:节省空间
    • 缺点:
      • 随机读
      • CommitLog里的历史文件(15天前)无法删除,而且这15天前的commitLog还得加载到内存里。
        在这里插入图片描述
  • 消息体
    • 消息存两份
    • 避免随机读
      在这里插入图片描述

结论:空间目前不是瓶颈,性能是瓶颈,因此按消息体存储。

ScheduleLog文件管理
  • 大文件切分
    • 一对多
  • 文件命名规则
    • 时间 + 偏移量
      在这里插入图片描述
      一个逻辑上的ScheduleLog文件由多个小文件组成。
      在这里插入图片描述
代码实现
  • DelayLogManager
    • Key:所代表时间;Value:ScheduleLog
      在这里插入图片描述
  • DelayLog
    • 管理一个区间内所有文件
  • mapedFIles(Key:启始偏移量;Value:文件内容
    • 文件名到内存文件映射
      在这里插入图片描述
  • ScheduleLog文件写入
    • 判读是否需要新建文件
      • 根据要写的数据长度来判断
      • 按照DelayLog整体文件维度偏移量与128M大小(mapedFileSize)取余得到当前偏移量
      • 当前偏移量 + 数据大小 + 结束标识长度是否大于mapedFileSize
    • 定位要写入的文件
    • 数据写入
      在这里插入图片描述
      在这里插入图片描述
内存时间轮

TimeWheel: 内存时间轮,其中保存的是30分钟内到期的延时消息索引

  • TimeWheel类

    • 使用Map(Key 消息到期时间,Value 相同时间的消息队列) + Queue
    • addToWheel(DelayMsgIndex delayMsgIndex)
      • 从ScheduleLog中装载数据进时间轮
    • getQueue(long delayEndSecond)
      • 拿到当前到期的队列
    • remove(long delayEndSecond)
      • 投递完之后清空队列
        在这里插入图片描述
  • 时间轮写入在这里插入图片描述

  • 数据装载(非实时写入)

    • 获取当前ScheduleLog
      • 根据时间从delayLog中取出下一个要到期的文件
    • 逐条装载消息索引信息
      • 迭代器逐条读取信息生成索引信息
    • 将索引信息装载到时间轮内
      在这里插入图片描述
  • 实时写入

    • 在当前时段内的消息需要同时写入时间轮
      在这里插入图片描述
  • 到期投递

    • 获取当前ScheduleLog
    • 逐条装载消息索引信息
      在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1717875.html

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

相关文章

线上 | OpenSergo - [规范]

INDEX 1 参考资料2 OpenSergo 与 Sentinel 关系3 规范体系3.1 服务元数据ReportMetadataRequest 信息![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ffba569841ae4668b4cff74e4d41d21f.png)##### ReportMetadataReply 信息![在这里插入图片描述](https://img-blog…

链表相交00

题目链接 链表相交 题目描述 注意点 题目数据保证整个链式结构中不存在环函数返回结果后,链表必须保持其原始结构设计一个时间复杂度 O(n) 、仅用 O(1) 内存的解决方案 解答思路 双指针分别指向headA和headB,当遍历完某个链表后,将指针指…

【面结构光三维重建】0.基于openCV实现相机的标定

1.标定结果 2.相机标定原理 相机标定是计算机视觉和机器视觉领域中的重要技术,用于确定相机成像的几何关系和畸变特性,以提高成像的精度和稳定性。该技术广泛应用于三维重建、机器人视觉、自动驾驶等领域。 世界坐标系:由用户定义的三维世界坐标系,描述物体和相机在真实世…

生产现场的作业标准化,这么做就对了!

制造型企业的生产过程是以计划的成本、工时生产出达到客户要求的产品。如果在制造过程中,产品工艺、作业方法或作业条件有所变化的话,一定无法生产出符合上述要求的产品。 因此,公司领导必须对作业工艺流程、作业方法、作业条件进行标准化管…

无缝接入GPT-4o:智创聚合API平台的创新与实践

在2024年5月13日,美国开放人工智能研究中心(OpenAI)发布了最新版本的ChatGPT——GPT-4o。这一更新标志着人工智能领域的又一重大进步,引起了全球科技界的广泛关注。GPT-4o的“o”代表“omni”(全能)&#x…

ARM-V9 RME(Realm Management Extension)系统架构之系统能力的设备隔离和保护

安全之安全(security)博客目录导读 目录 三、设备隔离和保护 1、外设隔离 2、非pe请求者(设备) 3、可编程完成端过滤器Programmable completer-side filters 4、RME设备分配 4.1 设备权限表 本博客探讨 RME 所需系统能力的设备隔离和保护,以保证 Arm CCA 对于…

辅导男朋友转算法岗的第2天|self Attention与kv cache

文章目录 公式KV CacheMHA、MQA、GQA 面试题为什么除以 d k \sqrt{d_k} dk​ ​Multihead的好处decoder-only模型在训练阶段和推理阶段的input有什么不同?手撕必背-多头注意力 公式 $ \text{Output} \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) \times …

SG7050EEN差分晶体振荡器:为5G路由器提供卓越的时钟源

随着5G技术的快速发展,5G路由器作为连接高速网络的重要设备,正迅速普及。为了确保5G路由器在高宽带和低延迟的网络环境中表现出色,选择一款高性能的晶体振荡器至关重要。爱普生推出的SG7050EEN差分晶体振荡器,以其高精度、低相位噪…

K210视觉识别模块学习笔记2:固件的下载升级_官方数字识别例程导入方法

今日开始学习K210视觉识别模块:固件的下载升级_官方数字识别例程导入方法 主要学习如何升级固件库,在哪下载固件库,以及如何在TF卡正确导入官方例程: 亚博智能的K210视觉识别模块...... 本次最终目的是正确导入官方的数字识别例程&#xff0…

Python 之SQLAlchemy使用详细说明

目录 1、SQLAlchemy 1.1、ORM概述 1.2、SQLAlchemy概述 1.3、SQLAlchemy的组成部分 1.4、SQLAlchemy的使用 1.4.1、安装 1.4.2、创建数据库连接 1.4.3、执行原生SQL语句 1.4.4、映射已存在的表 1.4.5、创建表 1.4.5.1、创建表的两种方式 1、使用 Table 类直接创建表…

小程序使用Canvas设置文字竖向排列

在需要使用的js页面引入js文件,传入对应参数即可 /** * 文本竖向排列 */ function drawTextVertical(context, text, x, y) {var arrText text.split();var arrWidth arrText.map(function (letter) {return 26; // 字体间距,需要自定义可以自己加参数,根据传入参数进行…

飞凌嵌入式FET3568/3568J-C核心板现已适配OpenHarmony4.1

近日,飞凌嵌入式为FET3568/3568J-C核心板适配了OpenHarmony4.1系统,新系统的加持使核心板在兼容性、稳定性与安全性等方面都得到进一步提升,不仅为FET3568/3568J-C核心板赋予了更强大的功能,也为开发者们提供了更加广阔的创新空间…

WordPress中借助Table of Contents Plus+Widget Options插件,实现仅在文章侧边栏显示文章目录的功能

本文转自博主的个人博客:https://blog.zhumengmeng.work,欢迎大家前往查看。 原文链接:点我访问 序言:今天心血来潮,写了一篇文章,忽然发现自己的文章极少有目录,这对于长文章的阅读来说是十分不利的&#…

vivado 时序约束

时间限制 以下ISE设计套件时序约束可以表示为XDC时序约束 Vivado设计套件。每个约束描述都包含一个UCF示例和 等效的XDC示例。 在未直接连接到边界的网络上创建时钟时,UCF和XDC不同 的设计(如端口)。在XDC中,当在上定义带有create…

微信小程序发送订阅消息

小程序后台。订阅消息里面,新建一个消息模板 小程序代码,登录后,弹出订阅信息 requestSubscribeMessage: function () {wx.requestSubscribeMessage({tmplIds: [-323232-32323], // 替换为你的模板IDsuccess(res) {// 用户订阅结果console.l…

【康耐视国产案例】Nvidia/算能+智能AI相机:用AI驱动 | 降低电动车成本的未来之路

受环保观念影响、政府激励措施推动与新能源技术的发展,消费者对电动汽车(EV)的需求正在不断增长,电动汽车已经成为了未来出行方式的重要组成部分。然而,电动汽车大规模取代燃油汽车的道路还很漫长。最大的障碍就是电动汽车的售价相对过高。尽…

day2数据结构

双链表的插入 循环链表,判断循环链表是否为空 指向的是自己 仅设表尾指针的循环链表合并 代码举例 删除线性表的最小值,并由函数返回删除的值,空的位置,由最后一个元素填补,若表为空显示出错信息 &L 因为L会发生…

深入理解flask规则构建与动态变量应用

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、引言 二、Flask规则基础 1. 静态规则与动态规则 2. 规则语法与结构 三、动态变量应用…

AI作画算法原理

1.概述 AI作画算法的原理相当复杂,涉及多个领域的知识,包括计算机视觉、机器学习和神经网络等。我们从以下几个方面来描述AI作画算法的基本原理。 2. 数据准备 在数据准备方面,AI作画算法通常需要大量的图像数据作为训练样本。可以是各种各…

52-QSplitter类QDockWidget类

一 QSplitter类 Qt提供QSplitter(QSplitter)类来进行分裂布局&#xff0c;QSplitter派生于QFrame。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>class MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~…