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