Python + Hive on AWS EMR で貧者のログサマリ
Upcoming SlideShare
Loading in...5
×
 

Python + Hive on AWS EMR で貧者のログサマリ

on

  • 321 views

PyCon JP 2014資料

PyCon JP 2014資料

Statistics

Views

Total Views
321
Views on SlideShare
273
Embed Views
48

Actions

Likes
2
Downloads
0
Comments
0

1 Embed 48

https://twitter.com 47

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Python + Hive on AWS EMR で貧者のログサマリ Python + Hive on AWS EMR で貧者のログサマリ Presentation Transcript

  • 1 Python + AWS EMR 貧者のログ集計 PyCon JP 2014, 09/14 Akira Chiku
  • achiku(29) 2 Name: Akira Chiku Twitter: @_achiku GitHub: @achiku 趣味:炎舞(Akira Chiku Fireで検索) 職業:エンジニア@kanmu
  • Goal 3 皆さんの話を聞きたい(自分が)  「なぜその構成なのか」に焦点を置いた事例の共有  「入門以上」を目指したPython+EMR活用方法の共有
  • Kanmu (Business) 4  カード会社と協業した決済データ分析  カードに紐づくクーポンの配信  Card Linked Offer(CLO)
  • Card Linked Offer (1/2) 5
  • Card Linked Offer (2/2) 「A店のクーポンエントリーし た!カードで買い物すればポ 6 イントゲット。」 カード 会社/ Kanmu 「こういうお客さんに こういうクーポン出したい!」 「こういう購買傾向のお客さんの方 がいいのでは?」 「こんな結果だったので、次回はこ ういうセグメント切りましょう!」 カード 会員 お店
  • Quick Survey 7  ログ分析に関わっていらっしゃる方?  Hadoop使ってらっしゃる方?  Hive使ってらっしゃる方?  EMR使ってらっしゃる方?
  • 8 「なぜその構成なのか」 に焦点を当てた事例の共有
  • 9 弊社の前提
  • 10 このトークのタイトル
  • 11 貧者のログ集計
  • 12 Poor man’s ?  今ある現状を元に  省リソース(人/時間/経験)で目的を達成する姿勢  目的を達成するスピードを可能な限り上げる姿勢  無用な支出を避ける姿勢
  • Kanmu (Engineer Team) 13 8maki (CEO/Engineer) _ideyuta (Designer) moqada (Engineer) _achiku (Engineer) 社長業/研究開発 デザイン/フロント/ スマホアプリ/ログ分析 フロント/バックエンド/ インフラ/スマホアプリ バックエンド/インフラ/ 分析基盤/ログ分析/対パートナー窓口
  • 14 Requirements  ある程度の量になるデータをストレス無く集計したい • Ave:1.7G/day, Max:3.0G/day (非圧縮) • 500GB+/月(非圧縮) • サービスの成長と共に増える見込み • 月単位でアドホックなクエリも投げたい  社内に大規模データを処理する知見を貯めたい • 「ペース配分をした上で」知見を貯める • 外部に出しにくいセンシティブなデータも存在  運用コスト/初期投資を低く抑えたい
  • 15 Not Requirements  分析がリアルタイムである必要性は現状高くない  アドホック分析基盤のサービスレベルは決して高くない • 普通のバッチ処理は落ちては駄目だけど • 常に利用可能な状態になっていなくても良い • 利用は社内に限定されている  ただし、上記がRequirementsになる可能性は十分有る
  • 16 Amazon Elastic MapReduce
  • 17 AWS EMR  数あるAWSサービスのうちの一つ  HadoopやHadoopエコシステム内のSWがデ フォルトで利用可能  APIで起動、Jobの実行、停止を操作可能  モニタリング等もよしなに実施してくれる  S3をHDFSの替りに利用可能  クラスタの台数変更が容易
  • 18 Architecture 管理サーバ クーポン 配信サーバ クーポン 配信サーバ • 配信サーバ上のFluentdでログ集取 • fluentd-s3-pluginで収集したログを S3上に保存 • EMR上のHiveでログを加工、集計 • 集計値をRDSに保存して可視化
  • 19 Data Analysis Flow (by tagomoris) Process Collect Parse Clean up Store Process Visualize 出典: http://www.slideshare.net/tagomoris/handling-not-so-big-data
  • 20 Poor man’s Data Analysis Flow Process Collect Parse Clean up Store Process Visualize
  • 21 Collect Process Collect Parse Clean up Store Process Visualize
  • 22 Collect  クーポン配信サーバからFluentd + fluentd-s3- pluginを利用してログを飛ばす  飛ばすログはユーザのアクションをQueryString に含めて飛ばす • 複雑なJSONは飛ばさず、QueryStringに情報載せる • Hiveでの集計時に全てJSONに変換 • https://example.com/beacon/?sub=100&obj=coupon&action=click&cid=2  Fluentd集約サーバは利用しない • リアルタイム集計の必要性は現状高くない • 冗長構成も考えねばならず複雑になる • S3の安定感にお任せしたい
  • 23 Process Collect Parse Clean up Store Process Visualize Store
  • 24 Store  とりあえずS3に飛ばす  S3のバケットは本番/検証で分けておく • バケット単位でアクセスコントロール可能 • example.com.production-log  サーバ役割別にキーを分けておく • 別サーバが増えても安心 • example.com.production-log/api/  日別にキーを分けておく • Hiveのパーティションを利用する為 • example.com.production-log/api/dt=20140801
  • 25 Process Collect Parse Clean up Store Process Visualize Process
  • 26 Process  信頼と実績の夜間バッチ • 管理サーバからHadoop + HiveのEMRを起動 • Fluentd集約サーバを利用していない為細切れとなったログファイ ルを圧縮、結合(Hadoopは細切れ小さいファイルの処理苦手) • ログに記録されているQueryStringをUDFを利用してJSONに変換 • 見るべき軸で集計して保存 • 上記全てのProcessをHDFSにデータを落とさずS3を利用して実行 • 最終的な集計値をRDSに格納  柔軟で速い昼間クエリ • 管理サーバからHadoop + Hive + PrestoのEMRを起動 • PrestoがHiveのメタストア(テーブル定義)を参照 • データは全てS3上にある
  • 27 Process Collect Parse Clean up Store Process Visualize Visualize
  • 28 Visualize  EMRで集計したデータをMySQLにロード  管理サーバ上で動くサービスを利用して値を可視化 • メンバー全員が同じ値を見て数値確認  余ってる社内サーバに試験的にElasticsearch +Kibanaを導 入 • データを弄りながら分析軸を考えたい時に便利
  • 29 Poor man’s Data Analysis Flow Process Collect Parse Clean up Store Process Visualize
  • 30 YAGNI
  • 31 でも必要になったら追加できる
  • 32 詰まないようにしておく
  • 33 Poor man’s Data Analysis Flow Process Collect Parse Clean up Store Process Visualize
  • 34 References  AWS Amazon EMR Best Practices • コレを読めば自分達のコンテクストに合ったEMR構成がわかる。 Hadoopの入門としても良いのでは。  mixi の解析基盤とApache Hive でのJSON パーサ の活用の紹介 • JSONで貯めてViewでテーブルっぽく扱うアイディアを貰った。ログ 集計に関わる人達のコミュニケーションコスト、という概念も貰った。  Batch Processing and Stream Processing by SQL • このトークを聞いて分析基盤にMPP系エンジンを利用する事を決意。 ImpalaとPrestoを比較し、S3にも直接クエリを投げれるPrestoを導入 した。(Impalaも次期バージョンではS3に直接クエリ投げれるらしい のでその時に再度検証予定)
  • 35 「入門以上」を目指した Python+EMR活用方法の共有 (ログ集計)
  • 36 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 37 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 38 aws-cli  2014/08/07リリースのVer 1.4.0からEMR機能のPreviewス テータスが取れ、晴れて安定したAPIとして利用可能  今までデファクトだったRubyのElastic-MapReduceスクリ プトから乗り換え • pipで簡単にインストールできる • 以前からaws-cliを使ってるのでツール統一 • GitHub上での開発が活発でPRも出せる
  • 39 We Love Python!!!
  • 40 $ mkvirtualenv pycon-emr-dev (pycon-emr-dev)$ pip install awscli (pycon-emr-dev)$ mkdir ~/.awscli (pycon-emr-dev)$ cat <<-EOF >> ~/.awscli/config [profile development] aws_access_key_id=<development_access_key> aws_secret_access_key=<development_secret_key> region=ap-northeast-1 EOF (pycon-emr-dev)$ cat <<-EOF >> $VIRTUAL_ENV/bin/activate export AWS_CONFIG_FILE=~/.awscli/config export AWS_DEFAULT_PROFILE=development source aws_zsh_completer.sh EOF
  • 41 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 42 $ aws emr create-cluster --ami-version 3.1.1 --name 'PyConJP 2014 (AMI 3.1.1 Hive)' --tags Name=pycon-jp-emr environment=development --ec2-attributes KeyName=yourkey --log-uri 's3://yourbucket/jobflow_logs/' --no-auto-terminate --visible-to-all-users --instance-groups file://./normal-instance-setup.json --applications file://./app-hive.json
  • 43 [ { normal-instance-group.json app-hive.json "Name": "emr-master", "InstanceGroupType": "MASTER", "InstanceCount": 1, "InstanceType": "m1.medium" }, { "Name": "emr-core", "InstanceGroupType": "CORE", "InstanceCount": 2, "InstanceType": "m1.medium" } ] [ { "Name": "HIVE" } ]
  • 44 result { "ClusterId": "j-8xxxxxxxxx" }
  • 45 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 46 $ aws emr add-steps --cluster-id j-8xxxxxxxxx --steps file://./hive-sample-step-1.json
  • 47 [ { "Args": [ "-f", "s3n://yourbucket/hive-script/sample01.hql", "-d", "BUCKET_NAME=yourbucket", "-d", "TARGET_DATE=20140818" ], "ActionOnFailure": "CONTINUE", "Name": "Hive Sample Program 01", "Type": "HIVE" }, { "Args": [ "-f", "s3n://yourbucket/hive-script/sample02.hql", "-d", "BUCKET_NAME=yourbucket", "-d", "TARGET_DATE=20140818" ], "ActionOnFailure": "CONTINUE", "Name": "Hive Sample Program 02", "Type": "HIVE" } ] hive-sample-step-1.json
  • 48 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 49 $ aws emr add-steps --cluster-id j-8xxxxxxxxx --steps file://./s3distcp-sample-step.json
  • 50 [ { "Name": "s3distcp Sample", "ActionOnFailure": "CONTINUE", "Jar": "/home/hadoop/lib/emr-s3distcp-1.0.jar", "Type": "CUSTOM_JAR", "Args": [ "--src", "s3n://yourbucket/access_log/dt=20140818", "--dest", "s3n://yourbucket/compressed_log/dt=20140818", "--groupBy", ".*(nginx_access_log-).*", "--targetSize", "100", "--outputCodec", "gzip" ] } ] s3distcp-sample-step.json
  • 51 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 52 $ aws emr create-cluster --ami-version 3.1.1 --name 'PyConJP 2014 (AMI 3.1.1 Hive)' --tags Name=pycon-jp-emr environment=development --ec2-attributes KeyName=yourkey --log-uri 's3://yourbucket/jobflow_logs/' --no-auto-terminate --visible-to-all-users --instance-groups file://./normal-instance-setup.json --applications file://./app-hive-with-config.json
  • 53 [ { "Args": [ "--hive-site=s3://yourbucket/libs/config/hive-site.xml" ], "Name": "HIVE" } ] app-hive-with-config.json
  • 54 <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>hive.optimize.s3.query</name> <value>true</value> <description>Optimize query on S3</description> </property> </configuration> hive-site.xml
  • 55 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 56 $ aws emr create-cluster --ami-version 3.1.1 --name 'PyConJP 2014 (AMI 3.1.1 Hive + Presto)' --tags Name=pycon-jp-emr environment=development --ec2-attributes KeyName=yourkey --log-uri 's3://yourbucket/jobflow_logs/' --no-auto-terminate --visible-to-all-users --instance-groups file://./normal-instance-setup.json --bootstrap-actions file://./bootstrap-presto.json --applications file://./app-hive-with-config.json
  • 57 [ { "Name": "Install/Setup Presto", "Path": "s3://yourbucket/libs/setup-presto.rb", "Args": [ "--task_memory", "1GB", "--log-level", "DEGUB", "--version", "0.75", "--presto-repo-url", "http://central.maven.org/maven2/com/facebook/presto/", "--sink-buffer-size", "1GB", "--query-max-age", "1h", "--jvm-config", "-server -Xmx2G -XX:+UseConcMarkSweepGC - XX:+ExplicitGCInvokesConcurrent -XX:+CMSClassUnloadingEnabled - XX:+AggressiveOpts -XX:+HeapDumpOnOutOfMemoryError - XX:OnOutOfMemoryError=kill -9 %p -XX:PermSize=150M - XX:MaxPermSize=150M -XX:ReservedCodeCacheSize=150M - Dhive.config.resources=/home/hadoop/conf/core-site. xml,/home/hadoop/conf/hdfs-site.xml" ] } ]
  • 58  setup-presto.rb実態は (https://github.com/awslabs/emr-bootstrap-actions/ blob/master/presto/install)  AWSが実験的に出してるPrestoをEMRに入れる為 のBootstrapスクリプト  AMI 3.1.1 or 3.1.0では動いたけど、AMI 3.2.0では 動かなかった(Hive 0.11 -> Hive 0.13)  Thrift Serviceのポートが異なるっぽい
  • 59 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  •  MetastoreとはHiveのテーブル定義等の情報を保存 60 しておく場所のこと  現在多くはMySQLが利用されている  何も設定しないとEMRのインスタンスのMySQLに 保存される  MetastoreをEMR外部のDBに設定しておくことで、 EMR立ち上げる際にDDLを再度流さなくても良く なる  DB側のSecurity Groupを修正する必要あり
  • 61 <configuration> <property> <name>hive.optimize.s3.query</name> <value>true</value> <description>Optimize query on S3</description> </property> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://hostname:3306/hive?createDatabaseIfNotExist=true</value> <description>JDBC connect string for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> <description>Driver class name for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>username</value> <description>Username to use against metastore database</description> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>password</value> <description>Password to use against metastore database</description> </property> </configuration> app-hive-with-config.json
  • 62 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  •  Pythonバッチ処理内でEMRを起動したい事もある  もしくはCeleryのTaskとして起動したいとか  そういった場合にはPythonの中からEMRを使う事 63 も可能  boto.emrを利用する  aws-cli内から便利なUtilityを取ってきて使うのもあ りかも?
  • 64 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 65 # -*- coding: utf-8 -*- from datetime import datetime from boto.emr import connect_to_region from boto.emr.step import InstallHiveStep def setup_emr(): # need to export AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY # as environment variables. conn = connect_to_region('ap-northeast-1') install_step = InstallHiveStep(hive_versions='0.11.0.2') jobid = conn.run_jobflow( name='Create EMR [{}]'.format(datetime.today().strftime('%Y%m%d')), log_uri='s3://yourbucket/jobflow_logs/', ec2_keyname='your_key', master_instance_type='m1.medium', slave_instance_type='m1.medium', num_instances=3, action_on_failure='TERMINATE_JOB_FLOW', keep_alive=True, enable_debugging=False, hadoop_version='2.4.0', steps=[install_step], bootstrap_actions=[], instance_groups=None, additional_info=None, ami_version='3.1.1', api_params=None, visible_to_all_users=True, job_flow_role=None) return jobid if __name__ == '__main__': jobflow_id = setup_emr() print "JobFlowID: {} started.".format(jobflow_id)
  • 66  AWSのクレデンシャルはソース内に入れない事 • 環境変数に入れるもやめた方が良い • ローカルマシンでテストしたい場合は已む無しか • EMRを立ち上げるEC2に付与するIAM Roleで制御
  • 67 from to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. Execute HiveQL use EMR
  • 68 長くなってしまったので雰囲気だけ jobid = conn.run_jobflow( name='Create EMR and Exec hiveql [{}]'.format(target_date), log_uri='s3://{}/jobflow_logs/'.format(bucket_name), ec2_keyname='your_key', master_instance_type='m1.medium', slave_instance_type='m1.medium', num_instances=3, action_on_failure='TERMINATE_JOB_FLOW', keep_alive=True, enable_debugging=False, hadoop_version='2.4.0', steps=[install_step], bootstrap_actions=[], instance_groups=None, additional_info=None, ami_version='3.1.1', api_params=None, visible_to_all_users=True, job_flow_role=None) query_files = ['sample01.hql', 'sample02.hql'] hql_steps = [] for query_file in query_files: hql_step = HiveStep( name='Executing Query [{}]'.format(query_file), hive_file='s3n://{0}/hive-script/{1}'.format( bucket_name, query_file), hive_versions=hive_version, hive_args=['-dTARGET_DATE={0}'.format(target_date), '-dBUCKET_NAME={0}'.format(bucket_name)]) hql_steps.append(hql_step) conn.add_jobflow_steps(jobid, hql_steps)
  • 69 use to do the following aws-cli Execute HiveQL Execute s3distcp Config Your EMR Bootstrp Presto Create Cluster Metastr Config Python Script Create Cluster Job Flow Mgmnt. from Execute HiveQL EMR
  • 70  バッチ処理に依存関係を作りたい • Aが終わったらBとC同時に実行する、等 • AとBが終わったらCを実行する、等  起動時間の管理をもっと手軽に行いたい
  • 71 • https://github.com/spotify/luigi • Python製のパイプライン管理フレームワーク • Hadoop Streamingを利用したMapReduceが簡単に書ける機構あり • Pythonのコードだけで依存性解決 • 依存性可視化(別サービスとして立ち上げ) • 依存性可視化ツールは認証等細かい機能は無い • HiveQLの実行に対応している • Pigの実行に対応している • S3の操作に対応してる • 現状だとオーバーキル
  • • 管理画面はDjangoを利用 • 同一のサーバでceleryとcelerybeatを起動 • django-celeryを利用して特定タスクを特定の時間にキューに入れるよ 72 うに設定 • celerybeatがキューに入ったタスクを拾って実行してくれる • django-celeryなくてもceleryとDjangoは連携できるけど、このスケ ジュール機能が便利なのでまだ使ってる
  • 73 References  https://github.com/aws/aws-cli • 本家の資料とソース  https://github.com/boto/boto • 本家の資料とソース
  • 74 Kanmu 絶賛仲間募集中
  • 75 まずはお話だけでも!
  • 76 https://www.wantedly.com/projects/9282
  • 77 若干今回のPyCon準備裏話
  • 78  先週金曜日時点で1200行くらいのMarkdown  Slide lessに挑戦しようとした  社内でレビュー会実施
  • 79
  • 80
  • 81 _人人人人人人人人人人人人人人人人_ > 本当にありがとうございました<  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
  •  初めて技術系の発表した  仕事でやってきた事をまとめるいい機会  他の方たちが仕事してる時に考えている事を知りたい  他の会社の構成がなぜその構成をとっているのか知りたい 82
  • 83 Goal 皆さんの話を聞きたい(自分が)  「なぜその構成なのか」に焦点を置いた事例の共有  「入門以上」を目指したPython+EMR活用方法の共有
  • 84 今回は発表の機会を頂き
  • 85 _人人人人人人人人人人人人人人人人_ > 本当にありがとうございました<  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄