Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

OozieをやめてAirflowを導入してみた話 #ApacheAirflow #Oozie

4,077 views

Published on

2017/05/11に開催された「Tokyo Airflow Meetup #1」での発表資料です。
ジョブ管理システムをApache OozieからApache Airflowに変えた際の事例紹介となります。

イベントURL
https://www.meetup.com/ja-JP/Tokyo-Apache-Airflow-incubating-Meetup/events/238731591/

Published in: Technology

OozieをやめてAirflowを導入してみた話 #ApacheAirflow #Oozie

  1. 1. OozieをやめてAirflowを導入してみた話 Tokyo Airflow Meetup #1 Yahoo! JAPAN D&S統括本部 データプラットフォーム本部開発2部 コマースインフラ 植草 智輝
  2. 2. 自己紹介 Airflowについて 事例紹介 Airflowを使って良かったこと 手が届かなかったところ まとめ アジェンダ
  3. 3. 自己紹介 名前 : 植草 智輝 入社 : 新卒入社2年目 twitter : @tmk_ueks github : tomueeen93 仕事 : Y!ショッピング広告関係のETL基盤構築 ジョブ管理システムをOozieからAirflowに 趣味 : ゲーム / ボルダリング / ハッカソン 3 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
  4. 4. Airflowについて Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 4
  5. 5. Airflowとは? • Airbnb製のWorkflow Engine • Apache(incubating)のOSSプロジェクト • Python製 • WebUIでタスクモニタリングできる • プラグインによる拡張が可能 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 5
  6. 6. Workflow Engineとは? 複数の処理の依存関係を定義し、それらの実行を管理するもの 近年、OSSでも多数のWorkflow Engineが公開されている。 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 6 参考: Workflow Engines Meetup#1
  7. 7. Airflowの特徴 • DAG(処理フロー)をコードで定義できる • 標準で様々なシステム連携がサポートされていて簡単に利用できる • Pythonによるプラグイン拡張ができる • 標準に含まれていない機能を補える • スケーラブル • 処理を実行するWorkerの分散が可能 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 7
  8. 8. 事例紹介 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 8
  9. 9. プロダクト概要 • ヤフーショッピング広告関連のETL基盤の開発 • ストア向けの広告レポートの集計 • 社内向けにはアナリストなどへのレポートの集計 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 9
  10. 10. 以前のETL基盤 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 10 運用者 ユーザーサービスログ • ショッピング関連広告データのレポーティング • クラスタ別に2つのOozieの運用 • ワークフロー定義もそれぞれ別に開発 • サービスデータの連携などはcronで動かしていた 運用 運用 hadoopクラスタ Job管理 Impalaクラスタ Job管理 cron load
  11. 11. Oozieを利用していた時に感じていた課題 • XMLがしんどい • タスクの確認や再実行が面倒 • CLIでJob IDを確認して、再実行とかするのがしんどい • クラスタごとにOozieを管理しなければいけない • Hadoop外の連携が面倒 • GMTでの時間指定のみ • コミュニティがあまり活発ではない Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 11
  12. 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. システムの規模 13 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 • タスク数 約40個 • 入力ソースのチェックタスク • Hiveクエリ • Kylinのキューブビルド関係のタスク • その他マスターデータとの連携など • デイリーのデータ増加量 約1TB • デイリーの実行時間平均 約4時間
  14. 14. Airflowを使ってよかったこと Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 14
  15. 15. WebUIで運用のしやすさが向上 再集計時がWebUIから一括で出来る 15 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 👆 依存関係を一覧で見れるので、原因究明が速い
  16. 16. Tree Viewを利用して運用 • 一番使っている画面 • 過去タスクの一覧表示されている • 仕様変更時など再集計時などに使う • 過去分の一括クリアなどが出来て便利 • 表示する日付が増えると見づらい 16 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
  17. 17. クエリチューニングなどもしやすい • ガントチャートで実行時間が見れる • 時間のかかっているタスクが分かる • クエリチューニングをする時などに利用 • 不自然に時間がかかっていたら見直す • 縦線が無いので若干見づらい(最新版はある) 17 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止
  18. 18. 標準に足りない部分はPluginを作れる • クラスタのネットワークポリシー上MetastorePartitionSensorが利用不可 • 全てのHiveOperatorで共通したhiveconfを指定したい • quota使用量のメトリクスが取得したい • etc.. 18 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 独自環境依存の部分に対してはPluginで対応
  19. 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. 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. 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. 22. airflow run 開発面の効率アップ 22 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 workflow修正 HDFSにPut oozie run(dryrun) 古いworkflow削除 DAG修正 ここでようやく構文チェック ここで構文チェック出来る 直接修正できないストレス Oozie Airflow
  23. 23. 手が届かなかったところ Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 23
  24. 24. 再集計時の実行順が選べなかった • 再集計時などに古い日付から順に実行を進めたい • 一気にタスクをクリアするとschedulerが拾った順にqueueに入る • 結果的に順不同に並列実行される • 並列実行NGかつ、古い順に実行したい • 現状では再集計するスクリプト(or DAG)を作成して対応 Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 24 順番に実行したい再実行タスク
  25. 25. Pluginによるコード肥大化・複雑化の可能性 • なんでもPluginにしていると何してるかわからなくなる • 一般的なPythonのパッケージ管理方法でしっかり分割管理 • 通知機能などはpip packageに分割している • Dagはあくまで定義に留める、Pluginもあくまで機能拡張 • 良い管理方法あったら教えて下さい Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 25
  26. 26. まとめ Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 26
  27. 27. まとめ • Good • WebUIがリッチになったことにより、運用のしやすさが激的にUP • 全てPythonベースで書けるので、読みやすくワークフロー定義の負担が少ない • Pluginを柔軟に作成できるので、外部のシステム連携がしやすい • Bad • 再集計時に一気に実行すると実行順が選べない • Pluginで色々やりすぎると何をしているかわからなくなるかもしれない Copyright (C) 2017 Yahoo Japan Corporation. All rights reserved. 無断引用・無断転載禁止 27

×