如何防止Airflow中的“执行失败:[Errno 32]管道损坏”

时间:2019-03-03 03:13:34

标签: airflow

我刚刚开始使用Airflow来协调我们的ETL管道。

运行dag时遇到管道错误。

我已经看到了关于堆栈溢出的一般讨论here

我的情况更多是在气流方面。根据该帖子中的讨论,可能的根本原因是:

  

如果您的请求被阻止或   花费的时间太长,在请求方超时后,它将关闭   连接,然后当响应端(服务器)尝试写入   套接字,它将引发管道损坏错误。

在我的情况下,这可能是真正的原因,我有一个pythonoperator将在Airflow之外启动另一项工作,而该工作可能会非常漫长(即10个小时以上),我想知道其中的机制是什么我可以利用它来防止这种错误的气流。

有人可以帮忙吗?

UPDATE1 20190303-1:

感谢@ y2k-shubham的SSHOperator,我能够使用它成功建立SSH连接,并且能够在远程站点上运行一些简单的命令(实际上,默认的ssh连接必须设置为localhost)因为该作业位于本地主机上),并且能够看到hostnamepwd的正确结果。

但是,当我尝试运行实际作业时,我再次收到相同的错误,该错误是来自jpipeline ob而不是Airflow dag / task。

UPDATE2:20190303-2

我成功运行了一次(气流测试),没有错误,然后又进行了另一个失败运行(调度程序),但管道出现了同样的错误。

1 个答案:

答案 0 :(得分:0)

虽然我建议您继续寻找一种优美的方式来尝试实现自己想要的目标,但我还是根据要求提供了


首先,您必须创建一个SSHHook。这可以通过两种方式完成

  • 从实例化挂钩的客户端代码提供所有必需设置(如主机,用户,密码(如果需要)等)的常规方法。我在此引用test_ssh_hook.py的示例,但您必须彻底检查SSHHook及其测试,以了解所有可能的用法

    ssh_hook = SSHHook(remote_host="remote_host",
                       port="port",
                       username="username",
                       timeout=10,
                       key_file="fake.file")
    
  • Airflow way中,您将所有连接详细信息放在Connection对象中,该对象可以从UI进行管理,并且仅传递conn_id来实例化钩子

    ssh_hook = SSHHook(ssh_conn_id="my_ssh_conn_id")
    

    当然,如果您依靠SSHOperator,则可以直接将ssh_conn_id传递给运算符。

    ssh_operator = SSHOperator(ssh_conn_id="my_ssh_conn_id")
    

现在,如果您打算要有一个专用任务来在SSH上运行命令,则可以使用SSHOperator。再次引用test_ssh_operator.py中的示例,但请仔细阅读源代码以获得更好的图片。

 task = SSHOperator(task_id="test",
                    command="echo -n airflow",
                    dag=self.dag,
                    timeout=10,
                    ssh_conn_id="ssh_default")

但是随后,您可能希望通过SSH运行命令,这是您的更大任务的一部分。在这种情况下,您不希望使用SSHOperator,您仍然可以只使用SSHHookSSHHook的{​​{3}}方法为您提供get_conn()的实例。这样,您可以使用paramiko SSHClient调用来运行命令

my_command = "echo airflow"
stdin, stdout, stderr = ssh_client.exec_command(
  command=my_command,
  get_pty=my_command.startswith("sudo"),
  timeout=10)

如果您查看SSHOperator的{​​{3}}方法,它是一段相当复杂(但功能强大)的代码,试图实现非常简单的事情。对于我自己的用途,我创建了一些exec_command(),您可能想看看

  • 要独立于SSHHook使用SSHOperator,请查看ssh_utils.py
  • 对于通过SSH运行多个命令的操作员(您可以使用execute()实现相同的操作),请参见MultiCmdSSHOperator