ネットワーク操作の性能最適化
2414 ワード
まず最適化前後の対比図を貼る(1月15日にオンラインを最適化し、19日に一部の細部の最適化を行った): webサーバのcpuを使用します.
webサーバのcpu使用
ウェブサーバのロード
ウェブサーバのロード
rpcの接続数(主にredisとの接続)
rpcの接続数
redisサービスのcpuは使用します.
redisサービスのcpuは使用します.
レディスがいるマシンの接続数
redisがいるマシンの接続数
現象ある製品は、いくつかの要因(運営、バージョンの更新及び体験など)によって、アクティブなユーザーと滞在時間を絶えず向上させ、さらにサーバ資源の使用を増加させ、元に設定された警報閾値が頻繁に触発され、具体的には以下のように表現される. webマシンのロードとcpuの使用が高くなりました. 依存キャッシュサービスredis接続数は、cpuと絶えず上昇している rpc(業務分離用)の接続数は に上昇しています.
どう解決しますか負荷バランス、サーバを追加します.最も簡単で乱暴で効果的な方法です. システムの性能のボトルネックを見つけて、最適化しました.これは一番経済的で挑戦的なことです. ——オンラインサービスに機能性がないことを考慮して、まず第二の方式 を試みる.
位置私の前のブログを参考にして、インターネット上の各サービス(いずれもjavaプロセス)に対してjstackを取り、stackAnalysisツールでそのボトルネックを分析してみました.多くのスレッドがredisの操作にとどまっていることが分かりました. は明らかです.redisの大量の要求はボトルネック です.
分析 stack dumpに似たstackstraceのスレッドがあり、キャッシュの動作には多くのshitの論理があることがわかった. 「同じデータを二回取る」ということです.例えば、interceptorでは同じuserオブジェクトに対して2回 上から見れば直接問題はないですが、よく分析すれば、userRpcServer.isForbidderUser(uid)の中で一回のgetsUser(id) も呼び出しられます.
「データを取っても使わない」ということです.例えば、Userオブジェクトを取得する際に、同時にその帳簿残高を取得しますが、アカウントに関する要求だけが残高を取得する必要があります.ほとんどのインターフェースは を必要としません.「キャッシュにデータがないと分かっていますが、取りに行きます.」しかし、より深く隠されているからこそ、資源の無駄遣いは容易に発見されない. 「大量にforサイクルでredisをネットワーク操作するロジックがある」というものがあります. のような論理は、できるだけ大量操作で を完成させるべきである.
はredis slow logsを分析して、その中の時間と頻繁な操作(特に削除操作)を探し出して、いくつかの最適化の空間があることを発見しました. 解決上で分析された問題に対応し、それぞれの解決策は以下の通りである. 同じデータを二回取ります.同じデータは一回だけ取ります. データを取りましたが、使わないです.使わないと を取りません.はキャッシュにデータが存在しないことを知っていますが、もう一度取りに行きます. 大量にforサイクルでredisをネットワーク操作するロジックがあります. Redisはクラスタであるため、ShardedJedPipelineを用いてバッチ要求を行う必要がある .
最適化後、アラームメッセージは完全に消えます. 最適化結果評価最適化方法を見つけ、最適化した後、それぞれの最適化に対して性能試験を行う .は各ステップの最適化に対して性能テストを行う必要があります. 思考人はいつも:1.ミスをします.2.最適な方法を選んで、現在の需要を解決します. エラーはいつも明らかに解決しやすいですが、製品の発展時間が経つにつれて、合理的なところが不合理になり、邪魔になることもあります. 現状から不合理なところを見つけ、改善していく必要があります.盲従や習慣や批判にとどまらないです.
webサーバのcpu使用
ウェブサーバのロード
rpcの接続数
redisサービスのcpuは使用します.
redisがいるマシンの接続数
どう解決しますか
位置
分析
e.g.:
User user = userRpcServer.getUser(uid);
//
boolean isForbidderUser = userRpcServer.isForbidderUser(uid);
を取得します.UserAccount userAccount = userRpcServer.getUserAccount(uid);
UserInfo userInfo = userRpcServer.getUserInfo(uid);
User user = makeUser(userAccount, userInfo);