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

Apache SeaTunnel 整体架构运行原理

概述

SeaTunnel 缘起

数据集成在现代企业的数据治理和决策支持中扮演着至关重要的角色。随着数据源的多样化和数据量的迅速增长及业务需求的快速变化,企业需要具备强大的数据集成能力来高效地处理数据。SeaTunnel通过其高度可扩展和灵活的架构,帮助企业快速实现多源数据的集成。

在现代数据生态中,AI的快速发展也对数据集成提出了新的要求。通过集成AI能力,SeaTunnel可以帮助企业在数据处理过程中进行智能分析、异常检测、数据质量评估及优化,从而进一步提升数据的质量和整体智能化水平。

在技术发展上,各种数据库、 湖仓、 向量、 SAAS、 非结构化、 对象存储等众多数据来源让传统的数据处理流程从ETL、ELT变为能更加快速满足业务需求和能够更加有效应对日益庞大数据量的EtLT架构,EtLT能更加敏捷应对离线/实时数据湖、数据仓库、AI模型训练当中的复杂多变的数据需求场景。

目标

本说明旨在为系统架构师、开发者、用户和运维人员提供SeaTunnel的技术架构介绍,以支持其在项目使用及优化中进行数据集成任务的开发和运维。

整体架构说明

SeaTunnel 主要由一套数据同步处理的 API 和核心计算引擎组成,包括三个主要的服务:CoordinatorService、TaskExecutionService 和 SlotService

CoordinatorService

CoordinatorService 是集群的 Master 服务,提供每个作业从 LogicalDag 到 ExecutionDag,再到 PhysicalDag 的生成流程,并且最终创建作业的 JobMaster 进行作业的调度执行和状态监控。

TaskExecutionService

TaskExecutionService 是集群的 Worker 服务,提供作业中每个 Task 的真正运行时环境,TaskExecutionService 使用 Dynamic Thread Sharing 技术降低 CPU 使用

SlotService

SlotService 在集群每个节点上都会运行,主要负责节点上资源的划分、申请和回收

SeaTunnel 模块说明

模块名介绍
seatunnel-apiSeaTunnel connector V2 API 模块
seatunnel-commonSeaTunnel 通用模块
seatunnel-connectors-v2SeaTunnel connector V2 模块, connector V2 处于社区重点开发中
seatunnel-core/seatunnel-spark-starterSeaTunnel connector V2 的 Spark 引擎核心启动模块
seatunnel-core/seatunnel-flink-starterSeaTunnel connector V2 的 Flink 引擎核心启动模块
seatunnel-core/seatunnel-starterSeaTunnel connector V2 的 SeaTunnel 引擎核心启动模块
seatunnel-e2eSeaTunnel 端到端测试模块
seatunnel-examplesSeaTunnel 本地案例模块, 开发者可以用来单元测试和集成测试
seatunnel-engineSeaTunnel 引擎模块, seatunnel-engine 是 SeaTunnel 社区新开发的计算引擎,用来实现数据同步
seatunnel-formatsSeaTunnel 格式化模块,用来提供格式化数据的能力
seatunnel-plugin-discoverySeaTunnel 插件发现模块,用来加载类路径中的SPI插件
seatunnel-transforms-v2SeaTunnel transform V2 模块, transform V2 处于社区重点开发中
seatunnel-translationSeaTunnel translation 模块, 用来适配Connector V2 和其他计算引擎, 例如Spark、Flink等
架构层次

数据集成产品的架构设计具有高度的模块化和可扩展性,基于SeaTunnel Zeta高性能集成引擎,可以支持数据批量和实时高效同步、批流一体等能力,SeaTunnel整体分为以下几个主要层次:

  • 数据源接入层(source):包括各种数据源的连接器和适配器。

SeaTunnel支持丰富的数据源(如数据库、消息队列、文件系统等等),通过其灵活的插件机制,可以高效采集来自各种来源的数据。

  • 数据转换层(transform):支持数据清洗和转换操作比如过滤数据、添加字段、自定义 SQL 等多种操作。同时,SeaTunnel 支持各种 AI 大模型来进行对数据的转换操作,包括异常数据处理、数据增强等等
  • 数据写入层(sink):多种数据仓库和数据库等目标数据源的输出,包括关系型数据库、NoSQL 数据库、分布式存储系统等。

可接入的数据源类型

  • 关系型数据库:支持 MySQL、PG、Oracle、DB2、SQLServer 等数十种数据库,采用并行提取策略优化大数据量场景下的同步性能。
  • NoSQL 数据库:如 MongoDB、Cassandra,支持以 JSON、BSON 等格式传输数据,保证高效的文档处理。
  • 文件系统:支持从本地文件系统、HDFS、Amazon S3 等读取结构化和半结构化数据,支持 CSV、JSON、Parquet等格式。
  • 消息队列:提供与 Kafka等消息系统 的原生集成,支持高并发下的流式数据消费。
  • Sass**接口:如 http**接口等
  • 数据仓库/数据湖:与Redshift 、Doris、Starrocks、GreenPlum、Clickhouse 等无缝集成,支持 Hudi、Iceberg、Paimon等数据湖集成
  • 电子表格与文档:支持 Excel(.xls、.xlsx)、Google Sheets、Txt 等结构化和半结构化文档数据的读取和解析,优化多样化数据的提取。

目前已经支持的各类数据源达到小 200 种,得益于 SeaTunnel 可扩展的插件化架构,对不支持的数据源类型可以自定义扩展。

数据处理流与执行逻辑

数据管道设计

数据管道设计考虑到不同的数据源、数据处理需求和目标存储,通过以下步骤实现:

  • 数据提取 (Extract):通过高效的多线程和批量拉取实现数据的快速提取。
  • 数据加载 (Load):数据的目标存储和输出,支持幂等性和分布式一致性。
  • 数据转换 (transform):包括数据清洗、格式转换、逻辑处理等。

Zeta引擎工作原理

SeaTunnel Engine 由三个主要的服务组成:CoordinatorServiceTaskExecutionServiceSlotService

CoordinatorService

CoordinatorService 是集群的 Master 服务,提供了每个作业从 LogicalDagExecutionDag,再到 PhysicalDag的生成流程,并最终创建作业的 JobMaster 进行作业的调度执行和状态监控。

CoordinatorService中 主要由 4 个大的功能模块组成:

  1. JobMaster,负责单个作业的 LogicalDag 到 ExecutionDag,再到 PhysicalDag 的生成流程,并由 PipelineBaseScheduler 进行调度运行。
  2. CheckpointCoordinator,负责作业的 Checkpoint 流程控制。
  3. ResourceManager,负责作业资源的申请和管理,目前支持 Standalone 模式,未来会支持 On Yarn 和 On K8s。
  4. Metrics Service,负责作业监控信息的统计和汇总。

客户端在提交任务时会找到master节点并将任务提交到CoordinatorService服务上,CoordinatorService会缓存任务信息并等待任务执行结束。

当任务结束后再对任务进行归档处理。

TaskExecutionService

TaskExecutionService 是集群的 Worker 服务,提供了作业中每个 Task 的真正运行时环境,TaskExecutionService 使用了 Dynamic Thread Sharing 技术降低 CPU 使用。

TaskExecutionService 是一个执行任务的服务,将在每个节点上运行一个实例。它从 JobMaster 接收 TaskGroup 并在其中运行 Task。并维护TaskID->TaskContext,对Task的具体操作都封装在TaskContext中。

而Task内部持有OperationService,也就是说Task可以通过OperationService远程调用其他Task或JobMaster进行通信。

SlotService
SlotService 在集群每个节点上都会运行,主要负责节点上资源的划分、申请和回收。

SlotService用于管理集群的可用Slot资源。SlotService运行在所有节点上并定期向master上报资源信息。

  1. SeaTunnel 运行流程

    第一步:jobconf转换为LogicDag

    通过ob的配置文件定义job流程,因此 SeaTunnelClient 需要做的第一件事是解析job配置文件并生成action列表。action 类似于 Flink 中的 operator,是对 SeaTunnel API 的封装。

    一个action包含 SeaTunnelSource 或 SeaTunnelTransform 或 SeaTunnelSink 的实例。每个action都需要知道它自己的上游。

    这一块主要是 Action 接口来负责的。
    目前支持 SourceAction 、SinkAction 和 TransformAction 三种类型的action。如果只有一个 Source和一个Sink,和一个 Transform

如果有多个source或多个transform或多个sink,我们将依赖 source\_table\_nameresult\_table\_name 来构建action pipeline

因此,在这种情况下,result\_table\_name对于source action是必需的,而所有result\_table\_namesource\_table\_name对于transform action都是必需的。

最后,source\_table\_name是 sink action必需的。

第二步:LogicPlan转换成PhysicalPlan

SeaTunnel引擎会收到客户端发送过来的逻辑计划,引擎需要将其转化为可以直接执行的物理计划。

因此,需要对逻辑执行计划进行处理,通过转换生成物理计划。具体过程如下:

  • 逻辑计划

收到逻辑计划,我们需要去除多余的Actions,并验证Schema(Transform2和Transform 5应该是一样的)

  • 执行计划

转换为执行计划时:

(1)Transforms需要合并,合并的依据是Transform后数据是否会被拆分(如果没有shuffle则会将transform合并)。

(2)将shuffle action转换成队列。

(3)拆分多个pipeline。

  • 物理计划

将Pipeline按照并行度拆分成单独的可执行任务,并且同时需要添加SourceSplitEnumeratorSinkAggregatedCommitter任务,可以将任务发送到executionService

然后任务就可以正常运行了。

第三步:将taskGroup调度到指定node上等待运行

在master节点上将physicalPlan拆分成pipeline并将pipeline拆分成taskGroup分别调度到不同节点上进行执行。

  • physicalPlan:用户提交的job被解析成可以运行的执行计划。
  • pipeline:在pipeline中的任务只有pipeline的上游和下游算子,不同pipeline没有相关联的算子。
  • taskGroup:每一个执行计划顶点将会创建一个taskGroup,一个taskGroup包含一个或者多个task,每一个taskGroup需要一个单位的计算资源。taskGroup是任务分配和执行的最小单位。如下:

下图是 SeaTunnel 整体运行流程图:

运行流程图

Zeta 引擎的优势与特点

SeaTunnel Zeta 引擎采用无中心化架构,为了在不依赖第三方服务组件(如 Zookeeper)的情况下实现集群的自治和作业的容错,SeaTunnel Zeta使用了 Hazelcast作为底层依赖。

Hazelcast 提供了一个分布式内存网络,让用户可以像在本地操作普通 Java 集合一样来操作一个分布式的集合,SeaTunnel 将作业的状态信息保存在Hazelcast 的内存网格中,当 Master 节点切换后,可以基于 Hazelcast 内存网格中的数据进行作业状态的恢复。

同时,我们还实现了 Hazelcast 内存网格数据的持久化,以WAL 的方式将作业状态信息持久化到存储中(JDBC 协议的数据库、HDFS、云存储)。

这样,即使整个集群挂掉重启,也可以修复作业的运行时信息。

数据缓存

SeaTunnel Zeta Engine 与传统的Spark/Flink计算引擎不同,是专门用来做数据同步的引擎。SeaTunnel 引擎天然支持数据 Cache,当集群中有多个同步作业共用一个数据源时,SeaTunnel 引擎会自动启用数据 Cache,由一个作业的 Source 将数据读取后写入 Cache 中,其它所有作业不再从数据源读取数据,而是自动被优化为从 Cache 中读取数据。这样做的好处是可以降低数据源的读取压力,降低数据同步对数据源的影响。

速度控制

SeaTunnel Engine 支持数据同步时的速度限制,这在高并发读取数据源时非常有用,合理的速度限制既可以保证数据按时同步完成,又可以尽量减小对数据源造成的压力影响。

共享连接池,降低数据库压力

数据库连接对数据库来说是昂贵的资源,过多的数据库连接会对数据库造成极大的压力,导致数据库读写延迟稳定性降低,这对业务数据库来说是非常严重的事故。为了解决这个问题,SeaTunnel Engine 使用共享连接池的方式,保证多张表可以共用 JDBC 连接,从而降低数据库连接的使用。

断点续传增量/全量,让用户无感知

Zeta Engine 支持离线同步下的断点续传。在数据量较大时,一次数据同步作业往往需要运行几十分钟或几个小时,如果中间作业挂了重跑,那意味着浪费时间。

Zeta Engine 会在离线同步的过程中不断地进行状态的保存(检查点),作业挂掉重跑时会从上一次的检查点继续运行,这有效解决了节点宕机等硬件问题可能导致的数据延迟。

Schema evolution 的路线

模式演化是一种允许用户轻松更改表的当前模式以适应随时间变化的数据的功能。

最常见的是,在执行追加或覆盖操作时使用它,以自动调整模式以包括一个或多个新列。

更细粒度的容错设计

Flink 的设计是整个作业级别的容错和回滚,表现为如果某一个 task 失败,那整个作业都会进行回滚重启操作

SeaTunnel Engine 在设计时考虑到了在数据同步场景下,很多q情况下一个 task 的失败应该只需要和它有上下游关系的 task 需要关注容错。

基于这一设计原则,SeaTunnel Zeta Engine 会先按用户配置的作业配置文件生成逻辑 DAG,再对逻辑DAG 进行优化,最终生成以 Pipeline(一个作业 DAG 中的一个连通子图)为粒度进行作业的调用和容错。

一个典型的使用场景

使用 CDC 连接器从 MySQL 的Binlog中读取数据后写入另一个 MySQL,如果使用 Flink 或 Spark 引擎,一旦目标端 MySQL 无法写入,会导致 CDC 读取 binlog 的任务也会中止,如果 MySQL 被设置了 log 的过期时间,会出现目标端 MySQL 问题解决了,但源 MySQL 的日志被清除了,进而引发数据丢失等问题。

SeaTunnel Engine 会自动优化这一同步任务,自动添加源到目标端的 Cache,再进一步将这个作业优化成两个 Pipeline,pipeline#1 负责从 CDC 读取数据并写入 SeaTunnel Cache,pipeline#2 负责从 SeaTunnel Cache 读取数据并写入目标MySQL。

如果目标端 MySQL 有问题导致无法写入,这个同步作业的 pipeline#2 会中止,pipeline#1 依然正常运行。

这种设计从根本上解决了上述的问题,更符合数据同步引擎的处理逻辑。

动态共享线程,减少资源占用

SeaTunne Zeta Engine 的 Task 设计使用了共享线程的技术,区别于 Flink/Spark,Zeta Engine 不会简单的让一个 Task 占用一个线程,而是通过一种动态感知的方式——动态线程共享(Dynamic Thread Sharing)来判断一个 Task 应该和其它 Task 共享一个线程还是应该独占一个线程。

多线程并行计算和单线程串行计算相比有更好的性能优势,但如果每个 Task 都占使用一个独立线程来运行,当数据同步的表比较多,Task 数量大时,会在 Worker 节点上启动非常多的线程。

在 CPU 核心数固定的情况下,线程数并不是越多越好,当线程数量过多时,CPU 需要花大量的时间进行线程的上下文切换,这反而会影响计算性能。

Flink/Spark 通常会限制每个节点上最大运行的 Task 的数量,通过这种方式来可避免起动太多的线程,而 Zeta Engine 为了能在一个节点上运行更多的 Task,通过共享线程技术可以让那些数据量较少的 Task 共享线程,而数据量较大的 Task 独占线程,这种方式使 Zeta Engine 在一个节点上运行几百上千张表同步任务成为了可能,以更少的资源占用,完成更多的表的同步。

本文由 白鲸开源科技 提供发布支持!

相关文章:

Apache SeaTunnel 整体架构运行原理

概述 SeaTunnel 缘起 数据集成在现代企业的数据治理和决策支持中扮演着至关重要的角色。随着数据源的多样化和数据量的迅速增长及业务需求的快速变化,企业需要具备强大的数据集成能力来高效地处理数据。SeaTunnel通过其高度可扩展和灵活的架构,帮助企业…...

Nginx如何实现 TCP和UDP代理?

文章目录 前言 Nginx之TCP和UDP代理 工作原理示意图 配置文件和命令参数注释 基本命令 配置实例说明 TCP代理实例UDP代理实例 总结 前言 Nginx是一个高性能的HTTP和反向代理服务器,同时也支持TCP/UDP代理。在1.9.13版本后,Nginx已经支持端口转发&…...

蓝桥杯思维训练营(三)

文章目录 题目详解680.验证回文串 II30.魔塔游戏徒步旅行中的补给问题观光景点组合得分问题 题目详解 680.验证回文串 II 680.验证回文串 II 思路分析:这个题目的关键就是,按照正常来判断对应位置是否相等,如果不相等,那么就判…...

开箱即用的.NET MAUI组件库 V-Control 发布了!

之前写过挺多的MAUI Sample,其中有很多代码可以打包成组件,当组件完善到一定程度,我会把控件封装起来放到控件库中。 今天,在这个仓库建立一年零八个月后,我觉得可以考虑将其作为开源库发布。 有很多网友在观望.NET …...

动手学图神经网络(9):利用图神经网络进行节点分类 WeightsBiases

利用图神经网络进行节点分类Weights&Biases 引言 在本篇博客中,将深入探讨如何使用图神经网络(GNNs)来完成节点分类任务。以 Cora 数据集为例,该数据集是一个引用网络,节点代表文档,推断每个文档的类别。同时,使用 Weights & Biases(W&B)来跟踪实验过程和…...

【文件上传、秒传、分片上传、断点续传、重传】

文章目录 获取文件对象文件上传&#xff08;秒传、分片上传、断点续传、重传&#xff09;优化 获取文件对象 input标签的onchange方法接收到的参数就是用户上传的所有文件 <html lang"en"><head><title>文件上传</title><style>#inp…...

使用Pygame制作“打砖块”游戏

1. 前言 打砖块&#xff08;Breakout / Arkanoid&#xff09; 是一款经典街机游戏&#xff0c;玩家控制一个可左右移动的挡板&#xff0c;接住并反弹球&#xff0c;击碎屏幕上方的砖块。随着砖块被击碎&#xff0c;不仅能获得分数&#xff0c;还可以体验到不断加速或复杂的反弹…...

【完整版】DeepSeek-R1大模型学习笔记(架构、训练、Infra)

文章目录 0 DeepSeek系列总览1 模型架构设计基本参数专家混合模型&#xff08;MoE&#xff09;[DeepSeek-V2提出, DeepSeek-V3改良]多头潜在注意力&#xff08;MLA&#xff09;[DeepSeek-V2提出]多token预测&#xff08;MTP&#xff09;[DeepSeek-V3提出] 2 DeepSeek-R1-Zero及…...

深入解析:如何利用 Python 爬虫获取商品 SKU 详细信息

在电商领域&#xff0c;SKU&#xff08;Stock Keeping Unit&#xff0c;库存单位&#xff09;详细信息是电商运营的核心数据之一。它不仅包含了商品的规格、价格、库存等关键信息&#xff0c;还直接影响到库存管理、价格策略和市场分析等多个方面。本文将详细介绍如何利用 Pyth…...

【3】高并发导出场景下,服务器性能瓶颈优化方案-文件压缩

使用EasyExcel导出并压缩文件是一种高效且常见的解决方案&#xff0c;尤其适用于需要处理大量数据的场景。 1. 导出多个Excel文件并压缩成ZIP文件的基本流程 &#xff08;1&#xff09;数据准备&#xff1a;从数据库或其他数据源获取需要导出的数据&#xff0c;并将其存储在Ja…...

FPGA|生成jic文件固化程序到flash

1、单击file-》convert programming files 2、flie type中选中jic文件&#xff0c;configuration decive里根据自己的硬件选择&#xff0c;单击flash loader选择右边的add device选项 3、选择自己的硬件&#xff0c;单击ok 4、选中sof选项&#xff0c;单机右侧的add file 5、选…...

【ArcGIS_Python】使用arcpy脚本将shape数据转换为三维白膜数据

说明&#xff1a; 该专栏之前的文章中python脚本使用的是ArcMap10.6自带的arcpy&#xff08;好几年前的文章&#xff09;&#xff0c;从本篇开始使用的是ArcGIS Pro 3.3.2版本自带的arcpy&#xff0c;需要注意不同版本对应的arcpy函数是存在差异的 数据准备&#xff1a;准备一…...

用Python获取股票数据并实现未来收盘价的预测

获取数据 先用下面这段代码获取上证指数的历史数据&#xff0c;得到的csv文件数据&#xff0c;为后面训练模型用的 import akshare as ak import pandas as pd# 获取上证指数历史数据 df ak.stock_zh_index_daily(symbol"sh000001")# 将数据保存到本地CSV文件 df.…...

Rust 所有权特性详解

Rust 所有权特性详解 Rust 的所有权系统是其内存安全的核心机制之一。通过所有权规则&#xff0c;Rust 在编译时避免了常见的内存错误&#xff08;如空指针、数据竞争等&#xff09;。本文将从堆内存与栈内存、所有权规则、变量作用域、String 类型、内存分配、所有权移动、Cl…...

Gateway路由匹配规则详解

在微服务架构中&#xff0c;Gateway作为请求的入口&#xff0c;扮演着至关重要的角色。它不仅负责路由转发&#xff0c;还具备安全、监控、限流等多种功能。其中&#xff0c;路由匹配规则是Gateway的核心功能之一&#xff0c;它决定了请求如何被正确地转发到目标服务。本文将详…...

项目实操:windows批处理拉取git库和处理目录、文件

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

前端开发知识梳理 - HTMLCSS

1. 盒模型 由内容区&#xff08;content&#xff09;、内边距&#xff08;padding&#xff09;、边框&#xff08;border&#xff09;和外边距&#xff08;margin&#xff09;组成。 &#xff08;1&#xff09;标准盒模型&#xff08;box-sizing默认值, content-box&#xff…...

nginx中的proxy_set_header参数详解

在使用 Nginx 作为反向代理服务器时&#xff0c;proxy_set_header 指令扮演着至关重要的角色。它允许我们自定义请求头信息&#xff0c;将客户端请求传递给上游服务器时&#xff0c;添加或修改特定的信息&#xff0c;从而实现更灵活的代理功能。本文将深入探讨 proxy_set_heade…...

MapReduce是什么?

MapReduce 是一种编程模型&#xff0c;最初由 Google 提出&#xff0c;旨在处理大规模数据集。它是分布式计算的一个重要概念&#xff0c;通常用于处理海量数据并进行并行计算。MapReduce的基本思想是将计算任务分解为两个阶段&#xff1a;Map 阶段和 Reduce 阶段。 Map 阶段&a…...

Text2Sql:开启自然语言与数据库交互新时代(3030)

一、Text2Sql 简介 在当今数字化时代&#xff0c;数据处理和分析的需求日益增长。对于众多非技术专业人员而言&#xff0c;数据库操作的复杂性常常成为他们获取所需信息的障碍。而 Text2Sql 技术的出现&#xff0c;为这一问题提供了有效的解决方案。 Text2Sql&#xff0c;即文…...

jvm 垃圾收集算法 详解

垃圾收集算法 分代收集理论 垃圾收集器的理论基础&#xff0c;它建立在两个分代假说之上&#xff1a; 弱分代假说&#xff1a;绝大多数对象都是朝生夕灭的。强分代假说&#xff1a;熬过越多次垃圾收集过程的对象就越难以消亡。 这两个分代假说共同奠定了多款常用的垃圾收集…...

Linux 下关于 ioremap 系列接口

1、序 在系统运行时&#xff0c;外设 IO 资源的物理地址是已知的&#xff0c;由硬件的设计决定&#xff08;参考SOC的datesheet&#xff0c;一般会有memorymap&#xff09;。驱动程序不能通过物理地址访问IO资源&#xff0c;必须将其映射到内核态的虚拟地址空间。常见的接口就是…...

php执行系统命令的四个常用函数

php执行系统命令有四个常用函数&#xff1a;1.exec()执行命令并返回最后一行输出&#xff0c;可传数组获取全部结果&#xff1b;2.shell_exec()返回完整输出结果&#xff0c;适合一次性获取&#xff1b;3.system()直接输出命令结果&#xff0c;可接收状态码&#xff1b;4.权限控…...

CSS radial-gradient函数详解

目录 基本语法 关键参数详解 1. 渐变形状&#xff08;Shape&#xff09; 2. 渐变大小&#xff08;Size&#xff09; 3. 中心点位置&#xff08;Position&#xff09; 4. 颜色断点&#xff08;Color Stops&#xff09; 常见应用场景 1. 基本圆形渐变 2. 椭圆渐变 3. 模…...

计算机网络第2章(下):物理层传输介质与核心设备全面解析

目录 一、传输介质1.1 传输介质的分类1.2 导向型传输介质1.2.1 双绞线&#xff08;Twisted Pair&#xff09;1.2.2 同轴电缆&#xff08;Coaxial Cable&#xff09;1.2.3 光纤&#xff08;Optical Fiber&#xff09;1.2.4 以太网对有线传输介质的命名规则 1.3 非导向型传输介质…...

使用VuePress2.X构建个人知识博客,并且用个人域名部署到GitHub Pages中

使用VuePress2.X构建个人知识博客&#xff0c;并且用个人域名部署到GitHub Pages中 什么是VuePress VuePress 是一个以 Markdown 为中心的静态网站生成器。你可以使用 Markdown 来书写内容&#xff08;如文档、博客等&#xff09;&#xff0c;然后 VuePress 会帮助你生成一个…...

蓝桥杯单片机之通过实现同一个按键的短按与长按功能

实现按键的短按与长按的不同功能 问题分析 对于按键短按&#xff0c;通常是松开后实现其功能&#xff0c;而不会出现按下就进行后续的操作&#xff1b;而对于按键长按&#xff0c;则不太一样&#xff0c;按键长按可能分为两种情况&#xff0c;一是长按n秒后实现后续功能&…...

Linux命令基础(2)

su和exit命令 可以通过su命令切换到root账户 语法&#xff1a;su [-] 用户名 -符号是可选的&#xff0c;表示是否在切换用户后加载环境变量&#xff0c;建议带上 参数&#xff1a;用户名&#xff0c;表示要切换的用户&#xff0c;用户名可以省略&#xff0c;省略表示切换到ro…...

​线性注意力 vs. 传统注意力:效率与表达的博弈新解

​核心结论​&#xff1a;线性注意力用计算复杂度降维换取全局建模能力&#xff0c;通过核函数和结构优化补足表达缺陷 一、本质差异&#xff1a;两种注意力如何工作&#xff1f; ​特性​传统注意力&#xff08;Softmax Attention&#xff09;线性注意力&#xff08;Linear At…...

内嵌式mqtt server

添加moquette依赖 <dependency><groupId>io.moquette</groupId><artifactId>moquette-broker</artifactId><version>0.17</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>…...