アドテク×scala×パフォーマンスチューニング

Post on 07-Jul-2015

6.647 Views

Category:

Software

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

アドテク×Scala meetup 2014-11-20 http://connpass.com/event/8384/

TRANSCRIPT

×

~ パフォーマンス改善の心構えと勘ドコロ ~

アドテク × Scala meetup 2014-11-20 @mogproject

アドテク パフォーマンス チューニング

Scala×

Agenda

Demand Side Science の紹介

パフォーマンスチューニング概論

開発フェーズ別のポイント

水谷 陽介 (@mogproject)

Scala Conference in Japan 2013 のスタッフ参加を機に2013年4月 Demand Side Science 入社

フルスタックエンジニア (笑)

前職は SIer のインフラエンジニア (9年)

自己紹介

http://about.me/mogproject

http://mogproject.blogspot.jp

http://demand-side-science.jp/blog

http://functional-news.com

2012年11月Demand Side Science 株式会社設立

DSS のこれまで

Demand× Side

Science×

2013年

プライベート DSP パッケージ fractale を開発

DSS のこれまで

Demand× Side

Platform×

リアルタイム広告取引 (RTB) における、広告主側のシステム

DSP とは

Supply Side Platform

2013年12月 インターネット広告代理店 オプト グループに参入

2014年10月 ダイナミック・クリエイティブツール unis 提供開始

DSS のこれまで

× ×

ロジックに従って、動的に広告を生成 http://www.opt.ne.jp/news/pr/detail/id=2492

unis

ベンチャーマインドとオプトグループの 強みを活かしつつ

DSS のこれから

Demand× Side

Science×

サイエンスを軸に 様々なプロダクトを生み出していきたい

DSS のこれから

???× ???

Science×

みんなが

DSS のこれから

広告主 ×メディア 利用者×Marketer Publishers Consumer

ハッピーになれる世界を目指して

DSS のこれから

Win × Win Win×

Demand Side Science は

DSS と Scala

創業以来×全てのプロダクトで

Scala を採用しています×

システム構成イメージRDBMS NOSQL

ログストレージ キャッシュ

ログ集計 機械学習

キャッシュ生成 etc.

JavaScript のチューニングについては 今回は触れません

システム構成イメージ

Agenda

Demand Side Science の紹介

パフォーマンスチューニング概論

開発フェーズ別のポイント

システムの課題の解消

インフラコストの削減

パフォーマンスチューニングの目的

高負荷時のアプリケーションの挙動に問題発生

ある条件下でレイテンシー(応答時間) が悪化

バッチ処理の所要時間が目標を超過

開発ツールの動作が遅い

システムの課題の解消

アドテク分野では特に重要

コストが肥大化しがち 大量トラフィック 厳しい応答性能 大規模データベース・ログデータ

配信量増による利益 > インフラ投資額でなければ、そもそもビジネスが成り立たない

インフラコストの削減

パフォーマンスチューニング自体の コスト (≒ エンジニアの労働時間) と

リスク (未知のトラブルを引き起こす可能性) を意識

目的を見失ってはいけない

単純なインフラ増強が最適解の場合も多い

目標を達成できたら、適当な所で手を引く

を繰り返す (場当たり的な対応はNG)

パフォーマンスチューニングの基本

メトリクスの測定

× ボトルネックの特定

仮説を立てて調整×

参考: http://www.atmarkit.co.jp/ait/articles/0501/29/news011.html

http://ja.wikipedia.org/wiki/パレートの法則

“プログラムの処理にかかる時間の 80%

はコード全体の 20% の部分が占める”

— パレートの法則

※個人の感想です。何の根拠もありません。

ボトルネックの傾向

その他 1%

ネットワーク 4%

JVMパラメータ 5%

ライブラリ 5%

OS 10%

Scala 10%

非同期処理・スレッド 15%

データベース (RDBMS/NOSQL)

50%

“正しい実装さえしていれば これまで経験してきたシステムの大半は

I/O バウンド だった”

— 弊社フルスタックエンジニア

※個人的な感想です ※機械学習アルゴリズムは除く

I/O の 3大要素

メモリ × ディスク

ネットワーク×

一般的なPCのオペレーション処理時間

http://norvig.com/21-days.html#answers

CPU命令 1 ナノ秒 = 1/1,000,000,000 秒

CPU L1キャッシュから読み込み 0.5 ナノ秒

CPU 分岐予測の失敗 5 ナノ秒

CPU L2キャッシュから読み込み 7 ナノ秒

mutex のロック/アンロック 25 ナノ秒

メインメモリにアクセス 100 ナノ秒

1Gbps ネットワークで 2KB 送信 20,000 ナノ秒

メインメモリから 1MB 順次読み込み 250,000 ナノ秒

ディスクのシーク 8,000,000 ナノ秒

ディスクから 1MB 順次読み込み 20,000,000 ナノ秒

日本~アメリカ西海岸間のパケット転送往復 150,000,000 ナノ秒=150ミリ秒

http://itpro.nikkeibp.co.jp/article/COLUMN/20100119/343461/

もしもCPU命令1回に1秒かかるならCPU命令 1秒

CPU L1キャッシュから読み込み 0.5秒

CPU 分岐予測の失敗 5秒

CPU L2キャッシュから読み込み 7秒

mutex のロック/アンロック 0.5分

メインメモリにアクセス 1.5分

1Gbps ネットワークで 2KB 送信 5.5分

メインメモリから 1MB 順次読み込み 3日

ディスクのシーク 3ヶ月

ディスクから 1MB 順次読み込み 6.5ヶ月

日本~アメリカ西海岸間のパケット転送往復 5年

https://www.coursera.org/course/reactive week3-2

間寛平 アースマラソン ヨットで太平洋横断

千葉 ~ ロサンゼルス (片道)

2009-01-03 -> 2009-03-11

70日で達成

ちなみに

http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%BC%E3%82%B9%E3%83%9E%E3%83%A9%E3%82%BD%E3%83%B3#.E3.83.A8.E3.83.83.E3.83.88.EF.BC.9A.E5.8D.83.E8.91.89_-

_.E3.83.AD.E3.82.B5.E3.83.B3.E3.82.BC.E3.83.AB.E3.82.B9

バッチ処理で 10KB 程度の小さなファイルを

ディスクから 100万個 読み込んでいた

合計サイズ:

10KB × 1,000,000 ≒ 10GB

本当にあった怖い話

100万回のシークが発生すると8ms × 106 + 20ms × 10,000 ≒ 8,200 sec ≒ 2.5 h

もし10GBのファイル1個で1回のシークで済むと

8ms × 1 + 20ms × 10,000 ≒ 200 sec ≒ 3.5 min

本当にあった怖い話

ディスクヘッドの気持ちを考えよう

http://en.wikipedia.org/wiki/Hard_disk_drive

JVM におけるトレードオフの関係

JVM パフォーマンス・トライアングル

メモリ占有空間 ↓

情報処理量 ↑ 応答時間 ↓

Memory Footprint

Throughput Latency

アプリケーションの 最長停止時間 ≒ Full GC の時間

言い換えると

JVM パフォーマンス・トライアングル

省メモリ

情報処理量 応答速度

Compactness

Throughput Responsiveness

C × T × R = k (定数)

JVM パフォーマンス・トライアングル

k に対して C, T, R のどこに比重を置くか変えるのがチューニング

k を増加させるのが最適化 (Optimization)

(Twitter社ソフトウェアエンジニアの発表)

http://www.beyondlinux.com/files/pub/qconhangzhou2011/Everything%20I%20ever%20learned%20about%20JVM%20performance%20tuning%20@twitter%28Attila%20Szegedi%29.pdf

Agenda

Demand Side Science の紹介

パフォーマンスチューニング概論

開発フェーズ別のポイント

1. 要件定義/フィージビリティ 2. 方式設計 3. 環境設計 4. 環境構築/プログラミング 5. システムテスト 6. 運用/保守

開発フェーズ

パフォーマンスに影響がありそうな ポイントを中心に取り上げます

性能要件について関係者の合意を得る

要件定義/フィージビリティ

想定ユーザーID数

日本のインターネット人口: 約1億人

日本のユニークブラウザ数: 2億~数億 増加率は? 情報を保持する期間は? デバイス/ブラウザの種別は? オプトアウトしているユーザの割合は?

要件定義/フィージビリティ

広告配信要求数 月間 impression 数

月間10億件の場合=> 平均すると 400 QPS (Query Per Second)

=> ピーク率 250% とすると 1,000 QPS

RTBの場合、入札率は? 勝率は?

目標応答時間は? コンテンツの容量は?

増加計画は? Cookie Sync リクエストの量は?

要件定義/フィージビリティ

トラッカー受信量 トラッカー発生のタイミング 広告クリックの確率は? コンバージョン(商品購入など)の発生確率は?

要件定義/フィージビリティ

集計に関する要件 集計すべき指標 ユニーク数の集計は必要か? 集計から除外すべき条件はあるか? 誰が、いつ見るのか 広告代理店が二次加工をして広告主にレポートしている? 更新頻度 集計データの保持期間

要件定義/フィージビリティ

ビジネスサイドの制約 売上計画 年末商戦に合わせたい、年度内に売上目標を達成したい、など インフラ予算

市場の変化が激しいアドテクの世界で 正確な見積りを行うのは至難の業であるが、 仮置きでもよいので数字を出すことが大事

要件定義/フィージビリティ

アーキテクチャ設計には前提が必要 性能テストには目標が必要

アーキテクチャ設計 フレームワーク選択

Webフレームワーク データベース選択

RDBMS NOSQL

方式設計

並行プログラミングモデルの設計 ブロッキングをいかに減らすか Future ベース コールバックを利用した関数合成が基本

Actor ベース メッセージパッシング

スレッドプールの設計 スレッドプールのサイズの適正値は本番環境で性能テストを行うまでわからない

方式設計

データベース設計 アクセスパターン/ルックアップ回数

1レコードあたりのサイズ サイズが一定でない場合は分布をモデル化 レコード数 増加率/保持期間 メモリ使用量 DB単体の性能をまず実測する

環境設計

ログ設計 ディスク容量の見積りでは圧縮率を考慮

キャッシュ設計 Redis など、バックアップのために 2倍のキャパシティが必要な場合もあるので注意

環境設計

この段階では、最適化よりも簡潔さ・明快さを優先したほうがよい

“正しいプログラムを速くすることは、

速いプログラムを正しくするより

はるかに、はるかに簡単だ。”

— C++ Coding Standards―101のルール、ガイドライン、ベストプラクティス (C++ in-depth series)

環境構築/プログラミング

— Donald Knuth

“時期尚早な最適化は諸悪の根源だ。”

— Jon Bentley

“一方で、効率性は無視できない。”

線形より悪いアルゴリズムはできるだけ避ける

推測するな、計測すべしhttp://ja.wikipedia.org/wiki/UNIX哲学

環境構築/プログラミング

sbt コンソールの中で OpenJDK jmh

(Java のベンチマークツール Java Microbenchmark Harness) を使うためのプラグインhttps://github.com/ktoso/sbt-jmh

マイクロベンチマーク: sbt-jmh

addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.1.6")

マイクロベンチマーク: sbt-jmh

plugins.sbt

jmhSettingsbuild.sbt

import org.openjdk.jmh.annotations.Benchmark class YourBench { @Benchmark def yourFunc(): Unit = ??? // 計測したい処理を書く}

YourBench.scala

アノテーションを付けるだけ

> run -i 3 -wi 3 -f 1 -t 1

マイクロベンチマーク: sbt-jmh

sbt コンソールを起動し、ベンチマーク実行

計測回数

ウォーミング アップ回数

全体の試行回数スレッド数

[info] Benchmark Mode Samples Score Score error Units[info] c.g.m.u.ContainsBench.listContains thrpt 3 41.033 25.573 ops/s[info] c.g.m.u.ContainsBench.setContains thrpt 3 6.810 1.569 ops/s

マイクロベンチマーク: sbt-jmh

実行結果 (抜粋)

デフォルトではスループット (単位時間あたりの処理回数) が表示される。 (大きほど良い)

http://mogproject.blogspot.jp/2014/10/micro-benchmark-in-scala-using-sbt-jmh.html

Scala 最適化の例

Scala コレクションを正しく使う

関数呼び出しよりも再帰を使う今年の Scala Matsuri で Martin Odersky 先生が発言

高速化ライブラリを試してみる

def f(xs: List[Int], acc: List[Int] = Nil): List[Int] = { if (xs.length < 4) { (xs.sum :: acc).reverse } else { val (y, ys) = xs.splitAt(4) f(ys, y.sum :: acc) }}

本当にあった怖い話 その2

List[Int] の要素を 4つずつグループにして それぞれの和を求める処理を再帰で

scala> f((1 to 10).toList)res1: List[Int] = List(10, 26, 19)

実行例

本当にあった怖い話 その2

List#length の計算量はリストの長さに比例

パラメータ xs の長さを n とすると O(n)

実装は LinearSeqOptimized#lengthhttps://github.com/scala/scala/blob/v2.11.4/src/library/scala/collection/LinearSeqOptimized.scala#L35-43

本当にあった怖い話 その2

関数 f を実行すると、xs.length はn / 4 + 1 回評価される。

つまり f の実行回数も n に比例する

従って、関数 f の計算量は O(n2)

n が大きくなると急速に性能が劣化する

本当にあった怖い話 その2

ちなみに、組み込みメソッドを使えば 1行で書ける

scala> (1 to 10).grouped(4).map(_.sum).toListres2: List[Int] = List(10, 26, 19)

ScalaBlitz

マクロ機能を利用して Scala コレクションの利用を最適化するライブラリ

http://scala-blitz.github.io/

Scala Days 2014 での発表https://parleys.com/play/53a7d2c6e4b0543940d9e549/chapter0/about

ScalaBlitz

システム機能テスト システム間インターフェーステスト 性能テスト 信頼性テスト セキュリティテスト 運用性テスト

システムテスト

単体負荷テスト

シナリオ負荷テスト 現実のユーザ操作を模した負荷

エージング(連続稼働)テスト

性能テスト

Apache 付属

シンプルなベンチマークツールhttp://httpd.apache.org/docs/2.2/programs/ab.html

単純な要件であればこれで十分 最新バージョンの利用を推奨(Amazon Linux プリインストールのバージョンでバグに苦しめられた) コマンド実行例

ab - Apache Bench

ab -C <Cookie名=値> -n <リクエスト件数> -c <同時実行数> “<URL>“

実行結果の例 (一部)

ab - Apache Bench

Benchmarking example.com (be patient)Completed 1200 requestsCompleted 2400 requests(略)Completed 10800 requestsCompleted 12000 requestsFinished 12000 requests(略)Concurrency Level: 200Time taken for tests: 7.365 secondsComplete requests: 12000Failed requests: 0Write errors: 0Total transferred: 166583579 bytesHTML transferred: 160331058 bytesRequests per second: 1629.31 [#/sec] (mean)Time per request: 122.751 [ms] (mean)Time per request: 0.614 [ms] (mean, across all concurrent requests)Transfer rate: 22087.90 [Kbytes/sec] received(略)Percentage of the requests served within a certain time (ms) 50% 116 66% 138 75% 146 80% 150 90% 161 95% 170 98% 185 99% 208 100% 308 (longest request)

Requests per second = QPS

Scala で書かれた負荷テストツール

http://gatling.io

Gatling

Apache JMeter の時代は終わった

GUI でシナリオを作るのはつらい

Gatling なら

負荷シナリオを Scala DSL で書ける 必読記事

WEB+DB PRESS Vol.83 (2014/10月) 「Javaの鉱脈」http://gihyo.jp/magazine/wdpress/archive/2014/vol83

筆者 @ryushi さんのブログ http://blog.satotaichi.info/gatling-is-awesome-loadtester

Gatling

負荷をかける側のリソースにも注意 サーバ (PC) のリソース

ネットワークルータの CPU がボトルネックになったことも

一度に 2箇所以上の調整をしない

変更履歴やログファイルをきちんと残す

テスト & チューニングの日々

運用/保守

ログ出力 × 異常検知

トレンド可視化×

日常的にログを記録し、監視する アプリケーションログ GCログ プロファイラー 各種メトリクスによる異常検知 サーバリソース (CPU, メモリ, ディスク等) レスポンスコード異常 レイテンシ 各種メトリクスのトレンド可視化

運用/保守

GCログJVM起動オプションで指定

JVM の運用設定

-verbose:gc-Xloggc:<ログファイルのパス>-XX:+PrintGCDetails-XX:+PrintGCDateStamps-XX:+UseGCLogFileRotation-XX:NumberOfGCLogFiles=10-XX:GCLogFileSize=10M

— Oracle 社の実際の顧客

“本番環境で

GCログを出してない奴は

撃ってやる!”

http://www.oracle.com/technetwork/server-storage/ts-4887-159080.pdf p55

“If someone doesn't enable GC logging in production, I shoot them!”

JMX (Java Management eXtensions)JVM起動オプションに以下を指定

JVM の運用設定

-Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.port=<ポート番号>-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false

標準出力/標準エラー出力 ファイルにリダイレクトさせる /dev/null に捨てない

スレッドダンプ の結果はここに出る

JVM の運用設定

kill -3 <プロセスID>

SLF4J + Profiler http://www.slf4j.org/extensions.html

コード例

プロファイラー

import org.slf4j.profiler.Profiler

val profiler: Profiler = new Profiler(this.getClass.getSimpleName)

profiler.start(“A”)doA()

profiler.start(“B”)doB()

profiler.stop()logger.warn(profiler.toString)

SLF4J + Profiler 出力例

利用例: タイムアウトが発生時にプロファイラーの結果をログに出力

プロファイラー

+ Profiler [BASIC]|-- elapsed time [A] 220.487 milliseconds. |-- elapsed time [B] 2499.866 milliseconds. |-- elapsed time [OTHER] 3300.745 milliseconds. |-- Total [BASIC] 6022.568 milliseconds.

異常検知ではなく、トレンド把握が目的 変化の兆候を見逃さないような運用も大事 インフラ/アプリだけなく、ビジネス指標も 誰のための画面? システム利用者 システム管理者 アプリ開発者 経営者 (ビジネスの判断を下す人)

メトリクスの可視化

Grafana (+Graphite)

Graphite - http://graphite.readthedocs.org 時系列の数値データを管理/可視化

Grafana - http://grafana.org/ Graphite のデータをカッコよく(Kibana っぽく) 可視化

Graphite にメトリクスを送るScala ライブラリを公開予定

Grafana (+Graphite)

Demand Side Science は

本物の Scala プログラマーを

募集しています。

相談・応募はこちら! ランチご馳走します!

recruit@demand-side-science.jp

DSS 広告

×

~ パフォーマンス改善の心構えと勘ドコロ ~

アドテク × Scala meetup 2014-11-20 @mogproject

ご清聴 ありがとう ございました!

どうも×

"Yosuke Mizutani - Kanagawa, Japan | about.me" - http://about.me/mogproject "mog project" - http://mogproject.blogspot.jp/ "DSS Tech Blog - Demand Side Science ㈱ の技術ブログ" - http://demand-side-

science.jp/blog/ "FunctionalNews - 関数型言語ニュースサイト" - http://functional-news.com/

"『ザ・アドテクノロジー』~データマーケティングの基礎からアトリビューションの概念まで~ / 翔泳社 新刊のご紹介" - http://markezine.jp/book/adtechnology/

"オプト、ダイナミック・クリエイティブツール「unis」の提供開始 ~ パーソナライズ化された広告を自動生成し、広告効果の最大化を目指す ~ | インターネット広告代理店 オプト" - http://www.opt.ne.jp/news/pr/detail/id=2492

"The Scala Programming Language" - http://www.scala-lang.org/ "Finagle" - https://twitter.github.io/finagle/ "Play Framework - Build Modern & Scalable Web Apps with Java and Scala" - https://www.playframework.com/ "nginx" - http://nginx.org/ja/ "Fluentd | Open Source Data Collector" - http://www.fluentd.org/ "Javaパフォーマンスチューニング(1):Javaパフォーマンスチューニングのルール (1/2) - @IT" - http://www.atmarkit.co.jp/ait/articles/0501/29/news011.html

"パレートの法則 - Wikipedia" - http://ja.wikipedia.org/wiki/パレートの法則

"Teach Yourself Programming in Ten Years" - http://norvig.com/21-days.html#answers "企業が作る国際ネットワーク最前線 - [4]いまさら聞けない国際ネットワークの基礎知識:ITpro" - http://itpro.nikkeibp.co.jp/article/COLUMN/20100119/

343461/ "Coursera" - https://www.coursera.org/course/reactive "アースマラソン - Wikipedia" - http://ja.wikipedia.org/wiki/アースマラソン

"Hard disk drive - Wikipedia, the free encyclopedia" - http://en.wikipedia.org/wiki/Hard_disk_drive "Everything I ever learned about JVM performance tuning @twitter(Attila Szegedi).pdf" - http://www.beyondlinux.com/files/pub/qconhangzhou2011/Everything%20I%20ever%20learned%20about%20JVM%20performance%20tuning%20@twitter%28Attila%20Szegedi%29.pdf

"Amazon.co.jp: C++ Coding Standards―101のルール、ガイドライン、ベストプラクティス (C++ in-depth series): ハーブ サッター, アンドレイ アレキサンドレスク, 浜田 光之, Herb Sutter, Andrei Alexandrescu, 浜田 真理: 本" - http://

www.amazon.co.jp/gp/product/4894716860 "UNIX哲学 - Wikipedia" - http://ja.wikipedia.org/wiki/UNIX哲学

"ktoso/sbt-jmh" - https://github.com/ktoso/sbt-jmh "ScalaBlitz | ScalaBlitz" - http://scala-blitz.github.io/ "Parleys.com - Lightning-Fast Standard Collections With ScalaBlitz by Dmitry Petrashko" - https://parleys.com/play/53a7d2c6e4b0543940d9e549/chapter0/about "mog project: Micro Benchmark in Scala - Using sbt-jmh" - http://mogproject.blogspot.jp/2014/10/micro-benchmark-in-scala-using-sbt-jmh.html "Gatling Project, Stress Tool" - http://gatling.io/ "WEB+DB PRESS Vol.83|技術評論社" - http://gihyo.jp/magazine/wdpress/

archive/2014/vol83 "「Javaの鉱脈」でGatlingの記事を書きました — さにあらず" - http://

blog.satotaichi.info/gatling-is-awesome-loadtester "Garbage Collection Tuning in the Java HotSpot™ Virtual Machine" - http://www.oracle.com/technetwork/server-storage/ts-4887-159080.pdf "SLF4J extensions" - http://www.slf4j.org/extensions.html "Graphite Documentation — Graphite 0.10.0 documentation" - http://graphite.readthedocs.org/en/latest/ "Grafana - Graphite and InfluxDB Dashboard and graph composer" - http://grafana.org/ "Grafana - Grafana Play Home" - http://play.grafana.org/#/dashboard/db/grafana-play-home "不動産関係に使える 無料画像一覧" - http://free-realestate.org/information/

list.html "AI・EPSの無料イラストレーター素材なら無料イラスト素材.com" - http://www.無料イラスト素材.com/

"大体いい感じになるKeynoteテンプレート「Azusa」作った - MEMOGRAPHIX" -

http://memo.sanographix.net/post/82160791768

参考文献

top related