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
990
ニジエチューニング2017-12
nijieinfra
0
2.6k
ニジエチューニング2016-12
nijieinfra
0
1k
ニジエチューニング2014-11
nijieinfra
0
430
ニジエチューニング2014-10
nijieinfra
0
510
ニジエチューニング2014-04
nijieinfra
0
360
ニジエチューニング2014-03
nijieinfra
0
610
Other Decks in Programming
See All in Programming
テーブルをDELETEした
yuzneri
0
130
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
3.9k
torikago - Ruby::Boxで照らすモジュラモノリスの実行境界
se4weed
1
330
VibeCodingからAgenticWorkflowへ
starfish719
0
220
AIエージェントで 変わるAndroid開発環境
takahirom
2
770
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
4
1.5k
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
460
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
210
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
550
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
340
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
18k
Featured
See All Featured
Visualization
eitanlees
152
17k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
420
[SF Ruby Conf 2025] Rails X
palkan
2
1.2k
Darren the Foodie - Storyboard
khoart
PRO
3
3.5k
Code Reviewing Like a Champion
maltzj
528
40k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
First, design no harm
axbom
PRO
2
1.2k
A Modern Web Designer's Workflow
chriscoyier
698
190k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
270
What does AI have to do with Human Rights?
axbom
PRO
1
2.3k
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解消 •
画像配信のトラフィック増への対策(増設予定) • バグ調査 ◦ 特に投稿関連は深刻に受け止めてます・・・