ETL на Python, или построение
идемпотентных дата пайплайнов
~$ whoami
● Пишу на Python 8 лет
● Tech Lead в Playrix (Marketing)
● Веду блог khashtamov.com
● 100TB+ данных
● 1000+ распределенных сотрудников
● 100+ миллионов событий в день
● 10+ миллионов игроков в день
Что такое ETL (Extract Transform Load):
Как оно бывает
● Кастомные скриптики/процедуры/вьюхи
● Ручной деплой
● Крон для запуска batch задач
Проблемы
● Задачи растут как снежный ком
● Зависимые задачи
● Мониторинг
● Retry механизм
Apache Airflow
● Разработан Spotify, открыт в 2012
● S3, Amazon, Hadoop, Spark, PostgreSQL…
● удобный retry механизм
● удобное определение зависимостей
● оповещения и хуки
● простой код
class DownloadFileTask(luigi.Task):
def run(self):
url = f'https://s3.amazonaws.com/nyc-tlc/trip+data/file.csv'
self.output().makedirs() # in case path does not exist
response = requests.get(url, stream=True)
response.raise_for_status()
with self.output().open(mode='w') as f:
for chunk in response.iter_lines():
f.write('{}n'.format(chunk.decode('utf-8')))
def output(self):
return luigi.LocalTarget(os.path.join('data', self.filename))
class AggregateTaxiTripTask(luigi.Task):
def requires(self):
return DownloadTaxiTripTask()
def run(self):
with self.input().open() as input,
self.output().open('w') as output:
self.output().makedirs()
result = aggregate_taxi_data(input)
output.write(result)
def output(self):
return luigi.LocalTarget(os.path.join('data', f'nyc-taxi-agg.csv'))
TASK
TARGET
Недостатки
● нет планировщика (есть координатор)
● проблемы с масштабированием
“In the future, Luigi might implement its own triggering. The dependency on crontab (or
any external triggering mechanism) is a bit awkward and it would be nice to avoid”
https://luigi.readthedocs.io/en/stable/execution_model.html#scheduler
Apache Airflow
● Разработан AirBnB (Maxime Beauchemin)
● Мощный каркас для сложных пайплайнов
● Flask + Celery
Killer фичи
● Мощный Web UI с планировщиком, базой и логами
● Легко масштабируется за счет очередей (Celery/Dask)
● Хранилище конфигов (с шифрованием)
● Набор готовых операторов (Redshift, Hadoop, Bash, Python)
Operator
from airflow.operators.redshift_to_s3_operator import RedshiftToS3Transfer
run_this = RedshiftToS3Transfer(
schema='public',
table='my_very_big_table',
s3_bucket='my-s3-bucket',
s3_key='unload-airflow',
redshift_conn_id='my_redshift_conn',
aws_conn_id='my_s3_conn',
task_id='redshift_unload',
dag=dag
)
Операторы
● BashOperator
● PostgresOperator
● EmailOperator
● PythonOperator
● ….
DAG
from datetime import datetime
from airflow.models import DAG
args = {
'owner': 'airflow',
'start_date': datetime(2018, 10, 5),
}
dag = DAG(
dag_id='my_unload_redshift',
default_args=args,
schedule_interval=None
)
Sensor
Тестирование
● Unit-тесты
● Не пишите логику в тасках (Luigi)
● localstack для AWS
А можно ещё ?
● Apache NiFi
● Prefect
● RQ
● Celery
● Dask
Что выбрать?
¿Q & A?
@adilkhash
telegram: @dataeng_chat

ETL на Python