Airflow ETL任务调度工具 介绍

2023-05-16

Airflow 是 Apache 基金会的一套用于创建、管理和监控工作流程的开源平台,是一套非常优秀的任务调度工具。截至2022年7月,在GitHub上已经拥有近27k的star。

本文主要介绍一下Airflow 2.3.2版本,各个功能模块,以及如何使用。只浅浅提了一下Airflow的功能点,具体内容还是链接到了官方文档。

前言

官网简介

Airflow是一个ETL中的任务调度工具。

ETL Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。

Airflow 是一个可编程、调度和监控的工作流平台。
Airflow 用户可以定义一组有依赖的任务,即有向无环图(DAG),按照依赖依次执行。
Airflow 提供了丰富的命令行和强大的Web UI,方便的管控调度任务,可以实时监控运行状态。

Linux crontab 不足

  • 在多任务调度执行的情况下,难以理清任务之间的依赖关系
  • 不便于查看当前执行到哪一个任务
  • 任务执行失败时没有自动的重试和报警机制
  • 不便于查看执行日志,即不方便定位报错的任务和错误原因
  • 不便于查看调度流下每个任务执行的起止消耗时间,这对于优化task作业是非常重要的
  • 没有记录历史调度任务的执行情况,而这对于优化作业和错误排查是很重要的

ETL 的常见痛点

  • 日益增加的数据量
  • 快速排查任务失败的原因
  • 每个新工具都要重新学习新的配置规范
  • 重试,监控,报警
  • 敏捷高效的开发以满足业务需求
  • 不均衡的数据峰值

使用场景

  • 监控自动化工作的情况(通过web UI和各个worker上记录的执行历史)
  • 自动处理并传输数据
  • 为机器学习或推荐系统提供一个数据管道和使用框架
  • 做代码部署调度

安装

单机版本地安装

本地安装Airflow非常简单,只需要按照官网的 Running Airflow locally 教程复制相应命令即可。

容器化安装

官网文档Running Airflow in Docker,需要提前将Docker和docker-compose装好。

系统流程图

单机版

基本概念

DAG: 即一个工作流,一个DAG由一系列的TASK组成。

DAG RUN: 即一次DAG工作流的执行。一个DAG在不同时间触发会生成一次 DAG RUN。

TASK: 任务,Airflow中最小的执行单位,一群TASK组成一个DAG,TASK之间有相互依赖的关系。

这里有三种基本的TASK类型

  • Operator:任务模板
  • Sensor:传感器
  • TaskFlow:其他Python代码

具体模块

Scheduler/调度器

调度器通常作为服务运行,是一种使用DAG定义结合元数据中的任务状态来决定哪些任务需要被执行以及任务执行优先级的过程。

调度器监控所有的DAG文件,加载文件中的变化,默认每分钟一次。

WebServer/web服务器 + User Interface/UI页面

提供图形页面,可以监控DAG运行状态,也可以对DAG操作。使用的是Gunicorn框架启动。

Metadata Database/元数据库

存储所有的DAG,任务定义,运行的历史,用户,权限等。
默认使用SQLite,可以支持MySQL、PostgreSQL。

Executor/执行器

Airflow中有多种执行器可选择,例如:

  • SequentialExecutor: 单进程顺序执行任务,默认执行器,通常用于测试
  • LocalExecutor: 多进程本地执行任务
  • CeleryExecutor: 分布式调度,生产常用
  • DaskExecutor: 动态任务调度,主要用于数据分析
  • ...

Ariflow + Celery 图

Worker/执行者

用来执行Executor接收的任务,这些是实际执行任务逻辑的进程,由正在使用的执行器确定。

Operator/操作员

一个TASK中的具体操作模板,例如

  • BashOperator-(airflow.operators.bash.BashOperator) 用来执行Bash脚本
  • PythonOperator-(airflow.operators.python.PythonOperator) 调用Python函数
  • EmailOperator-(airflow.operators.email_operator.EmailOperator) 发送邮件
  • MySqlOperator-(airflow.providers.mysql.operators.mysql.MySqlOperator) 在MySQL中执行SQL脚本
  • ...

Sensor/传感器

TASK的一种特殊Operator类型,由时间或事件触发。

例如我们在等待上游服务商处理后,读取服务商生成的文件,再执行后续任务。通常会定时使用Operator去检查上游服务商是否处理完毕,生成对应文件,未处理完毕则停止。

针对此场景,可以使用Sensor监听上游服务商。

UI介绍

GitHub上有UI 页面的介绍。

DAGs: 该页面展示所有的DAG任务

Grid: 网格表示DAG中TASK的执行情况,每一列即是一个DAG RUN

Graph: 每个TASK的依赖关系可视化,以及在一次DAG RUN中的运行状态

Task Duration : 随着时间的推移,在不同任务上花费的总时间。

Gantt: 甘特图

Code: 源码页面

创建DAG

首先需要声明一个DAG,这里有三种方式

通过上下文管理with隐式调用

with DAG(
    "my_dag_name", start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
    schedule_interval="@daily", catchup=False
) as dag:
    op = EmptyOperator(task_id="task")

标准构造方式

my_dag = DAG("my_dag_name", start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
             schedule_interval="@daily", catchup=False)
op = EmptyOperator(task_id="task", dag=my_dag)

装饰器方式

@dag(start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
     schedule_interval="@daily", catchup=False)
def generate_dag():
    op = EmptyOperator(task_id="task")

dag = generate_dag()

参数

  • dag_id 唯一标识
  • default_args 默认参数
  • description 描述
  • schedule_interval 调度时间
  • max_active_runs 最大并行执行个数

默认参数default_args

默认配置,通常在DAG中具体的Operator具有同样的配置,它下面有许多配置比如重试次数,邮件等。该参数支持将里面的参数和具体的TASK绑定。

default_args={
        'depends_on_past': False,
        'email': ['sajor@foxmail.com'],
        'email_on_failure': True,
        'email_on_retry': False,
        'retries': 1,
        'retry_delay': timedelta(minutes=5),
    },

depends_on_past

设置为True时,表示只有当上一个TASK成功时,当前TASK才能启动。

email

可以配置一个邮件列表,触发邮件发送时将往列表中的邮箱发送对应邮件。

email_on_failure

TASK失败时是否触发邮件发送

email_on_retry

TASK重试时是否触发邮件发送

retries

失败重试总次数

retry_delay

失败重试时,之间的时间间隔

重启相关

catchup

DAG执行通常带有时间范围,假如三天该任务都没有启动成功,第四天运行时会将前三天的数据补上,无需启动三次依次补数据,这时该参数配置为False。

max_active_runs

要求并发执行的任务数,例如在数据库操作时,多个任务同时执行可能会引发死锁。

连接

在使用TASK之前,先提一下连接,在使用Airflow时,会经常连接数据库、邮箱、文件服务器等,将连接的账号密码写到代码中不是一个好的习惯。

Airflow提供了统一管理连接凭据的功能。在 Menu -> Admin -> Connections 中可以管理。

然后在代码中可以使用Hook的方式获取

from airflow.hooks.base_hook import BaseHook

conn = BaseHook.get_connection('connection_id')

也可以通过模板变量获取

echo {{ conn.<conn_id>.host }}

创建TASK

一个TASK可以使用某个具体的Operator模板,例如上文提到的 BashOperator、PythonOperator,也可以使用自己实现的Operator。

BashOperator

from airflow.operators.bash import BashOperator

bash_task = BashOperator(
    task_id='print_date',
    # 这里也可以写脚本文件路径
    bash_command='date',
)

PythonOperator

from airflow.operators.python import PythonOperator

python_task = PythonOperator(
    task_id="python_task",
    # fun为函数名
    python_callable = fun
)

EmailOperator

from airflow.operators.email_operator import EmailOperator
email_task = EmailOperator(
    task_id = "email_task",
    to = "sajor@foxmail.com",
    subject = "Email Test",
    html_content = """ <h1> Email Test </h1> """,
    dag=dag
)

MySqlOperator

首先需要安装拓展包apache-airflow-providers-mysql

# ubuntu 
apt install libmysqlclient-dev

# centos
yum install mysql-devel

# pypi提到必须使用20.2.4版本的pip安装
python -m pip install pip==20.2.4

# 最后使用pip安装airflow依赖
pip install apache-airflow-providers-mysql

之后

from airflow.providers.mysql.operators.mysql import MySqlOperator

mysql_task = MySqlOperator(
    task_id = "mysql_task",
    # 提前配好连接
    mysql_conn_id = "connection_id",
    # 这里也可以写sql文件路径
    sql = "select * from tb_anchor limit 100",
    dag = dag
)

PostgresOperator

想使用这个模板之前,需要先安装一些库 libpq-dev、gcc、python-dev 见官网 和 Python的psycopg2包。

之后需要安装拓展包apache-airflow-providers-postgres

# ubuntu 
apt install libpq-dev

pip install psycopg2

# 最后使用pip安装airflow依赖
pip install apache-airflow-providers-postgres



下图描绘了一个TASK由none开始可能经历的状态

TASK依赖关系

有两种常用方式声明任务依赖

使用 >> 和 <<

bash_task >> python_task >> [mysql_task, email_task]

使用 set_upstream 和 set_downstream方法

bash_task.set_downstream(python_task)
mysql_task.set_upstream(python_task)

还有更简洁的复杂关系

from airflow.models.baseoperator import cross_downstream

# Replaces
# [op1, op2] >> op3
# [op1, op2] >> op4
cross_downstream([op1, op2], [op3, op4])

还有链式

from airflow.models.baseoperator import chain

# Replaces op1 >> op2 >> op3 >> op4
chain(op1, op2, op3, op4)

# You can also do it dynamically
chain(*[EmptyOperator(task_id='op' + i) for i in range(1, 6)])


# Replaces
# op1 >> op2 >> op4 >> op6
# op1 >> op3 >> op5 >> op6
chain(op1, [op2, op3], [op4, op5], op6)

任务传参XComs

任务之间是互相隔离的,甚至可能在不同的机器上执行。

在PythonOperator中,默认函数的返回值,自动加入至XComs中,在其他任务中,可以直接通过Task id 获取返回值。

# Pulls the return_value XCOM from "pushing_task"
value = task_instance.xcom_pull(task_ids='pushing_task')

模板变量

Airflow 集成了Jinja。变量,宏和过滤器可以在模板中使用。

DAG 依赖

这里有两种方法支持一个DAG触发另一个DAG

  • triggering 主动触发 TriggerDagRunOperator
  • waiting 传感器触发 ExternalTaskSensor
trigger_next_dag = TriggerDagRunOperator(
    # 触发的DAG ID
    trigger_dag_id = "Sajor_Dag",
    # 任务ID
    task_id = "trigger sajor",
    # 执行时间
    execution_date = "{{ds}}",
    # 是否等待触发的DAG完成
    wait_for_completion = False
)

可以在 Menu -> Browse -> DAG Dependencies 中看到 DAG 之间的依赖关系。

动态DAG

因为使用Python,所以DAG不一定是由声明式创建,也可以使用循环来创建一堆DAG。

有时一个DAG中的业务应该分为多个DAG,但是代码又高度相似。

命令行工具

可以输入 airflow -h 查看命令行支持情况

开放API

Airflow提供了开放的API接口,并提供了Swagger文档。

该功能特性可以支持其他项目,使用网络请求的方式调用Airflow中的功能。

Pools池

可以在 Menu -> Admin -> Pools 定义Pool,来约定在这个Pool中的资源大小,将多个DAG指定使用该Pool时,所有DAG整体资源消耗不会超过该Pool中的设置。

这可以用于生产环境中,限制整体DAG的资源消耗,防止影响生产中正常业务的执行。

*最佳实践

官网提供了一些,DAG编写指南,应当到官网仔细阅读。

尽量使用分布式架构和容器

将Airflow各个组件分开,尤其是Scheduler和Worker要分开。

在内存不足时,Scheduler和Worker抢占资源,有可能会发生两者失联的情况,导致任务被多次重启。

容器化可以使用容器监控工具,监控各个模块的资源占用情况。

任务的幂等性

在设计每一个任务时,尽量做到可以重复多次运行,即使在运行过程中被打断了,下次运行依然不会出现问题。

多实现自己的Operator

在各种不同系统中下载数据时,最好实现自己的Operator,至少是Hook,相当于封装了外来的API。

定期清理元数据库

数据库中有些表会保存每一次任务的信息,日积月累,这些表就变得越来越大,搜索时就会变得很慢,所以定期去数据库清理这些表,可以提升系统的效率。

在确认不需要Xcom功能时,可以禁用掉,因为在PythonOperator中,函数的返回值默认会启动Xcom功能,每一次执行都会新增一条Xcom记录至数据库中,不管是否使用。

注意资源管理

  • 链接数据库可以使用Connection,方便管理和查看。
  • Variable在官方文档中提到不要滥用,因为Variable是存在元数据库中的,会耗用数据库连接。
  • 在DAG定义文件中,不要调用昂贵的资源,例如调用三方API。因为调度器会频繁扫描DAG文件,在定义DAG外层,均会触发执行,会给服务器带来很大压力。包引用也应尽量放至最内层,如TASK层。

代码DEMO


from datetime import datetime, timedelta
from textwrap import dedent

# The DAG object; we'll need this to instantiate a DAG
from airflow import DAG

# Operators; we need this to operate
from airflow.operators.bash import BashOperator
from airflow.operators.python import PythonOperator
from airflow.operators.email_operator import EmailOperator
from airflow.providers.mysql.operators.mysql import MySqlOperator
from airflow.models.xcom import XCom



with DAG(
    'sajor',
    # [START default_args]
    # These args will get passed on to each operator
    # You can override them on a per-task basis during operator initialization
    default_args={
        'depends_on_past': False,
        'email': ['sajor@foxmail.com'],
        'email_on_failure': True,
        'email_on_retry': False,
        'retries': 1,
        'retry_delay': timedelta(minutes=5),
        # 'queue': 'bash_queue',
        # 'pool': 'backfill',
        # 'priority_weight': 10,
        # 'end_date': datetime(2016, 1, 1),
        # 'wait_for_downstream': False,
        # 'sla': timedelta(hours=2),
        # 'execution_timeout': timedelta(seconds=300),
        # 'on_failure_callback': some_function,
        # 'on_success_callback': some_other_function,
        # 'on_retry_callback': another_function,
        # 'sla_miss_callback': yet_another_function,
        # 'trigger_rule': 'all_success'
    },
    # [END default_args]
    description='Sajor\' Dags',
    schedule_interval=timedelta(minutes=10),
    start_date=datetime(2021, 1, 1),
    catchup=False,
    tags=['sajor'],
) as dag:
    # [END instantiate_dag]

    
    def get_variable():
        from airflow.models import Variable

        key = Variable.get("juaner")
        print("Hello %s" % key)

    
    def get_args(arg):
        s = "Hello %s" % arg
        print(s)
        return s
        
        
    # python中 *  关键字参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
    # python中 ** 关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
    def get_kwargs(*arg, **kwargs):
        
        print(arg)
        print(kwargs)
        print('-----------------')
        
 

    # 使用公共参数 variable
    python_task = PythonOperator(
        task_id="python_task",
        python_callable = get_variable,
    )
    
    # 函数传参
    python_get_args = PythonOperator(
        task_id="python_get_args",
        python_callable = get_args,
        op_kwargs={"arg": "Sajor"}
    )
    
    # 函数传参
    python_get_kwargs = PythonOperator(
        task_id="python_get_kwargs",
        python_callable = get_kwargs,
        op_kwargs={"id":"1","name":"zs","age":18},
        op_args=[1,2,3,"hello","world"],
        
    )
    
    mysql_task = MySqlOperator(
        task_id = "mysql_task",
        mysql_conn_id = "zmt_185",
        sql = "select * from test limit 100",
        dag = dag
    )
    
    email_task = EmailOperator(
        task_id = "email_task",
        to = "sajor@foxmail.com",
        subject = "Email Test",
        # Jinja 变量
        html_content = """ 
            <h3>Email Test</h3>
            {{ ds_nodash }}
            <br/>
            {{ dag }}
            <br/>
            {{ conf }}
            <br/>
            {{ next_ds }}
            <br/>
            {{ yesterday_ds }}
            <br/>
            {{ tomorrow_ds }}
            <br/>
            {{ execution_date }}
            <br/> 
        """,
        dag=dag
    )
    

    bash_task = BashOperator(
        task_id='bash_task',
        do_xcom_push=True,
        # 这里可以写Jinja,获取其他TASK中的xcom数据。return_value这个变量名是固定的
        # 也可以写脚本文件路径
        bash_command='echo "I get: {{ ti.xcom_pull(task_ids="python_get_args", key="return_value") }}"',
    )

    python_task >> python_get_args >> python_get_kwargs >> bash_task

 

  

其他

PXL (Pocket Excel File) files 相较于 CSV (Comma Separated Values File) 是压缩过的,导入数仓时间更短,成本更低。csv无法处理二进制数据,无法表示Null值。

DBT 工具

官方视频资料: airflow summit

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Airflow ETL任务调度工具 介绍 的相关文章

  • 使用 Airflow 将 mysql 数据加载到 bigquery 的 dag 出现“无效参数传递”错误

    我运行一个 DAG 提取 MySQL 数据并将其加载到气流中的 BigQuery 我目前收到以下错误 usr local lib python2 7 dist packages airflow models py 1927 PendingD
  • 释放对执行进程任务中使用的变量的锁定SSIS

    我有一个包裹Foreach容器 and 执行流程任务 inside 对于每个容器 在执行流程任务中出现一些错误时 它会重定向到OnError事件处理程序对于每个容器 我正在使用 exe 捕获错误标准误差变量任务的属性并在脚本任务中使用它On
  • 气流中的execution_date:需要作为变量访问

    我真的是这个论坛的新手 但有一段时间 我一直在为我们公司玩气流 抱歉 如果这个问题听起来很愚蠢 我正在使用一堆 BashOperators 编写一个管道 基本上 对于每个任务 我想简单地使用 curl 调用 REST api 这就是我的管道
  • 我怎样才能得到dag中的execution_date?运算符的外部?

    我怎样才能获得execution date参数在 dag 之外 execution min execution date strftime M if execution min 00 logging info YES It s 00 fin
  • ETL 工具...它们到底做什么?请通俗地说[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我最近接触了一些 ETL 工具 例如 Talend 和 Apatar 我想知道这些工具通俗地说的用途 主要目标到底是什么 谁主要使用它
  • 根据另一个数据库的查询结果查询一个数据库

    我在 VS 2013 中使用 SSIS 我需要从 1 个数据库获取 ID 列表 并使用该 ID 列表 我想查询另一个数据库 即SELECT from MySecondDB WHERE ID IN list of IDs from MyFir
  • 如何在 SSIS 变量中存储“完全限定”和“仅名称”文件名

    我有一个 SSIS 包 其中有一个 Foreach 循环容器 加载静态文件夹中的所有 txt 文件 我将完全限定的文件名作为在连接字符串中使用的变量传递 我现在只需将文件名传递给一个变量以用于执行存储过程 问题是如果我将 Foreach 循
  • 气流:Dag 每隔几秒安排两次

    我尝试每天仅运行一次 DAG00 15 00 午夜 15 分钟 然而 它被安排了两次 间隔几秒钟 dag DAG my dag default args default args start date airflow utils dates
  • 气流:找不到 dag_id

    我在不同的 AWS 机器上运行气流服务器和工作线程 我已经在它们之间同步了 dags 文件夹 然后运行airflow initdb在两者上 并在运行时检查 dag id 是否相同airflow list tasks
  • BashOperator 为其他 PythonOperators 中使用的库引发 ImportError

    我的 dag 构建器模块中有一组任务 该模块使用 Airflow 中全球使用的 Python 运算符 我正在 kubernetes 上使用 docker 部署气流 任务失败并显示错误消息 no module named pandas 使用
  • 如何忽略在另一个任务的 run() 内触发的 Luigi 任务的失败

    考虑以下任务 import luigi class YieldFailTaskInBatches luigi Task def run self for i in range 5 yield FailTask i j for j in ra
  • 气流获取重试次数

    在我的 Airflow DAG 中 我有一个任务需要知道它是第一次运行还是重试运行 如果是重试尝试 我需要调整任务中的逻辑 我对如何存储任务的重试次数有一些想法 但我不确定其中是否有合法的 或者是否有更简单的内置方法可以在任务中获取此信息
  • sqlite 插入表中 select * from

    我需要在 Android 应用程序中将数据从一个表移动到另一个表 我想使用以下sql insert into MYTABLE2 select id STATUS risposta DATETIME now data ins from MYT
  • Docker 中的 Airflow:如何将 DAG 添加到 Airflow?

    我想将 DAG 文件添加到 Airflow 它在 Ubuntu 上的 Docker 中运行 我用了以下git 存储库 https github com puckel docker airflow 包含配置和 docker 镜像的链接 当我跑
  • Airflow:网络服务器未找到新的 DAG

    在 Airflow 中 我应该如何处理错误 此 DAG 在网络服务器 DagBag 对象中不可用 它显示在此列表中 因为调度程序将其在元数据数据库中标记为活动状态 我已将新的 DAG 复制到 Airflow 服务器 并尝试过 取消暂停并刷新
  • 如何在 AWS Glue 中指定联接类型?

    我正在使用 AWS Glue 连接两个表 默认情况下 它执行INNER JOIN 我想做一个LEFT OUTER JOIN 我参考了 AWS Glue 文档 但无法将联接类型传递给Join apply 方法 有没有办法在 AWS Glue
  • Airflow Python 单元测试?

    我想为我们的 DAG 添加一些单元测试 但找不到任何单元测试 有 DAG 单元测试框架吗 有一个端到端的测试框架存在 但我猜它已经死了 https issues apache org jira browse AIRFLOW 79 https
  • 在单元测试中运行 Airflow 1.9 的测试 Dag

    我已经实现了运行单个 dag 的测试用例 但它似乎在 1 9 中不起作用 可能是由于气流 1 8 中引入了更严格的池 我正在尝试运行以下测试用例 from airflow import DAG from airflow operators
  • Airflow log_id 格式错误

    我正在使用 Airflow v2 2 3 和apache airflow providers elasticsearch 2 1 0 在 Kubernetes 中运行 我们的日志会自动发送到 Elasticsearch v7 6 2 我在
  • 即使安装了 Microsoft Visual C++ 14.0 也出现 Pip 错误

    我阅读了之前相关或询问的所有问题和答案 但仍然没有找到适合我的问题的答案 我正在使用 python 3 6 5 并且 pip 和 setuptools 是最新的 我从这里安装了 Microsoft Visual C Redistributa

随机推荐

  • 关于Modelsim SE-64 2020.4取消优化后不显示波形问题

    Modelsim取消优化后报错 Error suppressible vsim 12110 All optimizations are disabled because the novopt option is in effect This
  • 关于串口调试助手XCOM点击发送后卡住问题

    未成功安装CH340驱动 USB串口驱动 安装前先重启电脑 xff0c 再点击安装 串口选择错误 打开设备管理器 xff0c 查看USB连接的端口 xff08 COM xff09 号 xff0c 选择正确的端口 xff08 COM xff0
  • Makefile中Linux转Windows执行知识点

    makefile 是一个自动化编译工具 xff0c 可以简化编译过程 xff0c 自动化处理依赖关系和编译顺序 xff0c 提高了代码的可维护性 makefile 通常由一些规则和命令组成 xff0c 规则由目标 依赖和命令构成 xff0c
  • darknet2ncnn编译中 libopencv 库文件找不到

    问题描述 没有直接从 github 上下载 darknet2ncnn 包 xff0c 用的是他人提供的包 xff0c 包已经编译好 解压已经有 convert verify 文件 执行该文件 xff0c 问题描述如下 xff1a root
  • linux usb设备如何和u盘对应

    已知 usb 的 pid vid 如何对加载的u盘进行管理 思路 xff0c 找到 U盘的厂商信息中的pid和 vid 对应关系 xff0c 然后控制 U盘的加载 但是 U盘信息中没有pid 和 vid root 64 li PC sys
  • CV面试题(持续更新!!!)

    CV面试题 1 反卷积 反卷积又叫做转置卷积 xff0c 在计算机中计算的时候 xff0c 转置卷积先将卷积核转为稀疏矩阵C的形式 xff0c 然后计算的时候正向传播的时候左乘这个稀疏矩阵C的转置 xff0c 反向传播的时候左乘这个稀疏矩阵
  • 程序运行时数据保存位置

    程序运行时 xff0c 内存中有六个地方可以保存数据 1 寄存器 这是最快的保存区域 xff0c 寄存器位于处理器内部 然而寄存器的数量很有限 xff0c 所以寄存器是根据需要由编译器的分配的 我们对此没有直接的控制权限 也不可能在我们的程
  • ESP-Drone无人机控制板设计的第一个任务---绘制ESP32-S2-WROVER模块及周边电路

    第1步 xff0c 查看官方ESP Drone无人机ESP32 S2 WROVER模块的参考设计原理图 第二步 xff0c 用KiCAD绘制ESP32 S2 WROVER模块及周边电路 1 如图2 1所示 xff0c 从KiCAD的原理图符
  • ROS学习——读取摄像头数据image

    在ROS工作空间的src文件夹下创建read camera功能包 xff0c 并在包内创建include launch src cfg四个文件夹 在cfg文件夹中创建param yaml文件 xff0c 并写入以下内容 xff1a imag
  • ROS学习——控制小车转向

    给定一个旋转的角度 xff0c 让小车进行顺时针或逆时针旋转 span class token macro property span class token directive keyword include span span clas
  • PID参数设定

    在电机的控制领域 xff0c 不同的电机有不同的驱动方式 xff0c 其中应用最广泛的就是PID proportion integration differentiation 控制 P I和D分别指比例控制 xff0c 积分控制和微分控制
  • 系统编程__2__父子进程的创建和回收

    系统编程 这里写的是对于小白来说更多的了解系统编程的文章 xff0c 有写的不对的地方还恳请各位大佬指出错误 xff0c 小编一定会多多采纳 手动多谢 那么 xff0c 上一次我们稍微了解了一下关于系统编程的一些主要内容 没有看到的童鞋还请
  • php解决跨域访问

    php跨域问题解决判断 参考文章 xff1a php跨域 xff1a https blog csdn net ouxiaoxian article details 89332027 预检请求是什么 xff1a https www jians
  • 动态库与静态库的区别是什么

    区别 xff1a 1 静态库的扩展名一般为 a 或 lib xff1b 动态库的扩展名一般为 so 或 dll 2 静态库在编译时会直接整合到目标程序中 xff0c 编译成功的可执行文件可独立运行 xff1b 动态库在编译时不会放到连接的目
  • Ubuntu 使用 du 查看某个文件夹大小

    在 Ubuntu 系统中 xff0c 你可以使用 du 命令来查看文件夹的大小 例如 xff0c 如果你想查看文件夹 var log 的大小 xff0c 你可以使用如下的命令 xff1a du sh var log 其中 xff0c s 选
  • 无人机六旋翼数学建模[matlab-simulink]

    写在前面 xff0c 这篇文章是借鉴Drexel University 的Senior Design project的matlab simulink四旋翼模型 xff0c 在此基础上针对六旋翼进行的基本改进 xff0c 这里只对 43 型模
  • stm32连接DHT11温湿度传感器

    目录 1 DHT11简介 1 1 连接电路 1 2 串行接口 单线双向 2 cubeMX设置 3 代码开发 3 1 实现定时函数 3 2 打开串口调试 3 4 测试代码实现 4 运行效果 1 DHT11简介 1 1 连接电路 信息如下 xf
  • STM32CubeMX 真的不要太好用

    STM32CubeMX 真的不要太好用 由于工作内容的变动 xff0c 我已经很久没有正经的玩过单片机了 xff0c 近期又要用它做个小玩意了 xff0c 还是选 stm32 吧 xff0c 外设库开发不要太方便 xff0c 哈哈哈 先去
  • ESP-Drone控制板设计的第二个任务-绘制USB-TTL串口下载电路和ESP32-S2芯片内置USB接口电路

    1 摘要 ESP32系列处理器一般会需要采用串口来下载代码 xff0c 因此在其设计中都会保留一个USB TTL串口电路 xff0c 查看乐鑫官网的参考设计 xff0c 基本上是采用CP2102这颗USB转TTL串口芯片 xff0c 但在本
  • Airflow ETL任务调度工具 介绍

    Airflow 是 Apache 基金会的一套用于创建 管理和监控工作流程的开源平台 xff0c 是一套非常优秀的任务调度工具 截至2022年7月 xff0c 在GitHub上已经拥有近27k的star 本文主要介绍一下Airflow 2