airflow2.0.2分散式安裝文檔

需要安裝的組件

組件 功能
Airflow Webserver 查詢元數據以監控和執行DAGs的web介面。
Airflow Scheduler 它檢查元數據資料庫中的DAG和任務的狀態,
在必要時創建新任務,並將任務發送到隊列。
Airflow Metadata Database 它包含DAG運行和任務實例的狀態.
Airflow Message Broker 它將在隊列中存儲要運行的任務命令。
Airflow Workers 它們從隊列中檢索命令,執行命令,並更新元數據。

伺服器 結點 服務
DATACENTER01 master1 webserver, scheduler,worker,rabbitmq(選裝)
DATACENTER03 master2 webserver,scheduler
DATACENTER04 worker1 worker
DATACENTER05 worker2 worker

安裝步驟:

準備環境

一、安裝erlang

因為要用到RabbitMQ,由於rabbitmq是基於erlang語言開發的,所以必須先安裝erlang。

版本對應,若無要求按照文檔來即可

  • 安裝依賴

    yum -y install gcc glibc-devel make ncurses-devel openssl-devel xmlto perl wget gtk2-devel binutils-devel

  • 下載erlang

    wget //erlang.org/download/otp_src_24.0.tar.gz

    wget //fossies.org/linux/misc/otp_src_24.0.tar.gz(比較快)

  • 解壓otp_src_24.0.tar.gz

    tar -zxvf otp_src_24.0.tar.gz

  • 移動位置

    mv otp_src_24.0 /usr/local/

  • 切換目錄

    cd /usr/local/otp_src_24.0/

  • 創建即將安裝的目錄

    mkdir ../erlang

  • 配置安裝路徑

    ./configure --prefix=/usr/local/erlang

    如果遇到如下錯誤,不管

  • 安裝

    make && make install

  • 查看一下是否安裝成功

    ll /usr/local/erlang/bin

  • 添加環境變數

    echo 'export PATH=$PATH:/usr/local/erlang/bin' >> /etc/profile

  • 刷新環境變數

    source /etc/profile

  • 測試

    erl

  • 退出

    輸入halt().退出

至此 erlang 安裝完成


二、安裝RabbitMQ
  • 下載

    wget //github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.16/rabbitmq-server-generic-unix-3.8.16.tar.xz

  • 由於是tar.xz格式的所以需要用到xz,沒有的話就先安裝(可選)

    yum install -y xz

  • 第一次解壓

    /bin/xz -d rabbitmq-server-generic-unix-3.8.16.tar.xz

  • 第二次解壓

    tar -xvf rabbitmq-server-generic-unix-3.8.16.tar

  • 移走

    mv rabbitmq_server-3.8.16/ /usr/local/

  • 改名

    cd /usr/local/
    mv /usr/local/rabbitmq_server-3.7.15 rabbitmq

  • 配置環境變數

    echo 'export PATH=$PATH:/usr/local/rabbitmq/sbin' >> /etc/profile

  • 刷新環境變數

    source /etc/profile

  • 創建配置目錄(未使用單獨的配置文件,此步驟可以不用)

    mkdir /etc/rabbitmq

  • 啟動

    rabbitmq-server -detached

  • 停止

    rabbitmqctl stop

  • 狀態

    rabbitmqctl status

  • 開啟web插件

    rabbitmq-plugins enable rabbitmq_management

  • 訪問:15672埠

//127.0.0.1:15672/

默認帳號密碼:guest guest(這個帳號只允許本機訪問)

  • 查看所有用戶

    rabbitmqctl list_users

  • 添加一個用戶

    rabbitmqctl add_user lillcol 123456

  • 配置許可權

    rabbitmqctl set_permissions -p "/" lillcol ".*" ".*" ".*"

  • 查看用戶許可權

    rabbitmqctl list_user_permissions lillcol

  • 設置tag

    rabbitmqctl set_user_tags lillcol administrator

  • 刪除用戶(安全起見,刪除默認用戶)

    rabbitmqctl delete_user guest

  • 配置好用戶之後重啟一下rabbit,然後就可以用新帳號進行登陸


三、安裝python3.7.5

經測試,3.7.5一下版本安裝airflow過程中會出現各種問題,所以需要安裝3.7.5,(3.7.5+沒測試不知道會不會出問題)

  • 安裝編譯相關工具
yum -y groupinstall "Development tools"
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
yum install libffi-devel -y
  • 下載安裝包解壓

    wget //www.python.org/ftp/python/3.7.5/Python-3.7.5.tar.xz

    tar -xvJf Python-3.7.5.tar.xz

  • 編譯安裝python

    mkdir /usr/python3.7 #創建編譯安裝目錄

    cd Python-3.7.5

    ./configure --prefix=/usr/python3.7 --enable-optimizations

    make && make install

  • 創建軟連接

    ln -s /usr/python3.7/bin/python3 /usr/bin/python3.7

    ln -s /usr/python3.7/bin/pip3 /usr/bin/pip3.7

  • 驗證是否成功

    python3.7 -V

    pip3.7 -V

[root@DATACENTER04 bin]# python3.7 -V
Python 3.7.5
[root@DATACENTER04 bin]# pip3.7 -V

pip 19.2.3 from /usr/python3.7/lib/python3.7/site-packages/pip (python 3.7)
  • 升級pip3.7

    安裝airflow pip版本過低會導致安裝失敗

    pip3.7 install --upgrade pip==21.1.2

[root@DATACENTER04 bin]# pip3.7 install --upgrade pip==21.1.2
[root@DATACENTER04 bin]# pip3.7 -V
pip 21.1.2 from /usr/python3.7/lib/python3.7/site-packages/pip (python 3.7)
  • 安裝gunicorn

    pip3.7 install --upgrade pip==21.1.2

三、配置mysql

此處使用mysql進行元數據管理,要求mysql 5.7+以上版本。

  • 創建airflow_db庫
    CREATE DATABASE airflow_db CHARACTER SET UTF8mb3 COLLATE utf8_general_ci;

注意要用UTF8mb3,UTF8mb4在測試過程中出現錯誤

  • 修改許可權
CREATE USER 'airflow' IDENTIFIED BY 'airflow123';
GRANT ALL PRIVILEGES ON airflow_db.* TO 'airflow';

安裝airflow

一、安裝airflow
  • 配置apps sudo許可權(root)

    給apps用戶sudo許可權,vi /etc/sudoers,,加入下面語句,否則安裝install的時候可能會失敗

## Allow root to run any commands anywhere 
root	ALL=(ALL) 	ALL
apps    ALL=(ALL)                NOPASSWD: ALL #加入這一句
  • 配置airflow環境變數(root)

    安裝完後airflow安裝路徑默認為:/home/apps/.local/bin,vi /etc/profile尾部加入如下內容:

    export PATH=$PATH:/usr/python3/bin:/home/apps/.local/bin

    source /etc/profile

此處的/home/apps/.local/bin 為~/.local/bin,

根據實際配置PATH=$PATH:~/.local/bin

  • 配置hosts(root),vi /etc/hosts,加入下面語句
199.232.68.133 raw.githubusercontent.com
  • 配置環境變數(apps)(可選,默認~/airflow)
export AIRFLOW_HOME=~/airflow
  • 配置版本資訊(apps)
AIRFLOW_VERSION=2.0.2 # airflow版本
PYTHON_VERSION="$(python3.7 --version | cut -d " " -f 2 | cut -d "." -f 1-2)" # python版本
CONSTRAINT_URL="//raw.githubusercontent.com/apache/airflow/constraints-${AIRFLOW_VERSION}/constraints-${PYTHON_VERSION}.txt" # 約束url
  • 安裝airlfow(apps)

    執行安裝命令,注意要加sudo,否則會有部分缺失,但是沒有報錯

sudo pip3.7 install "apache-airflow==${AIRFLOW_VERSION}" --constraint "${CONSTRAINT_URL}" --use-deprecated legacy-resolver  [-i //pypi.douban.com/simple]
  • 如果上面的步驟順利執行,此時會有airflow命令,並且會創建~/airflow,進入airflow目錄如下

註:上述步驟需要在所有安裝結點進行操作


二、配置airflow

再看一遍安裝規劃

伺服器 結點 服務
DATACENTER01 master1 webserver, scheduler,worker,rabbitmq(選裝)
DATACENTER03 master2 webserver,scheduler
DATACENTER04 worker1 worker
DATACENTER05 worker2 worker

此時的架構如下

隊列服務及元資料庫(Metestore)的高可用

隊列服務採用RabbitMQ,已經安裝在DATACENTER01,可以通過部署高可用實現隊列的高可用,(本案例沒有對隊列做高可用)

元資料庫(Metestore) 高可用
取決於所使用的資料庫,此處採用mysql。可以通過部署主從備份實現高可用

  • 配置scheduler高可用

    我們可以通過第三方組件 airflow-scheduler-failover-controller 實現 scheduler 的高可用,安裝配置步驟如下:

1. 下載failover
gitclone //github.com/teamclairvoyant/airflow-scheduler-failover-controller
//網路不穩定有時候下不下來,可以去找其他資源然後上傳伺服器安裝

2. 安裝failover
cd{AIRFLOW_FAILOVER_CONTROLLER_HOME}
sudo pip3.7 install -e . [-i //pypi.douban.com/simple] 

3. 初始化 failover
sudo pip3.7 install -e . [-i //pypi.douban.com/simple] 
//初始化 failover 會向${AIRFLOW_HOME}/airflow.cfg中追加內容

4. 更改${AIRFLOW_HOME}/airflow.cfg配置,4~7 步驟之後的所有步驟可以後面統一操作
scheduler_nodes_in_cluster= DATACENTER01,DATACENTER03

5. 配置DATACENTER01,DATACENTER03之間免密登陸

6. 測試免密登陸
scheduler_failover_controller test_connection  
scheduler_failover_controller get_current_host //獲取當前的host,可以用於查看安裝情況

7. 啟動failover
nohup scheduler_failover_controller start >/dev/null 2>&1 &
  1. failover需要在運行scheduler的伺服器上部署,此處需要在DATACENTER01,DATACENTER03部署
  2. 免密登陸配置參考Centos7下實現免密碼登錄
  • 配置{AIRFLOW_HOME}/airflow.cfg

    將一下內容配置進{AIRFLOW_HOME}/airflow.cfg

1.  Executor 為 CeleryExecutor
# executor = LocalExecutor
executor = CeleryExecutor

2. 指定元資料庫(metestore)
#sql_alchemy_conn = sqlite:////home/apps/airflow/airflow.db
sql_alchemy_conn = mysql+pymysql://airflow:[email protected]:3306/airflow_db

3. 設置broker,即消息隊列,此處使用 RabbitMQ
# broker_url = redis://redis:6379/0
broker_url = amqp://lillcol:123456@DATACENTER01:5672/

4. 設定結果存儲後端 backend
# result_backend = db+postgresql://postgres:airflow@postgres/airflow
# 當然您也可以使用 Redis :celery_result_backend =redis://{REDIS_HOST}:6379/1
# celery_result_backend = db+mysql://airflow:[email protected]:3306/airflow_db 
# 注意此處要用result_backend,有些部落格使用celery_result_backend,但是在測試過程中會無法識別
result_backend = db+mysql://airflow:[email protected]:3306/airflow_db

5. 配置scheduler_nodes_in_cluster容錯結點
scheduler_nodes_in_cluster= DATACENTER01,DATACENTER03

6.修改時區 
# default_timezone = utc
default_timezone = Asia/Shanghai

7. 配置web埠(默認8080,因為已被佔用此處改為8081)
endpoint_url = //localhost:8081
base_url = //localhost:8081
web_server_port = 8081

8. 關閉載入案例(可選)
# load_examples = True
load_examples = False

9. 郵件相關配置(可選)
[smtp]
smtp_host = mail.ndpmedia.com
smtp_starttls = True
smtp_ssl = False
smtp_user = user
smtp_password = pass
smtp_port = 25
smtp_timeout = 30
smtp_mail_from =與user相同
smtp_retry_limit = 5

將修改後的{AIRFLOW_HOME}/airflow.cfg同步到所有安裝airflow的伺服器上


三、啟動airflow集群
  • 初始化資料庫(apps@DATACENTER0):airflow db init

次步驟會在mysql上創建相關元數據表

  • 創建用戶(apps@DATACENTER01):
airflow users create \
    --username admin \
    --firstname Peter \
    --lastname Parker \
    --role Admin \
    --email [email protected]
Password:123456
  • 啟動webserver:
airflow webserver -D

次步驟在DATACENTER01,DATACENTER03執行

  • 啟動scheduler
#1. 需要先啟動scheduler容錯插件scheduler_failover_controller,
#   此步驟在DATACENTER01,DATACENTER03執行
nohup scheduler_failover_controller start >/dev/null 2>&1 &

#2. 啟動scheduler,次步驟只需要在DATACENTER01執行
nohup airflow scheduler >/dev/null 2>&1 &

同一時間只能啟動一個scheduler,一旦運行 scheduler 守護進程的機器出現故障,立刻啟動另一台機器上的 scheduler 。

  • 啟動worker
#1. 確保必要軟體已經安裝
sudo pip3.7 install pymysql
sudo pip3.7 install celery
sudo pip3.7 install flower
sudo pip3.7 install psycopg2-binary

#2. 先啟動flower,在需要啟動worker伺服器執行,此處在DATACENTER01,DATACENTER04執行
airflow celery flower -D

#3. 啟動worker,在需要啟動worker伺服器執行,此處在DATACENTER01,DATACENTER04執行
airflow celery worker -D

確保worker的8793已經開放,WEB UI查看log的時候無法載入相關日誌


四、啟動airflow集群
  • 登陸web UI
# 因為在DATACENTER01、DATACENTER03啟動了webserver,可以通過下面二選一打開WEB UI
//DATACENTER01:8081
//DATACENTER03:8081

帳號:Admin 密碼:123456

登陸後可以新增其他的用戶

五、配置、執行dag

  • 配置dags

    airflow 的dags默認在{AIRFLOW_HOME}/dags

    任務通過scheduler調度,並通過worker執行

    所以在所有有啟動scheduler和worker的伺服器上都要有相同的dags與相關腳本

    即我們需要保證所有結點下的{AIRFLOW_HOME}/dags以及依賴的腳本是一致的

    如果不一致可能導致兩個結果:

  1. WEB UI中的dags與{AIRFLOW_HOME}/dags中不一致

取決於當前scheduler上面的{AIRFLOW_HOME}/dags

  1. 任務執行失敗

在對應的woker上找不到執行的dag或相關腳本

比如目前scheduler 運行在DATACENTER03,此時{AIRFLOW_HOME}/dags如下:

[apps@DATACENTER03 dags]$ ll
total 40
-rw-r--r-- 1 apps dolphinscheduler 12513 May 28 15:14 DAG_**_D2.py
-rw-r--r-- 1 apps dolphinscheduler 12512 May 25 17:51 DAG_**_D.py
drwxr-xr-x 2 apps dolphinscheduler   132 Jun  4 18:03 __pycache__
-rw-r--r-- 1 apps dolphinscheduler  1381 Jun  4 16:43 TEST_RUN2.py
-rw-r--r-- 1 apps dolphinscheduler  1380 Jun  1 09:02 TEST_RUN.py

WEB UI如下:

  • 啟動任務

  • 觀測執行情況

執行任務的(woker)結點為:DATACENTER01

執行任務的(woker)結點為:DATACENTER04

所以我們必須保證所有結點的dags 與 依賴腳本同步


錯誤處理

  • Specified key was too long
[apps@DATACENTER03 airflow]$ airflow db init
...
    raise errorclass(errno, errval)
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1071, 'Specified key was too long; max key length is 3072 bytes')
[SQL: ALTER TABLE xcom ADD CONSTRAINT pk_xcom PRIMARY KEY (dag_id, task_id, `key`, execution_date)]

解決辦法:

#創建airflow_db時候指定編碼
#CREATE DATABASE airflow_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE airflow_db CHARACTER SET UTF8mb3 COLLATE utf8_general_ci;

CREATE USER 'airflow' IDENTIFIED BY 'airflow123';
GRANT ALL PRIVILEGES ON airflow_db.* TO 'airflow';

  • explicit_defaults_for_timestamp 錯誤
MySQL [(none)]> show global variables like '%timestamp%';
+---------------------------------+--------+
| Variable_name                   | Value  |
+---------------------------------+--------+
| explicit_defaults_for_timestamp | OFF    |
| log_timestamps                  | SYSTEM |
+---------------------------------+--------+
2 rows in set (0.02 sec)

# 修改explicit_defaults_for_timestamp=1
MySQL [(none)]> set global explicit_defaults_for_timestamp =1;
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> show global variables like '%timestamp%';
+---------------------------------+--------+
| Variable_name                   | Value  |
+---------------------------------+--------+
| explicit_defaults_for_timestamp | ON     |
| log_timestamps                  | SYSTEM |
+---------------------------------+--------+

  • -bash: airflow: command not found

    安裝完後沒有出現airflow命令以及相關結構,解決辦法有兩個

  1. 卸載apache-airflow,重新安裝一次,命令如下:
sudo pip3.7 uninstall apache-airflow==2.0.2
pip3.7 install "apache-airflow==${AIRFLOW_VERSION}" --constraint "${CONSTRAINT_URL}" --use-deprecated legacy-resolver
  1. 將~/.local/bin加入PATH ,(推薦,在airflow安裝前配置)
PATH=$PATH:~/.local/bin

  • No module named ‘airflow’
# 在啟動webserver的時候可能會出現下面的錯誤,同樣的處理方法
No module named 'airflow'
No module named 'airflow.www'
No module named 'airflow.www.gunicorn_config'
FileNotFoundError: [Errno 2] No such file or directory: 'gunicorn': 'gunicorn'

解決辦法:

#創建/usr/python3.7/bin/gunicorn的軟連接替換原來的gunicorn,
#可能在``/usr/python3/bin``或``/usr/bin``下,具體看情況操作
1. 刪除原來的軟連接 
sudo rm -rf /usr/python3/bin/gunicorn
2. 創建新的軟連接 
sudo ln -s /usr/python3.7/bin/gunicorn /usr/python3/bin

airflow webserver啟動時,會調用subprocess.Popen創建子進程,webserver使用gunicorn

執行gunicorn啟動時,可能是在PATH中找不到該命令報錯

也可能是gunicorn的版本過低導致報錯

目前的版本至少是gunicorn (version 19.10.0)

  • ModuleNotFoundError: No module named ‘MySQLdb’

    啟動worker的時候ModuleNotFoundError: No module named 'MySQLdb'

    解決辦法安裝mysqlclient(python 3.7 要安裝mysqlclient):

sudo pip3.7 install mysqlclient

  • 無法讀取worker端的log

    airlfow日誌默認存儲在{AIRFLOW_PATH}/logs/{dag}/…下,

    此時在讀取在web 端讀取不到日誌可能有兩種情況

  1. 未開放worker的8793埠,解決辦法開放埠
  2. 此目錄的的許可權問題,開放{AIRFLOW_PATH}的許可權即可

  • 配置免密登陸,但是執行scheduler_failover_controller test_connection的時候還是需要輸入密碼

    免密配置問題,可能兩個原因:

  1. 許可權問題

    sshd為了安全,對屬主的目錄和文件許可權有所要求。如果許可權不對,則ssh的免密碼登陸不生效。
    要求如下:

#用戶目錄許可權為 755 或者 700,就是不能是77x。
#.ssh目錄許可權一般為755或者700。
#rsa_id.pub 及authorized_keys許可權一般為644
#rsa_id許可權必須為600
將目錄改成對應的許可權即可
  1. 防火牆的問題

    關閉防火牆測試

systemctl status firewalld

參考文檔:

官方安裝文檔

airflow 的安裝部署與填坑

如何部署一個健壯的 apache-airflow 調度系統