Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
ニジエチューニング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
1k
ニジエチューニング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
370
ニジエチューニング2014-03
nijieinfra
0
610
Other Decks in Programming
See All in Programming
Java 27新機能 / Java 27 new features
kishida
2
150
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
140
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
240
cdk deploy JawsSonic #MARATHONしながらAWSリソースをデプロイしてみよう
akihisaikeda
2
130
Webの地図
yosuke_furukawa
PRO
6
4.6k
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
480
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
160
Are APIs Still Relevant in the AI Era?
soyuka
0
230
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
120
AHC070解法紹介
eijirou
0
120
Heart of Swift Concurrency
koher
0
880
AI活用は、個人から組織へ|マルチプレイヤーエージェントハーネス「QM」の社内活用事例 / AI use is moving from individuals to orgs
rkaga
1
110
Featured
See All Featured
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
600
The Invisible Side of Design
smashingmag
301
52k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Building Adaptive Systems
keathley
44
3.2k
エンジニアに許された特別な時間の終わり
watany
109
250k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Making Projects Easy
brettharned
120
6.8k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Design in an AI World
tapps
1
320
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解消 •
画像配信のトラフィック増への対策(増設予定) • バグ調査 ◦ 特に投稿関連は深刻に受け止めてます・・・