设置数据库后端¶
Airflow 构建用于使用 SqlAlchemy 与其元数据进行交互。
以下文档描述了数据库引擎配置,使用 Airflow 所需的配置更改,以及连接到这些数据库的 Airflow 配置更改。
选择数据库后端¶
如果您想真正试用 Airflow,应考虑将数据库后端设置为 PostgreSQL 或 MySQL。默认情况下,Airflow 使用 SQLite,它仅用于开发目的。
Airflow 支持以下数据库引擎版本,请确保您拥有哪个版本。旧版本可能不支持所有 SQL 语句。
PostgreSQL: 12, 13, 14, 15, 16
MySQL: 8.0, 创新版 (Innovation)
SQLite: 3.15.0+
如果您计划运行多个调度器,则必须满足额外要求。有关详细信息,请参阅调度器高可用性数据库要求。
警告
尽管 MariaDB 和 MySQL 有很大相似之处,我们 **不** 支持将 MariaDB 作为 Airflow 的后端。MariaDB 和 MySQL 之间存在已知问题(例如索引处理),我们也不在 MariaDB 上测试我们的迁移脚本或应用程序执行。我们知道有些人曾将 MariaDB 用于 Airflow,这给他们带来了很多操作上的麻烦,因此我们 **强烈不建议** 尝试使用 MariaDB 作为后端,用户也无法期待获得任何社区支持,因为尝试将 MariaDB 用于 Airflow 的用户数量非常少。
数据库 URI¶
Airflow 使用 SQLAlchemy 连接到数据库,这需要您配置数据库 URL。您可以在 [database]
部分的选项 sql_alchemy_conn
中进行配置。通常也可以使用 AIRFLOW__DATABASE__SQL_ALCHEMY_CONN
环境变量来配置此选项。
注意
有关设置配置的更多信息,请参阅设置配置选项。
如果您想检查当前值,可以使用 airflow config get-value database sql_alchemy_conn
命令,如下例所示。
$ airflow config get-value database sql_alchemy_conn
sqlite:////tmp/airflow/airflow.db
具体格式描述请参见 SQLAlchemy 文档,请参阅 数据库 URL。我们还会在下方展示一些示例。
设置 SQLite 数据库¶
SQLite 数据库可用于开发目的的 Airflow 运行,因为它不需要任何数据库服务器(数据库存储在本地文件中)。使用 SQLite 数据库有很多限制,您可以轻松地在线找到,并且 **绝不** 应将其用于生产环境。
运行 Airflow 2.0+ 需要最低版本的 sqlite3 - 最低版本是 3.15.0。一些较旧的系统默认安装了早期版本的 sqlite,对于这些系统,您需要手动升级 SQLite 以使用 3.15.0 以上的版本。请注意,这不是 python library
的版本,而是需要升级的 SQLite 系统级应用程序。SQLite 的安装方式多种多样,您可以在 SQLite 官方网站以及针对您操作系统发行版的文档中找到相关信息。
故障排除
有时,即使您将 SQLite 升级到更高版本并且您的本地 python 报告了更高版本,Airflow 使用的 python 解释器可能仍然使用用于启动 Airflow 的 python 解释器设置的 LD_LIBRARY_PATH
中提供的旧版本。
您可以通过运行此检查来确定解释器使用了哪个版本:
root@b8a8e73caa2c:/opt/airflow# python
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.sqlite_version
'3.27.2'
>>>
但请注意,为您的 Airflow 部署设置环境变量可能会改变首先找到的 SQLite 库,因此您可能需要确保系统中安装的 SQLite 版本足够高,并且是唯一安装的版本。
sqlite 数据库的 URI 示例
sqlite:////home/airflow/airflow.db
在 AmazonLinux AMI 或容器镜像上升级 SQLite
AmazonLinux SQLite 只能使用源代码仓库升级到 v3.7。Airflow 需要 v3.15 或更高版本。使用以下说明来设置具有最新 SQLite3 的基础镜像(或 AMI)
先决条件:您需要 wget
, tar
, gzip
, gcc
, make
和 expect
来使升级过程正常工作。
yum -y install wget tar gzip gcc make expect
从 https://sqlite.ac.cn/ 下载源码,进行编译和本地安装。
wget https://www.sqlite.org/src/tarball/sqlite.tar.gz
tar xzf sqlite.tar.gz
cd sqlite/
export CFLAGS="-DSQLITE_ENABLE_FTS3 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_JSON1 \
-DSQLITE_ENABLE_LOAD_EXTENSION \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_STAT4 \
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT \
-DSQLITE_SOUNDEX \
-DSQLITE_TEMP_STORE=3 \
-DSQLITE_USE_URI \
-O2 \
-fPIC"
export PREFIX="/usr/local"
LIBS="-lm" ./configure --disable-tcl --enable-shared --enable-tempstore=always --prefix="$PREFIX"
make
make install
安装后将 /usr/local/lib
添加到库路径
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
设置 PostgreSQL 数据库¶
您需要创建一个数据库以及 Airflow 将用于访问此数据库的数据库用户。在下面的示例中,将创建数据库 airflow_db
和用户名为 airflow_user
、密码为 airflow_pass
的用户:
CREATE DATABASE airflow_db;
CREATE USER airflow_user WITH PASSWORD 'airflow_pass';
GRANT ALL PRIVILEGES ON DATABASE airflow_db TO airflow_user;
-- PostgreSQL 15 requires additional privileges:
-- Note: Connect to the airflow_db database before running the following GRANT statement
-- You can do this in psql with: \c airflow_db
GRANT ALL ON SCHEMA public TO airflow_user;
注意
数据库必须使用 UTF-8 字符集
您可能需要更新您的 Postgres pg_hba.conf
文件,将 airflow
用户添加到数据库访问控制列表;并重新加载数据库配置以加载您的更改。有关更多信息,请参阅 Postgres 文档中的pg_hba.conf 文件。
警告
当您使用 SQLAlchemy 1.4.0+ 时,需要在 sql_alchemy_conn
中使用 postgresql://
作为数据库。在早期版本的 SQLAlchemy 中可以使用 postgres://
,但在 SQLAlchemy 1.4.0+ 中使用它会导致:
> raise exc.NoSuchModuleError(
"Can't load plugin: %s:%s" % (self.group, name)
)
E sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres
如果您无法立即更改 URL 前缀,Airflow 仍可与 SQLAlchemy 1.3 一起工作,并且您可以降级 SQLAlchemy,但我们建议更新前缀。
详细信息请参见 SQLAlchemy 更新日志。
我们建议使用 psycopg2
驱动并在您的 SqlAlchemy 连接字符串中指定它。
postgresql+psycopg2://<user>:<password>@<host>/<db>
另请注意,由于 SqlAlchemy 未提供在数据库 URI 中指定特定 schema 的方式,您需要确保 schema public
包含在您的 Postgres 用户的 search_path 中。
如果您为 Airflow 创建了一个新的 Postgres 账户
新 Postgres 用户的默认 search_path 为:
"$user", public
,无需更改。
如果您使用具有自定义 search_path 的现有 Postgres 用户,可以通过命令更改 search_path:
ALTER USER airflow_user SET search_path = public;
有关设置 PostgreSQL 连接的更多信息,请参阅 SQLAlchemy 文档中的PostgreSQL 方言。
注意
众所周知,Airflow(尤其是在高性能设置中)会打开许多连接到元数据数据库。这可能会导致 Postgres 资源使用问题,因为在 Postgres 中,每个连接都会创建一个新进程,当打开大量连接时,这会使 Postgres 资源消耗巨大。因此,我们建议在所有 Postgres 生产安装中使用 PGBouncer 作为数据库代理。PGBouncer 可以处理来自多个组件的连接池,而且如果您有一个连接可能不稳定的远程数据库,它将使您的数据库连接对临时网络问题更具弹性。PGBouncer 部署的示例实现可以在Apache Airflow 的 Helm Chart 中找到,您可以通过翻转一个布尔标志来启用预配置的 PGBouncer 实例。您可以参考我们在那里采用的方法,并在准备自己的部署时将其作为参考,即使您不使用官方的 Helm Chart。
另请参阅Helm Chart 生产指南
注意
对于托管的 Postgres 服务,如 Azure Postgresql、CloudSQL、Amazon RDS,您应该在连接参数中使用 keepalives_idle
并将其设置为小于空闲时间,因为这些服务会在一段时间不活动后(通常是 300 秒)关闭空闲连接,从而导致错误 The error: psycopg2.operationalerror: SSL SYSCALL error: EOF detected
。可以通过 [database]
部分中的 sql_alchemy_connect_args
配置参数 配置参考 来更改 keepalive
设置。您可以在例如您的 local_settings.py 文件中配置这些参数,sql_alchemy_connect_args
应该是存储配置参数的字典的完整导入路径。您可以阅读有关 Postgres Keepalives 的信息。一个已被观察到能解决问题的 keepalives
设置示例可能是:
keepalive_kwargs = {
"keepalives": 1,
"keepalives_idle": 30,
"keepalives_interval": 5,
"keepalives_count": 5,
}
然后,如果将其放置在 airflow_local_settings.py
中,配置导入路径将是:
sql_alchemy_connect_args = airflow_local_settings.keepalive_kwargs
有关如何配置本地设置的详细信息,请参阅配置本地设置。
设置 MySQL 数据库¶
您需要创建一个数据库以及 Airflow 将用于访问此数据库的数据库用户。在下面的示例中,将创建数据库 airflow_db
和用户名为 airflow_user
、密码为 airflow_pass
的用户:
CREATE DATABASE airflow_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'airflow_user' IDENTIFIED BY 'airflow_pass';
GRANT ALL PRIVILEGES ON airflow_db.* TO 'airflow_user';
注意
数据库必须使用 UTF-8 字符集。您必须注意的一个小问题是,较新版本 MySQL 中的 utf8 实际上是 utf8mb4,这会导致 Airflow 索引变得过大(请参阅https://github.com/apache/airflow/pull/17603#issuecomment-901121618)。因此,自 Airflow 2.2 起,所有 MySQL 数据库的 sql_engine_collation_for_ids
都自动设置为 utf8mb3_bin
(除非您覆盖它)。这可能导致 Airflow 数据库中 ID 字段的 collation id 混合,但由于 Airflow 中所有相关的 ID 仅使用 ASCII 字符,因此没有负面影响。
为了拥有合理的默认设置,我们依赖于 MySQL 更严格的 ANSI SQL 设置。请确保在 my.cnf
文件中的 [mysqld]
部分指定了 explicit_defaults_for_timestamp=1
选项。您还可以通过传递给 mysqld
可执行文件的 --explicit-defaults-for-timestamp
开关来激活这些选项:
我们建议使用 mysqlclient
驱动并在您的 SqlAlchemy 连接字符串中指定它。
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
重要提示
MySQL 后端的集成仅在 Apache Airflow 的持续集成 (CI) 过程中使用 mysqlclient
驱动进行了验证。
如果您想使用其他驱动,请访问 SQLAlchemy 文档中的MySQL 方言,以获取有关下载和设置 SqlAlchemy 连接的更多信息。
此外,您还应特别注意 MySQL 的编码。尽管 utf8mb4
字符集在 MySQL 中越来越流行(实际上,utf8mb4
在 MySQL 8.0 中成为了默认字符集),但在 Airflow 2+ 中使用 utf8mb4
编码需要额外设置(详情请参阅#7570)。如果您使用 utf8mb4
作为字符集,您还应设置 sql_engine_collation_for_ids=utf8mb3_bin
。
注意
在严格模式下,MySQL 不允许将 0000-00-00
作为有效日期。在这种情况下,您可能会遇到类似 "Invalid default value for 'end_date'"
的错误(某些 Airflow 表使用 0000-00-00 00:00:00
作为时间戳字段的默认值)。为了避免此错误,您可以在您的 MySQL 服务器上禁用 NO_ZERO_DATE
模式。请阅读https://stackoverflow.com/questions/9192027/invalid-default-value-for-create-date-timestamp-field 了解如何禁用它。有关更多信息,请参阅SQL Mode - NO_ZERO_DATE。
MsSQL 数据库¶
警告
经过讨论和投票过程,Airflow 的 PMC 成员和提交者已达成决议,不再将 MsSQL 作为受支持的数据库后端进行维护。
自 Airflow 2.9.0 起,已移除对 MsSQL 作为 Airflow 数据库后端的支持。这不影响现有的 providers (operators 和 hooks),dags 仍然可以访问和处理来自 MsSQL 的数据。但是,进一步使用可能会抛出错误,导致 Airflow 的核心功能无法使用。
从 MsSQL Server 迁移¶
由于 Airflow 2.9.0 已终止对 MSSQL 的支持,因此可以使用迁移脚本帮助 Airflow 2.7.x 或 2.8.x 版本从 SQL-Server 迁移出来。该迁移脚本位于 Github 上的airflow-mssql-migration 仓库中。
请注意,此迁移脚本不提供支持和担保。
其他配置选项¶
有更多配置选项可用于配置 SQLAlchemy 行为。有关详细信息,请参阅 [database]
部分中 sqlalchemy_*
选项的参考文档。
例如,您可以指定 Airflow 创建所需表的数据库 schema。如果您希望 Airflow 将其表安装在 PostgreSQL 数据库的 airflow
schema 中,请指定以下环境变量:
export AIRFLOW__DATABASE__SQL_ALCHEMY_CONN="postgresql://postgres@localhost:5432/my_database?options=-csearch_path%3Dairflow"
export AIRFLOW__DATABASE__SQL_ALCHEMY_SCHEMA="airflow"
请注意 SQL_ALCHEMY_CONN
数据库 URL 末尾的 search_path
。
初始化数据库¶
在 Airflow 配置中配置数据库并连接到它之后,您应该创建数据库 schema。
airflow db migrate
Airflow 中的数据库监控和维护¶
Airflow 广泛使用关系型元数据数据库进行任务调度和执行。监控和正确配置此数据库对于 Airflow 的最佳性能至关重要。
关键考量¶
性能影响:长或过多的查询会显著影响 Airflow 的功能。这可能由工作流特性、缺乏优化或代码错误引起。
数据库统计信息:数据库引擎做出不正确的优化决策(通常是由于数据统计信息过时)会降低性能。
职责¶
在 Airflow 环境中,数据库监控和维护的职责因您是使用自管数据库和 Airflow 实例还是选择托管服务而异。
自管环境:
在数据库和 Airflow 都是自管的设置中,部署经理负责设置、配置和维护数据库。这包括监控其性能、管理备份、定期清理以及确保其与 Airflow 的最佳运行。
托管服务:
托管数据库服务:使用托管数据库服务时,许多维护任务(如备份、补丁和基本监控)由服务提供商处理。但是,部署经理仍然需要监督 Airflow 的配置,优化针对其工作流的性能设置,管理定期清理,并监控其数据库以确保与 Airflow 的最佳运行。
托管 Airflow 服务:使用托管 Airflow 服务时,服务提供商负责 Airflow 及其数据库的配置和维护。但是,部署经理需要与服务配置方协作,以确保大小和工作流要求与托管服务的大小和配置匹配。
监控方面¶
定期监控应包括:
CPU、I/O 和内存使用。
查询频率和数量。
识别和记录慢查询或长时间运行的查询。
检测低效的查询执行计划。
分析磁盘交换与内存使用以及缓存交换频率。
工具和策略¶
Airflow 不直接提供数据库监控工具。
使用服务器端监控和日志记录来获取指标。
根据定义的阈值启用长时间运行查询的跟踪。
定期运行内部维护任务(如
ANALYZE
SQL 命令)进行维护。
数据库清理工具¶
Airflow DB Clean 命令:利用
airflow db clean
命令来帮助管理和清理您的数据库。``airflow.utils.db_cleanup`` 中的 Python 方法:此模块提供了额外的 Python 方法用于数据库清理和维护,为特定需求提供更细粒度的控制和自定义。
建议¶
主动监控:在生产环境中实施监控和日志记录,同时不显著影响性能。
数据库特定指南:查阅所选数据库的文档,获取具体的监控设置说明。
托管数据库服务:检查您的数据库提供商是否提供自动维护任务。
SQLAlchemy 日志记录¶
为了进行详细的查询分析,启用 SQLAlchemy 客户端日志记录(在 SQLAlchemy 引擎配置中设置 echo=True
)。
此方法更具侵扰性,可能影响 Airflow 的客户端性能。
它会生成大量日志,尤其是在繁忙的 Airflow 环境中。
适用于非生产环境,如预发系统。
您可以按照SQLAlchemy 日志记录文档中的说明,将 echo=True
作为 sqlalchemy 引擎配置进行设置。
使用 sql_alchemy_engine_args 配置参数将 echo 参数设置为 True。
注意¶
启用大量日志记录时,请注意对 Airflow 性能和系统资源的影响。
对于生产环境,优先使用服务器端监控而非客户端日志记录,以最大程度地减少性能干扰。
下一步是什么?¶
默认情况下,Airflow 使用 LocalExecutor
。您应考虑配置不同的executor以获得更好的性能。