Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ニジエチューニング2014-12
Search
ニジエインフラ
December 27, 2014
Programming
680
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ニジエチューニング2014-12
ニジエインフラ
December 27, 2014
More Decks by ニジエインフラ
See All by ニジエインフラ
ニジエチューニング2023-12
nijieinfra
0
980
ニジエチューニング2017-12
nijieinfra
0
2.6k
ニジエチューニング2016-12
nijieinfra
0
1k
ニジエチューニング2014-11
nijieinfra
0
420
ニジエチューニング2014-10
nijieinfra
0
510
ニジエチューニング2014-04
nijieinfra
0
360
ニジエチューニング2014-03
nijieinfra
0
600
Other Decks in Programming
See All in Programming
net-httpのHTTP/2対応について
naruse
0
490
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
140
Oxlintのカスタムルールの現況
syumai
6
1.1k
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.1k
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
130
Claspは野良GASの夢をみるか
takter00
0
190
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
190
AIで効率化できた業務・日常
ochtum
0
140
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
1
240
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
580
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.7k
RTSPクライアントを自作してみた話
simotin13
0
610
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Six Lessons from altMBA
skipperchong
29
4.3k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
390
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
290
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Navigating Weather and Climate Data
rabernat
0
220
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
410
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.5k
How to make the Groovebox
asonas
2
2.2k
Optimizing for Happiness
mojombo
378
71k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
Transcript
ニジエチューニング12月 2014/12/27 インフラボランティア:
あんただれ • 名前 ◦ ٩( )( )۶とか₍₍⁽⁽(◌ી( ・◡・ )ʃ)とか ◦
匿名ボードだとインちゃんと呼ばれてる • インフラ・バックエンドのボランティアスタッフです • 2014/03/18にJoin • 最近ニジエオフィスで絵を教えてもらいました ◦ みんなうまくてやばい • 誕生月でした TwitterID作ったんでフォローしてね!@nijieinfra
DKIM対応 40分後 さらに2時間後 改善ネタをチャットで話してた時に
DKIM対応 ごめんやんのフットワークは神 多分更に迷惑メールにされる可能性は低くなるんじゃないかなと・・( SPFは以前から対応済)
ニジエサーバの村に◦◦が攻めこんでくるなんて・・・
!? 同時間帯
フィルタ来襲
フィルタ機能リリース
フィルタ機能リリース • 土曜の夜にDB負荷が上がって気づいた ◦ 遅延も発生 • gwの負荷も増えており新機能のフィルタを疑う Master Slave Standby
フィルタ機能リリース • 土曜の夜にDB負荷が上がって気づいた ◦ 遅延も発生 • gwの負荷も増えており新機能のフィルタを疑う • 実はフィルタは全く関係なかった ◦
DBのレプリケーションはSBRで行っていた ◦ 臨時で動いていたbatchがinsertで 非常に重いselectのサブクエリを発行していた ▪ slave/standbyで重いselectを評価していた • 遅延の原因 • 止めてもらった Master Slave Standby まぁこれはおいておいて・・・
フィルタ機能リリース • とりあえずせっかくの新機能だしもうちょい快適に見れるようにしよう ◦ ついでに実トラフィックも下げよう ◦ 今まで小さめにしていたサイトの静的ファイルのTTLを ユーザの滞在時間を参考に引き上げ ▪ cache-controlで同時にブラウザキャッシュも強化
◦ 投稿画像はもともと長い+切り離されているので関係なし • wsのリクエスト数を減らそう ◦ 結構ESIのリクエストが多い ◦ 既にmemoryは使いきってる ◦ じゃぁfileに突っ込もう 実はこのへんから対策してたけど焼け石に水
ニジエのVarnishキャッシュポリシー • nukeするとシステムの速度が落ちる+高速である必要があるもの(pri=1) ◦ css/js ◦ 共通系のESI • 多少遅くても問題ないができれば落としたくないもの(pri=2) ◦
css/js以外の静的ファイル ◦ 閲覧ページのリコメンドやプロファイルのESI等 • ヒットレートがさほど見込めないが高コストのためキャッシュしたいもの(pri=3) ◦ 自由記入が出来る検索系のESI等 pri=1 pri=3 pri=2 多くのページで使われる その人の絵を見る際に必 ず使われる 自由文検索だしHITすれ ば儲けモンぐらいの感覚
フィルタ機能リリース • とある大きめのESI要素をmemory→fileに変更 • 当然ながらio負荷は上がるが許容範囲内 ◦ memoryのnukeがだいぶ収まった・・・ ◦ が全部収まっていない •
これで様子見するかなー・・・ この辺りで 変更
あぶない!
純粋にヤバイ刺さり方 • 何かしらのリソース不足でピーク時に刺さっているがどれが足りていないか 見えてない状態 • Twitterで「ニジエ 重い」で調べると大変心が痛む • 対策としては ◦ とりあえずリクエスト数を減らす
▪ キャッシュ強化 ◦ 計測ツールを強化 ▪ プロファイラ投入しての改善
とはいえキャッシュしたいがリソースはない • ESIを行っているgwサーバのリソース状況 ◦ ディスクの使用率は89% ◦ メモリは当然足りない ◦ CPUはwioに既に結構持ってかれてる ▪
user/sysは大したこと無いけど・・・ ▪ SSDにしたとはいえやはりキャッシュサイズ大きいとね・・・ ▪ varnishplusとかあるけどお金ないよ! • 増やすしか無いかなー・・・
wsリソース memory空いてる disk空いてる CPU空いてる めっちゃ空いてるよ!
多段化計画 • wsはCPUバウンドでメモリ・ioは比較的余裕があるのでそこも使ってしまおう計画 • じゃぁwsでもvarnish動かしてあふれた分を吸収しよう • そのうちgwは冗長構成取るつもりだったんだし早目に多段にしとけばいいよね ◦ gwは現在シングルポイント ◦
とはいえ増やすとシステム負荷が増大する ▪ 重複リクエスト問題 ▪ 動的生成のキャッシュ不整合問題 ▪ 多段にすると解決できるよ
重複リクエスト問題 • すごく単純な話でランダムアクセスされる 1段目を増やすとwsへ行くリクエストが増大する ◦ 最悪値は単純にgwの台数に比例する ws1 ws2 ws3 gw
ws1 ws2 gw ws3 gw file=Aをリクエスト ここでキャッシュされるので 3reqされてもwsに行くのは1req file=Aをリクエスト gwが2台のため重複リクエストが発生 どのgwかはDNSによる (インフラからすると実質ランダム) じゃぁ交通整理(=hash)をしてあげれば良い
重複リクエスト問題 • どのオブジェクトをリクエストしているかという情報をハッシュ化する ◦ 代表的な値はホスト名・URLで場合 ◦ 上記で足りないケースもあって同一URLでPC/SPで異なるオブジェクトを帰す場合は その情報もハッシュに含める必要がある • 1段目はランダムでリクエストされるので、1段目→2段目の際にハッシュに基づいて振り分けをする
◦ 考え的には剰余を取ってその余りで振り分けを決める • 障害時も有利 ◦ gwが1台死んでもcacheが保持しているし逆にcacheが死んでもgwが保持している • キャッシュサイズが増える ◦ ハッシュ分散なので同一階層では同オブジェクトを持たない ◦ つまり同一階層のノードのキャッシュサイズを足したサイズになる • デメリットもなくはない ◦ 一番大きいのはサーバを経由することによるlatencyの増大 ◦ 今回は同一サーバに立てるので少ない ws1 ws2 cache ws3 cache hash振り分けで同一 Objectの場合 は同じサーバを経由する gw gw 結果重複リクエストが発生しない
本当にハッシュでいいのか?
• すべてのリクエストがキャッシュ可能な場合はハッシュは非常に効果的(画像など静的コンテンツ) • しかし動的コンテンツの場合はすべてをキャッシュ出来るわけではない • キャッシュが出来ないページかつ同一ハッシュ(同じ URL等)のものは? ◦ 同一ハッシュだと常に同じサーバに振り分けられる ◦
負荷が寄ってしまう ▪ システムの負荷耐性が低くなる(!) gw多段化計画 ハッシュ振り分けするときは寄らないか注意深く考える必要がある
• ではどうしたかというとすごく単純 ◦ ハッシュ振り分け ▪ キャッシュするもの ◦ ランダム振り分け ▪ キャッシュしないもの
gw多段化計画 Varnishはこういう振り分けも簡単
TTLも注意が必要
動的生成のキャッシュ不整合問題 • 例えばとあるページの TTL=60秒とした場合で10秒毎にリクエストが来た場合 ◦ gw1にreq、ws1までreqが行き経由したcache1とgw1にオブジェクトがキャッシュされる ◦ 10秒後にgw2にreq、cache1のキャッシュを使用。 gw2はcache1のオブジェクトをキャッシュする •
ここで問題なのがgwXがcacheXでの経過時間(Age)をきちんと減算しているかということ ◦ gw2は10秒たったcache1のオブジェクトを使っているので TTL50秒のでなくてはならない • 静的コンテンツの場合はさほど問題にならないが動的コンテンツの場合は問題が起きてくる ◦ リロードしてリクエストする gwが変わるたびに違う結果がかえってくる可能性がある • つまり同一ハッシュのオブジェクトが消えるタイミングは同じでなくてはならない ws1 ws2 cache2 ws3 cache1 gw1 gw2
多段でのTTLの罠 • TTLを多段環境で同一にした場合に 1段目で場合によってはキャッシュされないことが起こりうる ◦ 1段目がnukeしまくってる ◦ 1段目が障害などでキャッシュが飛んだ • 要は2段目のキャッシュが使われる状況になると
Age分TTLが減る ◦ ある程度のところで均衡するケースもあるが最悪の場合はほぼ 2段目のキャッシュを使う ◦ ハッシュ分散しているためストレージサイズが 2段目>1段目になるのでなりやすい ◦ ESIを使っている場合だと合成を行う Varnishでキャッシュをなるだけ保持したいので痛い • 解決方法は状況によっていくつかあるが今回の場合は 2段目のTTLを短くしてgraceを長めにした ◦ こんな感じ set beresp.ttl = std.duration(req.http.******,10s) / 2;
結果 nuke自体がなくなった!
更なるキャッシュへ • 今までVarnishでは「すべてのユーザ」で「同じオブジェクト」を返すものをキャッシュしていた • つまり「ユーザ毎」のキャッシュは行っていなかった • 技術的な問題というより安全側に倒すというのと他に効果があるところがあったため • キャッシュで一番怖いのがハッシュ混じりで、本来ユーザ毎のオブジェクトをすべてのユーザで共有し てしまうと当然ながら他人のデータが見えたり酷いことになる
• 今回は比較的安全な方法でキャッシュを行うようにした ◦ 「すべてのユーザ」向けのリクエスト時はユーザーを特定できる情報を削除する(前からしてた) ◦ 特定のディレクトリ以下にあるときのみ「ユーザ毎」でのキャッシュを行うようにした ▪ このディレクトリ以下みたいな決めはわかりやすくミスしづらい ◦ 「ユーザ毎」のURLへアクセスがあってユーザを特定出来ない場合はキャッシュしない ◦ などのいくつか対策をやった
結果 軽くなった! 昔自分のTopは 2秒ぐらいかかってたような・・
• とりあえずxhprofを入れた • コードの問題となる箇所(呼び出しすぎとか重いとか)が視覚的にわかるので改善しやすい ◦ ごめんやんが速攻コード改善した プロファイラ投入 めっちゃCPU負荷減った 当然ながら計測と見える化は大事 そしてごめんやんの改善は速い・・
問題箇所の特定
プロファイラ投入 • そしてピーク時に重い関数を特定 ◦ mcryptだった! • 要はエントロピーの枯渇 ◦ 物理マシンの場合は対して問題にならないが VMの場合は枯渇しやすい
◦ 正直これ失念してたスマンカッタ • jump.phpで使う飛び先URLを暗号化していた ◦ そのためview.php / members.phpでエントロピー枯渇で刺さってしまった • 別に暗号化必要ないロジックだったので使わないように変更 ◦ 他の対策法もあるけど・・
結果 改善 わかりづらいけど緑の部分 (busy)が 無くなってるのがわかる 当然ながら速度も改善!
対策の8時間後ぐらいに・・ ツール来襲、しかし遅延なく耐えた 各種対策していなかったら間違いなく刺さった めっちゃ迷惑なので rate-limit入れます
ツールにも耐えたしコスト減らそう
2015/01のサーバ費用予定 • 2014/09比で29.4%のサーバ費用減の見込 • 2014/12比で11.1% • もうちょい絞れる • 一応、PVは落ちてるわけではないのでサービスシュリンクからの削減ではないです
まとめとか今後とか • 構成管理 • ミドルウェアバージョンアップによるパフォーマンスアップ • rate-limitいれてく • gwのspof解消 •
画像配信のトラフィック増への対策(増設予定) • バグ調査 ◦ 特に投稿関連は深刻に受け止めてます・・・