SlideShare a Scribd company logo
1 of 49
Download to read offline
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
2019/03/12
矢端 喜楽 後藤
Yahoo!ニュースにおける
BFFパフォーマンス
チューニング事例
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
自己紹介
矢端 智光
2012新卒からニュースを担当。アプリの新規開発やスピーカー開発を経て今に至る。
AndroidやSpring BootでJavaばかり触っていたが、今期からScriptがついた。はじめてのwebページ新規開発。
noimage
noimage
noimage
喜楽 智規 (@gladenjoy)
2016新卒からニュース一筋約3年。PHP→Java→TypeScriptと渡り歩いて来た。フロントエンド・BFFあたりの開発に従事。
後藤 拓実(@oTheRwoRldy)
2012新卒からニュースを担当。フロントエンド技術、API設計、アプリケーションのアーキテクチャに興味。TL。
2
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
今日の内容
Node.js経験の浅いメンバーによるパフォーマンス改善のお話
3
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
本題
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
開発したWebアプリケーションの概要
名称:NewsWeb
news.yahoo.co.jp配下の一部ページを担うWebアプリケーションです。
キーワード
Node.js / TypeScript / React / Redux / Express / InversifyJS /
axios / Storybook / Backend for Frontend / Server Side Rendering / Layered Architecture
実行環境
Pivotal Cloud Foundry(Private PaaS)
開発メンバー
10名弱
東京拠点と九州拠点のメンバーで開発を行っています
補足
Javaで一度書いた後、SSRの課題が出てきたのでNode.jsに置き換えています
5
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
アプリケーションの概要図
NewsWeb
記事サービス
ランキング
サービス
トピックス
サービス
お知らせ
サービス
…
Edge Server
Redis
Cluster
※省略していますが、Edge Serverの後ろには他にもフロントエンドサーバがあります。
段階的にページを移行しており、現時点でYahoo! ニュースの全リクエストを新システムが担っているわけではないです。
旧システム
6
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
パフォーマンスに関する要件
秒間リクエスト数
- 4000req/s以上
レスポンスタイム
- 99パーセンタイル値が1秒以下
- 80パーセンタイル値が0.5秒以下
現行のシステムの性能をベースにした要件で、概ね上記を満たしたい。
7
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ベンチマークを取るツール
Apache Bench(ab)を利用
Apache HTTP Serverに付属するベンチマークツール
yumなどでhttpdをインストールするか、apr-utilパッケージを入れることで利用できます。
※今回はabを使いましたが、abでなければいけない理由は特にありません。
$ sudo yum install httpd
$ sudo yum install apr-util
8
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ベンチマークをとるときの構成
9
NewsWeb
記事サービス
ランキング
サービス
トピックス
サービス
お知らせ
サービス
…
ベンチ用
仮想サーバ
Redis
Cluster
- 本番相当の環境に1インスタンス用意
- ベンチマーク用のVMからabを実行
すべてローカル環境で実行する方法もあるが
今回はこの方法でベンチマークを実施した。
Wi-Fiなどネットワークがボトルネックになる
ことがあるので注意する。
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ベンチマークの手順
並列数を増加させながら秒間リクエスト数が頭打ちになる箇所を探る
10
$ ab -t 30 -c 5 -k http://dummy-domain.yahoo.co.jp/
$ ab -t 30 -c 10 -k http://dummy-domain.yahoo.co.jp/
$ ab -t 30 -c 15 -k http://dummy-domain.yahoo.co.jp/
$ ab -t 30 -c 20 -k http://dummy-domain.yahoo.co.jp/
$ ab -t 30 -c 25 -k http://dummy-domain.yahoo.co.jp/
-k: Keep Alive有効
-t: ベンチマークの実行時間(sec)
-c: 並列アクセス数
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ベンチマークの結果(改善前)
0
5
10
15
20
25
30
5 10 15 20 25 30 35 40 45 50
秒間リクエスト数
並列数
並列数毎の秒間リクエスト数の推移
改善前
11
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ベンチマークの結果(改善前)
12
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ベンチマークの結果
想像以上にパフォーマンスが良くない
- 秒間リクエスト数は23req/s程度で頭打ち
- レスポンスタイムも並列数に比例してあがっていく
多数のインスタンスを並べれば要件は満たせるが…
何らかのボトルネックがありそうな気がする。
13
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
さてどうしよう
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
先入観
「SSR時のrenderToNodeStreamが重いのかなと思っています」
「SSR自体重いと聞きますし、確かに怪しそうですね」
喜楽
後藤
15
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
まずはボトルネックを特定したい
- 地道にconsole.time, console.timeEndを仕込む?
- sjspのようなプロファイリングコードを挿入してくれるツールを使う?
- functionの実行時間と実行回数が出力できる
- nodeの—profオプションを使う?
- ちょっと調べた感じ難しそう…
16
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
Nodeサポートチームに相談
「ボトルネック特定するベストプラクティスを教えてほしいです」
「まずは profile を取ることからだと思います」
後藤
Nodeサポート
17
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
プロファイルをとる?
Node.js (V8)に備わっているプロファイリング機能がある
--profオプションを指定してアプリケーションサーバを起動すると
isolate-0xnnnnnnnnnnnn-v8.logというファイルにログが出力される
このファイルにnode --process-profを適用することで読める形に変換される
Easy profiling for Node.js Applications | Node.js
https://nodejs.org/en/docs/guides/simple-profiling/
$ node —prof index.js
$ node —process-prof isolate-0xnnnnnnnnnnnn-v8.log > result.txt
18
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
プロファイル結果の見方
プロファイル結果はいくつかのセクションに分かれているが、
まずはSummaryセクションを確認する。
今回の場合、C++ のCPU Timeが多いことがわかる
[Summary]:
ticks total nonlib name
186 9.2% 9.3% JavaScript
1788 88.5% 89.8% C++
39 1.9% 2.0% GC
29 1.4% Shared libraries
18 0.9% Unaccounted
19
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
プロファイル結果の見方
[C++]:
ticks total nonlib name
453 22.4% 22.7% t node::fs::Open(v8::FunctionCallbackInfo<v8::Value> const&)
379 18.8% 19.0% T node::contextify::ContextifyScript::New(v8::FunctionCallbackInfo<v8::Value> const&)
90 4.5% 4.5% t node::fs::InternalModuleReadJSON(v8::FunctionCallbackInfo<v8::Value> const&)
85 4.2% 4.3% t node::fs::Read(v8::FunctionCallbackInfo<v8::Value> const&)
C++の処理の内訳を確認すると、File関連の処理が重そう
20
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
プロファイル結果の見方
[Bottom up (heavy) profile]:
ticks parent name
453 22.4% t node::fs::Open(v8::FunctionCallbackInfo<v8::Value> const&)
453 100.0% T v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
453 100.0% LazyCompile: ~openSync fs.js:429:18
453 100.0% LazyCompile: ~readFileSync fs.js:341:22
Bottom upの項目を確認すると、readFileSyncが重そう
21
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
ボトルネックの可視化
重い箇所のあたりはついてきた。
ボトルネックをコードレベルで特定するのに以下のツールを使う。
- flamebearer
- node --inspect
22
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
flamebearerによる可視化
プロファイルログをフレームグラフで表示してくれるツール
$ node --prof-process --preprocess -j isolate*.log | flamebearer
23
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
flamebearerによる可視化
パスを一部を指定するとハイライト表示してくれる(緑色の部分)
24
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
node —inspect
--inspectを付けてnodeを立ち上げることで、Chromeと連携してデバッグが可能
起動後、chrome://inspect/ を開くと
実行中のプロセスにアタッチできる
$ node —inspect dist/index.js
Debugger listening on ws://127.0.0.1:9229/0dbdaf5f-7012-4ad0-8693-4af2906a9fb7
For help, see: https://nodejs.org/en/docs/inspector
25
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
node —inspect
Chart表示が視覚的に時間がかかっている箇所を特定しやすくおすすめ
26
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
わかったこと
JSON.parseの頻繁な呼び出しがボトルネックになっていた
- axios-cache-adapterのキャッシュ結果が文字列で保持されており、
キャッシュ取得時はJSON.parseしていた
- JSON.parseは同期処理なためボトルネックに
Intl.DateTimeFormatがボトルネックになっていた
- 社内製ライブラリで使われていた
DIコンテナからインスタンスを取り出すとき毎回constructorが呼ばれていた
- constructor内でreadFileSyncがあった
- Spring Bootの経験からデフォルトがシングルトンだと思い込んでいた
27
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
それぞれ対応
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
改善1:axiosのキャッシュパフォーマンス改善
課題
axios-cache-adapterのキャッシュ結果が文字列で保持されており、
キャッシュ取得時は毎回JSON.parseしていた。
NewsWebではバックエンドAPIの数が多く、また、
JSON.parseは同期処理なためボトルネックになっていた。
対応
axiosのキャッシュアダプタを自作。
JSON(文字列)ではなくオブジェクトをキャッシュして返すように変更した。
※ボトルネック解消を目的としているため、これが設計として良いかどうかは別の問題です
29
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
改善2:社内製のライブラリの実装改善
課題
Intl.DateTimeFormatを使ったある社内ライブラリ(ExpressのMiddleware)
の処理が重く、ボトルネックになっていた。
対応
ライブラリの開発者にDate.toUTCStringを使った実装へ変更してもらい、
そちらを利用するようにした。
30
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
参考: Intl.DateTimeFormatのパフォーマンス
31
const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
console.time('Intl.DateTimeFormat');
for(let i = 0; i < 10000; i++) {
new Intl.DateTimeFormat('en-US').format(date);
}
console.timeEnd('Intl.DateTimeFormat');
console.time('Date.toUTCString');
for(let i = 0; i < 10000; i++) {
date.toUTCString();
}
console.timeEnd('Date.toUTCString');
$ node index.js
Intl.DateTimeFormat: 5991.971ms
Date.toUTCString: 5.954ms
検証コード 実行結果
1万回のループで検証。1000倍近いパフォーマンスの差がありそう。
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
改善3:DIコンテナ内のインスタンスをシングルトンに
課題
DIコンテナのインスタンスを参照する度にコンストラクタが実行されている。
コンストラクタ内でReadFileSyncするクラスがありボトルネックになっていた。
対応
コンテナにSingletonスコープでオブジェクトを登録をした。
https://github.com/inversify/InversifyJS/blob/master/wiki/scope.md
// 修正前
container.bind(DISymbols.TopicsService).to(TopicsService);
// 修正後
container.bind(DISymbols.TopicsService).to(TopicsService).inSingletonScope();
32
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
改善4:App起動時にDIコンテナのwarmup
課題
InversifyJSのコンテナからオブジェクトを取り出すとき、
コンストラクタが実行されるため、初回の呼び出しが遅い。
対応
App起動時に、コンテナに登録された全オブジェクトをgetし、
コンストラクタを実行しておく。
// 予めDI Containerのすべてを呼び出して、singletonインスタンスを初期化する
// typescriptのチェックを回避するために型定義をして再代入しています
const symbols: { [key: string]: symbol } = {
...DISymbols
};
for (const key in symbols) {
if (key) {
container.get(symbols[key]);
}
}
33
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
それ以外にも気づきベースで対応したこと
ボトルネック調査の結果とは別に、以下の改善の実施
- Clusterモジュールの利用
- バックエンドAPIへのKeep Alive対応
34
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
改善5:Clusterモジュールの導入
課題
Private PaaS は1インスタンスあたり8コア割り当てられていた。
Node.jsはデフォルトでは1コアしか使わないため、有効活用できていなかった。
対応
Node.jsの標準モジュールのClusterモジュールを導入した。
https://nodejs.org/api/cluster.html 35
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
Clusterモジュールの実装
36
import cluster from 'cluster';
import express from 'express';
import os from 'os';
const port = process.env.PORT || '3000';
if (cluster.isMaster) {
for (let i = 0; i < os.cpus().length; i++) {
cluster.fork();
}
cluster.on('exit', worker => {
cluster.fork();
});
} else {
const app = express();
app.listen(port);
}
import express from 'express';
const port = process.env.PORT || '3000';
const app = express();
app.listen(port);
導入前 導入後
得られる恩恵の割に非常に導入が容易です。
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
補足:Clusterモジュールとnode --inspect
Clusterモジュールを導入した後、node --inspectを使うと
各プロセスでデバッグ機能が有効になってしまい使い勝手が悪い
例えば、以下のように--inspectパラメータが指定されているかを判定し、
Clusterモジュールを使わずに起動できるようにしておくと捗ります。
37
const debug = /--inspect/.test(process.execArgv.join(' '));
if (debug) {
// expressを起動
} else {
// clusterモジュールでforkして、アプリケーションを起動
if (cluster.isMaster) {
// fork...
} else {
// expressを起動...
}
}
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
改善6:バックエンドAPIへのKeep Alive対応
課題
バックエンドAPIへのリクエスト時にKeep Aliveが有効になっていなかった。
対応
axiosに以下のように設定をしてKeep Aliveを有効化
特に、ユーザ情報を含むようなRedisにキャッシュできないAPIに対して効果
接続時のレイテンシ低減、APIサーバの負荷軽減に繋がる。
const axiosClient = axios.create({
timeout,
adapter: createCacheAdapter(axios, {
maxAge
}),
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true })
});
38
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
再ベンチマーク
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
対応実施後の性能を要件毎にみていきます
以下の3パターンに分けて、再度性能評価を行いました。
- 対応前
- Clusterモジュール導入を除く改善実施後
- Clusterモジュール導入を含んだ改善実施後
40
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
要件のおさらい
秒間リクエスト数
- 4000req/s以上
レスポンスタイム
- 99パーセンタイル値が1秒以下
- 80パーセンタイル値が0.5秒以下
現行のシステムの性能をベースにした要件で、概ね上記を満たしたい。
41
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
要件のおさらい
秒間リクエスト数
- 4000req/s以上
レスポンスタイム
- 99パーセンタイル値が1秒以下
- 80パーセンタイル値が0.5秒以下
現行のシステムの性能をベースにした要件で、概ね上記を満たしたい。
👈
42
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
秒間リクエスト数の比較
Clusterモジュールを除いた改善で1インスタンスあたり57req/sec、
Clusterモジュール導入で330req/sec程度の性能がでることがわかりました。
0
50
100
150
200
250
300
350
400
並列数ごとの秒間リクエスト数
対応前 Cluster以外の対応後 Cluster含む対応後
43
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
改善の結果
必要インスタンス数の大幅な削減
1インスタンス
あたりのreq/sec
4000 req/secに必要な
インスタンス数
対応前 23 req/sec 約174 インスタンス
Cluster導入前 57 req/sec 約70 インスタンス
Cluster含む対応後 330 req/sec 約12 インスタンス
44
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
要件のおさらい
秒間リクエスト数
- 4000req/s以上
レスポンスタイム
- 99パーセンタイル値が1秒以下
- 80パーセンタイル値が0.5秒以下
現行のシステムの性能をベースにした要件で、概ね上記を満たしたい。
👈
45
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
80パーセンタイル値のレスポンスタイム数の比較
Cluster以外の対応で30並列、Cluster込で200並列まで、目標値の0.5秒を満
たしていることがわかります。
46
0
0.5
1
1.5
2
2.5
3
3.5
4
4.5
80パーセンタイル値のレスポンスタイム比較
対応前 Cluster以外の対応後 Cluster含む対応後
👈
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
99パーセンタイル値のレスポンスタイム数の比較
Cluster以外の対応で25並列、Cluster込で200並列まで、目標値の1.0秒を満
たしていることがわかります。
47
0
0.5
1
1.5
2
2.5
3
3.5
4
4.5
99パーセンタイル値のレスポンスタイム比較
対応前 Cluster以外の対応後 Cluster含む対応後
👈
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
まとめ
- 以下のようなツールでボトルネックの調査ができる
- node --prof
- node –inspect
- flamebearer
- 想像でCPUバウンド/同期的な処理を疑うのではなく、
プロファイルを取ってボトルネック特定→改善をするのが近道
- 今後
- 継続的なパフォーマンス改善をしていきたい
- 今わかっている限りだとmoment-duration-formatが重そう
48
Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
EOP

More Related Content

What's hot

ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところY Watanabe
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Akihiro Suda
 
ゲームエンジニアのためのデータベース設計
ゲームエンジニアのためのデータベース設計ゲームエンジニアのためのデータベース設計
ゲームエンジニアのためのデータベース設計sairoutine
 
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜Preferred Networks
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話Kumazaki Hiroki
 
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)NTT DATA OSS Professional Services
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Shin Ohno
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)mosa siru
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
 
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Etsuji Nakai
 
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -onozaty
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
Apache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsApache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsYoshiyasu SAEKI
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)Yoshitaka Kawashima
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 

What's hot (20)

ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
ゲームエンジニアのためのデータベース設計
ゲームエンジニアのためのデータベース設計ゲームエンジニアのためのデータベース設計
ゲームエンジニアのためのデータベース設計
 
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
PostgreSQLアーキテクチャ入門
PostgreSQLアーキテクチャ入門PostgreSQLアーキテクチャ入門
PostgreSQLアーキテクチャ入門
 
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門
 
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
 
TLS, HTTP/2演習
TLS, HTTP/2演習TLS, HTTP/2演習
TLS, HTTP/2演習
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
Apache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsApache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once Semantics
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 

Similar to Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例

Unification of the middle scale services by Nuxt.js
Unification of the middle scale services by Nuxt.jsUnification of the middle scale services by Nuxt.js
Unification of the middle scale services by Nuxt.jsHajimeSasanuma
 
Apache CloudStack コントリビューション
Apache CloudStack コントリビューションApache CloudStack コントリビューション
Apache CloudStack コントリビューションSatoshi KOBAYASHI
 
東京Node学園 今できる通信高速化にトライしてみた
東京Node学園 今できる通信高速化にトライしてみた東京Node学園 今できる通信高速化にトライしてみた
東京Node学園 今できる通信高速化にトライしてみたYoshiki Shibukawa
 
Spring I/O 2016 報告 Test / Cloud / Other Popular Sessions
Spring I/O 2016 報告 Test / Cloud / Other Popular SessionsSpring I/O 2016 報告 Test / Cloud / Other Popular Sessions
Spring I/O 2016 報告 Test / Cloud / Other Popular SessionsTakuya Iwatsuka
 
Android 開発を加速するオープンソースライブラリ
Android 開発を加速するオープンソースライブラリAndroid 開発を加速するオープンソースライブラリ
Android 開発を加速するオープンソースライブラリ健一 辰濱
 
HDFSのスケーラビリティの限界を突破するためのさまざまな取り組み | Hadoop / Spark Conference Japan 2019 #hc...
HDFSのスケーラビリティの限界を突破するためのさまざまな取り組み | Hadoop / Spark Conference Japan 2019  #hc...HDFSのスケーラビリティの限界を突破するためのさまざまな取り組み | Hadoop / Spark Conference Japan 2019  #hc...
HDFSのスケーラビリティの限界を突破するためのさまざまな取り組み | Hadoop / Spark Conference Japan 2019 #hc...Yahoo!デベロッパーネットワーク
 
XPagesDay 2015 RESTの総復習
XPagesDay 2015 RESTの総復習XPagesDay 2015 RESTの総復習
XPagesDay 2015 RESTの総復習Masahiko Miyo
 
AI分野におけるコンテナオーケストレーションとは
AI分野におけるコンテナオーケストレーションとはAI分野におけるコンテナオーケストレーションとは
AI分野におけるコンテナオーケストレーションとはTetsurou Yano
 
Tokyo H2O.ai Meetup#2 by Iida
Tokyo H2O.ai Meetup#2 by IidaTokyo H2O.ai Meetup#2 by Iida
Tokyo H2O.ai Meetup#2 by IidaHidenori Fujioka
 
CRDF2011(20110225)
CRDF2011(20110225)CRDF2011(20110225)
CRDF2011(20110225)真 岡本
 
ドリコムを支える課金ライブラリを支えるJenkins
ドリコムを支える課金ライブラリを支えるJenkinsドリコムを支える課金ライブラリを支えるJenkins
ドリコムを支える課金ライブラリを支えるJenkinsGo Sueyoshi (a.k.a sue445)
 
Zappa で Serverless CMS を作ってみる
Zappa で Serverless CMS を作ってみるZappa で Serverless CMS を作ってみる
Zappa で Serverless CMS を作ってみるIosif Takakura
 
NHNグループ合同勉強会 ライブドア片野
NHNグループ合同勉強会 ライブドア片野NHNグループ合同勉強会 ライブドア片野
NHNグループ合同勉強会 ライブドア片野livedoor
 
おすすめインフラ! for スタートアップ
おすすめインフラ! for スタートアップおすすめインフラ! for スタートアップ
おすすめインフラ! for スタートアップKoichiro Sumi
 
20191228_jaws-ug_okayama-2019_winter
20191228_jaws-ug_okayama-2019_winter20191228_jaws-ug_okayama-2019_winter
20191228_jaws-ug_okayama-2019_winterTakeshi Furusato
 
FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術dena_study
 
Introduction to JIT Compiler in JVM
Introduction to JIT Compiler in JVMIntroduction to JIT Compiler in JVM
Introduction to JIT Compiler in JVMKoichi Sakata
 

Similar to Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例 (20)

Unification of the middle scale services by Nuxt.js
Unification of the middle scale services by Nuxt.jsUnification of the middle scale services by Nuxt.js
Unification of the middle scale services by Nuxt.js
 
Apache CloudStack コントリビューション
Apache CloudStack コントリビューションApache CloudStack コントリビューション
Apache CloudStack コントリビューション
 
東京Node学園 今できる通信高速化にトライしてみた
東京Node学園 今できる通信高速化にトライしてみた東京Node学園 今できる通信高速化にトライしてみた
東京Node学園 今できる通信高速化にトライしてみた
 
Spring I/O 2016 報告 Test / Cloud / Other Popular Sessions
Spring I/O 2016 報告 Test / Cloud / Other Popular SessionsSpring I/O 2016 報告 Test / Cloud / Other Popular Sessions
Spring I/O 2016 報告 Test / Cloud / Other Popular Sessions
 
Storm の新機能について @HSCR #hadoopreading
Storm の新機能について @HSCR #hadoopreadingStorm の新機能について @HSCR #hadoopreading
Storm の新機能について @HSCR #hadoopreading
 
Android 開発を加速するオープンソースライブラリ
Android 開発を加速するオープンソースライブラリAndroid 開発を加速するオープンソースライブラリ
Android 開発を加速するオープンソースライブラリ
 
HDFSのスケーラビリティの限界を突破するためのさまざまな取り組み | Hadoop / Spark Conference Japan 2019 #hc...
HDFSのスケーラビリティの限界を突破するためのさまざまな取り組み | Hadoop / Spark Conference Japan 2019  #hc...HDFSのスケーラビリティの限界を突破するためのさまざまな取り組み | Hadoop / Spark Conference Japan 2019  #hc...
HDFSのスケーラビリティの限界を突破するためのさまざまな取り組み | Hadoop / Spark Conference Japan 2019 #hc...
 
現場のインフラエンジニアから見たヤフー #ヤフー名古屋
現場のインフラエンジニアから見たヤフー #ヤフー名古屋現場のインフラエンジニアから見たヤフー #ヤフー名古屋
現場のインフラエンジニアから見たヤフー #ヤフー名古屋
 
XPagesDay 2015 RESTの総復習
XPagesDay 2015 RESTの総復習XPagesDay 2015 RESTの総復習
XPagesDay 2015 RESTの総復習
 
AI分野におけるコンテナオーケストレーションとは
AI分野におけるコンテナオーケストレーションとはAI分野におけるコンテナオーケストレーションとは
AI分野におけるコンテナオーケストレーションとは
 
Tokyo H2O.ai Meetup#2 by Iida
Tokyo H2O.ai Meetup#2 by IidaTokyo H2O.ai Meetup#2 by Iida
Tokyo H2O.ai Meetup#2 by Iida
 
CRDF2011(20110225)
CRDF2011(20110225)CRDF2011(20110225)
CRDF2011(20110225)
 
ドリコムを支える課金ライブラリを支えるJenkins
ドリコムを支える課金ライブラリを支えるJenkinsドリコムを支える課金ライブラリを支えるJenkins
ドリコムを支える課金ライブラリを支えるJenkins
 
Zappa で Serverless CMS を作ってみる
Zappa で Serverless CMS を作ってみるZappa で Serverless CMS を作ってみる
Zappa で Serverless CMS を作ってみる
 
NHNグループ合同勉強会 ライブドア片野
NHNグループ合同勉強会 ライブドア片野NHNグループ合同勉強会 ライブドア片野
NHNグループ合同勉強会 ライブドア片野
 
おすすめインフラ! for スタートアップ
おすすめインフラ! for スタートアップおすすめインフラ! for スタートアップ
おすすめインフラ! for スタートアップ
 
20191228_jaws-ug_okayama-2019_winter
20191228_jaws-ug_okayama-2019_winter20191228_jaws-ug_okayama-2019_winter
20191228_jaws-ug_okayama-2019_winter
 
ニュースアプリで起きた不具合から学んだ 最適への一歩
ニュースアプリで起きた不具合から学んだ 最適への一歩ニュースアプリで起きた不具合から学んだ 最適への一歩
ニュースアプリで起きた不具合から学んだ 最適への一歩
 
FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術
 
Introduction to JIT Compiler in JVM
Introduction to JIT Compiler in JVMIntroduction to JIT Compiler in JVM
Introduction to JIT Compiler in JVM
 

More from Yahoo!デベロッパーネットワーク

ヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるかヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるかYahoo!デベロッパーネットワーク
 
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2Yahoo!デベロッパーネットワーク
 
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtcヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtcYahoo!デベロッパーネットワーク
 
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtcYahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtcYahoo!デベロッパーネットワーク
 
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtcヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtcYahoo!デベロッパーネットワーク
 
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtcYahoo!デベロッパーネットワーク
 
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtcPC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtcYahoo!デベロッパーネットワーク
 
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtcモブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtcYahoo!デベロッパーネットワーク
 
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtcユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtcYahoo!デベロッパーネットワーク
 

More from Yahoo!デベロッパーネットワーク (20)

ゼロから始める転移学習
ゼロから始める転移学習ゼロから始める転移学習
ゼロから始める転移学習
 
継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator
 
ヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるかヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるか
 
オンプレML基盤on Kubernetes パネルディスカッション
オンプレML基盤on Kubernetes パネルディスカッションオンプレML基盤on Kubernetes パネルディスカッション
オンプレML基盤on Kubernetes パネルディスカッション
 
LakeTahoe
LakeTahoeLakeTahoe
LakeTahoe
 
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
 
Persistent-memory-native Database High-availability Feature
Persistent-memory-native Database High-availability FeaturePersistent-memory-native Database High-availability Feature
Persistent-memory-native Database High-availability Feature
 
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
 
eコマースと実店舗の相互利益を目指したデザイン #yjtc
eコマースと実店舗の相互利益を目指したデザイン #yjtceコマースと実店舗の相互利益を目指したデザイン #yjtc
eコマースと実店舗の相互利益を目指したデザイン #yjtc
 
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtcヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
 
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtcYahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
 
ビッグデータから人々のムードを捉える #yjtc
ビッグデータから人々のムードを捉える #yjtcビッグデータから人々のムードを捉える #yjtc
ビッグデータから人々のムードを捉える #yjtc
 
サイエンス領域におけるMLOpsの取り組み #yjtc
サイエンス領域におけるMLOpsの取り組み #yjtcサイエンス領域におけるMLOpsの取り組み #yjtc
サイエンス領域におけるMLOpsの取り組み #yjtc
 
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtcヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
 
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtcYahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
 
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
 
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtcPC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
 
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtcモブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
 
「新しいおうち探し」のためのAIアシスト検索 #yjtc
「新しいおうち探し」のためのAIアシスト検索 #yjtc「新しいおうち探し」のためのAIアシスト検索 #yjtc
「新しいおうち探し」のためのAIアシスト検索 #yjtc
 
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtcユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
 

Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例

  • 1. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 2019/03/12 矢端 喜楽 後藤 Yahoo!ニュースにおける BFFパフォーマンス チューニング事例
  • 2. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 自己紹介 矢端 智光 2012新卒からニュースを担当。アプリの新規開発やスピーカー開発を経て今に至る。 AndroidやSpring BootでJavaばかり触っていたが、今期からScriptがついた。はじめてのwebページ新規開発。 noimage noimage noimage 喜楽 智規 (@gladenjoy) 2016新卒からニュース一筋約3年。PHP→Java→TypeScriptと渡り歩いて来た。フロントエンド・BFFあたりの開発に従事。 後藤 拓実(@oTheRwoRldy) 2012新卒からニュースを担当。フロントエンド技術、API設計、アプリケーションのアーキテクチャに興味。TL。 2
  • 3. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 今日の内容 Node.js経験の浅いメンバーによるパフォーマンス改善のお話 3
  • 4. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 本題
  • 5. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 開発したWebアプリケーションの概要 名称:NewsWeb news.yahoo.co.jp配下の一部ページを担うWebアプリケーションです。 キーワード Node.js / TypeScript / React / Redux / Express / InversifyJS / axios / Storybook / Backend for Frontend / Server Side Rendering / Layered Architecture 実行環境 Pivotal Cloud Foundry(Private PaaS) 開発メンバー 10名弱 東京拠点と九州拠点のメンバーで開発を行っています 補足 Javaで一度書いた後、SSRの課題が出てきたのでNode.jsに置き換えています 5
  • 6. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. アプリケーションの概要図 NewsWeb 記事サービス ランキング サービス トピックス サービス お知らせ サービス … Edge Server Redis Cluster ※省略していますが、Edge Serverの後ろには他にもフロントエンドサーバがあります。 段階的にページを移行しており、現時点でYahoo! ニュースの全リクエストを新システムが担っているわけではないです。 旧システム 6
  • 7. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. パフォーマンスに関する要件 秒間リクエスト数 - 4000req/s以上 レスポンスタイム - 99パーセンタイル値が1秒以下 - 80パーセンタイル値が0.5秒以下 現行のシステムの性能をベースにした要件で、概ね上記を満たしたい。 7
  • 8. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ベンチマークを取るツール Apache Bench(ab)を利用 Apache HTTP Serverに付属するベンチマークツール yumなどでhttpdをインストールするか、apr-utilパッケージを入れることで利用できます。 ※今回はabを使いましたが、abでなければいけない理由は特にありません。 $ sudo yum install httpd $ sudo yum install apr-util 8
  • 9. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ベンチマークをとるときの構成 9 NewsWeb 記事サービス ランキング サービス トピックス サービス お知らせ サービス … ベンチ用 仮想サーバ Redis Cluster - 本番相当の環境に1インスタンス用意 - ベンチマーク用のVMからabを実行 すべてローカル環境で実行する方法もあるが 今回はこの方法でベンチマークを実施した。 Wi-Fiなどネットワークがボトルネックになる ことがあるので注意する。
  • 10. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ベンチマークの手順 並列数を増加させながら秒間リクエスト数が頭打ちになる箇所を探る 10 $ ab -t 30 -c 5 -k http://dummy-domain.yahoo.co.jp/ $ ab -t 30 -c 10 -k http://dummy-domain.yahoo.co.jp/ $ ab -t 30 -c 15 -k http://dummy-domain.yahoo.co.jp/ $ ab -t 30 -c 20 -k http://dummy-domain.yahoo.co.jp/ $ ab -t 30 -c 25 -k http://dummy-domain.yahoo.co.jp/ -k: Keep Alive有効 -t: ベンチマークの実行時間(sec) -c: 並列アクセス数
  • 11. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ベンチマークの結果(改善前) 0 5 10 15 20 25 30 5 10 15 20 25 30 35 40 45 50 秒間リクエスト数 並列数 並列数毎の秒間リクエスト数の推移 改善前 11
  • 12. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ベンチマークの結果(改善前) 12
  • 13. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ベンチマークの結果 想像以上にパフォーマンスが良くない - 秒間リクエスト数は23req/s程度で頭打ち - レスポンスタイムも並列数に比例してあがっていく 多数のインスタンスを並べれば要件は満たせるが… 何らかのボトルネックがありそうな気がする。 13
  • 14. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. さてどうしよう
  • 15. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 先入観 「SSR時のrenderToNodeStreamが重いのかなと思っています」 「SSR自体重いと聞きますし、確かに怪しそうですね」 喜楽 後藤 15
  • 16. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. まずはボトルネックを特定したい - 地道にconsole.time, console.timeEndを仕込む? - sjspのようなプロファイリングコードを挿入してくれるツールを使う? - functionの実行時間と実行回数が出力できる - nodeの—profオプションを使う? - ちょっと調べた感じ難しそう… 16
  • 17. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. Nodeサポートチームに相談 「ボトルネック特定するベストプラクティスを教えてほしいです」 「まずは profile を取ることからだと思います」 後藤 Nodeサポート 17
  • 18. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. プロファイルをとる? Node.js (V8)に備わっているプロファイリング機能がある --profオプションを指定してアプリケーションサーバを起動すると isolate-0xnnnnnnnnnnnn-v8.logというファイルにログが出力される このファイルにnode --process-profを適用することで読める形に変換される Easy profiling for Node.js Applications | Node.js https://nodejs.org/en/docs/guides/simple-profiling/ $ node —prof index.js $ node —process-prof isolate-0xnnnnnnnnnnnn-v8.log > result.txt 18
  • 19. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. プロファイル結果の見方 プロファイル結果はいくつかのセクションに分かれているが、 まずはSummaryセクションを確認する。 今回の場合、C++ のCPU Timeが多いことがわかる [Summary]: ticks total nonlib name 186 9.2% 9.3% JavaScript 1788 88.5% 89.8% C++ 39 1.9% 2.0% GC 29 1.4% Shared libraries 18 0.9% Unaccounted 19
  • 20. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. プロファイル結果の見方 [C++]: ticks total nonlib name 453 22.4% 22.7% t node::fs::Open(v8::FunctionCallbackInfo<v8::Value> const&) 379 18.8% 19.0% T node::contextify::ContextifyScript::New(v8::FunctionCallbackInfo<v8::Value> const&) 90 4.5% 4.5% t node::fs::InternalModuleReadJSON(v8::FunctionCallbackInfo<v8::Value> const&) 85 4.2% 4.3% t node::fs::Read(v8::FunctionCallbackInfo<v8::Value> const&) C++の処理の内訳を確認すると、File関連の処理が重そう 20
  • 21. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. プロファイル結果の見方 [Bottom up (heavy) profile]: ticks parent name 453 22.4% t node::fs::Open(v8::FunctionCallbackInfo<v8::Value> const&) 453 100.0% T v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) 453 100.0% LazyCompile: ~openSync fs.js:429:18 453 100.0% LazyCompile: ~readFileSync fs.js:341:22 Bottom upの項目を確認すると、readFileSyncが重そう 21
  • 22. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ボトルネックの可視化 重い箇所のあたりはついてきた。 ボトルネックをコードレベルで特定するのに以下のツールを使う。 - flamebearer - node --inspect 22
  • 23. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. flamebearerによる可視化 プロファイルログをフレームグラフで表示してくれるツール $ node --prof-process --preprocess -j isolate*.log | flamebearer 23
  • 24. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. flamebearerによる可視化 パスを一部を指定するとハイライト表示してくれる(緑色の部分) 24
  • 25. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. node —inspect --inspectを付けてnodeを立ち上げることで、Chromeと連携してデバッグが可能 起動後、chrome://inspect/ を開くと 実行中のプロセスにアタッチできる $ node —inspect dist/index.js Debugger listening on ws://127.0.0.1:9229/0dbdaf5f-7012-4ad0-8693-4af2906a9fb7 For help, see: https://nodejs.org/en/docs/inspector 25
  • 26. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. node —inspect Chart表示が視覚的に時間がかかっている箇所を特定しやすくおすすめ 26
  • 27. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. わかったこと JSON.parseの頻繁な呼び出しがボトルネックになっていた - axios-cache-adapterのキャッシュ結果が文字列で保持されており、 キャッシュ取得時はJSON.parseしていた - JSON.parseは同期処理なためボトルネックに Intl.DateTimeFormatがボトルネックになっていた - 社内製ライブラリで使われていた DIコンテナからインスタンスを取り出すとき毎回constructorが呼ばれていた - constructor内でreadFileSyncがあった - Spring Bootの経験からデフォルトがシングルトンだと思い込んでいた 27
  • 28. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. それぞれ対応
  • 29. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 改善1:axiosのキャッシュパフォーマンス改善 課題 axios-cache-adapterのキャッシュ結果が文字列で保持されており、 キャッシュ取得時は毎回JSON.parseしていた。 NewsWebではバックエンドAPIの数が多く、また、 JSON.parseは同期処理なためボトルネックになっていた。 対応 axiosのキャッシュアダプタを自作。 JSON(文字列)ではなくオブジェクトをキャッシュして返すように変更した。 ※ボトルネック解消を目的としているため、これが設計として良いかどうかは別の問題です 29
  • 30. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 改善2:社内製のライブラリの実装改善 課題 Intl.DateTimeFormatを使ったある社内ライブラリ(ExpressのMiddleware) の処理が重く、ボトルネックになっていた。 対応 ライブラリの開発者にDate.toUTCStringを使った実装へ変更してもらい、 そちらを利用するようにした。 30
  • 31. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 参考: Intl.DateTimeFormatのパフォーマンス 31 const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0)); console.time('Intl.DateTimeFormat'); for(let i = 0; i < 10000; i++) { new Intl.DateTimeFormat('en-US').format(date); } console.timeEnd('Intl.DateTimeFormat'); console.time('Date.toUTCString'); for(let i = 0; i < 10000; i++) { date.toUTCString(); } console.timeEnd('Date.toUTCString'); $ node index.js Intl.DateTimeFormat: 5991.971ms Date.toUTCString: 5.954ms 検証コード 実行結果 1万回のループで検証。1000倍近いパフォーマンスの差がありそう。
  • 32. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 改善3:DIコンテナ内のインスタンスをシングルトンに 課題 DIコンテナのインスタンスを参照する度にコンストラクタが実行されている。 コンストラクタ内でReadFileSyncするクラスがありボトルネックになっていた。 対応 コンテナにSingletonスコープでオブジェクトを登録をした。 https://github.com/inversify/InversifyJS/blob/master/wiki/scope.md // 修正前 container.bind(DISymbols.TopicsService).to(TopicsService); // 修正後 container.bind(DISymbols.TopicsService).to(TopicsService).inSingletonScope(); 32
  • 33. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 改善4:App起動時にDIコンテナのwarmup 課題 InversifyJSのコンテナからオブジェクトを取り出すとき、 コンストラクタが実行されるため、初回の呼び出しが遅い。 対応 App起動時に、コンテナに登録された全オブジェクトをgetし、 コンストラクタを実行しておく。 // 予めDI Containerのすべてを呼び出して、singletonインスタンスを初期化する // typescriptのチェックを回避するために型定義をして再代入しています const symbols: { [key: string]: symbol } = { ...DISymbols }; for (const key in symbols) { if (key) { container.get(symbols[key]); } } 33
  • 34. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. それ以外にも気づきベースで対応したこと ボトルネック調査の結果とは別に、以下の改善の実施 - Clusterモジュールの利用 - バックエンドAPIへのKeep Alive対応 34
  • 35. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 改善5:Clusterモジュールの導入 課題 Private PaaS は1インスタンスあたり8コア割り当てられていた。 Node.jsはデフォルトでは1コアしか使わないため、有効活用できていなかった。 対応 Node.jsの標準モジュールのClusterモジュールを導入した。 https://nodejs.org/api/cluster.html 35
  • 36. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. Clusterモジュールの実装 36 import cluster from 'cluster'; import express from 'express'; import os from 'os'; const port = process.env.PORT || '3000'; if (cluster.isMaster) { for (let i = 0; i < os.cpus().length; i++) { cluster.fork(); } cluster.on('exit', worker => { cluster.fork(); }); } else { const app = express(); app.listen(port); } import express from 'express'; const port = process.env.PORT || '3000'; const app = express(); app.listen(port); 導入前 導入後 得られる恩恵の割に非常に導入が容易です。
  • 37. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 補足:Clusterモジュールとnode --inspect Clusterモジュールを導入した後、node --inspectを使うと 各プロセスでデバッグ機能が有効になってしまい使い勝手が悪い 例えば、以下のように--inspectパラメータが指定されているかを判定し、 Clusterモジュールを使わずに起動できるようにしておくと捗ります。 37 const debug = /--inspect/.test(process.execArgv.join(' ')); if (debug) { // expressを起動 } else { // clusterモジュールでforkして、アプリケーションを起動 if (cluster.isMaster) { // fork... } else { // expressを起動... } }
  • 38. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 改善6:バックエンドAPIへのKeep Alive対応 課題 バックエンドAPIへのリクエスト時にKeep Aliveが有効になっていなかった。 対応 axiosに以下のように設定をしてKeep Aliveを有効化 特に、ユーザ情報を含むようなRedisにキャッシュできないAPIに対して効果 接続時のレイテンシ低減、APIサーバの負荷軽減に繋がる。 const axiosClient = axios.create({ timeout, adapter: createCacheAdapter(axios, { maxAge }), httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }) }); 38
  • 39. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 再ベンチマーク
  • 40. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 対応実施後の性能を要件毎にみていきます 以下の3パターンに分けて、再度性能評価を行いました。 - 対応前 - Clusterモジュール導入を除く改善実施後 - Clusterモジュール導入を含んだ改善実施後 40
  • 41. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 要件のおさらい 秒間リクエスト数 - 4000req/s以上 レスポンスタイム - 99パーセンタイル値が1秒以下 - 80パーセンタイル値が0.5秒以下 現行のシステムの性能をベースにした要件で、概ね上記を満たしたい。 41
  • 42. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 要件のおさらい 秒間リクエスト数 - 4000req/s以上 レスポンスタイム - 99パーセンタイル値が1秒以下 - 80パーセンタイル値が0.5秒以下 現行のシステムの性能をベースにした要件で、概ね上記を満たしたい。 👈 42
  • 43. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 秒間リクエスト数の比較 Clusterモジュールを除いた改善で1インスタンスあたり57req/sec、 Clusterモジュール導入で330req/sec程度の性能がでることがわかりました。 0 50 100 150 200 250 300 350 400 並列数ごとの秒間リクエスト数 対応前 Cluster以外の対応後 Cluster含む対応後 43
  • 44. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 改善の結果 必要インスタンス数の大幅な削減 1インスタンス あたりのreq/sec 4000 req/secに必要な インスタンス数 対応前 23 req/sec 約174 インスタンス Cluster導入前 57 req/sec 約70 インスタンス Cluster含む対応後 330 req/sec 約12 インスタンス 44
  • 45. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 要件のおさらい 秒間リクエスト数 - 4000req/s以上 レスポンスタイム - 99パーセンタイル値が1秒以下 - 80パーセンタイル値が0.5秒以下 現行のシステムの性能をベースにした要件で、概ね上記を満たしたい。 👈 45
  • 46. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 80パーセンタイル値のレスポンスタイム数の比較 Cluster以外の対応で30並列、Cluster込で200並列まで、目標値の0.5秒を満 たしていることがわかります。 46 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 80パーセンタイル値のレスポンスタイム比較 対応前 Cluster以外の対応後 Cluster含む対応後 👈
  • 47. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. 99パーセンタイル値のレスポンスタイム数の比較 Cluster以外の対応で25並列、Cluster込で200並列まで、目標値の1.0秒を満 たしていることがわかります。 47 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 99パーセンタイル値のレスポンスタイム比較 対応前 Cluster以外の対応後 Cluster含む対応後 👈
  • 48. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. まとめ - 以下のようなツールでボトルネックの調査ができる - node --prof - node –inspect - flamebearer - 想像でCPUバウンド/同期的な処理を疑うのではなく、 プロファイルを取ってボトルネック特定→改善をするのが近道 - 今後 - 継続的なパフォーマンス改善をしていきたい - 今わかっている限りだとmoment-duration-formatが重そう 48
  • 49. Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. EOP