airflow2.0.2分散式安裝文件

lillcol發表於2021-06-07

更多內容可關注兔八哥雜談

需要安裝的元件

元件 功能
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 http://erlang.org/download/otp_src_24.0.tar.gz

    wget https://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 https://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埠

http://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 https://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="https://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 https://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 https://github.com/teamclairvoyant/airflow-scheduler-failover-controller
//網路不穩定有時候下不下來,可以去找其他資源然後上傳伺服器安裝

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

3. 初始化 failover
sudo pip3.7 install -e . [-i https://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:airflow123@10.0.0.1: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:airflow123@10.0.0.1:3306/airflow_db 
# 注意此處要用result_backend,有些部落格使用celery_result_backend,但是在測試過程中會無法識別
result_backend = db+mysql://airflow:airflow123@10.0.0.1: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 = http://localhost:8081
base_url = http://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 spiderman@superhero.org
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
http://DATACENTER01:8081
http://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 排程系統

更多內容可關注兔八哥雜談

相關文章