我一直在我们的系统上设置气流集群,并且以前一直在工作。我不确定该做些什么。
我有一个DAG,我想按计划运行。为了确保它能正常工作,我还想手动触发它。目前,这两个似乎都不起作用,并且似乎没有为任务实例编写日志。唯一可用的日志是通常看起来很健康的气流调度程序日志。
我经常收到以下消息:
Task is not ready for retry yet but will be retried automatically. Current date is 2018-12-12T11:34:46.978355+00:00 and task will be retried at 2018-12-12T11:35:08.093313+00:00.
但是,如果我稍等片刻,除了时间稍有改变外,还会再次显示完全相同的消息。因此,似乎从未真正尝试过执行任务。
我正在使用LocalExecutor,任务是SSHOperator。下面的简化代码。它要做的就是将ssh切换到另一台机器上,并使用预定的目录结构启动一堆应用程序。
DB_INFO_FILE = 'info.json'
START_SCRIPT = '/bin/start.sh'
TIME_IN_PAST = timezone.convert_to_utc(datetime.today() -
timedelta(days=1))
DEFAULT_ARGS = {
'owner': 'airflow',
'depends_on_past': False,
'start_date': TIME_IN_PAST,
'email': ['some_email@blah.com'],
'email_on_failure': False,
'email_on_retry': False,
'retries': 1,
'retry_delay': timedelta(minutes=1),
}
def _extract_instance_id(instance_string):
return re.findall(r'\d+', instance_string)[0]
def _read_file_as_json(file_name):
with open(file_name) as open_file:
return json.load(open_file)
DB_INFO = _read_file_as_json(DB_INFO_FILE)
CONFIG_CLIENT = ConfigDbClient(**DB_INFO)
APP_DIRS = CONFIG_CLIENT.get_values('%my-app-info%')
INSTANCE_START_SCRIPT_PATHS = {
_extract_instance_id(instance_string): directory+START_SCRIPT
for instance_string, directory in APP_DIRS.items()
}
# Create an ssh hook which refers to pre-existing connection information
# setup and stored by airflow
SSH_HOOK = SSHHook(ssh_conn_id='my-conn-id')
# Create a DAG object to add tasks to
DAG = DAG('my-dag-id',
default_args=DEFAULT_ARGS)
# Create a task for each app instance.
for instance_id, start_script in INSTANCE_START_SCRIPT_PATHS.items():
task = SSHOperator(
task_id='run-script-{0}'.format(instance_id),
command='bash {0}'.format(start_script),
ssh_hook=SSH_HOOK,
dag=DAG)
当我通过命令行而不是通过UI单独运行任务时,它可以工作。看来我可以运行任务,但是我根本无法触发DAG运行。我还尝试了start_date s和interval计划的许多组合,也只是为了进行健全性检查。
有什么想法吗?
是的,我知道这个问题以前曾被问过,我已经研究了所有问题,但是没有解决方案对我有帮助。
答案 0 :(得分:0)
哦。您的start_date
的更改速度或速度比计划间隔时间长。
调度器每隔几秒钟就会看到以下内容:
start_date: 2018-12-11T12:12:12.000Z # E.G. IFF now is 2018-12-12T12:12:12.000Z, a day ago
schedule_interval: timedelta(days=1) # The default
这是调度程序运行DAG所需要的:上一次运行发生是在一个以上调度间隔之前。如果没有发生预定的运行,则自start_date
起已经过去了一个完整的预定间隔,则可以立即开始第一个预定的运行,因为这是最早的允许日期execution_date
。在这种情况下,应创建将dag_run
设置为该间隔时间段的开始的execution_date
。然后,只要task_instance
task_instance
在DAG的execution_date
之后,就可以为DAG中满足依赖关系的任何任务创建start_date
dag_run
对象上,但通过在检查dag的状态时加载DAG文件来重新计算。
因此,由于开始日期随着间隔的变化而不断变化,因此它不会自动排定。但是,如果是-2d,则至少要安排一次跑步,然后再进行其他跑步,必须等到安排之后的1d。不过,如果您仅在datetime
上设置一个固定的start_date
,则会更容易。
但是手动运行中那些奇怪的重试呢?
您确实开始了一两次手动运行。除非您另外指定,否则这些运行将当前时间作为execution_date
。这应该在start_date
之后,至少要到明天,这应该清除它们的运行。但是,在您的日志中,您似乎看到它们正在失败并且被标记为重试,并且也没有减少重试次数。我不确定为什么会这样,但是SSHOperator
可能有问题吗?
您是否另外安装了[ssh]
气流,以便在Web服务器和调度程序上都满足SSHOperator的依赖性(特别是paramiko
和sshtunnel
)?其中之一正在工作,因为我认为它是根据添加到数据库中后在UI中进行解析和显示的。
执行后会得到什么?
airflow test my-dag-id run-script-an_instance_id 2018-12-12T12:12:12
您知道调度程序和Web服务器正在循环填充其DAG包,因此每天要重新运行此DAG文件几次1000次,重新加载json(它是本地访问权限,因此类似于导入模块),然后重新创建{ {1}}与数据库查找。我看不到任何设置此挂钩的幻想,为什么不从SSHHook
删除ssh_hook
并用SSHOperator
代替它以便可以在执行时创建一次?
我怀疑这是导致重试的问题,但是重试只是向前滚动。
答案 1 :(得分:0)
我有一个任务在up_for_retry
停留了将近24小时,然后才注意到,它与start_date,end_date或任何其他经典初学者的问题无关。
我求助于阅读源代码,并发现Airflow如果将up_for_retry
任务作为回填DAG运行的一部分,则会以不同的方式对待。
因此,我连接到元数据数据库,并在与卡住的任务相对应的backfill_
行中将scheduled__
改为dag_run
。 Airflow立即开始执行卡住的任务。