设置数据库后端
Airflow 构建于 SqlAlchemy 之上,用于与其元数据进行交互。
下文介绍了数据库引擎配置、为配合 Airflow 使用所需的配置变更,以及用于连接这些数据库的 Airflow 配置变更。
选择数据库后端
如果您想真正试用 Airflow,应考虑将数据库后端设置为 PostgreSQL 或 MySQL。默认情况下,Airflow 使用 SQLite,它仅供开发使用。
Airflow 支持以下数据库引擎版本,因此请确认您所使用的版本。旧版本可能不支持所有的 SQL 语句。
PostgreSQL: 13, 14, 15, 16, 17
MySQL: 8.0, 8.4, Innovation
SQLite: 3.15.0+
如果您计划运行多个调度器(scheduler),则必须满足额外要求。有关详细信息,请参阅 调度器高可用数据库要求。
警告
尽管 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 解释器可能仍在使用 LD_LIBRARY_PATH 中设置的旧版本。
您可以通过运行此检查来确定解释器使用的版本
[Breeze:3.10.19] 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)的方法,您需要确保 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 不仅可以处理来自多个组件的连接池,而且如果您拥有连接不稳定的远程数据库,它还可以使您的 DB 连接对临时的网络问题更具弹性。PGBouncer 部署的实施示例可以在 Apache Airflow 的 Helm Chart 中找到,您可以通过切换布尔标志来启用预配置的 PGBouncer 实例。您可以参考我们采取的方法,并在准备自己的部署时将其作为灵感,即使您不使用官方的 Helm Chart。
另请参阅 Helm Chart 生产指南
注意
对于 Azure Postgresql、CloudSQL、Amazon RDS 等托管 Postgres 服务,您应该在连接参数中使用 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 字段的排序规则混合,但这没有负面后果,因为 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 中的默认字符集),但使用 utf8mb4 编码在 Airflow 2+ 中需要额外设置(更多详情请参见 #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 模式 - NO_ZERO_DATE。
MsSQL 数据库
警告
经过 讨论 和 投票过程,Airflow 的 PMC 成员和提交者已达成决议,不再维护 MsSQL 作为受支持的数据库后端。
自 Airflow 2.9.0 起,MsSQL 的支持已从 Airflow 数据库后端中移除。这不会影响现有的提供程序(operators 和 hooks),DAG 仍然可以访问和处理来自 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_* 选项的 参考文档。
例如,您可以指定一个数据库模式(schema),Airflow 将在其中创建所需的表。如果您希望 Airflow 将其表安装在 PostgreSQL 数据库的 airflow 模式中,请指定这些环境变量
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 配置后,您应该创建数据库模式。
airflow db migrate
Airflow 中的数据库监控与维护
Airflow 大量使用关系型元数据数据库来进行任务调度和执行。监控和正确配置此数据库对于 Airflow 的最佳性能至关重要。
关键注意事项
性能影响:过长或过多的查询会严重影响 Airflow 的功能。这些可能由于工作流特性、缺乏优化或代码错误引起。
数据库统计信息:数据库引擎做出的不正确优化决策(通常是由于数据统计信息过时导致)可能会降低性能。
职责
Airflow 环境中数据库监控和维护的职责,取决于您是使用自托管数据库和 Airflow 实例,还是选择托管服务。
自托管环境:
在数据库和 Airflow 均为自托管的设置中,部署管理器负责设置、配置和维护数据库。这包括监控其性能、管理备份、定期清理并确保其与 Airflow 的最佳运行。
托管服务:
托管数据库服务:当使用托管数据库服务时,许多维护任务(如备份、修补和基本监控)由服务提供商处理。但是,部署管理器仍需监督 Airflow 的配置并优化特定于其工作流的性能设置,管理定期清理并监控数据库以确保其与 Airflow 的最佳运行。
托管 Airflow 服务:对于托管 Airflow 服务,服务提供商负责 Airflow 及其数据库的配置和维护。但是,部署管理器需要与服务配置进行协作,以确保规模和工作流要求与托管服务的规模和配置相匹配。
监控方面
日常监控应包括
CPU、I/O 和内存使用情况。
查询频率和数量。
识别和记录缓慢或长时间运行的查询。
检测低效的查询执行计划。
分析磁盘交换与内存使用情况以及缓存交换频率。
工具与策略
Airflow 不提供用于数据库监控的直接工具。
使用服务器端监控和日志记录来获取指标。
根据定义的阈值启用对长时间运行查询的跟踪。
定期运行内务处理任务(如
ANALYZESQL 命令)进行维护。
数据库清理工具
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) 以获得更好的性能。