Upload
voyage-group
View
164
Download
1
Embed Size (px)
Citation preview
Data Engineering at VOYAGE GROUP
JAWS DAYS 2015 2015/03/22 @suzu_v
自己紹介
• 鈴木健太、すずけん、@suzu_v
• http://suzuken.hatenablog.jp/
• ソフトウェアエンジニア
• アドテクノロジー事業(SSP, DMP)に従事
https://www.facebook.com/voyagegroup/photos/a.365470036810049.90562.176439939046394/752116391478743/?type=3&permPage=1
データエンジニアリング
• 日々増え続けるデータをビジネスに活かし、ユーザに恩恵を届けるためには、信頼性の高いデータの保持、処理、そしてクエリ可能な状態をつくる必要がある。そのために、スケーラブルで信頼性の高いデータ基盤をつくり、データのパイプラインを組み立てるエンジニアリングのこと
私達とAWS• 2009年から利用開始
• 2011年からアドテクノロジー領域でも利用を開始
• 今日はアドテクノロジー領域でのAWS利用についてお話します
ディスプレイ広告
広告リクエスト
ブラウザ アドサーバ
そのときどきで良さそうな 広告を選んで
ブラウザ アドサーバ
広告
広告
広告
広告を表示する
ブラウザ アドサーバ
広告
広告
広告
ex. 行動ターゲティング基盤 アーキテクチャ
行動ターゲティングの課題• なるべく速く書き込みたい。ユーザが何かをみたら、すぐにターゲティング可能な状態にしてほしい。反映が速ければ速いほどいい。
• 案件や対象ユーザが増えても、システム全体が問題なくスケールすること
• 読み込みが安定して低レイテンシであること。できれば5ms以内。
Targeting Infrastructure
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
配信用VPC
ターゲティング 基盤VPC
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
Fluentdの forwardで連携
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
Event Streamノード c3.xlarge複数台
td-agent2
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
out_exec_filterでログを加工 DynamoDBに書き込み
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
ユーザのセグメント情報を書き込み
全てのログ
http://www.slideshare.net/repeatedly/fluentd-unified-logging-layer-at-fossasia
http://www.slideshare.net/repeatedly/fluentd-unified-logging-layer-at-fossasia
シンプルなストリーム処理in_forwardで受け入れたレコード
out_exec_filterで加工
{id: "hoge", segment: "seg1", created: 1426406962, ...}
DynamoDBテーブルへ
{id: "hoge", url: "http://fuga.com/kuke", user_agent: ..} {id: "hoge", url: "http://hoge.com/a", user_agent: ..}
if (domain(url) == "fuga.com") seg = "seg1"
<match hoge.log> type exec_filter command ./our/special/filter/command buffer_type file buffer_path /path/to/ephemeral/disk/hoge </match> !<match filtered.hoge.log> type dynamodb dynamo_db_table our_targeting_table buffer_type file buffer_path /path/to/ephemeral/disk/filtered ... <secondary> type s3 s3_bucket your-bucket s3_region ap-northeast-1 s3_object_key_format ... buffer_type file buffer_path /path/to/ephemeral/disk/filtered.secondary ... </secondary> </match>
in_forwardでおくられてきた ログをうけとり、フィルターする
filterしたログをDynamoDBに書き込む batchWriteItemを利用
もし書き込みが失敗したらs3へ
書ききれてませんが、s3への転送もしてます
<match hoge.log> type exec_filter command ./our/special/filter/command buffer_type file buffer_path /path/to/ephemeral/disk/hoge </match> !<match filtered.hoge.log> type dynamodb dynamo_db_table our_targeting_table buffer_type file buffer_path /path/to/ephemeral/disk/filtered ... <secondary> type s3 s3_bucket your-bucket s3_region ap-northeast-1 s3_object_key_format ... buffer_type file buffer_path /path/to/ephemeral/disk/filtered.secondary ... </secondary> </match>
バッファは全てファイル ephemeral diskに
EventStreamノードの運用• ノードを作り直す場合にはforward側からフェイルしたノードを外し、全ての転送が終わったら落とす
• Output先を詰まらせないこと。fluentdにバッファをなるべく貯めないことが望ましい。定常的にバッファが貯まるようなら改善が必要。
• バッファがたまってしまった場合は原因を特定して詰まりを解消した上で、強制的にflush
• $ pkill -USR1 -f fluentd
ストリーム処理における状態
プロセッサ
データ
ストリーム処理における状態
プロセッサ
id: 1 k: 2
データあるidがk: 1を満たしていたら通したい
ストリーム処理における状態
プロセッサ
id: 1 k: 2
データ
NG
あるidがk: 1を満たしていたら通したい
ストリーム処理における状態
プロセッサ
データあるidがk: 1を満たしていたら通したい
ストリーム処理における状態
プロセッサ
データ
id: 1 k: 1
あるidがk: 1を満たしていたら通したい
ストリーム処理における状態
プロセッサ
データ
id: 1 k: 1 OK!
あるidがk: 1を満たしていたら通したい
ストリーム処理における状態
プロセッサ
データ
id: 1 k: 1
プロセッサにとどまる 時間は限りなく短い
あるidがk: 1を満たしていたら通したい
留めるデータが増えるケース
プロセッサ
id: 1 k: 2
データあるidがk: 1とk: 2両方を満たしていたら通したい
プロセッサ
id: 1 k: 2
データ stayあるidがk: 1とk: 2両方を満たしていたら通したい留めるデータが増えるケース
プロセッサid: 1 k: 3
id: 1 k: 2
id: 1 k: 1
データ 条件がくるまで 滞留させる必要がある
あるidがk: 1とk: 2両方を満たしていたら通したい留めるデータが増えるケース
プロセッサ
id: 1 v: “ok”
データ
条件をみたしたのでOK
あるidがk: 1とk: 2両方を満たしていたら通したい留めるデータが増えるケース
ストリーム処理における状態
プロセッサid: 1 k: 3
id: 1 k: 2
id: 1 k: 1
データ 条件がくるまで 滞留させる必要がある
対象とする時間の幅(window)が長くなればなるほど多くのデータをストリーム処理可能な場所に保持する必要がある。データの流量が増えるとそれだけ多くのリソース(RAM等)が必要になる。
あるidがk: 1とk: 2両方を満たしていたら通したい
行動ターゲティングの課題 (再掲)
• なるべく速く書き込みたい。ユーザが何かをみたら、すぐにターゲティング可能な状態にしてほしい。反映が速ければ速いほどいい。
• 案件や対象ユーザが増えても、システム全体が問題なくスケールすること
• 読み込みが安定して低レイテンシであること。できれば5ms以内。
いろいろ試した結果• シンプルなmap処理のみリアルタイムに
• (30日前にページAをみた and さっきページBをみた)というセグメントにも対応しなければいけなかった・・。のでバッチも併用することに。
• 結果横に並べればシンプルなmap処理についてはスケールする構成になったので良かった
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
EMRでDynamoDBとS3からデータ抽出 再集計してDynamoDBへ書き込み
EMR / Hive• Amazon Hadoop 2.4.0, Hive 0.13.1, core: m1.xlarge * 30, task: c3かr3系統をspot instanceで。専用のSecurity Groupを用意。基本的にRCFileで扱う。
• 200クエリ / 日。1日1クラスタ立ち上げて、ひたすらそこに投げている。DynamoDBとs3からデータを読み込み、集計し、s3に書き出している。使うHiveクエリは管理ツールから自動生成 or リポジトリにコミットしてJenkinsからs3に上げている。
• アドホックに使う場合には都度別クラスタを立ち上げている。分析者も手元からThrift経由で。
SET dynamodb.throughput.read.percent=0.8; !CREATE EXTERNAL TABLE IF NOT EXISTS users ( id string, seg string, created bigint ) stored as rcfile location 's3://path/to/my/user/table'; !CREATE EXTERNAL TABLE if not exists users_from_dynamodb ( id string, seg string, created bigint) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ( "hive.jdbc.update.on.duplicate" = "true", "dynamodb.table.name" = "our_special_user_table_name", "dynamodb.column.mapping" = "id:id,seg:seg,created:created"); !INSERT OVERWRITE TABLE users SELECT * FROM users_from_dynamodb;
DynamoDBのthroughputをどれくらい使うか
DynamoDBカラムとHiveテーブルの カラム対応関係
DynamoDBから全データを 抽出してs3に書き込み
EMRの利点と課題• 利点
• Hadoopのバージョンアップなど、EMR側がやってくれるので楽
• 潰して、立ち上げなおして、が簡単にできる
• bootstrapを工夫すれば様々なHadoop関連ミドルウェアを手軽に試せる
• https://github.com/awslabs/emr-bootstrap-actions
• 課題
• クラスタ立ち上げは時間がかかる
• ジョブスケジューリングは自前で頑張る必要あり
• EMRコマンドのデバッグには極論EMRを立ち上げるしか無い
TODO このへんで水を飲む
行動ターゲティングの課題 (再掲)
• なるべく速く書き込みたい。ユーザが何かをみたら、すぐにターゲティング可能な状態にしてほしい。反映が速ければ速いほどいい。
• 案件や対象ユーザが増えても、システム全体が問題なくスケールすること
• 読み込みが安定して低レイテンシであること。できれば5ms以内。
DynamoDB、最高です
• ご存知フルマネージドNoSQL DB on AWS
• 2年半ほど継続して利用。AWSを使っていて最も選んでよかったと思っているデータストア。
• 30億レコード入っている。1リクエスト3msで返る。しかも1度もダウンしたことがない。
「DynamoDBからの読み込み遅いんですけど・・・」 「(;・∀・)?」
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
配信サーバからセグメントデータを読み込み
apache (prefork) + PHP
apacherequest DynamoDB
apache (prefork) + PHP
apacherequest
Process
DynamoDB
apache (prefork) + PHP
apacherequest
Process
DynamoDB
新規コネクション (≒10ms)
apache (prefork) + PHP
apacherequest
Process
DynamoDB
GetItem
apache (prefork) + PHP
apache
Process
DynamoDB
response
apache (prefork) + PHP
apache DynamoDB
response
apache (prefork) + PHP
apache DynamoDB
response
リクエストからレスポンスまで ≒30ms
秒間リクエスト数が増えた時
apache DynamoDB
秒間リクエスト数が増えた時
apache
request
Process
DynamoDB
requestrequestrequestrequestrequestrequestrequestrequestrequestrequestrequestrequest
Process
Process
Process待ちプロセスが増える
= LAが上がる
• PHP製のapiをScalaで再実装。Servletを利用。
• DynamoDBへのコネクションをプールするように
• responseが早くなり、同時接続数が増えすぎることなく、安定して稼働
fluentd「DynamoDBつまって書けないんですけど」 私「( ゚д゚)」
ELB
EC2
EC2 EC2
EC2
request
EC2
S3
DynamoDB
EMR ELB
EC2
EC2 EC2
EC2
http api
fluentd
fluentd (aggregator)
out_exec_filter
out_dynamodb servlet (scala)
dynamic-dynamoEC2
Growth Forecast
EC2
EC2
VPC 1
VPC 1
VPC 2 (targeting)
VPC Peering
VPC Peering
ephemeral cluster
out_exec_filterでログを加工 DynamoDBに書き込み
書き込む量が増えてWrite capacityが 足りなくなった!
• 勝手にスケールするようにしよう!ということでdynamic-dynamodbの導入
結果
Write Capacity
Read Capacity
Query Latency
テーブル設計イメージuser_id String
(hash key)
segment String
(range key)
created Number …
hoge seg1 1426406962
hoge seg2 1426406962
fuga seg1 1426406962
kuke seg1 1426406962
DynamoDB Tips• 1Itemあたりのバイト数を小さくする(1KBを超えないように
• hot keyを作らないようにする(hash keyに同じIDが大量に存在する状態にしないようにする
• DynamoDB - EC2の新規コネクションはそれなりにコストが高い(≒10ms)ので、コネクションをプールする(つながれば安定して速い
参考: http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-amazon-dynamodb
若手解析者「すずけんさん、Hive遅いんすけど何とかならないっすか?」 私「(́・ω・`)」
アドホックな データ分析
部分的にBigQueryを利用• EC2 -> S3 -> SQS -> EC2(worker) -> GCS
• アドホックな分析用はこちらに移行中
https://cloud.google.com/bigquery/?hl=ja
BigQuery• いいところ
• クラスタのメンテしなくていい。(Hadoopクラスタの面倒見なくていいし)。速い。コンソールも最初からついてる。Google Appsと連携できる。
• 使いづらい所
• 権限周り。まだAWSと比べて細かい制御が難しそう。UDFが(まだ)使えない。
現状の使い分け
• Large Batch: EMR + Hive
• Short Batch: BigQuery
• Stream Processing: Fluentd + out_exec_filter
参考: http://www.slideshare.net/tagomoris/hcj2014-sql
データと組織
プロダクトオーナーシップ• インフラも、データも、サービスも、営業も
• 「このデータを取れるようにしたいだけど?」に対して、全方面に答えられる必要がある。ログに10バイト情報を増やすだけで、10バイト × 250億だけ月に扱う量が増える。帯域、ディスク、関連するコストが増える。それらに見合うだけの価値があとから出せるのかを考える必要がある。
–Amazon’s Leadership PrinciplesのOwnershipより
“リーダーにはオーナーシップが必要です。リーダーは長期的な視野で考え、短期的な結果のために、長期的な価値を犠牲にしません。リーダーは自分のチームだけでなく、会社全体のために行動します。リーダーは「それは私の仕事では
ありません」とは決して口にしません。”
cf. Amazon• Amazon Kinesis Developer ManagerのGoさんの話
• AmazonのLeadership PrinciplesのOwnershipについて
• インフラチームもサービスチームもOwnershipを
ビジネス的な改善の重視• VOYAGE GROUPのエンジニアは技術的なレビューを受ける。人事評価も影響する。
• 現場のエンジニアでもプロダクトの数値を「見える」ようにすることを意識させられる。
• データをうまく扱う環境をつくること -> ビジネスを改善すること
参考: http://gihyo.jp/design/serial/01/creative/0006
まとめ
普通のことを普通にやる
• パフォーマンスも、運用も、コストも。データの配置も、必要なところだけ、必要なことを。データやトラフィックが増えても、普通のことを普通にやる。