本文原載于:https://old-panda.com/2018/10/26/airflow-101/
距離上回寫小作文過了多半年芍锚,這幾個月來發(fā)生了一些事情萧福,最大的就是這個月初我換了工作绎狭,從抬闯、 Palo Alto 換到了 Mountain View 溉躲,附近吃的喝的玩的較之以前有了很大的提升星岗。但總歸主業(yè)是過來干活的,上班大概三周了首有,很開心剛?cè)肼毦妥屛已芯块_發(fā)一個新項目燕垃,其核心就是 Airflow ,一個有向無環(huán)圖任務(wù)( Directed Acyclic Graph – DAG)的調(diào)度工具井联,看了不少文檔博客卜壕,踩了大大小小的坑,算是成功的把它運(yùn)行到了服務(wù)器上烙常,下一步就可以在這個基礎(chǔ)上開發(fā)一些東西轴捎。既然告一段落,那么應(yīng)該寫點(diǎn)文字蚕脏,以 Airflow 為例轮蜕,簡單描述如何把一個程序作為一個服務(wù)運(yùn)行在 Linux 機(jī)器上。
安裝
我創(chuàng)建了一個用戶 airflow
專門負(fù)責(zé) Airflow 的運(yùn)行蝗锥,即無論是安裝運(yùn)行 Airflow ,還是修改 Airflow 的配置率触,都通過該用戶來進(jìn)行终议,為了進(jìn)展順利,給這個用戶開了綠燈葱蝗,授予 root 權(quán)限穴张。安裝 Airflow 這一步其實是最簡單的,官網(wǎng)有詳細(xì)的說明两曼。我的環(huán)境是 Python 3.6.6 皂甘, Airflow 的版本是 1.10.0 ,為了避免與已有的包沖突悼凑,我將其安裝在一個 virtualenv 中偿枕,在 /home/airflow
下執(zhí)行如下命令
virtualenv venv -p `which python3`
source venv/bin/activate
pip install apache-airflow[postgres,crypto,gcp_api]==1.10.0
方括號中的是可選的依賴,在這里我用 PostgreSQL 作為 Airflow metadata 的數(shù)據(jù)庫(默認(rèn)是 SQLite )户辫,并且想要加密我的各種鏈接參數(shù)如密碼渐夸,同時想要與谷歌云服務(wù)進(jìn)行交互,所以安裝這三個渔欢。用戶可以根據(jù)自己的實際情況選擇不同的依賴墓塌,詳細(xì)說明可以參考官方文檔。
插一句題外話, 如果想給自己開發(fā)的 Python 包添加可選依賴的話(方括號)苫幢,可以通過定義 setup.py
的 extra_require
來實現(xiàn)访诱,具體可參考這里。
配置文件
因為我們希望把 Airflow 作為一個服務(wù)運(yùn)行起來韩肝,便于以后的繼續(xù)開發(fā)及維護(hù)触菜,而不是運(yùn)行一次給人看看效果就拉倒,所以我采用了 systemd 來管理 Airflow 進(jìn)程的運(yùn)行伞梯。
關(guān)于 systemd 的配置玫氢, Airflow 的文檔上有個簡要介紹,具體來說谜诫,在我的配置中漾峡,我將環(huán)境變量 AIRFLOW_HOME
設(shè)置為 /etc/airflow
,將 AIRFLOW_CONFIG
設(shè)置為 /etc/airflow/airflow.cfg
喻旷,這樣生逸,在我的文件 /etc/sysconfig/airflow
中只有這兩行環(huán)境變量
AIRFLOW_CONFIG=/etc/airflow/airflow.cfg
AIRFLOW_HOME=/etc/airflow
為了將 Airflow 能順利運(yùn)行起來,有兩個必需的服務(wù)且预,一個 webserver 槽袄,用于顯示 web UI ,一個 scheduler 锋谐,用于執(zhí)行 DAG 中的任務(wù)遍尺,好在 Airflow 已經(jīng)提供給了我們這兩個服務(wù)的示例文件: airflow-webserver.service
和 airflow-scheduler.service
,唯一需要修改的一行就是 ExecStart
涮拗,因為我們將要在虛擬環(huán)境中運(yùn)行 Airflow 乾戏,最終這兩個文件分別如下所示
- airflow-webserver.service
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
[Unit]
Description=Airflow webserver daemon
After=network.target postgresql.service mysql.service redis.service rabbitmq-server.service
Wants=postgresql.service mysql.service redis.service rabbitmq-server.service
[Service]
EnvironmentFile=/etc/sysconfig/airflow
User=airflow
Group=airflow
Type=simple
ExecStart=/bin/bash -c 'source /home/airflow/venv/bin/activate ; airflow webserver --pid /run/airflow/webserver.pid'
Restart=on-failure
RestartSec=5s
PrivateTmp=true
[Install]
WantedBy=multi-user.target
- airflow-scheduler.service
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
[Unit]
Description=Airflow scheduler daemon
After=network.target postgresql.service mysql.service redis.service rabbitmq-server.service
Wants=postgresql.service mysql.service redis.service rabbitmq-server.service
[Service]
EnvironmentFile=/etc/sysconfig/airflow
User=airflow
Group=airflow
Type=simple
ExecStart=/bin/bash -c 'source /home/airflow/venv/bin/activate ; airflow scheculer'
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
具體 bash 的位置因系統(tǒng)而異,需要注意的一點(diǎn)就是必須用絕對路徑來執(zhí)行三热。然后將兩者置于 /etc/systemd/system
下鼓择。還有一個文件是不可缺少的 airflow.conf
,這個直接抄下來放在 /etc/systemd
里就漾。
這樣 systemd 的部分算是完成了呐能,但還不算完,我們還需要一個 airflow.cfg 來告訴 Airflow 如何配置抑堡。每個用戶的具體情況不一樣摆出,我就不一一贅述了,這里只提幾個比較重要的夷野。
-
sql_alchemy_conn = postgresql+psycopg2://<user>:<password>@<host>:<port>
我們在生產(chǎn)環(huán)境采用 PostgreSQL 作為 metadata 數(shù)據(jù)庫 -
load_examples = False
示例 DAG 自己在開發(fā)測試的時候是很好的參考懊蒸,但明顯在生產(chǎn)環(huán)境中用不到它們,所以關(guān)掉 -
fernet_key = <some base64 string>
這個肯定得有悯搔,要不然 Airflow 會把各種鏈接的敏感參數(shù)存成明文骑丸,生成方法可以參考這里 -
executor = LocalExecutor
LocalExecutor 可以最大程度的利用單機(jī)的并行能力舌仍,即運(yùn)行多個進(jìn)程來同時執(zhí)行不同的任務(wù),對于目前的需求來說是足夠了通危,以后還可以考慮使用 redis + celery 的方式進(jìn)行橫向擴(kuò)展
運(yùn)行
首先要初始化數(shù)據(jù)庫铸豁,這個得手動搞,還是以 airflow 的身份運(yùn)行
source ~/venv/bin/activate
export AIRFLOW_HOME=/etc/airflow
airflow initdb
然后就可以用 systemd 來控制 Airflow 的啟停了
sudo systemctl [start|stop|restart|status] airflow-webserver
sudo systemctl [start|stop|restart|status] airflow-scheduler
每次希望新加入一個 DAG 時菊碟,只需要把 Python 文件放到 /etc/airflow/dags
里即可节芥。
參考
- https://airflow.readthedocs.io/en/latest/
- https://github.com/apache/incubator-airflow
- https://wecode.wepay.com/posts/airflow-wepay
- https://medium.com/@vando/airflow-inside-a-virtual-enviroment-and-integrated-with-systemd-3b6427bd6430
- https://robinhood.engineering/why-robinhood-uses-airflow-aed13a9a90c8