Python 如何有效地使气流dag定义数据库驱动
背景 我有一些从第三方api中提取数据的DAG 我们需要提取的账户可能会随着时间的推移而变化。为了确定要拉取哪些帐户,我们可能需要查询数据库或发出HTTP请求,具体取决于进程 在开始之前,我们只需要在python脚本的开头获得帐户列表。然后,我们将遍历帐户列表,并将每个帐户拉入文件或执行我们需要执行的任何操作 但是现在,使用airflow,在帐户级别定义任务并让airflow处理重试功能、日期范围和并行执行等是有意义的 因此,我的dag可能看起来像这样: 问题 由于每个帐户都是一个任务,因此每次dag解析都需要访问帐户列表。但是,由于dag文件经常被解析,所以您不一定要查询数据库,或者整天等待来自每台机器的每次dag解析的REST调用。这可能是资源密集型的,而且可能需要花钱 问题 有没有一种很好的方法可以在本地文件中缓存这种类型的配置信息,最好是在指定的生存时间内 思想 我考虑过两种不同的方法:Python 如何有效地使气流dag定义数据库驱动,python,airflow,Python,Airflow,背景 我有一些从第三方api中提取数据的DAG 我们需要提取的账户可能会随着时间的推移而变化。为了确定要拉取哪些帐户,我们可能需要查询数据库或发出HTTP请求,具体取决于进程 在开始之前,我们只需要在python脚本的开头获得帐户列表。然后,我们将遍历帐户列表,并将每个帐户拉入文件或执行我们需要执行的任何操作 但是现在,使用airflow,在帐户级别定义任务并让airflow处理重试功能、日期范围和并行执行等是有意义的 因此,我的dag可能看起来像这样: 问题 由于每个帐户都是一个任务,因此每
- 这样做的问题是,如果两个进程同时试图使文件过期,可能会发生冲突。我不知道这种可能性有多大,也不知道后果会是什么,但可能没什么可怕的
- 需要更详细的代码和依赖项李>
- 这样做的好处是,它使用现有的数据库,所以每个查询不需要$1,也不需要合理的网络延迟,但它仍然需要网络往返李>
- 具有在多节点设置中所有节点都相同的优点
- 确定何时过期可能会有问题,因此可能会创建配置管理器dag来定期更新配置变量李>
- 但这会增加部署和开发过程的复杂性——需要填充变量才能正确定义DAG——所有开发人员也需要在本地管理这一点,而不是采用更具创建-读取缓存的方法
- 从未使用过,但我怀疑它们可能在这里使用。但是社区似乎不鼓励使用它们
你处理过这个问题吗?你找到好的解决办法了吗?所有这些似乎都不是很好。默认的DAG解析间隔非常合适:5分钟。但即使对大多数人来说,这也是相当多的,因此,如果您的部署不太接近新DAG的到期时间,那么增加这一数量也是相当合理的 总的来说,我认为在每次DAG解析心跳时发出REST请求并不是那么糟糕。此外,现在的调度过程与解析过程是解耦的,因此不会影响任务调度的速度。气流为您缓存DAG定义 如果您认为仍然有理由将自己的缓存放在上面,那么我的建议是将缓存放在定义服务器上,而不是放在服务器端。例如,在REST端点上使用缓存头,并在需要时自行处理缓存失效。但这可能是一些过早的优化,所以我的建议是从没有它开始,只有当你衡量出你需要它的令人信服的证据时才实施它 编辑:关于Web服务器和工作程序 的确,Web服务器也会触发DAG解析,但不确定其频率。可能遵循guicorn workers刷新间隔(默认为30秒)。默认情况下,工人也会在每个任务开始时执行此操作,但如果激活酸洗DAG,则可以保存此操作。不确定这是不是一个好主意,但我听说这是注定要被弃用的东西
您可以尝试做的另一件事是将其缓存在流程本身中,记忆发出昂贵请求的函数。Python有一个内置的函数工具(
lru\u cache
),再加上pickle,它可能就足够了,而且比其他选项要简单得多。我有同样的场景
对多个帐户进行API调用。最初创建了一个python脚本来迭代列表
当我开始使用气流时,我想到了你打算做什么。尝试了您列出的两个备选方案。经过一些实验后,决定在python中处理重试逻辑,如果HTTP调用失败,则使用简单的try-except块。原因是
最后,这取决于你,这是我的经验。是的,我们进行了过早的优化,我只是在考虑这是否可行。。。至于其他方面,你是对的,但我们的主要数据库是雪花,如果我们使用dag defs,那么我们承诺全天都有仓库,这是$$$。我认为解决方案是在airflow metastore服务器上为此创建一个DB,并使用它。我明白了。是的,这是一种特殊的情况,因为您的存储解决方案有特定的定价模型,所以即使是5分钟的间隔也是不可接受的。在这种情况下,使用廉价的DB作为视图是一个好办法;它们也被Web服务器解析;更糟