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.

ElasticSearch勉強会 第6回

19,047 views

Published on

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

Published in: Internet
  • Be the first to comment

ElasticSearch勉強会 第6回

  1. 1. 秒間3万の広告配信ログをElasticSearchで リアルタイム集計してきた戦いの記録 2014年9月16日 第6回ElasticSearch勉強会 山田 直行
  2. 2. 目次 • 自己紹介 • ディスプレイ広告配信DSP「Smalgo」について • インフラ選定と設計 • データ構造とリアルタイム集計 • 運用開始して分かったこと • トラブルとその対応
  3. 3. 自己紹介 • 山田 直行(やまだ なおゆき) Twitter @satully blog.kirishikistudios.com • 株式会社サイバーエージェント アドテクスタジオ エンジニア 2011年入社。前職はソーシャルゲームのエンジニア • 担当分野:DevOps インフラ設計/運用・データ集計/分析・CIなど • AWS認定ソリューションアーキテクト アソシエイト • データの活用について、インフラ構築から分析、実サービスへの適用までを通して できるエンジニアを目指しています
  4. 4. ディスプレイ広告配信DSP「Smalgo」について プロダクト概要 • ディスプレイ広告(≒バナー広告)の配信プラットフォーム • 2014年5月から提供(前身となるプロダクトを含めると2014年2月から) • スマートフォン向けがメインだが、PC向け配信も行っている • RTBがメインだが、第三者配信など他の配信方法にも対応 • 成果報酬型課金が特徴
  5. 5. ディスプレイ広告配信DSP「Smalgo」について DSPの位置づけ 引用元:日本一やさしいアドテク教室 https://www.cyberagent.co.jp/ir/personal/adtech/adtech_05/
  6. 6. インフラ選定と設計 DSPの配信~集計の全体像 様々なログを集計し、そのデータを使って配信、の繰り返し メメデディィアアメメデディィアアメディア Bid/Ad サーバー Impression サーバー Click サーバー アドネットワーク またはSSP Conversion サーバー Mark サーバー Fluentd ElasticSearch クラスタ MySQL Redis S3
  7. 7. インフラ選定と設計 データインフラとして何を使うか? 機能要件 • 柔軟なスキーマ ログのデータ構造は機能追加に伴って変化していく。キャンペーンやクリエイティブの情報の他、広 告枠の情報やレスポンスタイムなどをまず含め、それ以降のデータ拡張にも対応したい ネストしたデータ形式を扱えるようなドキュメントDBを検討した • 小さく始められ、かつスケールアウトが容易であること 当初は10億req/monthからスタート。そこから2000億req/monthまでスケールアウトできること がいったんの目標。できればスケールアウトを無停止で行いたい • リアルタイムとバッチでの両方の分析ができること リアルタイムにデータを集計できると、クリックやコンバージョンのテスト、レスポンスタイムのモ ニタリング、リアルタイムのターゲティングが可能になる。ログが吐かれて数秒以内にはデータを利 用可能にしたい。それと同時に、任意のデータ列を軸にした集計処理にも活用したい
  8. 8. インフラ選定と設計 ElasticSearchを採用 • 前ページの要件を全て満たしていた • Kibanaの存在が採用を後押しした。データの分析・可視化ツールを独自に開発する よりも、良い選択肢だと考えた • 当初は、全件データサービスとしての利用を主目的として考えていた。これまでは広 告運用者は「集計されたデータ」を扱うことは多くても、「生の配信データ」にアク セスするには一手間かかっており、これを直接検索できるようにして分析や調査に利 用できるようにしたいという狙いがあった • ただし、ElasticSearchの”何でもできる感”と、急激なプロダクトの拡大と機能追加 により、ElasticSearchを広告配信のためのバッチ集計にも利用していくことになる • 多くの要件を一度に満たせる夢のデータベースなんてあるの? →運用には苦労することに
  9. 9. インフラ選定と設計 ElasticSearchクラスタの2014年7月ごろの構成 Fluentd ElasticSearch Search Nodes ElasticSearch Coordinate Nodes ElasticSearch Search Nodes ElasticSearch Coordinate Nodes master: false data: false 2ノード r3.large ElasticSearch Data Nodes ElasticSearch Data Nodes ElasticSearch Data Nodes master: true data: false 2ノード r3.large ElasticSearch Data Nodes ElasticSearch Data Nodes バッチ サーバー Kibana REST Client ELB ELB 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
  10. 10. データ構造とリアルタイム集計 Bid RequestからConversionまでをデータ格納時にひもづける • DSPのログは、Bid Request - Bid Response- WinNotice - Impression - Click - Conversionといった種類があり、これらのどの ログとどのログが対応しているかをひもづけていく必要がある Bid Request/Response (bidした) (bidしなかった) Impression Win Notice Click Conversion • Bid Requestログは最も多量であり、 そこからBidしたものの中からオーク ションに勝利したものがインプレッショ ンとなり、そこからクリックされたも の、コンバージョンしたもの、という 具合で減少していく
  11. 11. データ構造とリアルタイム集計 インデックスとデータスキーマ { "_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を書いてその中 で処理)
  12. 12. 運用開始して分かったこと クラスタデータベース + リアルタイム集計ならではの問題 • 新しい配信の機能をElasticSearchを使って実現することで、リリースをどんどん していくことができた • Kibanaが活用され、多くのダッシュボードが作られた。それらはリアルタイムのモ ニタリングや配信ログの調査に効果を発揮した • ただし、Kibanaの利用のされ方が読めず、重いクエリが流れてKibanaがクラスタ に負荷をかけることが頻繁にあった • ピーク時に書き込みが間に合わず、データ格納が遅延することが多くあった • 別データベースでバッチ処理でやっている集計との間で集計結果に微妙なズレが生 じて、一致させることが困難だった • シャードの再配置中には負荷が高まり、それを静めるのに苦労した
  13. 13. 運用開始して分かったこと どういう設定が最適か、を事前に見極めるのが難しい • インデックスとドキュメントの設計は非常に大切 当初はbidしたログとbidしていないログが1つのインデックス内にあり、負荷が非常に高 かったが、分割したことでかなり負荷が下がった ドキュメントの設計は最適だったのかどうかは今でも悩むところ • シャード数をいくつにするか 4 -> 8 -> 12と増やしてきた 増やしすぎることで運用が難しくなるのではないかという懸念があって増やすのに慎重だっ たが、もっと多くても良いかもしれない。1ノードあたりに同一インデックスは1シャード までという構成をとったが、そうする必然性はない • production環境でないと分からないことが多い development環境、staging環境はあったが、構成の確認はできても負荷チューニングは できず。本番で実際適用してみて分かることが多かった。負荷試験の環境をもっとうまく 作れたらよかった
  14. 14. トラブルとその対応 バージョンアップ & SSDへの変更が大きかった • バージョンアップでかなり安定した 当初はver1.0.2でサービスイン。Out of memoryでノードが反応しなくなる問題に悩まされた。 ver1.2.3にしてからかなり安定。 • データドライブのEBSをSSDに変更して高速化 Amazon Web Services ブログ: 【AWS発表】新しいSSDベースのElastic Block Storage http://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))にすること により検索が高速化し、パフォーマンスが安定した
  15. 15. トラブルとその対応 運用ツール • 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からの書き込みの監視
  16. 16. トラブルとその対応 Fluentdのチューニング • FluentdでElasticSearchに書き込むのと同じデータをS3にも 保存しておき、S3のデータから復旧するスクリプトを用意 • ElasticSearch自体が持つバックアップ機能は非使用 • Fluentd(td-agent)のパラメータをチューニングして最適値を 探した <match es.app.bid> flush_interval 1s buffer_type file buffer_chunk_limit 8m buffer_queue_limit 10000 retry_limit 5 </match>
  17. 17. トラブルとその対応 elasticsearch.ymlの設定値 • 正直なところ、最適な値がいくつかは今でもわかっていない。 その都度試行錯誤している • オンラインで変更可能なものと、再起動が必要なものがある • いろいろなウェブサイトを参考に設定値を変えて試してみたが、 大きなパフォーマンスアップは見られず、デフォルトに近いパ ラメータで運用している index.number_of_shards: 12 index.number_of_replicas: 1 indices.fielddata.cache.size: 50% script.disable_dynamic: false bootstrap.mlockall: true
  18. 18. トラブルとその対応 基本の確認コマンド • クラスタの設定を確認 curl -XGET localhost:9200/_cluster/settings?pretty • クラスタの設定を確認 curl -XGET localhost:9200/_cluster/health?pretty • シャードの配置状況を確認 curl -XGET localhost:9200/_cat/shards 2>/dev/null
  19. 19. トラブルとその対応 ノードの入れ替え • ノードをグレードアップするときには、新しいインスタンスを 同数用意して、全部入れ替える手法を取った バージョンアップ時やインスタンスタイプを変えたときなど。例えば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“ } }'
  20. 20. トラブルとその対応 特定のノードにシャードが固まっているときに移動をさせる • あるノードが落ちたときなど、特定のノードにシャードが固 まっていて負荷になっていたときは、手動で再配置をかけて対 応したことも 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" } } ] }'
  21. 21. トラブルとその対応 unassignedのシャードをノードに割り振る • たまにunassignedになったままのシャードがあるので、自動 での割り当てを待たずにRESTで割り当てノードを指定 curl -XPOST 'localhost:9200/_cluster/reroute' -d '{ "commands" : [ { "allocate" : { "index" : "deliver-2014.06.29", "shard" : 4, "node": "loganalytics-data25", "allow_primary": true } } ] }'
  22. 22. トラブルとその対応 initializingのままのシャードをキャンセル • 原因不明だが、initializingのままずっとスタックしている シャードがあった。そのときはシャードをキャンセル curl -XPOST 'localhost:9200/_cluster/reroute' -d '{ "commands" : [ { "cancel" : { "index" : "deliver-2014.07.03", "shard" : 2, "node" : "loganalytics-data24" } } ] }'
  23. 23. トラブルとその対応 同時に再配置を行う数をコントロール • 時間帯をみて、再配置を行う数を変更して負荷を調整 Excludeしたノードから一気に引っ越しさせるときもこれ curl -XPUT localhost:9200/_cluster/settings -d '{ "transient" : { "cluster.routing.allocation.cluster_concurrent_rebalance" : 8 } }'
  24. 24. まとめ • データインフラにElasticSearchを採用した経緯とメリット・ デメリットについて話しました • システム全体の中で、どういう位置づけで、どういうSLAで運 用していくかを明確にしておくことが大事だと感じました • 構成や設定については日々悩みながら運用していて、最適値に ついても試行錯誤中です • ある程度の規模で構築・運用した事例として、参考になれば幸 いです

×