Weitere ähnliche Inhalte
Mehr von Yahoo!デベロッパーネットワーク (20)
Kürzlich hochgeladen (12)
OozieをやめてAirflowを導入してみた話 #ApacheAirflow #Oozie
- 3. 自己紹介
名前 : 植草 智輝
入社 : 新卒入社2年目
twitter : @tmk_ueks
github : tomueeen93
仕事 : Y!ショッピング広告関係のETL基盤構築
ジョブ管理システムをOozieからAirflowに
趣味 : ゲーム / ボルダリング / ハッカソン
3
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
- 5. Airflowとは?
• Airbnb製のWorkflow Engine
• Apache(incubating)のOSSプロジェクト
• Python製
• WebUIでタスクモニタリングできる
• プラグインによる拡張が可能
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
5
- 10. 以前のETL基盤
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
10
運用者
ユーザーサービスログ
• ショッピング関連広告データのレポーティング
• クラスタ別に2つのOozieの運用
• ワークフロー定義もそれぞれ別に開発
• サービスデータの連携などはcronで動かしていた
運用
運用
hadoopクラスタ
Job管理
Impalaクラスタ
Job管理
cron
load
- 12. 現在のETL基盤
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
12
hadoopクラスタ
Kylinサーバー
(on HBaseクラスタ)
Job管理
運用者
ユーザーサービスログ
運用
• 集計システムをImpalaからKylinに変更
• Hiveによる集計に変更
• ジョブ管理をOozieからAirflow1.7.1.3に変更
• プロジェクトのみでのパイロット導入
Job管理
Job管理
load
- 13. システムの規模
13
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
• タスク数 約40個
• 入力ソースのチェックタスク
• Hiveクエリ
• Kylinのキューブビルド関係のタスク
• その他マスターデータとの連携など
• デイリーのデータ増加量 約1TB
• デイリーの実行時間平均 約4時間
- 16. Tree Viewを利用して運用
• 一番使っている画面
• 過去タスクの一覧表示されている
• 仕様変更時など再集計時などに使う
• 過去分の一括クリアなどが出来て便利
• 表示する日付が増えると見づらい
16
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
- 19. プラグインの書き方と種類
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
19
• 基本的なクラスを継承したクラスを作成
• 代表的なもの
• Operator : execute関数に書かれた処理を実行する
• Sensor : poke関数の返り値がTrueになるまで処理を実行する
• Hook : MySQLやHiveなど他のシステムを実行する際に利用する
• AIRFLOW_HOME/plugins以下にpythonスクリプトを作成
• 作成したクラス
• AirflowPluginを継承したクラスに作成したPluginを定義したもの
- 20. class MyHivePartitionSensor(HivePartitionSensor):
ui_color = '#83ccd2'
@apply_defaults
def __init__(self,
table,
partition="ds='{{ ds }}'",
hive_cli_conn_id='hiveserver_default',
schema='default',
poke_interval=60 * 3,
*args, **kwargs):
super(MyHivePartitionSensor, self).__init__(
table=table,
partition=partition,
metastore_conn_id=hive_cli_conn_id,
schema=schema,
poke_interval=poke_interval,
*args, **kwargs)
self.hive_cli_conn_id = hive_cli_conn_id
def poke(self, context):
if '.' in self.table:
self.schema, self.table = self.table.split('.')
logging.info(
'Poking for table {self.schema}.{self.table}, '
'partition {self.partition}'.format(**locals()))
if not hasattr(self, 'hook'):
self.hook = DspfecHiveCliHook(
hive_cli_conn_id=self.hive_cli_conn_id)
return self.hook.check_for_partition(
self.schema, self.table, self.partition)
MetastorePartitionSensorの代替Plugin拡張
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
20
HivePartitionSensorを継承したクラスを作成
SHOW PARTITIONSの出力を取得
class MyHiveCliHook(HiveClre.compile(riHook):
re_partition_ok = '^1 row selected', re.MULTILINE)
def check_for_partition(self, schema, table, partition):
hive_result = self.run_cli(
'SHOW PARTITIONS {schema}.{table} PARTITION({partition})'.format(
**locals()))
matches = self.re_partition_ok.findall(hive_result)
return len(matches) > 0
Beelineの出力から正規表現によってパーティション判定
パーティションが出来る(Trueになる)まで定期実行
←Sensor側
↓Hook側
継承したHookが呼び出される
- 21. HiveOperatorでhiveconf共通化するPlugin拡張
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
21
class MyHiveOperator(HiveOperator):
@apply_defaults
def __init__(self,
hql,
hive_cli_conn_id='hive_cli_default',
schema='default',
hiveconf_jinja_translate=False,
script_begin_tag=None,
run_as_owner=False,
hiveconf=None,
*args, **kwargs):
super(MyHiveOperator, self).__init__(
hql=hql,
hive_cli_conn_id=hive_cli_conn_id,
schema=schema,
hiveconf_jinja_translate=hiveconf_jinja_translate,
script_begin_tag=script_begin_tag,
run_as_owner=run_as_owner,
*args, **kwargs)
self.hive_cli_params = ''.join(
[' --hiveconf {}={}'.format(k, v) for k, v in hiveconf.items()]
) if hiveconf else ''
def execute(self, context):
self.hook = self.get_hook()
# add own setting
self.hook.hive_cli_params += self.hive_cli_params
logging.info('Executing: ' + self.hql)
self.hook.run_cli(hql=self.hql, schema=self.schema)
Hookに渡すhive_cli_paramsを上書きする
※本来はConnectionsのExtraに入力されているものが入る
DAGで共通のhiveconfを指定できるようにする
hiveconfs = {
'tez.queue.name': 'scheduled',
'mapred.job.queue.name': 'scheduled',
'hive.exec.scratchdir': '/user/owner/airflow_tmp',
'hive.tez.exec.print.summary': 'true',
'hive.stats.dbclass': 'fs',
'tez.am.view-acls': '*'
}
beeline実行時のオプションに上のhiveconfを連結
DAG側
Plugin側
- 22. airflow run
開発面の効率アップ
22
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
workflow修正
HDFSにPut
oozie run(dryrun)
古いworkflow削除
DAG修正
ここでようやく構文チェック
ここで構文チェック出来る
直接修正できないストレス
Oozie Airflow
- 27. まとめ
• Good
• WebUIがリッチになったことにより、運用のしやすさが激的にUP
• 全てPythonベースで書けるので、読みやすくワークフロー定義の負担が少ない
• Pluginを柔軟に作成できるので、外部のシステム連携がしやすい
• Bad
• 再集計時に一気に実行すると実行順が選べない
• Pluginで色々やりすぎると何をしているかわからなくなるかもしれない
Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
27