ElasticSearch勉強会 第6回

24
2014年9月16日 第6回ElasticSearch勉強会 山田 直行 秒間3万の広告配信ログをElasticSearchで リアルタイム集計してきた戦いの記録

description

秒間3万の広告配信ログをElasticSearchで リアルタイム集計してきた戦いの記録

Transcript of ElasticSearch勉強会 第6回

Page 1: ElasticSearch勉強会 第6回

2014年9月16日 第6回ElasticSearch勉強会 山田 直行

秒間3万の広告配信ログをElasticSearchで リアルタイム集計してきた戦いの記録

Page 2: ElasticSearch勉強会 第6回

• 自己紹介

• ディスプレイ広告配信DSP「Smalgo」について

• インフラ選定と設計

• データ構造とリアルタイム集計

• 運用開始して分かったこと

• トラブルとその対応

目次

Page 3: ElasticSearch勉強会 第6回

• 山田 直行(やまだ なおゆき)Twitter @satully blog.kirishikistudios.com

• 株式会社サイバーエージェント アドテクスタジオ エンジニア2011年入社。前職はソーシャルゲームのエンジニア

• 担当分野:DevOpsインフラ設計/運用・データ集計/分析・CIなど

• AWS認定ソリューションアーキテクト アソシエイト

• データの活用について、インフラ構築から分析、実サービスへの適用までを通してできるエンジニアを目指しています

自己紹介

Page 4: ElasticSearch勉強会 第6回

• ディスプレイ広告(≒バナー広告)の配信プラットフォーム

• 2014年5月から提供(前身となるプロダクトを含めると2014年2月から)

• スマートフォン向けがメインだが、PC向け配信も行っている

• RTBがメインだが、第三者配信など他の配信方法にも対応

• 成果報酬型課金が特徴

ディスプレイ広告配信DSP「Smalgo」について プロダクト概要

Page 5: ElasticSearch勉強会 第6回

ディスプレイ広告配信DSP「Smalgo」について DSPの位置づけ

引用元:日本一やさしいアドテク教室 https://www.cyberagent.co.jp/ir/personal/adtech/adtech_05/

Page 6: ElasticSearch勉強会 第6回

インフラ選定と設計 DSPの配信~集計の全体像

メディアメディアメディアメディアメディア

Bid/Ad サーバー

Impression サーバー

Click サーバー

アドネットワーク またはSSP

Conversion サーバー

Mark サーバー

Fluentd

ElasticSearch クラスタ

MySQL

Redis

S3

様々なログを集計し、そのデータを使って配信、の繰り返し

Page 7: ElasticSearch勉強会 第6回

インフラ選定と設計 データインフラとして何を使うか? 機能要件

• 柔軟なスキーマログのデータ構造は機能追加に伴って変化していく。キャンペーンやクリエイティブの情報の他、広告枠の情報やレスポンスタイムなどをまず含め、それ以降のデータ拡張にも対応したいネストしたデータ形式を扱えるようなドキュメントDBを検討した

• 小さく始められ、かつスケールアウトが容易であること 当初は10億req/monthからスタート。そこから2000億req/monthまでスケールアウトできることがいったんの目標。できればスケールアウトを無停止で行いたい

• リアルタイムとバッチでの両方の分析ができることリアルタイムにデータを集計できると、クリックやコンバージョンのテスト、レスポンスタイムのモニタリング、リアルタイムのターゲティングが可能になる。ログが吐かれて数秒以内にはデータを利用可能にしたい。それと同時に、任意のデータ列を軸にした集計処理にも活用したい

Page 8: ElasticSearch勉強会 第6回

インフラ選定と設計 ElasticSearchを採用

• 前ページの要件を全て満たしていた

• Kibanaの存在が採用を後押しした。データの分析・可視化ツールを独自に開発するよりも、良い選択肢だと考えた

• 当初は、全件データサービスとしての利用を主目的として考えていた。これまでは広告運用者は「集計されたデータ」を扱うことは多くても、「生の配信データ」にアクセスするには一手間かかっており、これを直接検索できるようにして分析や調査に利用できるようにしたいという狙いがあった

• ただし、ElasticSearchの”何でもできる感”と、急激なプロダクトの拡大と機能追加により、ElasticSearchを広告配信のためのバッチ集計にも利用していくことになる

• 多くの要件を一度に満たせる夢のデータベースなんてあるの? →運用には苦労することに

Page 9: ElasticSearch勉強会 第6回

インフラ選定と設計 ElasticSearchクラスタの2014年7月ごろの構成

Fluentd

ElasticSearch Data Nodes

ElasticSearch Search Nodes

ElasticSearch Coordinate Nodes

ElasticSearch Data NodesElasticSearch Data NodesElasticSearch Data NodesElasticSearch Data Nodes

Kibana

バッチ サーバー

REST Client

ELB ELB

ElasticSearch Search Nodes

ElasticSearch Coordinate Nodes

master: true data: false 2ノード r3.large

master: false data: false 2ノード r3.large

master: false data: true 28ノード

12シャード & 1レプリカ r3.xlarge/1GB SSD

バッチは1時間に1回 その中で数回のaggregationクエリ

KibanaやRESTクライアントは 任意のタイミングで使われる

fluentd(td-agent)は10ノード 5ノードがBidログ用

3ノードがそれ以外のログ用 2ノードがアクティブスタンバイ

!月間ログ数400億行

ピーク時秒間30000writes

Page 10: ElasticSearch勉強会 第6回

データ構造とリアルタイム集計 Bid RequestからConversionまでをデータ格納時にひもづける

• DSPのログは、Bid Request - Bid Response- WinNotice - Impression - Click - Conversionといった種類があり、これらのどのログとどのログが対応しているかをひもづけていく必要がある

Bid Request/Response

Impression Win Notice

Click

Conversion

(bidした) (bidしなかった)

• Bid Requestログは最も多量であり、そこからBidしたものの中からオークションに勝利したものがインプレッションとなり、そこからクリックされたもの、コンバージョンしたもの、という具合で減少していく

Page 11: ElasticSearch勉強会 第6回

データ構造とリアルタイム集計 インデックスとデータスキーマ

{ "_index": "deliver-2014.09.15", "_type": "unite", "_id": "T4xi1p67y6l6gk2bnsf0oib5g6", "_score": 1, "_source": { "bid": { "time": "2014/09/15 20:41:40", "host": "bid16", ... }, "wn": { ... }, "imp": { ... }, "click": { ... }, "cv": { ... } } }

• インデックスは1日ごとに1個切る。ただしbidしたものとbidしていないものを別インデックスとした(集計時にどちらかしか見ないことが多いため)つまり1日あたり2つのインデックスが作られる

• データは右図のように、ひもづいたログを1つのドキュメントに格納するデータ形式を取る。そのためにデータ更新時に1回search queryを投げ、ひもづくドキュメントにappendする処理にした(fluentdのpluginを書いてその中で処理)

Page 12: ElasticSearch勉強会 第6回

運用開始して分かったこと クラスタデータベース + リアルタイム集計ならではの問題

• 新しい配信の機能をElasticSearchを使って実現することで、リリースをどんどんしていくことができた

• Kibanaが活用され、多くのダッシュボードが作られた。それらはリアルタイムのモニタリングや配信ログの調査に効果を発揮した

• ただし、Kibanaの利用のされ方が読めず、重いクエリが流れてKibanaがクラスタに負荷をかけることが頻繁にあった

• ピーク時に書き込みが間に合わず、データ格納が遅延することが多くあった

• 別データベースでバッチ処理でやっている集計との間で集計結果に微妙なズレが生じて、一致させることが困難だった

• シャードの再配置中には負荷が高まり、それを静めるのに苦労した

Page 13: ElasticSearch勉強会 第6回

運用開始して分かったこと どういう設定が最適か、を事前に見極めるのが難しい

• インデックスとドキュメントの設計は非常に大切当初はbidしたログとbidしていないログが1つのインデックス内にあり、負荷が非常に高かったが、分割したことでかなり負荷が下がったドキュメントの設計は最適だったのかどうかは今でも悩むところ

• シャード数をいくつにするか4 -> 8 -> 12と増やしてきた増やしすぎることで運用が難しくなるのではないかという懸念があって増やすのに慎重だったが、もっと多くても良いかもしれない。1ノードあたりに同一インデックスは1シャードまでという構成をとったが、そうする必然性はない

• production環境でないと分からないことが多いdevelopment環境、staging環境はあったが、構成の確認はできても負荷チューニングはできず。本番で実際適用してみて分かることが多かった。負荷試験の環境をもっとうまく作れたらよかった

Page 14: ElasticSearch勉強会 第6回

トラブルとその対応 バージョンアップ & SSDへの変更が大きかった

• バージョンアップでかなり安定した当初はver1.0.2でサービスイン。Out of memoryでノードが反応しなくなる問題に悩まされた。 ver1.2.3にしてからかなり安定。

• データドライブのEBSをSSDに変更して高速化Amazon Web Services ブログ: 【AWS発表】新しいSSDベースのElastic Block Storagehttp://aws.typepad.com/aws_japan/2014/06/new-ssd-backed-elastic-block-storage.html このリリースで、EBSを全てSSDに入れ替えたところ、書き込みのスループットが改善

• 検索処理のキャッシュ化

当初はデータノードにc3.2xlarge(8CPU 16GB)を利用していた。データ格納時の事前検索で多量のCPUを使っていたためだが、ElastiCacheを使ってひもづくデータのキーをキャッシュすることによりCPU使用率を大幅に下げて、メモリ重視のインスタンス(r3.xlarge(4CPU, 30GB))にすることにより検索が高速化し、パフォーマンスが安定した

Page 15: ElasticSearch勉強会 第6回

• ElasticSearch Head http://mobz.github.io/elasticsearch-head/ シャードの状況把握にはこれ

• bigdesk for elasticsearch http://bigdesk.org/ 細かな負荷監視に利用

• ElasticHQ - ElasticSearch monitoring and management application. http://www.elastichq.org/ 全体の俯瞰とチューニング箇所の特定に利用

• Homepage of Zabbix :: An Enterprise-Class Open Source Distributed Monitoring Solution http://www.zabbix.com/ 全般的な死活監視と、Fluendからの書き込みの監視

トラブルとその対応 運用ツール

Page 16: ElasticSearch勉強会 第6回

• FluentdでElasticSearchに書き込むのと同じデータをS3にも保存しておき、S3のデータから復旧するスクリプトを用意

• ElasticSearch自体が持つバックアップ機能は非使用

• Fluentd(td-agent)のパラメータをチューニングして最適値を探した

トラブルとその対応 Fluentdのチューニング

<match es.app.bid> flush_interval 1s buffer_type file buffer_chunk_limit 8m buffer_queue_limit 10000 retry_limit 5 </match>

Page 17: ElasticSearch勉強会 第6回

• 正直なところ、最適な値がいくつかは今でもわかっていない。その都度試行錯誤している

• オンラインで変更可能なものと、再起動が必要なものがある

• いろいろなウェブサイトを参考に設定値を変えて試してみたが、大きなパフォーマンスアップは見られず、デフォルトに近いパラメータで運用している

トラブルとその対応 elasticsearch.ymlの設定値

index.number_of_shards: 12 index.number_of_replicas: 1 indices.fielddata.cache.size: 50% script.disable_dynamic: false bootstrap.mlockall: true

Page 18: ElasticSearch勉強会 第6回

トラブルとその対応 基本の確認コマンド

• クラスタの設定を確認

curl -XGET localhost:9200/_cluster/settings?pretty

• クラスタの設定を確認

curl -XGET localhost:9200/_cluster/health?pretty

• シャードの配置状況を確認

curl -XGET localhost:9200/_cat/shards 2>/dev/null

Page 19: ElasticSearch勉強会 第6回

トラブルとその対応 ノードの入れ替え

• ノードをグレードアップするときには、新しいインスタンスを同数用意して、全部入れ替える手法を取った バージョンアップ時やインスタンスタイプを変えたときなど。例えば16台のデータノード運用していたときは、同数の16の新しいデータノードを用意し、合わせて32台にして、そこからcluster.routing.allocation.exclude._nameを使って古いノードから新しいノードにシャードを移動させ、全部移動し終わったら古いノードを全て止めて削除する、というようにした。新しい構成で何か問題が発生した際に、戻すということを可能にするため。

curl -XPUT localhost:9200/_cluster/settings -d '{ "transient" : { "cluster.routing.allocation.exclude._name" : “logananlytics-data10,loganalytics-data11“ } }'

Page 20: ElasticSearch勉強会 第6回

• あるノードが落ちたときなど、特定のノードにシャードが固まっていて負荷になっていたときは、手動で再配置をかけて対応したことも

トラブルとその対応 特定のノードにシャードが固まっているときに移動をさせる

curl -XPOST 'localhost:9200/_cluster/reroute' -d '{ "commands" : [ { "move" : { "index" : "deliver-nobid-2014.06.23", "shard" : 1, "from_node" : "loganalytics-data38", "to_node" : "loganalytics-data37" } } ] }'

Page 21: ElasticSearch勉強会 第6回

• たまにunassignedになったままのシャードがあるので、自動での割り当てを待たずにRESTで割り当てノードを指定

トラブルとその対応 unassignedのシャードをノードに割り振る

curl -XPOST 'localhost:9200/_cluster/reroute' -d '{ "commands" : [ { "allocate" : { "index" : "deliver-2014.06.29", "shard" : 4, "node": "loganalytics-data25", "allow_primary": true } } ] }'

Page 22: ElasticSearch勉強会 第6回

• 原因不明だが、initializingのままずっとスタックしているシャードがあった。そのときはシャードをキャンセル

トラブルとその対応 initializingのままのシャードをキャンセル

curl -XPOST 'localhost:9200/_cluster/reroute' -d '{ "commands" : [ { "cancel" : { "index" : "deliver-2014.07.03", "shard" : 2, "node" : "loganalytics-data24" } } ] }'

Page 23: ElasticSearch勉強会 第6回

• 時間帯をみて、再配置を行う数を変更して負荷を調整Excludeしたノードから一気に引っ越しさせるときもこれ

トラブルとその対応 同時に再配置を行う数をコントロール

curl -XPUT localhost:9200/_cluster/settings -d '{ "transient" : { "cluster.routing.allocation.cluster_concurrent_rebalance" : 8 } }'

Page 24: ElasticSearch勉強会 第6回

• データインフラにElasticSearchを採用した経緯とメリット・デメリットについて話しました

• システム全体の中で、どういう位置づけで、どういうSLAで運用していくかを明確にしておくことが大事だと感じました

• 構成や設定については日々悩みながら運用していて、最適値についても試行錯誤中です

• ある程度の規模で構築・運用した事例として、参考になれば幸いです

まとめ