尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Apache Airflow Breeze 后端数据库持久化方案:ADR-0007 数据卷设计解析

Apache Airflow Breeze 后端数据库持久化方案:ADR-0007 数据卷设计解析 Apache Airflow Breeze 后端数据库持久化方案ADR-0007 数据卷设计解析【免费下载链接】airflowApache Airflow - A platform to programmatically author, schedule, and monitor workflows项目地址: https://gitcode.com/GitHub_Trending/ai/airflowApache Airflow 仓库中的 Breeze 是开发者本地的容器化开发环境它通过--backend参数选择元数据库metadata db后端。本文基于 dev/breeze/doc/adr/0007-using-database-volumes-for-backends.md 这份已采纳Accepted的架构决策记录深入解析 Breeze 如何通过 Docker 数据卷让数据库数据在容器重启后依然保留同时提供一键彻底清理环境的机制。读完本文你将掌握 Breeze 各后端Postgres、MySQL、SQLite的卷声明方式、breeze down的清理语义以及源码中对应的实现细节。ADR 背景为什么需要数据库卷在默认情况下Breeze 将各类数据库后端Postgres、MySQL、SQLite 等以独立容器的方式运行用户通过breeze命令的--backend开关启用它们。这些数据库的数据文件默认存储在容器本地文件系统中这意味着一旦数据库容器停止数据库数据即告丢失。对于开发场景这种每次从零开始的行为在特定情境下是方便的例如希望快速获得一份干净的环境但更多时候开发者希望数据库数据在容器重启后依然保留。与此同时也存在另一种需求当开发者切换 Git 分支时本地数据库的表结构可能比当前代码所认知的结构更新此时需要一种彻底抹除环境连同所有数据库数据的途径以便从零重建数据库。正是在持久化与可彻底清理这对矛盾的权衡下ADR-0007 于 2022-01-29 被提出并最终采纳Status: Accepted。决策内容每个后端的数据都落入自动创建的卷ADR 的核心决策非常明确每个 Breeze 后端出于一致性考虑SQLite 也包含在内在通过相应的--backend标志启用时都会将数据库文件存储在一个自动创建的卷volume中。这一逻辑在backend-BACKEND.ymldocker-compose 文件中实现。该卷会一直存在直到被手动删除或执行breeze down命令。breeze down会停止所有容器并移除所有卷从而为从零启动 Breeze 环境提供一条便捷路径。这套设计同时满足了两个目标重启数据库不丢数据需要重启数据库的开发者无需担心数据丢失一键重建环境仍可通过简单操作丢弃并重建数据库。源码验证backend compose 文件中的卷声明决策中提到在backend-BACKEND.ymldocker-compose 文件中实现该文件位于 scripts/ci/docker-compose/ 目录。逐一查看各后端的卷声明Postgres 后端backend-postgres.ymlbackend-postgres.yml 定义了具名卷postgres-data-volume并将其挂载到 Postgres 的数据目录services: airflow: environment: - BACKENDpostgres - AIRFLOW__DATABASE__SQL_ALCHEMY_CONNpostgresql${POSTGRES_DRIVER:-psycopg}://postgres:airflowpostgres/airflow - AIRFLOW__CELERY__RESULT_BACKENDdbpostgresql${POSTGRES_DRIVER:-psycopg}://postgres:airflowpostgres/airflow depends_on: postgres: condition: service_healthy postgres: image: postgres:${POSTGRES_VERSION} environment: - POSTGRES_USERpostgres - POSTGRES_PASSWORDairflow - POSTGRES_DBairflow - POSTGRES_HOST_AUTH_METHODpassword volumes: - postgres-data-volume:/var/lib/postgresql/{$POSTGRES_VERSION}/docker healthcheck: test: [CMD, psql, -h, localhost, -U, postgres, -c, select 1, airflow] interval: 10s timeout: 10s start_period: 30s retries: 5 restart: on-failure volumes: postgres-data-volume: name: postgres${POSTGRES_VERSION}-db-volume值得注意的细节卷名带有版本后缀postgres${POSTGRES_VERSION}-db-volume即不同 Postgres 版本使用不同的卷避免版本升级时数据结构不兼容导致启动失败airflow服务通过AIRFLOW__DATABASE__SQL_ALCHEMY_CONN指向postgres主机postgres:airflowpostgres/airflowCelery 结果后端同样复用该数据库连接通过depends_on: condition: service_healthy与 healthcheck 配合确保 airflow 容器在数据库就绪后才启动。MySQL 后端backend-mysql.ymlbackend-mysql.yml 定义了mysql-db-volume卷挂载到 MySQL 的数据目录/var/lib/mysqlservices: airflow: environment: - BACKENDmysql - AIRFLOW__DATABASE__SQL_ALCHEMY_CONNmysql://rootmysql/airflow?charsetutf8mb4 - AIRFLOW__CELERY__RESULT_BACKENDdbmysql://rootmysql/airflow?charsetutf8mb4 depends_on: mysql: condition: service_healthy mysql: image: mysql:${MYSQL_VERSION} environment: - MYSQL_ALLOW_EMPTY_PASSWORDtrue - MYSQL_ROOT_HOST% - MYSQL_DATABASEairflow - MYSQL_INITDB_SKIP_TZINFO1 volumes: - ../mysql/conf.d:/etc/mysql/conf.d:ro - mysql-db-volume:/var/lib/mysql healthcheck: test: [CMD, mysqladmin, status, -h, localhost, -u, root] interval: 10s timeout: 15s start_period: 60s retries: 5 restart: on-failure command: [ mysqld, --character-set-serverutf8mb4, --collation-serverutf8mb4_unicode_ci, ] volumes: mysql-db-volume:MySQL 容器还显式指定了 utf8mb4 字符集与排序规则--character-set-serverutf8mb4、--collation-serverutf8mb4_unicode_ci并与 airflow 服务的连接串?charsetutf8mb4保持一致。SQLite 后端backend-sqlite.ymlbackend-sqlite.yml 内容最简只注入后端标识与连接串services: airflow: environment: - BACKENDsqlite - AIRFLOW__DATABASE__SQL_ALCHEMY_CONN${SQLITE_URL}SQLite 的连接串由 Breeze 注入在 shell_params.py 中可以看到其默认值为sqlite:////root/airflow/sqlite/airflow.db即数据库文件位于 airflow 容器内的固定路径该路径对应的数据目录在 Breeze 环境装配时以卷形式持久化从而与 ADR 决策保持一致。值得注意的是sqlite 后端不会像 Postgres/MySQL 那样叠加-port.yml端口转发 compose 文件这一点从get_backend_compose_files的逻辑backend in (sqlite, none, custom)时只返回单一 compose 文件可以得到印证。源码级例外脚本运行场景下的无卷SQLiteADR 决策要求一致性但仓库源码中存在一处经过深思熟虑的例外。shell_params.py 中的get_backend_compose_files方法揭示了这一点def get_backend_compose_files(self, backend: str) - list[Path]: if backend sqlite and self.project_name ! breeze: # When running scripts, we do not want to mount the volume to make sure that the # sqlite database is not persisted between runs of the script and that the # breeze database is not cleaned accidentally backend_docker_compose_file SCRIPTS_CI_DOCKER_COMPOSE_PATH / fbackend-{backend}-no-volume.yml else: backend_docker_compose_file SCRIPTS_CI_DOCKER_COMPOSE_PATH / fbackend-{backend}.yml ...也就是说在 Breeze 交互式开发环境project_name breeze中使用带卷的 backend-sqlite.yml在 CI 脚本或其他 compose 项目中project_name ! breeze改用不带卷的 backend-sqlite-no-volume.yml两者内容唯一区别即在于是否持久化 SQLite 数据。源码注释明确说明了这样做的两个目的一是避免脚本多次运行之间 SQLite 数据被意外持久化串扰二是防止脚本误清理 Breeze 自己的数据库。这是决策 例外在工程实践中的典型体现也印证了 ADR 中出于一致性 SQLite 也包含在内的措辞在落地时是带有条件判断的。清理语义breeze down 与卷的生命周期ADR 决策的第二半是breeze down的清理能力。在 developer_commands.py 中down命令的签名如下def down( preserve_volumes: bool, cleanup_mypy_cache: bool, cleanup_build_cache: bool, all_projects: bool, project_name: str | None, ):其核心行为是调用bring_all_compose_projects_down(preserve_volumespreserve_volumes, ...)将 Breeze 管理的所有 compose 项目停止并移除包括数据库卷从而实现从零开始。该命令还支持--preserve-volumes保留卷配合数据迁移场景使用--cleanup-mypy-cache额外移除mypy-cache-volume卷及本地.mypy_cache等缓存developer_commands.py--cleanup-build-cache额外移除airflow-cache-volume构建缓存卷--all-projects将非 Breeze 管理的无关 compose 项目也一并停止。因此日常使用的两个极值操作是# 停止容器但保留数据重启数据库不丢数据 breeze down --preserve-volumes # 彻底清理停止全部容器并删除所有卷从零重建环境 breeze down后果与适用边界按照 ADR 的 Consequences 描述该决策带来的直接收益是需要重启数据库的开发者可以在不丢失任何数据库数据的前提下完成重启同时由于breeze down的存在也始终保留着一条丢弃并重建数据库的捷径。适用前提与边界该方案针对的是Breeze 本地开发环境通过--backend启用的元数据库后端不涉及生产部署的数据库持久化策略卷只有在手动删除或**执行breeze down不带--preserve-volumes**时才会被移除仅停止容器如breeze down --preserve-volumes不会删除数据Postgres 卷名带版本号postgres${POSTGRES_VERSION}-db-volume切换--postgres-version会使用不同的卷这可以避免旧数据结构对新版本代码造成干扰——这与 ADR 中切换分支时本地 DB 结构比代码认知更新的动机相呼应SQLite 在非 Breeze 的脚本运行场景中会被刻意排除持久化backend-sqlite-no-volume.yml以确保脚本运行结果的确定性。总结ADR-0007 以一份简洁的架构决策记录了 Breeze 数据库后端的持久化约定数据默认持久化于自动创建的 Docker 卷breeze down负责提供一键彻底清理的出口。通过阅读 backend-*.yml 系列 compose 文件、shell_params.py 中的 compose 文件装配逻辑以及 developer_commands.py 中的down实现可以完整还原这套机制的落地细节——包括版本化卷名、SQLite 的例外处理与清理命令的参数化设计。对于 Breeze 的日常使用者记住breeze down重置一切、加--preserve-volumes则保留数据这一条即可从容应对绝大多数开发场景。【免费下载链接】airflowApache Airflow - A platform to programmatically author, schedule, and monitor workflows项目地址: https://gitcode.com/GitHub_Trending/ai/airflow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表