火曜日の東京に続いて大阪にも参加です。
Tech Deep Dive #1 Revenge Edition「Javaアプリケーションのチューニングとトラブルシューティング」(3/13) - 構築中。(火曜日)
Webアプリに低レイテンシ・高可用性を求めるのは間違っているのだろうか reloaded(いとうちひろさん)
基本的には東京の初回、#0と同じ内容だったようです。スライドもほぼ#0のままでした。
#0スライド:
Webアプリに低レイテンシ・高可用性を求めるのは間違っているのだろうか
流れをざっくり箇条書きします(勝手に意訳)。
- なぜ性能と可用性が重要か→特にクラウドで、悪いコード(性能低い)を書くとコストが跳ね上がるから
- レスポンス目標値:目標値(1s以内)と実際(1s超え)の差がある
- 即時復旧と整合性:RTOとRPOの問題
- アプリとインフラは疎結合にしたい(アプリでインフラのことを考えたくない)
- ECサイトでデモ(注:リアルタイムに実行して見せるわけではない。失敗するので)
- テストケースA:複数ユーザで複数リソースを扱う→こちらのスケールは割と簡単
- テストケースB:みんなで単一リソース(特定の席とか商品とか)を取り合う→スケールしづらい
- ①データストアとしてRDBMSを使う場合:RDBMSが詰まって性能が伸びにくい
・特にBで、APサーバ/DBサーバ両方のCPUリソースをほとんど使えてない
・Bでは行ロックしている
・リソースを使いきれない=札束攻勢が使えない
- ②データストアとしてキャッシュを使う場合:Aは伸びるがBは伸びない
・RDBMSもデータはほぼメモリ上
・APサーバから見たDBアクセス時間の大半はNWの往復
・ロック待ち:何もしない(できない)
・ロックが短いとシステム性能が上がる
- ③キャッシュ(Coherence)側でIn-place処理する場合:Bも伸びる
・キャッシュ側でデータにアクセスして一連の処理を担当
・クエリ/コマンドがネットワーク上を都度往復しない
・APサーバがまとまった処理をキャッシュ側に依頼
・キャッシュ側でそれを処理して返す
・APサーバ側でキャッシュへのアクセス待ちが短くなる
・ロック時間の短縮
・APサーバ側で「スレ詰まり」が生じにくくなる
【注】「単発のクエリに長時間かかる」ことの解決策にはならない
その他、気になった話・思ったことなども箇条書きします。
- ゾンビ化など「ダメになったコネクション」に対する処理は重要(事あるごとに強調)
- あとネットワーク上の通信が処理時間全体を支配する、とも。
- アプリケーションの画面にエラーが出る→ユーザがTwitterで騒ぐ→さらに負荷ががが…
- データがないときに切り替えテストしていきなり本番投入する強者がいる→所要時間や処理の正しさ等の確認にならないので、本番(相当)のデータが入った状態でやること
- 「JDBCドライバを作ってみるとわかる」(TCPのSessionの扱いとか。また、Connection Poolingも。息をしていないConnectionの検知→生き返らせるための実装などなど)
- グラフの角度が変わるポイント=性能限界が来てるポイント(ロックの場合)
- 負荷テストでは負荷の曲線を意識して負荷を掛ける
- Bのテストをやらないことが多いので、後から問題になりやすい→やれ
- メンテのやりやすさは重要(パッチ当てとか)。メンテインのとき、瞬時に待機系に切り替わってほしい!
- Connection Pool側が、インスタンスの復旧を検知して再振り分けする仕組みが必要
- スケールイン(負荷減→規模縮小)重要。だが実装は難しい。Connectionが切れたところで停止しないといけないので(AWSのELBでいうところのDraining処理。ELBはKeepalive推奨なのでConnection Poolingと似た状況に。因みにALBではDrainingが完璧には処理できず、一部のConnectionがタイムアウト前に切られてしまうが、これは仕様なのでどうしようもないとのこと)
- キャッシュ・インメモリDBの類は新しそうに見えるが、歴史はJavaとそれほど変わらない(それなりに枯れてる)
- 90%tile、99%tileでどのくらいまで処理できてる?は重要
- 「ダメになったコネクション」「ネットワーク通信が処理時間全体を支配」の2点については、オンプレからパブリッククラウドに移ってきたときに苦労したポイントなので、強く同意
- レスポンスタイムの目標値は、すべての機能(画面)共通で考えられるとシンプルな運用ができるけど、現実的に考えると「普通の画面」と「時間が掛かる画面」(集計・分析処理など)で分けて対処することになりそう。その場合、後者のスレッドが前者をブロックしないように工夫する必要がある
- 「どのレベルで対応するか」は場合によるので、何が何でもエラー回避を目指す、というのは必要がないことも多い。割り切りも必要。但し、割り切ったがゆえに人のコスト(対応の手間)が雪だるま式に増えるのだけは避けたほうが良い。「運用でカバー」はNG
- 途中で↓をTweetしたけど、これはConnectionがリークしてPoolに戻らない状況ではなくて、Poolの管理そのもののオーバーヘッドが大きくて(DBへの接続とQuery送信→DB側で処理→ResultSet受信の時間以外にも、Pool内のConnectionをロックしている時間が長くて)詰まった、という話
DBのせいだと思ったら、APのConnection Poolingが詰まってたことがある。 #oratdd
— hmatsu47 (@hmatsu47) 2018年3月17日
- 会場内で、どこからともなくインメモリ・データ・グリッドとAuroraを比較検証していたような話が聞こえてきたが、Auroraはクラスタ内のリードレプリカへの振り分けをちゃんと考えないといけない用途ではその部分を自前調達しないといけない(MySQL向けのProxy類とは仕様上相性が良くない)のと、インスタンスがコケた(or メンテで再起動した)後復活してきたときにバッファキャッシュのウォームアップなどの手当てをしてくれない点で、そもそもインメモリ系と比較する対象ではない気がする(AWSの「売り方」が誤解を招いている気が…で、よくわからないままSIerさんに調査を投げるクライアントが…)
もしもみなみんがアプリケーション開発者だったら(みなみんさん)
タイトルで内容を勘違いしていましたが、一言でいうと「(WebLogic Serverとの組み合わせで)Oracle RACを採用すると、これだけ手厚く備えて/やってくれるよ」という話でした。
確かに、OSS等を組み合わせて性能と可用性が高いシステムを組もうとすると「DBAの職人芸」が必要ですが、それができる人は限られるため、最近のパブリッククラウドでも「メンテフリー」を意識したマネージドRDBMSサービスを推しているケースが多いですね(サービスごとに「フリー」のレベルの差がありますが)。
正直、RACを易々と採用できる状況ではないですが、今回の話を参考にして、他サービス(AzureのSQL Databaseなど)の方向性などと比較しつつ、同じ「メンテフリー」でも具体的にどの分野で「フリー」になっていくのか、トレンドを追っていきたいと思います。
全体を通して感じたことは(本題とは全く関係ありませんが)、
- 近い世界にいても文化の違いがある
- 東京とは反応がかなり違ったと思う(推測)
- ポジショントークとはちょっと違うけれど、文化の微妙な違いによる「常識」や「行間にあるコンテキスト」の違いが感じられるのが面白い(スピーカー・オーディエンスの両方で)
- PHP勢・Ruby(Rails)勢とも違うのは当然として、同じJava使いでもコミュニティごとに違いが感じられるし、Oracle/MySQLでも結構違う
でした。
いろんなところに出掛けて行って、それぞれの違いを楽しむのもいいかも?