天天看點

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 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

    如果遇到如下錯誤,不管
    airflow2.0.2分布式安裝文檔
  • 安裝

    make && make install

  • 檢視一下是否安裝成功

    ll /usr/local/erlang/bin

  • 添加環境變量

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

  • 重新整理環境變量

    source /etc/profile

  • 測試

    erl

  • 退出

    輸入halt().退出

    airflow2.0.2分布式安裝文檔

至此 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,然後就可以用新賬号進行登陸
    airflow2.0.2分布式安裝文檔
三、安裝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目錄如下
    airflow2.0.2分布式安裝文檔
注:上述步驟需要在所有安裝結點進行操作
二、配置airflow

再看一遍安裝規劃

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

此時的架構如下

airflow2.0.2分布式安裝文檔

隊列服務及中繼資料庫(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:[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 = 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 [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
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如下:

airflow2.0.2分布式安裝文檔
  • 啟動任務
    airflow2.0.2分布式安裝文檔
  • 觀測執行情況
    airflow2.0.2分布式安裝文檔
執行任務的(woker)結點為:DATACENTER01
airflow2.0.2分布式安裝文檔
執行任務的(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 排程系統