# 常見問題
## 為什么我的任務沒有安排好?
您的任務可能無法安排的原因有很多。 以下是一些常見原因:
* 您的腳本是否“編譯”,Airflow引擎是否可以解析它并找到您的DAG對象。 要對此進行測試,您可以運行`airflow list_dags`并確認您的DAG顯示在列表中。 您還可以運行`airflow list_tasks foo_dag_id --tree`并確認您的任務按預期顯示在列表中。 如果您使用CeleryExecutor,您可能需要確認這既適用于調度程序運行的位置,也適用于工作程序運行的位置。
* 包含DAG的文件是否在內容的某處包含字符串“airflow”和“DAG”? 在搜索DAG目錄時,Airflow忽略不包含“airflow”和“DAG”的文件,以防止DagBag解析導入與用戶的DAG并置的所有python文件。
* 你的`start_date`設置正確嗎? 在傳遞`start_date + scheduler_interval`之后,Airflow調度程序會立即觸發任務。
* 您的`schedule_interval`設置正確嗎? 默認`schedule_interval`是一天( `datetime.timedelta(1)` )。 您必須直接為實例化的DAG對象指定不同的`schedule_interval` ,而不是`default_param` ,因為任務實例不會覆蓋其父DAG的`schedule_interval` 。
* 您的`start_date`超出了在UI中可以看到的位置嗎? 如果將`start_date`設置為3個月之前的某個時間,您將無法在UI的主視圖中看到它,但您應該能夠在`Menu -> Browse ->Task Instances`看到它。
* 是否滿足任務的依賴性。 直接位于任務上游的任務實例需要處于`success`狀態。 此外,如果已設置`depends_on_past=True` ,則上一個任務實例需要成功(除非它是該任務的第一次運行)。 此外,如果`wait_for_downstream=True` ,請確保您了解其含義。 您可以從`Task Instance Details`頁面查看如何設置這些屬性。
* 您需要創建并激活DagRuns嗎? DagRun表示整個DAG的特定執行,并具有狀態(運行,成功,失敗,......)。 調度程序在向前移動時創建新的DagRun,但永遠不會及時創建新的DagRun。 調度程序僅評估`running` DagRuns以查看它可以觸發的任務實例。 請注意,清除任務實例(從UI或CLI)確實將DagRun的狀態設置為恢復運行。 您可以通過單擊DAG的計劃標記來批量查看DagRuns列表并更改狀態。
* 是否達到了DAG的`concurrency`參數? `concurrency`定義了允許DAG `running`任務實例的數量,超過這一點,事物就會排隊。
* 是否達到了DAG的`max_active_runs`參數? `max_active_runs`定義允許的DAG `running`并發實例的數量。
您可能還想閱讀文檔的“計劃程序”部分,并確保完全了解其進度。
## 如何根據其他任務的失敗觸發任務?
查看文檔“概念`Trigger Rule`部分中的“ `Trigger Rule`部分
## 安裝airflow [crypto]后,為什么連接密碼仍未在元數據db中加密?
查看文檔“配置”部分中的“ `Connections`部分
## 與`start_date`什么關系?
`start_date`是前DagRun時代的部分遺產,但它在很多方面仍然具有相關性。 創建新DAG時,您可能希望使用`default_args`為任務設置全局`start_date` 。 要創建的第一個DagRun將基于所有任務的`min(start_date)` 。 從那時起,調度程序根據您的schedule_interval創建新的DagRuns,并在滿足您的依賴項時運行相應的任務實例。 在向DAG引入新任務時,您需要特別注意`start_date` ,并且可能希望重新激活非活動DagRuns以正確啟用新任務。
我們建議不要使用動態值作為`start_date` ,尤其是`datetime.now()`因為它可能非常混亂。 一旦周期結束,任務就會被觸發,理論上, `@hourly` DAG永遠不會達到一小時后,因為`now()`會移動。
以前我們還建議使用與`schedule_interval`相關的舍入`start_date` 。 這意味著`@hourly`將在`00:00`分鐘:秒,午夜的`@monthly`工作,在這個月的第一個月的`@monthly`工作。 這不再是必需的。 現在,Airflow將自動對齊`start_date`和`schedule_interval` ,方法是使用`start_date`作為開始查看的時刻。
您可以使用任何傳感器或`TimeDeltaSensor`來延遲計劃間隔內的任務執行。 雖然`schedule_interval`允許指定`datetime.timedelta`對象,但我們建議使用宏或cron表達式,因為它強制執行舍入計劃的這種想法。
使用`depends_on_past=True`時,必須特別注意`start_date`因為過去的依賴關系不會僅針對為任務指定的`start_date`的特定計劃強制執行。 除非您計劃為新任務運行回填,否則在引入新的`depends_on_past=True`時及時觀察DagRun活動狀態也很重要。
另外需要注意的是,在回填CLI命令的上下文中,任務`start_date`會被回填命令`start_date`覆蓋。 這允許對具有`depends_on_past=True`任務實際啟動的回填,如果不是這樣,則回填就不會啟動。
## 如何動態創建DAG?
Airflow在`DAGS_FOLDER`查找其全局命名空間中包含`DAG`對象的模塊,并在`DagBag`添加它找到的對象。 知道這一切我們需要的是一種在全局命名空間中動態分配變量的方法,這可以在python中使用`globals()`函數輕松完成,標準庫的行為就像一個簡單的字典。
```
for i in range ( 10 ):
dag_id = 'foo_ {} ' . format ( i )
globals ()[ dag_id ] = DAG ( dag_id )
# or better, call a function that returns a DAG object!
```
## 我的進程列表中的所有`airflow run`命令是什么?
`airflow run`命令有很多層,這意味著它可以調用自身。
* 基本`airflow run` :啟動執行程序,并告訴它運行`airflow run --local`命令。 如果使用Celery,這意味著它會在隊列中放置一個命令,使其在worker上運行遠程。 如果使用LocalExecutor,則轉換為在子進程池中運行它。
* 本地`airflow run --local` :啟動`airflow run --raw`命令(如下所述)作為子`airflow run --raw` ,負責發出心跳,監聽外部`airflow run --raw`信號,并確保在子進程失敗時進行一些清理
* 原始`airflow run --raw`運行實際操作員的執行方法并執行實際工作
## 我的氣流dag如何運行得更快?
我們可以控制三個變量來改善氣流dag性能:
* `parallelism` :此變量控制氣流工作者可以同時運行的任務實例的數量。 用戶可以增加`airflow.cfg`的并行度變量。
* `concurrency` :Airflow調度程序在任何給定時間都將為您的DAG運行不超過`$concurrency`任務實例。 并發性在Airflow DAG中定義。 如果未在DAG上設置并發性,則調度程序將使用`dag_concurrency`條目的缺省值。
* `max_active_runs` :在給定時間,Airflow調度程序將運行不超過DAG的`max_active_runs` DagRuns。 如果未在DAG中設置`max_active_runs` ,則調度程序將使用`airflow.cfg` `max_active_runs_per_dag`條目的缺省值。
## 我們如何減少氣流UI頁面加載時間?
如果你的dag需要很長時間才能加載,你可以將`airflow.cfg`中`default_dag_run_display_number`配置的值`airflow.cfg`到一個較小的值。 此可配置控制在UI中顯示的dag run的數量,默認值為25。
## 如何修復異常:全局變量explicit_defaults_for_timestamp需要打開(1)?
這意味著在mysql服務器中禁用了`explicit_defaults_for_timestamp` ,您需要通過以下方式啟用它:
1. 在my.cnf文件的mysqld部分下設置`explicit_defaults_for_timestamp = 1` 。
2. 重啟Mysql服務器。
## 如何減少生產中的氣流dag調度延遲?
* `max_threads` :Scheduler將并行生成多個線程來安排dags。 這由`max_threads`控制,默認值為2.用戶應在生產中將此值增加到更大的值(例如,調度程序運行的cpus的數量 - 1)。
* `scheduler_heartbeat_sec` :用戶應考慮將`scheduler_heartbeat_sec`配置增加到更高的值(例如60秒),該值控制氣流調度程序獲取心跳的頻率并更新作業在數據庫中的條目。